From 2db9822531bb868966c7223cdedb49913763ac3f Mon Sep 17 00:00:00 2001 From: xlx1212 Date: Fri, 7 Aug 2026 02:51:56 +0800 Subject: [PATCH] fix(nav-panel): add collapsible chevron indicator to workspace section header SectionHeader now renders a ChevronRight icon that rotates based on isOpen state for collapsible sections (not just scene-entry sections). Collapsed state shows chevron pointing right; expanded shows rotated 90deg. Also auto-expands workspace section when a new workspace is added, so newly created workspaces are immediately visible even if the user had previously collapsed the section. Fixes #976 --- pr-body.md | 27 +++++++++++++++++++ .../src/app/components/NavPanel/MainNav.tsx | 13 +++++++++ .../src/app/components/NavPanel/NavPanel.scss | 8 ++++++ .../NavPanel/components/SectionHeader.tsx | 13 +++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 pr-body.md diff --git a/pr-body.md b/pr-body.md new file mode 100644 index 0000000000..52a329dd99 --- /dev/null +++ b/pr-body.md @@ -0,0 +1,27 @@ +## Fix: Workspace section collapsed/expanded states look identical (#976) + +### Problem + +The workspace section header in the NavPanel uses `collapsible` mode without `onSceneOpen`, so the `ChevronRight` indicator was never rendered. Users could collapse/expand the section but had no visual cue showing the current state — collapsed and expanded headers looked identical. + +Additionally, when a user manually collapsed the workspace section and then added a new workspace, the section stayed collapsed, making the new workspace invisible until the user manually expanded it. + +### Root Cause + +In `SectionHeader.tsx`, the chevron indicator was gated behind `onSceneOpen ?` (line 63), so collapsible-only sections (workspace, assistant sessions) never showed an indicator. + +### Changes + +1. **`SectionHeader.tsx`** — Render the chevron for both `onSceneOpen` and `collapsible` sections. Added `--collapsed` and `--expanded` CSS modifier classes that rotate the chevron based on `isOpen` state. + +2. **`NavPanel.scss`** — Added `transform: rotate(0deg)` for collapsed state and `transform: rotate(90deg)` for expanded state, with the existing `transition: transform` providing smooth animation. + +3. **`MainNav.tsx`** — Added a `useEffect` that auto-expands the workspace section when a new workspace is added (tracks `normalWorkspacesList.length`), so newly created workspaces are immediately visible even if the user had previously collapsed the section. + +### Validation + +- `tsc --noEmit` — no errors in changed files +- `vitest run NavPanelLayout.test.ts` — 4/4 tests pass +- Existing chevron hover behavior (`translateX(1px)` for scene-link sections) is preserved — the rotation classes only apply to `collapsible` sections without `onSceneOpen` + +Fixes #976 diff --git a/src/web-ui/src/app/components/NavPanel/MainNav.tsx b/src/web-ui/src/app/components/NavPanel/MainNav.tsx index 8ac08217c5..5a7ca10617 100644 --- a/src/web-ui/src/app/components/NavPanel/MainNav.tsx +++ b/src/web-ui/src/app/components/NavPanel/MainNav.tsx @@ -128,6 +128,19 @@ const MainNav: React.FC = ({ }); }, []); + // Auto-expand workspace section when a new workspace is added + const prevWorkspaceCountRef = useRef(normalWorkspacesList.length); + useEffect(() => { + if (normalWorkspacesList.length > prevWorkspaceCountRef.current) { + setExpandedSections(prev => { + const next = new Set(prev); + next.add('workspace'); + return next; + }); + } + prevWorkspaceCountRef.current = normalWorkspacesList.length; + }, [normalWorkspacesList.length]); + const closeWorkspaceMenu = useCallback(() => { setWorkspaceMenuClosing(true); window.setTimeout(() => { diff --git a/src/web-ui/src/app/components/NavPanel/NavPanel.scss b/src/web-ui/src/app/components/NavPanel/NavPanel.scss index 6f388e0d58..c9a4d579fe 100644 --- a/src/web-ui/src/app/components/NavPanel/NavPanel.scss +++ b/src/web-ui/src/app/components/NavPanel/NavPanel.scss @@ -1049,6 +1049,14 @@ $_section-header-height: 24px; } } + &__section-indicator--collapsed { + transform: rotate(0deg); + } + + &__section-indicator--expanded { + transform: rotate(90deg); + } + &__section-action { display: inline-flex; align-items: center; diff --git a/src/web-ui/src/app/components/NavPanel/components/SectionHeader.tsx b/src/web-ui/src/app/components/NavPanel/components/SectionHeader.tsx index 93893d0823..150dedfbaa 100644 --- a/src/web-ui/src/app/components/NavPanel/components/SectionHeader.tsx +++ b/src/web-ui/src/app/components/NavPanel/components/SectionHeader.tsx @@ -60,8 +60,17 @@ const SectionHeader: React.FC = ({ } > {label} - {onSceneOpen ? ( -