FN-7834: restyle Task Documents sidebar with clearer task-card grouping

Gives the Artifacts view's Task Documents sidebar a distinct card-per-task look with more breathing room between task groups, replacing the flat bordered-row list.

- Restyle .documents-task-sidebar-group into a bordered, rounded card with shadow and inter-group gap instead of a bottom-border-only divider
- Strengthen the group header (bolder task id/title, tinted background) so it reads as a container rather than a peer row
- Add hover/selected background treatment and left-indent to .documents-task-document-item entries, scoped under .documents-task-documents-sidebar so Project Files and Artifacts stay unaffected
- Add a regression test asserting group headers remain non-selectable containers distinct from selectable document rows
- Update dashboard-guide.md wording to describe the new distinct task-card grouping
- Add changeset (patch) documenting the sidebar restyle

Files changed:
 .changeset/fn-7834-task-documents-grouping.md      |  7 +++
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/DocumentsView.css     | 38 +++++++++++++---
 .../components/__tests__/DocumentsView.test.tsx    | 50 ++++++++++++++++++++++
 4 files changed, 90 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7834

Fusion-Task-Lineage: 9bac7666-19ba-410b-81dc-d9201a61d0b5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-11 20:48:20 -07:00
parent 49faf0afe2
commit 06bf0b85b9
4 changed files with 90 additions and 7 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Artifacts view — Task Documents sidebar now shows clearer task grouping and more space between tasks.
category: fix
dev: DocumentsView Task Documents sidebar restyles .documents-task-sidebar-group-header vs .documents-task-document-item hierarchy and increases inter-group separation, scoped under .documents-task-documents-sidebar so Project Files and Artifacts tabs are unaffected.

View File

@@ -830,7 +830,7 @@ Artifacts view aggregates registered artifacts, project markdown files, and task
Features:
- Browse **Task Documents** in the same left-sidebar/right-pane pattern as **Project Files**: the sidebar groups document entries by task ID with revision metadata and parent task status badges when available, while the right pane loads the selected document content
- Browse **Task Documents** in the same left-sidebar/right-pane pattern as **Project Files**: the sidebar groups document entries by task ID in distinct task cards with clear spacing between tasks, revision metadata, and parent task status badges when available, while the right pane loads the selected document content
- Search documents across tasks
- Open project markdown files and task documents with inline preview
- Browse the **Artifacts** tab for registry media registered by any agent, dashboard chat/user action, or system tool across tasks

View File

@@ -370,27 +370,37 @@ Task-document header actions group the Markdown/Plain toggle with the new Edit (
/*
FNXC:DocumentsView 2026-07-10-17:40:
FN-7811 reuses the Project Files shell for Task Documents, while task-scoped sidebar groups preserve task id/title/status context before each selectable document entry. Keep these styles scoped so Project Files continues to own the generic markdown-file list visuals.
FNXC:DocumentsView 2026-07-11-19:03:
FN-7834 requires task-document groups to scan as discrete task containers, not a flat sequence of peer rows. Keep the stronger card/header hierarchy and inter-group gap scoped under .documents-task-documents-sidebar so Project Files' shared .markdown-file-item list and the Artifacts gallery remain visually unchanged.
*/
.documents-task-documents-sidebar {
display: flex;
flex-direction: column;
gap: var(--space-md);
padding: var(--space-sm);
background: var(--surface);
}
.documents-task-sidebar-group {
border-bottom: 1px solid var(--border);
overflow: hidden;
border: thin solid var(--border);
border-radius: var(--radius-lg);
background: var(--card);
box-shadow: var(--shadow-sm);
}
.documents-task-sidebar-group:last-child {
border-bottom: none;
border-bottom: thin solid var(--border);
}
.documents-task-sidebar-group-header {
display: flex;
flex-direction: column;
gap: var(--space-sm);
padding: var(--space-md);
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: var(--space-md) var(--space-lg);
background: color-mix(in srgb, var(--todo) 8%, var(--card));
border-bottom: thin solid var(--border);
}
.documents-task-sidebar-title-wrap {
@@ -415,8 +425,23 @@ FN-7811 reuses the Project Files shell for Task Documents, while task-scoped sid
gap: var(--space-sm);
}
.documents-task-documents-sidebar .documents-task-document-list {
background: var(--card);
}
.documents-task-document-item {
border-left-color: transparent;
padding-inline-start: var(--space-lg);
background: color-mix(in srgb, var(--surface) 44%, transparent);
}
.documents-task-document-item:hover {
background: var(--card-hover);
}
.documents-task-document-item.markdown-file-item--selected {
border-left-color: var(--todo);
background: color-mix(in srgb, var(--todo) 14%, var(--card));
}
/*
@@ -433,13 +458,14 @@ The meta line (author · revision · date) renders as its own row directly under
.documents-group-task-id {
font-family: var(--font-mono);
font-size: 12px;
font-weight: 700;
color: var(--text-muted);
flex-shrink: 0;
}
.documents-group-task-title {
font-size: 14px;
font-weight: 500;
font-weight: 700;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;

View File

@@ -389,6 +389,56 @@ describe("DocumentsView", () => {
expect(screen.queryByText("Alpha document content")).not.toBeInTheDocument();
});
/*
FNXC:DocumentsView 2026-07-11-19:03:
FN-7834 protects the Task Documents sidebar hierarchy: task headers must remain non-clickable group containers while each document stays a selectable child row, so CSS-only visual hierarchy changes cannot accidentally collapse the two surfaces into peer list items again.
*/
it("keeps task document group headers structurally distinct from document entries", () => {
mockUseProjectMarkdownFiles.mockReturnValue({
files: [],
loading: false,
error: null,
refresh: vi.fn().mockResolvedValue(undefined),
});
mockUseDocuments.mockReturnValue({
documents: mockStatusTaskDocuments,
projectFiles: [],
loading: false,
error: null,
refresh: vi.fn().mockResolvedValue(undefined),
});
render(<DocumentsView addToast={addToast} onOpenDetail={onOpenDetail} />);
fireEvent.click(screen.getByRole("tab", { name: /show task documents/i }));
const sidebar = screen.getByLabelText("Task documents");
expect(sidebar).toHaveClass("documents-task-documents-sidebar");
const groups = Array.from(sidebar.querySelectorAll(".documents-task-sidebar-group"));
expect(groups.length).toBeGreaterThan(1);
const doneGroup = screen.getByRole("heading", { name: /KB-DONE.*Done task/i }).closest(".documents-task-sidebar-group") as HTMLElement;
const doneHeader = doneGroup.children[0];
const doneDocumentList = doneGroup.children[1];
expect(doneHeader).toHaveClass("documents-task-sidebar-group-header");
expect(doneHeader).not.toHaveClass("markdown-file-item");
expect(doneHeader.querySelector(".documents-task-document-item")).toBeNull();
expect(doneDocumentList).toHaveClass("documents-task-document-list");
const doneEntries = within(doneDocumentList as HTMLElement).getAllByRole("button", { name: /open KB-DONE/i });
expect(doneEntries).toHaveLength(2);
doneEntries.forEach((entry) => {
expect(entry).toHaveClass("markdown-file-item", "documents-task-document-item");
expect(entry.closest(".documents-task-sidebar-group-header")).toBeNull();
});
const legacyGroup = screen.getByRole("heading", { name: /KB-MISSING.*Legacy task/i }).closest(".documents-task-sidebar-group") as HTMLElement;
expect(legacyGroup.children[0]).toHaveClass("documents-task-sidebar-group-header");
expect(legacyGroup.querySelector(".documents-group-status")).not.toBeInTheDocument();
});
it("selecting a task document loads content and marks the sidebar entry current", () => {
render(<DocumentsView addToast={addToast} onOpenDetail={onOpenDetail} />);