Dev #7
@@ -1240,9 +1240,12 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
{/* View Grouping Selector */}
|
{/* View Grouping Selector */}
|
||||||
<div className="flex rounded-btn bg-panel p-0.5 border border-border">
|
<div className="flex items-center rounded-btn bg-panel p-0.5 border border-border shadow-xs">
|
||||||
|
<span className="text-[10px] uppercase font-bold text-faint px-1.5 hidden sm:inline">
|
||||||
|
Ansicht:
|
||||||
|
</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -1254,11 +1257,12 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
? 'bg-panel-elevated text-main shadow-xs'
|
? 'bg-panel-elevated text-main shadow-xs'
|
||||||
: 'text-muted hover:text-main'
|
: 'text-muted hover:text-main'
|
||||||
}`}
|
}`}
|
||||||
title="Gruppieren nach Ordner und Notiz"
|
title="Erst nach Ordner, dann nach Notiz gruppieren"
|
||||||
>
|
>
|
||||||
<Folder className="w-3 h-3 text-accent" />
|
<Folder className="w-3 h-3 text-accent" />
|
||||||
<span>+</span>
|
<span>+</span>
|
||||||
<FileText className="w-3 h-3 text-accent" />
|
<FileText className="w-3 h-3 text-accent" />
|
||||||
|
<span>Ordner & Notiz</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1488,76 +1492,100 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
<div className="p-2 space-y-3">
|
<div className="p-2 space-y-3">
|
||||||
{Array.from(docGroupsMap.values()).map(({ doc, items: docItems }) => {
|
{Array.from(docGroupsMap.values()).map(({ doc, items: docItems }) => {
|
||||||
const docOpenCount = docItems.filter((i) => !i.checked).length;
|
const docOpenCount = docItems.filter((i) => !i.checked).length;
|
||||||
|
const isDocCollapsed = collapsedTodoNotes.has(doc.id);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={doc.id}
|
key={doc.id}
|
||||||
className="border border-border/60 rounded-btn p-2 bg-panel-elevated/30 space-y-1.5"
|
className="border border-border/60 rounded-btn p-2 bg-panel-elevated/30 space-y-1.5"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between pb-1 border-b border-border/40">
|
<div className="flex items-center justify-between pb-1 border-b border-border/40">
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setCollapsedTodoNotes((prev) => {
|
||||||
|
const next = new Set(prev);
|
||||||
|
if (next.has(doc.id)) next.delete(doc.id);
|
||||||
|
else next.add(doc.id);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="flex items-center gap-1.5 text-xs font-semibold text-main hover:text-accent cursor-pointer select-none"
|
||||||
|
>
|
||||||
|
{isDocCollapsed ? (
|
||||||
|
<ChevronRight className="w-3 h-3 text-faint" />
|
||||||
|
) : (
|
||||||
|
<ChevronDown className="w-3 h-3 text-accent" />
|
||||||
|
)}
|
||||||
|
<span>{doc.icon || '📝'}</span>
|
||||||
|
<span>{doc.title}</span>
|
||||||
|
<span className="badge-neutral text-[9px] font-mono">
|
||||||
|
{docOpenCount} offen
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleJumpToDocBlock(doc.id)}
|
onClick={() => handleJumpToDocBlock(doc.id)}
|
||||||
className="flex items-center gap-1.5 text-xs font-semibold text-accent hover:underline cursor-pointer"
|
className="text-[10px] text-accent hover:underline px-1.5 py-0.5 rounded-btn hover:bg-canvas cursor-pointer flex items-center gap-1"
|
||||||
|
title="Notiz öffnen"
|
||||||
>
|
>
|
||||||
<span>{doc.icon || '📝'}</span>
|
<span>Notiz öffnen</span>
|
||||||
<span>{doc.title}</span>
|
<ExternalLink className="w-2.5 h-2.5" />
|
||||||
<span className="badge-neutral text-[9px]">
|
|
||||||
{docOpenCount} offen
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-0.5">
|
{!isDocCollapsed && (
|
||||||
{docItems.map((item) => (
|
<div className="space-y-0.5">
|
||||||
<div
|
{docItems.map((item) => (
|
||||||
key={`${item.doc.id}-${item.blockId}`}
|
<div
|
||||||
className="flex items-center justify-between gap-2 p-1 rounded-btn hover:bg-canvas text-xs transition-colors group cursor-pointer"
|
key={`${item.doc.id}-${item.blockId}`}
|
||||||
>
|
className="flex items-center justify-between gap-2 p-1 rounded-btn hover:bg-canvas text-xs transition-colors group cursor-pointer"
|
||||||
<div className="flex items-center gap-2 min-w-0 flex-1">
|
>
|
||||||
|
<div className="flex items-center gap-2 min-w-0 flex-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleToggleRollupTodo(
|
||||||
|
item.doc,
|
||||||
|
item.blockId,
|
||||||
|
item.checked
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
className={`w-3.5 h-3.5 checkbox-square flex items-center justify-center transition-colors border cursor-pointer ${
|
||||||
|
item.checked
|
||||||
|
? 'bg-status-ok border-status-ok text-on-accent'
|
||||||
|
: 'border-strong hover:border-accent text-transparent'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Check className="w-2.5 h-2.5 stroke-[3]" />
|
||||||
|
</button>
|
||||||
|
<span
|
||||||
|
onClick={() =>
|
||||||
|
handleJumpToDocBlock(item.doc.id, item.blockId)
|
||||||
|
}
|
||||||
|
className={`truncate flex-1 ${
|
||||||
|
item.checked
|
||||||
|
? 'line-through text-faint'
|
||||||
|
: 'text-main font-medium group-hover:text-accent'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.content}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleToggleRollupTodo(
|
|
||||||
item.doc,
|
|
||||||
item.blockId,
|
|
||||||
item.checked
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
className={`w-3.5 h-3.5 checkbox-square flex items-center justify-center transition-colors border cursor-pointer ${
|
|
||||||
item.checked
|
|
||||||
? 'bg-status-ok border-status-ok text-on-accent'
|
|
||||||
: 'border-strong hover:border-accent text-transparent'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<Check className="w-2.5 h-2.5 stroke-[3]" />
|
|
||||||
</button>
|
|
||||||
<span
|
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleJumpToDocBlock(item.doc.id, item.blockId)
|
handleJumpToDocBlock(item.doc.id, item.blockId)
|
||||||
}
|
}
|
||||||
className={`truncate flex-1 ${
|
className="text-faint hover:text-accent opacity-0 group-hover:opacity-100 transition-opacity p-1"
|
||||||
item.checked
|
title="Zu dieser Zeile springen"
|
||||||
? 'line-through text-faint'
|
|
||||||
: 'text-main font-medium group-hover:text-accent'
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{item.content}
|
<ExternalLink className="w-3 h-3" />
|
||||||
</span>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
))}
|
||||||
type="button"
|
</div>
|
||||||
onClick={() =>
|
)}
|
||||||
handleJumpToDocBlock(item.doc.id, item.blockId)
|
|
||||||
}
|
|
||||||
className="text-faint hover:text-accent opacity-0 group-hover:opacity-100 transition-opacity p-1"
|
|
||||||
title="Zu dieser Zeile springen"
|
|
||||||
>
|
|
||||||
<ExternalLink className="w-3 h-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in new issue
Block a user