Add collapsible Schema View sidebar with shared sidebar shell#1875
Conversation
Add a persisted, collapsible sidebar to the Schema View (issues aws#1722, aws#1541) and extract the shared presentational shell now that a second view consumes it. Schema View: - schemaViewLayoutAtom (key "schema-view-layout") storing active tab, width, and detailsAutoOpenOnSelection - useSchemaViewSidebar deep hook (toggle, resize, close, auto-open, toggleDetailsAutoOpen) - collapse-to-icon-strip behavior; auto-open details only fires for a single selection (shouldAutoOpenDetailsForSelection), matching the graph view — a multiple/cleared selection no longer yanks the user to the empty Details state - DetailsPanelHeader and the Node/Edge Styling panels all carry the sidebar close button Shared shell: - extract CollapsibleSidebar + tab sub-components to @/components, and refactor the Graph View sidebar onto it (its second consumer); drop the now-unused CLOSED_SIDEBAR_WIDTH constant. BadgeIndicator keeps wrapping every trigger in `.stack` as before. - CollapsibleSidebar owns the closed/default width directly (no defaultWidth prop); SidebarTabs no longer takes an unused slot prop. Both sidebars share one default width (DEFAULT_SIDEBAR_WIDTH); the schema view no longer defines its own width constant. Sidebar-header buttons are uniformly size "icon-small" across both views (schema Details header plus the graph view's auto-open and refresh buttons). Auto-open: treat undefined detailsAutoOpenOnSelection as enabled, and toggle via toggleDetailsAutoOpen so the button flips state internally. All three value states are covered by tests in both views. Docs: document the schema sidebar in docs/features/schema-view.md and align "Schema Explorer" → "Schema View" wording in docs/agents/{schema,product}.md.
noel-improv
left a comment
There was a problem hiding this comment.
lgtm, just a few non-blocking findings posted for confirmation.
| const [graphSelection, setGraphSelection] = useState<SelectedElements | null>( | ||
| null, | ||
| ); | ||
| const { autoOpenDetails } = useSchemaViewSidebar(); |
There was a problem hiding this comment.
non-blocking: SchemaGraph calls useSchemaViewSidebar() only for autoOpenDetails but the hook reads the atom with useAtom (schemaViewLayout.ts:11), so the whole Cytoscape canvas subscribes to the layout atom. Could the write path use useSetAtom instead so a sidebar resize or tab click doesn't re-render the graph?
There was a problem hiding this comment.
This is a non-issue because we use React Compiler to reduce re-renders based on unused subscriptions.
| const newSelection = toSchemaGraphSelection(selected); | ||
| setSelection(newSelection); | ||
|
|
||
| if (shouldAutoOpenDetailsForSelection(newSelection)) { |
There was a problem hiding this comment.
[non-blocking]:shouldAutoOpenDetailsForSelection → autoOpenDetails() fires on every single selection and detailsAutoOpenOnSelection defaults to true (schemaViewLayout.ts:38, ?? true). So selecting a node force-switches the sidebar to Details even when I'm mid-edit in Node Styling. I recall speaking about persisting states during session or did you want selection to override a tab I've explicitly opened or only a closed sidebar?
There was a problem hiding this comment.
Style editing is inside a dialog and is therefore the user can't change the selection.
However, the search and node expansion sidebars are cases where you could be in the middle of editing and change your selection in the canvas. That said, this behavior has existed for quite a while and should be expected. The edits you're in the middle of making in the search and expansion sidebar should remain if you switch back to that sidebar, so it shouldn't be an issue.
| reconcileMapByKey, | ||
| ), | ||
| atomWithLocalForage("graph-view-layout", defaultGraphViewLayout), | ||
| atomWithLocalForage("schema-view-layout", defaultSchemaViewLayout), |
There was a problem hiding this comment.
[non-blocking]: atomWithLocalForage("schema-view-layout", defaultSchemaViewLayout) is registered with no reconcile function, unlike the sibling atoms on lines 80/86/96/102/110 that all pass reconcileMapByKey. With the Schema View open in two tabs, does a resize or tab switch in one get clobbered when the other writes its stale layout back?
There was a problem hiding this comment.
Yes, currently, by design. I have backlog items to refine this behavior but they haven't been pushed yet.
I consider this a minor frustration and not data loss, so I'm ok with the inconvenience for the time being.
|
|
||
| import { DEFAULT_SIDEBAR_WIDTH } from "@/core/StateProvider/graphViewLayoutDefaults"; | ||
| import { schemaViewLayoutAtom } from "@/core/StateProvider/storageAtoms"; | ||
| import { renderHookWithJotai } from "@/utils/testing"; |
There was a problem hiding this comment.
[non-blocking]: Imports renderHookWithJotai, used in all 14 tests (lines 12–175). docs/agents/testing.md says to use renderHookWithState instead. just flagging incase release catches this during pass
There was a problem hiding this comment.
I'm choosing to fix this now. It might end up as a separate PR if the scope is large.
There was a problem hiding this comment.
I will do this as a follow up as it is larger than I hoped.
| return ( | ||
| <Resizable | ||
| size={{ width: isSidebarOpen ? sidebarWidth : CLOSED_WIDTH }} | ||
| minWidth={isSidebarOpen ? DEFAULT_SIDEBAR_WIDTH : CLOSED_WIDTH} |
There was a problem hiding this comment.
[non-blocking]: The shared shell sets minWidth={DEFAULT_SIDEBAR_WIDTH} (400) when open, and the schema default width is now 400 too. The old schema sidebar floor was 350 (DEFAULT_SCHEMA_SIDEBAR_WIDTH in the now-deleted schemaExplorerLayout.ts). Was raising the min to 400 intentional? It might be worth testing on a narrow screen to ensure draggability and that the canvas doesn't lose room.
There was a problem hiding this comment.
This is just cleaning up a minor oversight in past code. They should never have been different, so bringing them into consistency was always the goal.
There are likely many issues with smaller screens, as this is primarily a desktop app. However, those issues are now consistent across both views and should be resolved in the same way — but that's not the intent of this PR.
Description
Adds a collapsible, persisted sidebar to the Schema View, matching the behavior the Graph View sidebar already has, and resolves the open auto-open question from #1541.
What users get:
schema-view-layoutIndexedDB key).The shared sidebar shell (
CollapsibleSidebar+ tab sub-components) is extracted to@/componentsnow that a second view needs it, and the Graph View sidebar is refactored onto it — so both views share one presentational implementation and one default width. As a small consistency pass that the shared shell motivates, all sidebar-header buttons now use theicon-smallsize.A prior PR (#1874) did the graph-view layout rename + hook flattening this builds on.
Validation
pnpm checkspasses (types, lint, format).pnpm testpasses. New coverage:schemaViewLayout.test.ts(toggle/close/resize/persist + all three auto-open states + toggle states),toSchemaGraphSelection.test.ts(the single-selection auto-open gate), and component-level collapse/reopen inSchemaExplorerSidebar.test.tsx.How to read
Related Issues
Check List
pnpm checkspasses with no errors.pnpm testpasses with no failures.