From a4ae13057cdd87b0b191e4f9345965fc1efc82c1 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sun, 21 Jun 2026 18:08:27 -0700 Subject: [PATCH] FN-6889: move Secrets and Todos out of left sidebar Keep auxiliary Secrets and Todos navigation anchored to the right dock instead of the left sidebar.\n\n- Remove Secrets and Todos entries and unused icons from LeftSidebarNav.\n- Update sidebar tests to assert those shortcuts are omitted while other routes still work.\n- Refresh dashboard navigation docs for right-dock Todos and Secrets placement.\n\nFiles changed:\n docs/dashboard-guide.md | 6 +++---\n packages/dashboard/app/components/LeftSidebarNav.tsx | 11 ++++-------\n .../app/components/__tests__/LeftSidebarNav.test.tsx | 8 +++-----\n 3 files changed, 10 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-6889 Fusion-Task-Lineage: de135281-a9a8-4583-8251-e78a6b28122e --- docs/dashboard-guide.md | 6 +++--- packages/dashboard/app/components/LeftSidebarNav.tsx | 11 ++++------- .../app/components/__tests__/LeftSidebarNav.test.tsx | 8 +++----- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index 1e810cb47c..0c397daf4f 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -23,7 +23,7 @@ Task Detail modal opens from onboarding, activity log, and task-to-task navigati **Left Sidebar Navigation** is enabled by default for desktop/tablet project screens, moving project navigation out of the Header and into a persistent left sidebar. To opt out, open **Settings → Experimental Features** and turn **Left Sidebar Navigation** off (`leftSidebarNav: false`). -When enabled on desktop or tablet project screens, the sidebar contains the primary destinations (Board, List, Agents, Command Center, Missions, Chat, Documents, Mailbox, and plugin primary views), Header overflow destinations as regular entries (Research, Insights, Skills, Memory, Secrets, Stash Recovery, Evals, Goals, Dev Server, Todos, and plugin overflow views when their flags/plugins are enabled), and a footer with the collapse toggle directly above the Settings button. The Header retains the Fusion brand and project selector, keeps its non-navigation controls, and hides the view-toggle row and **More views** trigger so there is only one canonical navigation surface. +When enabled on desktop or tablet project screens, the sidebar contains the primary destinations (Board, List, Agents, Command Center, Missions, Chat, Documents, Mailbox, and plugin primary views), selected auxiliary destinations as regular entries (Research, Insights, Skills, Memory, Stash Recovery, Evals, Goals, Dev Server, and plugin overflow views when their flags/plugins are enabled), and a footer with the collapse toggle directly above the Settings button. Secrets and Todos are intentionally not listed in the left sidebar; use the Right Dock for those auxiliary views on desktop/tablet. The Header retains the Fusion brand and project selector, keeps its non-navigation controls, and hides the view-toggle row and **More views** trigger so there is only one canonical primary navigation surface. While the sidebar is active on desktop/tablet project screens, Board and List workflow controls move into the Header slot that replaces the hidden view toggle. Board and List share one workflow dropdown: each workflow row includes an inline edit action, and a persistent **New workflow** action remains at the bottom of the dropdown while the workflow list scrolls. The standalone workflow row above the board/list content is removed in this mode. When the flag is off, outside project screens, or on mobile, workflow controls remain inline with the same consolidated dropdown. @@ -522,8 +522,8 @@ Todo View is an experimental full-height dashboard surface for managing per-proj > Available when `experimentalFeatures.todoView` is enabled. Navigation: -- Desktop/tablet with Left Sidebar Navigation enabled: **Left sidebar → Todos** -- Desktop/tablet without the left sidebar: **Header → More views → Todos** +- Desktop/tablet with Right Dock enabled: **Right Dock → Todos** +- Desktop/tablet without the right dock / with the left-sidebar opt-out layout: **Header → More views → Todos** - Mobile: **More** sheet → **Todos** For full behavior, API contracts, and storage details, use the canonical [Todo View guide](./todo-view.md). diff --git a/packages/dashboard/app/components/LeftSidebarNav.tsx b/packages/dashboard/app/components/LeftSidebarNav.tsx index 902d7352fc..9e74d7b3be 100644 --- a/packages/dashboard/app/components/LeftSidebarNav.tsx +++ b/packages/dashboard/app/components/LeftSidebarNav.tsx @@ -11,13 +11,11 @@ import { Brain, ChevronLeft, ChevronRight, - CheckSquare, FileText, Gauge, History, LayoutGrid, List, - Lock, Mail, MessageSquare, Monitor, @@ -151,7 +149,6 @@ export function LeftSidebarNav({ view, onChangeView, onOpenSettings, - todosEnabled = false, mailboxUnreadCount = 0, mailboxPendingApprovalCount = 0, chatHasUnreadResponse = false, @@ -324,6 +321,10 @@ export function LeftSidebarNav({ }), ]; + /* + FNXC:Navigation 2026-06-21-00:00: + Secrets and Todos are intentionally omitted from the left sidebar. They live in the right dock through RightDock/overflowViewRegistry, while mobile keeps its More-sheet entries and the Header opt-out layout keeps its overflow entries. + */ const secondaryEntries: SidebarNavEntry[] = [ ...(experimentalFeatures?.evalsView ? [{ id: "evals", label: t("header.evalsView", "Evals"), view: "evals" as TaskView, isActive: view === "evals", icon: Target, testId: "sidebar-nav-evals", onSelect: () => onChangeView("evals") }] @@ -344,13 +345,9 @@ export function LeftSidebarNav({ ...(experimentalFeatures?.memoryView ? [{ id: "memory", label: t("header.memoryView", "Memory"), view: "memory" as TaskView, isActive: view === "memory", icon: Brain, testId: "sidebar-nav-memory", onSelect: () => onChangeView("memory") }] : []), - { id: "secrets", label: t("header.secretsView", "Secrets"), view: "secrets", isActive: view === "secrets", icon: Lock, testId: "sidebar-nav-secrets", onSelect: () => onChangeView("secrets") }, ...(experimentalFeatures?.devServerView ? [{ id: "devserver", label: t("header.devServerView", "Dev Server"), view: "devserver" as TaskView, isActive: view === "dev-server" || view === "devserver", icon: Monitor, testId: "sidebar-nav-devserver", onSelect: () => onChangeView("devserver") }] : []), - ...(todosEnabled - ? [{ id: "todos", label: t("header.todosView", "Todos"), view: "todos" as TaskView, isActive: view === "todos", icon: CheckSquare, testId: "sidebar-nav-todos", onSelect: () => onChangeView("todos") }] - : []), ...overflowPluginViews.map((entry): SidebarNavEntry => { const PluginIcon = getPluginNavIcon(entry.view.icon); const targetView = getPluginEntryView(entry); diff --git a/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx b/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx index b6efbe3e51..acba3a648f 100644 --- a/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx +++ b/packages/dashboard/app/components/__tests__/LeftSidebarNav.test.tsx @@ -139,7 +139,6 @@ describe("LeftSidebarNav", () => { "sidebar-nav-insights", "sidebar-nav-skills", "sidebar-nav-memory", - "sidebar-nav-secrets", "sidebar-nav-devserver", "sidebar-nav-plugin-fusion-plugin-primary-primary-view", "sidebar-nav-plugin-fusion-plugin-overflow-overflow-view", @@ -195,7 +194,6 @@ describe("LeftSidebarNav", () => { }); expect(screen.getByTestId("sidebar-nav-board")).toBeDefined(); - expect(screen.getByTestId("sidebar-nav-secrets")).toBeDefined(); expect(screen.getByTestId("sidebar-nav-stash-recovery")).toBeDefined(); expect(screen.queryByTestId("sidebar-nav-agents")).toBeNull(); expect(screen.queryByTestId("sidebar-nav-research")).toBeNull(); @@ -438,7 +436,7 @@ describe("LeftSidebarNav", () => { expect(window.localStorage.getItem("fusion:left-sidebar-width")).toBe("160"); }); - it("routes clicks to view changes, todos view, and settings callback", () => { + it("routes clicks to view changes and settings callback without Secrets/Todos shortcuts", () => { const onOpenSettings = vi.fn(); const { onChangeView } = renderSidebar({ todosEnabled: true, onOpenSettings }); @@ -448,8 +446,8 @@ describe("LeftSidebarNav", () => { fireEvent.click(screen.getByTestId("sidebar-nav-plugin-fusion-plugin-overflow-overflow-view")); expect(onChangeView).toHaveBeenCalledWith("plugin:fusion-plugin-overflow:overflow-view"); - fireEvent.click(screen.getByTestId("sidebar-nav-todos")); - expect(onChangeView).toHaveBeenCalledWith("todos"); + expect(screen.queryByTestId("sidebar-nav-secrets")).toBeNull(); + expect(screen.queryByTestId("sidebar-nav-todos")).toBeNull(); fireEvent.click(screen.getByTestId("sidebar-nav-settings")); expect(onOpenSettings).toHaveBeenCalledOnce();