diff --git a/packages/dashboard/app/components/DocumentsView.css b/packages/dashboard/app/components/DocumentsView.css index 5311a34e87..afbc3d9621 100644 --- a/packages/dashboard/app/components/DocumentsView.css +++ b/packages/dashboard/app/components/DocumentsView.css @@ -15,6 +15,9 @@ The header row now comes from the shared .view-header (which supplies the --spac FNXC:ViewHeader 2026-06-23-03:45: The shared ViewHeader now owns the single border-bottom divider + surface background, so this wrapper drops its own border-bottom/background to avoid a doubled divider under the title row (the divider sits directly under the canonical title row, and the controls row reads as body content below it). The controls row keeps its own side/bottom padding so the tab bar/search stay aligned. + +FNXC:ViewHeader 2026-06-22-12:00: +Artifacts controls are the first page content below the shared header, so add a top inset there instead of on the header wrapper. This keeps the tab/search row from bumping against the title divider while preserving the existing body alignment. */ .documents-view-header { background: var(--surface); @@ -30,7 +33,7 @@ The shared ViewHeader now owns the single border-bottom divider + surface backgr align-items: center; gap: var(--space-md); flex-wrap: nowrap; - padding: 0 var(--space-lg) var(--space-lg); + padding: var(--space-lg) var(--space-lg) var(--space-lg); } .documents-tab-bar { diff --git a/packages/dashboard/app/components/MemoryView.css b/packages/dashboard/app/components/MemoryView.css index 1eef76aada..0cd8be4c68 100644 --- a/packages/dashboard/app/components/MemoryView.css +++ b/packages/dashboard/app/components/MemoryView.css @@ -1,7 +1,7 @@ /* === MemoryView === */ /* FNXC:Navigation 2026-06-22-01:10: -The title row now comes from the shared .view-header (which supplies the --space-lg top/side padding). The root drops its uniform padding; the description, tab bar, and content area carry their own horizontal inset so they align under the header. +The title row now comes from the shared .view-header (which supplies the --space-lg top/side padding). The root drops its uniform padding; the tab bar and content area carry their own horizontal inset so they align under the header. */ .memory-view { display: flex; @@ -12,16 +12,8 @@ The title row now comes from the shared .view-header (which supplies the --space /* FNXC:Navigation 2026-06-22-02:30: -After the header migrated to the shared .view-header (which is flex-shrink:0), the sibling description and tab bar must also be flex-shrink:0. Without it they collapse under the flex column at constrained heights, letting .memory-view-content overlap the header/tabs. The scroll owner is the active tab pane (.memory-*-tab, flex:1 + min-height:0 + overflow-y:auto); the editor container keeps min-height:0 through the chain so CodeMirror bounds itself and never overruns the action bar. +After the header migrated to the shared .view-header (which is flex-shrink:0), the sibling tab bar must also be flex-shrink:0. Without it the tabs collapse under the flex column at constrained heights, letting .memory-view-content overlap the header/tabs. The scroll owner is the active tab pane (.memory-*-tab, flex:1 + min-height:0 + overflow-y:auto); the editor container keeps min-height:0 through the chain so CodeMirror bounds itself and never overruns the action bar. */ -.memory-view-description { - color: var(--text-muted); - font-size: 13px; - margin: 0; - padding: 0 var(--space-lg); - flex-shrink: 0; -} - .memory-view-tabs { display: flex; flex-direction: row; @@ -476,7 +468,6 @@ The memory editor box is CAPPED to about a page (max-height: 60vh) so a long mem /* Mobile responsive for memory view */ @media (max-width: 768px) { /* ViewHeader supplies its own responsive padding; the body blocks tighten their horizontal inset here. */ - .memory-view-description, .memory-view-tabs { padding-inline: var(--space-md); } @@ -524,4 +515,3 @@ The memory editor box is CAPPED to about a page (max-height: 60vh) so a long mem padding-top: var(--space-md); } } - diff --git a/packages/dashboard/app/components/MemoryView.tsx b/packages/dashboard/app/components/MemoryView.tsx index ad4e5a0dc2..2fa69c84fb 100644 --- a/packages/dashboard/app/components/MemoryView.tsx +++ b/packages/dashboard/app/components/MemoryView.tsx @@ -352,12 +352,12 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
{/* FNXC:Navigation 2026-06-22-01:10: - Memory adopts the shared ViewHeader (CC-modeled) for a consistent main-content title row; the prior description renders just below the header, and the Working/Insights/Engines tab bar stays beneath it. + Memory adopts the shared ViewHeader (CC-modeled) for a consistent main-content title row. + + FNXC:Memory 2026-06-22-12:00: + The Memory view header should be title-only; remove the "Working memory, long-term insights, and engine status" subtitle so the tab bar becomes the first content under the header. */} -

- {t("memory.description", "Working memory, long-term insights, and engine status")} -

{/* Tab bar */}
diff --git a/packages/dashboard/app/components/WorkflowNodeEditor.css b/packages/dashboard/app/components/WorkflowNodeEditor.css index bad33cb04f..08eb5eed2a 100644 --- a/packages/dashboard/app/components/WorkflowNodeEditor.css +++ b/packages/dashboard/app/components/WorkflowNodeEditor.css @@ -129,6 +129,76 @@ embedded view. overflow-y: auto; } +/* +FNXC:WorkflowSidebar 2026-06-22-12:00: +Workflow authors need to reclaim horizontal graph-editing space without leaving +the workflow view. Hide only the sidebar shell when collapsed and keep the +restore control attached to the canvas so the state is always reversible. +*/ +.wf-editor-body--sidebar-collapsed .wf-editor-sidebar { + display: none; +} + +.wf-editor-sidebar-head { + display: flex; + align-items: center; + gap: var(--space-xs); + min-width: 0; +} + +.wf-editor-sidebar-head .wf-editor-new { + flex: 1 1 auto; + justify-content: center; +} + +.wf-sidebar-shell-toggle, +.wf-sidebar-shell-restore { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--space-xs); + min-height: 30px; + padding: var(--space-xs) var(--space-sm); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + background: var(--surface); + color: var(--text-muted); + box-shadow: var(--shadow-sm); + font: inherit; + font-size: 0.72rem; + font-weight: 600; + cursor: pointer; + white-space: nowrap; + transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast); +} + +.wf-sidebar-shell-toggle { + flex: 0 0 auto; + width: 30px; + padding-inline: 0; +} + +.wf-sidebar-shell-restore { + position: absolute; + top: var(--space-sm); + left: var(--space-sm); + z-index: 6; + white-space: nowrap; +} + +.wf-sidebar-shell-toggle:hover, +.wf-sidebar-shell-restore:hover { + border-color: var(--accent); + background: var(--surface-hover); + color: var(--accent); +} + +.wf-sidebar-shell-toggle:focus-visible, +.wf-sidebar-shell-restore:focus-visible { + outline: none; + box-shadow: var(--focus-ring); +} + /* U12: columns + fields authoring sections moved into the left sidebar, below the workflow list. Each is a collapsible disclosure whose toggle button is the section header; the panels' own internal

is suppressed to avoid a double @@ -321,6 +391,7 @@ embedded view. flex-direction: column; flex: 1; min-width: 0; + position: relative; } .wf-editor-mobile-back { @@ -430,6 +501,20 @@ embedded view. gap: var(--space-xs); } +/* +FNXC:WorkflowToolbar 2026-06-22-12:00: +Toolbar commands such as Export should move as whole controls when space is +tight; do not allow their short labels to split onto multiple lines. +*/ +.wf-editor-toolbar .wf-editor-action, +.wf-editor-toolbar .wf-editor-delete, +.wf-editor-toolbar .wf-editor-save, +.wf-editor-readonly-banner .wf-editor-action, +.wf-editor-readonly-banner .wf-editor-save { + white-space: nowrap; + overflow-wrap: normal; +} + .wf-editor-readonly-note { font-size: 0.75rem; color: var(--text-dim); diff --git a/packages/dashboard/app/components/WorkflowNodeEditor.tsx b/packages/dashboard/app/components/WorkflowNodeEditor.tsx index 29f199e7e9..857984bb38 100644 --- a/packages/dashboard/app/components/WorkflowNodeEditor.tsx +++ b/packages/dashboard/app/components/WorkflowNodeEditor.tsx @@ -824,10 +824,25 @@ function InnerEditor({ // U12: the columns/fields authoring panels live in the left sidebar (below the // workflow list) as collapsible disclosure sections. Each section's collapsed // state persists in localStorage; default expanded. + /* + FNXC:WorkflowSidebar 2026-06-22-12:00: + The workflow view needs the entire left sidebar collapsible, not only its + internal column/field/settings groups, so graph editing can use the full + canvas width. Persist the shell state and keep a visible restore control in + the canvas area when the sidebar is hidden. + */ + const sidebarCollapsedStorageKey = "fusion:wf-left-sidebar-collapsed"; const columnsCollapsedStorageKey = "fusion:wf-sidebar-columns-collapsed"; const fieldsCollapsedStorageKey = "fusion:wf-sidebar-fields-collapsed"; const settingsCollapsedStorageKey = "fusion:wf-sidebar-settings-collapsed"; const optionalStepsCollapsedStorageKey = "fusion:wf-sidebar-optional-steps-collapsed"; + const [sidebarCollapsed, setSidebarCollapsed] = useState(() => { + try { + return localStorage.getItem(sidebarCollapsedStorageKey) === "1"; + } catch { + return false; + } + }); const [columnsCollapsed, setColumnsCollapsed] = useState(() => { try { return localStorage.getItem(columnsCollapsedStorageKey) === "1"; @@ -856,6 +871,13 @@ function InnerEditor({ return false; } }); + useEffect(() => { + try { + localStorage.setItem(sidebarCollapsedStorageKey, sidebarCollapsed ? "1" : "0"); + } catch { + // localStorage unavailable (private mode / SSR): non-fatal. + } + }, [sidebarCollapsed]); useEffect(() => { try { localStorage.setItem(columnsCollapsedStorageKey, columnsCollapsed ? "1" : "0"); @@ -2540,17 +2562,32 @@ function InnerEditor({ simpleLayoutEnabled ? " wf-editor-body--simple-layout" : "" }${mobileNodeDetailStage ? " wf-editor-body--mobile-node-detail" : ""}${ mobileEdgeDetailStage ? " wf-editor-body--mobile-edge-detail" : "" - }`} + }${sidebarCollapsed ? " wf-editor-body--sidebar-collapsed" : ""}`} >
+ {sidebarCollapsed && !isMobileMode && ( + + )}