Skip to content

T-SK5T-stacked-left-panel

State: planning/proposed · Impact: high · Complexity: large

The secondary region today renders exactly one thing at a time — either a page’s registered content or the shell’s Browse fallback — so Agent Manager’s tree, the shell’s Browse, and an eventual Git section cannot coexist in the left column the way the mock groups them. This task builds a stacked, collapsible-section container for that region so several sources of content sit together as named sections instead of competing for the one slot.

LocationRole today
packages/ts/app-frame/app/composables/usePaneRegistry.tsRegion-to-one-render-fn channel; a region holds exactly one filler
packages/ts/app-frame/app/components/PaneContent.vueRegisters a page’s slot content into one named region on mount, clears it on unmount
packages/ts/app-frame/app/components/PaneOutlet.vueReads and renders whatever one render fn a region currently holds
packages/ts/app-frame/app/layouts/default.vuesecondary pane has two mutually exclusive fillers: a page-registered PaneOutlet, or the shell’s own fallback
packages/ts/node-tree/src/NodeTreePane.vueA role: 'section' row is a header inside one flat scrollable tree, not a separate collapsible container
solutions/determined/docs/planning/desktop-framework/multi-vault-ux/f2-stacked-sidebar.htmlPrior-art mock of the stacked sections this task builds toward
solutions/determined/docs/planning/desktop-framework/multi-vault-ux/README.mdNarrates the mock set the stacked-sidebar mock belongs to
solutions/determined/packages/shell/app/components/ShellVaultBrowsePane.vueToday’s sole occupant of the secondary region’s shell-fallback slot
solutions/determined/experiences/agent-pants/app/components/ApComponentTree.vueAgent Manager’s tree; today fills the region directly through PaneContent, not as one of several sections

A new PaneSectionStack.vue in @sksizer/app-frame renders inside the secondary pane as several independently collapsible sections, fed by a usePaneSections() registry that mirrors usePaneRegistry’s shape — a region maps to an ordered list of sections rather than to one render fn — with each section’s collapsed state persisted the way usePaneGroup persists pane state. Agent Manager registers its component tree as one section, the shell registers Browse as another, and the git task registers a third. The chosen density and grouping variant comes from stories-shell-chrome-directions.

  1. Design usePaneSections(): a registry of {region, id, title, render, order} entries, provided above the layout the way usePaneRegistry is, with register/unregister calls a descendant page or the shell’s own app.vue can make.
  2. Persist per-section collapsed state — either a small wrapper over usePaneGroup’s existing storage-key pattern, or an extension letting usePaneGroup track several sub-panes within one region; name the choice as an open decision.
  3. Build PaneSectionStack.vue: renders every registered section for its region in order, each with a header (title and collapse chevron) and a body that mounts the section’s render fn while expanded.
  4. layouts/default.vue: mount PaneSectionStack for the secondary region in place of the current single-PaneOutlet-or-fallback branch; a host that registers no section renders nothing, as today.
  5. ShellVaultBrowsePane.vue: register itself as a “Browse” section through the new API instead of filling the region directly.
  6. ApComponentTree.vue: register itself as an “Agent Manager” section through the same API.
  7. Leave the registration point open for the git section (git-panel-commit-with-validation) to fill later; do not build the git section’s content here.
  8. Capture light and dark screenshots of the stacked panel, collapsed and expanded.
AreaNote
packages/ts/app-frame/app/composables/usePaneSections.tsPer-region ordered section registry
packages/ts/app-frame/app/components/PaneSectionStack.vueRenders a region’s registered sections, each collapsible
packages/ts/app-frame/app/layouts/default.vueMount PaneSectionStack for secondary
solutions/determined/packages/shell/app/components/ShellVaultBrowsePane.vueRegister as a section instead of filling the region directly
solutions/determined/experiences/agent-pants/app/components/ApComponentTree.vueRegister as a section
  • AC-1: The secondary region renders PaneSectionStack with the Agent Manager and Browse sections both present and independently collapsible.
  • AC-2: Collapsing one section leaves the other’s expanded state untouched, and both persist across a reload.
  • AC-3: A host that registers no section renders the region exactly as before, so usePaneRegistry’s existing single-filler contract stays intact for main and aux.
  • AC-4: ShellVaultBrowsePane.vue renders through the new section registry rather than filling secondary directly.
  • AC-5: Light and dark screenshots of the stacked panel, collapsed and expanded, are added to the S-0012 contact sheet.
  • The Git section’s own content — T-L7YP-git-panel-commit-with-validation registers it once this stack exists.
  • Moving main or aux to the same stacked model; only secondary changes here.
  • Drag-to-reorder sections.

From the user’s planning request of 2026-09-07.

T-PL39-stories-shell-chrome-directions


← Back to Tasks