Files
headquarter/apps/web/src/components/features/workspace/workspace-tab-bar.tsx
T
Developer ce8b5dc86d feat: complete reorganize-long-files cleanup
- Extract tool instance lifecycle endpoints (start/stop/restart/delete) from
  api/tool/tool_instances.py into new api/tool/tool_lifecycle.py.
- Register tool_lifecycle_router in main.py and api/tool/__init__.py.
- Extract inline WorkspaceDetailPage components into
  components/features/workspace/: detail header, tab bars, file/git/tools/settings
  panels. Slim page from ~446 to ~62 lines.
- Update OpenSpec reorganize-long-files tasks to reflect completed work and
  current source state; mark change completed.
- Regenerate project maps.

Quality gates: python3 -m py_compile (backend clean), npm run typecheck,
npm run lint, npm test -- --run (87 passed), pytest workspace integration
and unit tests (27 passed, 1 skipped).
2026-06-12 18:53:23 +00:00

69 lines
1.6 KiB
TypeScript

/** Tab bar for the workspace detail page. */
import { Icon } from "../../icon";
export type WorkspaceTab = "files" | "git" | "tools" | "settings";
interface Tab {
id: WorkspaceTab;
label: string;
icon: string;
}
const TABS: Tab[] = [
{ id: "files", label: "Files", icon: "folder" },
{ id: "git", label: "Git", icon: "branch" },
{ id: "tools", label: "Tools", icon: "terminal" },
{ id: "settings", label: "Settings", icon: "settings" },
];
interface WorkspaceTabBarProps {
active: WorkspaceTab;
onChange: (tab: WorkspaceTab) => void;
}
export function WorkspaceTabBar({ active, onChange }: WorkspaceTabBarProps) {
return (
<nav className="tab-bar" role="tablist">
{TABS.map((tab) => (
<button
key={tab.id}
className={`tab ${active === tab.id ? "active" : ""}`}
onClick={() => onChange(tab.id)}
role="tab"
aria-selected={active === tab.id}
type="button"
>
<Icon
name={tab.icon as "folder" | "branch" | "terminal" | "settings"}
size="sm"
/>
{tab.label}
</button>
))}
</nav>
);
}
export function WorkspaceMobileTabBar({ active, onChange }: WorkspaceTabBarProps) {
return (
<nav className="mobile-tab-bar" role="tablist">
{TABS.map((tab) => (
<button
key={tab.id}
className={`mobile-tab ${active === tab.id ? "active" : ""}`}
onClick={() => onChange(tab.id)}
role="tab"
aria-selected={active === tab.id}
type="button"
>
<Icon
name={tab.icon as "folder" | "branch" | "terminal" | "settings"}
/>
<span>{tab.label}</span>
</button>
))}
</nav>
);
}