feat(workspace): enhance todo view switcher and add note-level collapsible cards in folder_note mode
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 17s

This commit is contained in:
sandrodach committed 2026-10-27 07:21:31 +01:00
1 parent 5144f7b01b
commit 928cc72491
1 file changed
+81 -53
@@ -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>
); );
})} })}