From 61072f4c07aef8b94bf02743f1ba832f9d9a4619 Mon Sep 17 00:00:00 2001 From: Developer Date: Fri, 5 Jun 2026 18:58:14 +0000 Subject: [PATCH] refactor: reorganize CSS and Tool Workshop page - Extract styles.css into styles/ directory (tokens, global, utilities, syntax-highlight, pages) - Extract ToolWorkshopPage into components: - ToolTypeListSidebar, ToolTypeEditorPanel, ToolWorkshopMobileView - use-tool-workshop hook for state management - Slim ToolWorkshopPage from 1,269 to 110 lines Quality gates: tsc --noEmit passes, npm run build passes --- .../tool-workshop/ToolTypeEditorPanel.tsx | 373 +++ .../tool-workshop/ToolTypeListSidebar.tsx | 161 ++ .../tool-workshop/ToolWorkshopMobileView.tsx | 350 +++ apps/web/src/hooks/use-tool-workshop.ts | 370 +++ apps/web/src/main.tsx | 29 +- apps/web/src/pages/ToolWorkshopPage.tsx | 1311 +-------- apps/web/src/styles/global.css | 1206 ++++++++ apps/web/src/styles/pages/git-history.css | 257 ++ apps/web/src/styles/pages/projects.css | 132 + apps/web/src/styles/pages/repo-workspace.css | 709 +++++ apps/web/src/styles/pages/sessions.css | 69 + apps/web/src/styles/pages/ssh-keys.css | 25 + .../web/src/styles/pages/workspace-detail.css | 504 ++++ apps/web/src/styles/syntax-highlight.css | 195 ++ apps/web/src/styles/tokens.css | 92 + apps/web/src/styles/utilities.css | 2541 +++++++++++++++++ 16 files changed, 7079 insertions(+), 1245 deletions(-) create mode 100644 apps/web/src/components/features/tool-workshop/ToolTypeEditorPanel.tsx create mode 100644 apps/web/src/components/features/tool-workshop/ToolTypeListSidebar.tsx create mode 100644 apps/web/src/components/features/tool-workshop/ToolWorkshopMobileView.tsx create mode 100644 apps/web/src/hooks/use-tool-workshop.ts create mode 100644 apps/web/src/styles/global.css create mode 100644 apps/web/src/styles/pages/git-history.css create mode 100644 apps/web/src/styles/pages/projects.css create mode 100644 apps/web/src/styles/pages/repo-workspace.css create mode 100644 apps/web/src/styles/pages/sessions.css create mode 100644 apps/web/src/styles/pages/ssh-keys.css create mode 100644 apps/web/src/styles/pages/workspace-detail.css create mode 100644 apps/web/src/styles/syntax-highlight.css create mode 100644 apps/web/src/styles/tokens.css create mode 100644 apps/web/src/styles/utilities.css diff --git a/apps/web/src/components/features/tool-workshop/ToolTypeEditorPanel.tsx b/apps/web/src/components/features/tool-workshop/ToolTypeEditorPanel.tsx new file mode 100644 index 0000000..32dbcb9 --- /dev/null +++ b/apps/web/src/components/features/tool-workshop/ToolTypeEditorPanel.tsx @@ -0,0 +1,373 @@ +import { Icon } from "../../icon"; +import { ManifestEditor } from "../tool/manifest-editor"; +import type { ToolType } from "../../../api/tool-types"; +import type { ToolDefinitionManifest } from "../../../api/tool-definitions"; + +export interface ToolTypeFormState { + name: string; + display_name: string; + description: string; + category: string; + interface_type: "web" | "terminal"; + requires_port: boolean; + default_port: string; + definition_type: "compose" | "dockerfile" | "manifest"; + compose_template: string; + dockerfile_template: string; + readiness_command: string; + readiness_timeout: string; + readiness_interval: string; + required_variables: string; + startup_command: string; +} + +interface ToolTypeEditorPanelProps { + isCreating: boolean; + selectedToolType: ToolType | null; + form: ToolTypeFormState; + manifestData: Record | null; + manifestDefinitionId: string | null; + baseDefinitions: ToolDefinitionManifest[]; + toolTypeError: string | null; + toolTypeDirty: boolean; + onFormChange: (changes: Partial) => void; + onManifestChange: (manifest: Record | null) => void; + onSubmit: (e: React.FormEvent) => void; + onReset: () => void; +} + +export const ToolTypeEditorPanel = ({ + isCreating, + selectedToolType, + form, + manifestData, + manifestDefinitionId, + baseDefinitions, + toolTypeError, + toolTypeDirty, + onFormChange, + onManifestChange, + onSubmit, + onReset, +}: ToolTypeEditorPanelProps) => { + const hasSelection = isCreating || selectedToolType; + + return ( +
+ {!hasSelection ? ( +
+
+ +
+

+ Select a tool type +

+

+ Choose a tool from the list to edit, or create a new one. +

+
+ ) : ( +
+
+

+ {isCreating + ? "Create Tool Type" + : selectedToolType?.display_name} +

+ {!isCreating && ( +

+ {selectedToolType?.name} · {selectedToolType?.definition_type}{" "} + ·{" "} + {selectedToolType?.interface_type === "web" + ? `Port ${selectedToolType?.default_port}` + : "Terminal"} +

+ )} +
+ +
+
+ + +
+ +
+
+ + { + onFormChange({ name: e.target.value }); + }} + disabled={!isCreating} + placeholder="e.g., code-server" + className="form-input" + required + /> +
+
+ + { + onFormChange({ display_name: e.target.value }); + }} + placeholder="e.g., VS Code Server" + className="form-input" + required + /> +
+
+ +
+ + { + onFormChange({ description: e.target.value }); + }} + placeholder="Optional description" + className="form-input" + /> +
+ +
+
+ + { + onFormChange({ category: e.target.value }); + }} + placeholder="e.g., editor, notebook, ai-assistant" + className="form-input" + /> +
+
+ + +
+
+ + {form.interface_type === "terminal" && ( +
+ + { + onFormChange({ startup_command: e.target.value }); + }} + placeholder="e.g., cd /workspace && ls" + className="form-input" + /> + + Command to run before the interactive shell for each new + terminal session. + +
+ )} + + {form.requires_port && ( +
+ + { + onFormChange({ default_port: e.target.value }); + }} + placeholder="e.g., 8443" + className="form-input" + required + /> +
+ )} + + {form.definition_type === "manifest" ? ( + { + onManifestChange(m); + }} + definitionId={manifestDefinitionId} + /> + ) : ( +
+ +