From 09e7f212b700e037d3b87d2711daec81d3072c3f Mon Sep 17 00:00:00 2001 From: Blomios Date: Sun, 12 Jul 2026 15:08:34 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20refonte=20menus=20&=20fen=C3=AAtres?= =?UTF-8?q?=20=E2=80=94=20menu=20unique=20Panneaux=20et=20onglets=20projet?= =?UTF-8?q?=20(#26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sous-menus flyout dans MenuBar ; ProjectsView expose un menu unique Panneaux et supprime les menus View/Window/File ainsi que le sélecteur de projet ; ProjectTabs gère les onglets et le bouton +. Tests migrés en conséquence. QA vert : tsc --noEmit exit 0, vitest 62 fichiers / 616 tests passés, invariants préservés. Co-Authored-By: Claude Opus 4.8 --- .../src/features/projects/ProjectTabs.tsx | 49 +++-- .../projects/ProjectsView.detach.test.tsx | 47 +++-- .../projects/ProjectsView.docking.test.tsx | 21 +- .../projects/ProjectsView.ls7.test.tsx | 18 +- .../src/features/projects/ProjectsView.tsx | 196 ++++++++---------- .../src/features/projects/projects.test.tsx | 62 +++--- frontend/src/shared/ui/MenuBar.tsx | 129 +++++++++--- 7 files changed, 305 insertions(+), 217 deletions(-) diff --git a/frontend/src/features/projects/ProjectTabs.tsx b/frontend/src/features/projects/ProjectTabs.tsx index 33054bb..2bec108 100644 --- a/frontend/src/features/projects/ProjectTabs.tsx +++ b/frontend/src/features/projects/ProjectTabs.tsx @@ -1,9 +1,13 @@ /** * `ProjectTabs` — the project tab bar rendered below the app header. * - * Shows one tab per open project with a close control, and a "+" button to - * return to the launcher. Purely presentational: all state lives in the - * parent (ProjectsView via useProjects). + * Shows one tab per open project with a close control, and a "+" button to the + * right that opens the **Projects** panel (floating) — the single entry point + * for creating a project or switching to a known one (#26). Purely + * presentational: all state lives in the parent (ProjectsView via useProjects). + * + * The bar is always present (even with no open project) so the "+" stays + * reachable; the empty case shows a muted placeholder next to it. */ import type { TabItem } from "@/shared"; @@ -14,9 +18,10 @@ export interface ProjectTabsProps { activeTabId: string | null; onSelect: (id: string) => void; onClose: (id: string) => void; - /** Whether the launcher overlay is currently visible (no active tab). */ - showingLauncher: boolean; - onShowLauncher: () => void; + /** Whether the Projects panel is currently open (in any placement). */ + projectsPanelOpen: boolean; + /** Open the Projects panel (floating) — create/switch project. */ + onOpenProjectsPanel: () => void; className?: string; } @@ -25,31 +30,33 @@ export function ProjectTabs({ activeTabId, onSelect, onClose, - showingLauncher, - onShowLauncher, + projectsPanelOpen, + onOpenProjectsPanel, className, }: ProjectTabsProps) { - if (items.length === 0) return null; - return (
- + {items.length === 0 ? ( +

No open tabs.

+ ) : ( + + )} - ))} + {menu.items.map((item) => { + const hasSub = (item.submenu?.length ?? 0) > 0; + const subOpen = hasSub && openSubId === item.id; + return ( +
+ setOpenSubId(hasSub ? item.id : null) + } + > + + {subOpen && ( +
+ {item.submenu!.map((sub) => ( + + ))} +
+ )} +
+ ); + })}
)}