feat(app): GUI backlog — splitter, drag-reorder, fit, persist, modal focus

- LayoutEngine: fix splitter resize (track pointer 1:1 via delta-from-start)
  and add panel drag-to-reorder using raw pointer events with drop indicators
- TerminalView: auto-fit xterm to container via FitAddon + ResizeObserver
- App/TopBar: toggleable sidebar; persist sidebar/events collapse in
  localStorage; bell icon opens the activity log
- Wizard: new-workspace modal now grabs focus and handles keyboard
- deps: add @xterm/addon-fit

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 08:01:15 +07:00
parent 6a3875670a
commit 58c75c71ae
7 changed files with 287 additions and 126 deletions
+9 -6
View File
@@ -1,4 +1,4 @@
import { FolderGit2, PanelRight, Search, Bell, Settings, ChevronDown } from "lucide-react";
import { FolderGit2, PanelLeft, PanelRight, Search, Bell, Settings, ChevronDown } from "lucide-react";
import { COLORS, FONT } from "./theme";
import type { WorkspaceView } from "./layoutTypes";
import { leafIds } from "./layoutTypes";
@@ -29,11 +29,14 @@ function IconBtn({ icon, onClick, active, title }: { icon: React.ReactNode; onCl
}
export function TopBar({
active, eventsOpen, onToggleEvents, unread,
active, eventsOpen, onToggleEvents, onShowEvents, sidebarOpen, onToggleSidebar, unread,
}: {
active: WorkspaceView | null;
eventsOpen: boolean;
onToggleEvents: () => void;
onShowEvents: () => void;
sidebarOpen: boolean;
onToggleSidebar: () => void;
unread: number;
}) {
return (
@@ -44,8 +47,8 @@ export function TopBar({
borderBottom: `1px solid ${COLORS.borderSubtle}`,
}}
>
{/* macOS traffic-light spacer — real lights are drawn by the window chrome. */}
<div style={{ width: 60, flex: "0 0 60px" }} />
{/* Left: sidebar toggle, flush to the left edge. */}
<IconBtn icon={<PanelLeft size={15} />} onClick={onToggleSidebar} active={sidebarOpen} title="Toggle Sidebar" />
{/* Workspace breadcrumb */}
<div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
@@ -67,10 +70,9 @@ export function TopBar({
{/* Right cluster */}
<div style={{ display: "flex", alignItems: "center", gap: 6 }}>
<IconBtn icon={<PanelRight size={15} />} onClick={onToggleEvents} active={eventsOpen} title="Toggle Event Center" />
<IconBtn icon={<Search size={16} />} title="Search (mock)" />
<div style={{ position: "relative", display: "flex" }}>
<IconBtn icon={<Bell size={16} />} title="Notifications (mock)" />
<IconBtn icon={<Bell size={16} />} onClick={onShowEvents} active={eventsOpen} title="Open activity log" />
{unread > 0 && (
<span style={{
position: "absolute", top: -2, right: -2, minWidth: 14, height: 14, padding: "0 3px",
@@ -82,6 +84,7 @@ export function TopBar({
</span>
)}
</div>
<IconBtn icon={<PanelRight size={15} />} onClick={onToggleEvents} active={eventsOpen} title="Toggle Event Center" />
<IconBtn icon={<Settings size={16} />} title="Settings (mock)" />
<span style={{ width: 1, height: 18, background: COLORS.borderStrong, margin: "0 2px" }} />
<button