refactor: organize frontend components into features/ directories

Moved 43 component files into 9 feature domains:
- features/git/ — commit-dialog, commit-panel, file-editor, git-mount-editor,
  git-toolbar, merge-dialog
- features/project/ — repositories-settings-tab, repository-create-dialog
- features/terminal/ — special-keys-panel, special-keys-strip,
  terminal-session-tabs, terminal
- features/workspace/ — workspace-card, workspace-create-form,
  workspace-header, workspace-instance-chips
- features/session/ — create-session-form, session-card, session-list
- features/tool/ — instance-list, manifest-editor, start-tool-fab,
  start-tool-modal, tool-starter, tools-bottom-sheet
- features/notification/ — event-toast-bridge, notification-center,
  notification-item
- features/settings/ — settings-tab-layout
- features/mobile/ — mobile-action-sheet, mobile-detail-view, mobile-edit-view,
  mobile-fab, mobile-list-view, mobile-nav, mobile-page-header,
  mobile-terminal-header, mobile-terminal-wrapper

Updated all imports across pages and components.
Root components/ now only contains generic UI pieces:
app-shell, code-editor, data-states, icon, protected-route, syntax-highlighter.

Quality gates: verified no remaining old imports.
This commit is contained in:
2026-06-04 12:37:24 +02:00
parent 7224afafd1
commit 1021d61be3
54 changed files with 31 additions and 31 deletions
@@ -0,0 +1,114 @@
/** Modal for starting a tool on a workspace. */
import { useState } from "react";
import { Icon } from "./icon";
import { listToolTypes, type ToolType } from "../api/tool-types";
import { useAsyncData } from "../hooks/use-async-data";
import type { Workspace } from "../types/workspace";
export interface StartToolModalProps {
workspace: Workspace;
onClose: () => void;
onStart: (toolTypeId: string, configProfileId?: string) => Promise<void>;
}
export function StartToolModal({
workspace,
onClose,
onStart,
}: StartToolModalProps) {
const [toolTypeId, setToolTypeId] = useState("");
const [configProfileId, setConfigProfileId] = useState("");
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const {
data: toolTypes,
status,
error: loadError,
} = useAsyncData<ToolType[]>(listToolTypes, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!toolTypeId) {
setError("Please select a tool type");
return;
}
setSubmitting(true);
setError(null);
try {
await onStart(toolTypeId, configProfileId || undefined);
onClose();
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to start tool");
} finally {
setSubmitting(false);
}
};
return (
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h3>
<Icon name="play" size="sm" /> Start Tool on {workspace.name}
</h3>
<button className="btn btn-icon" onClick={onClose}>
<Icon name="cancel" size="sm" />
</button>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="tool-type">Tool Type</label>
<select
id="tool-type"
value={toolTypeId}
onChange={(e) => setToolTypeId(e.target.value)}
disabled={submitting || status === "loading"}
>
<option value="">Select a tool...</option>
{toolTypes?.map((tt) => (
<option key={tt.id} value={tt.id}>
{tt.display_name}
</option>
))}
</select>
{status === "loading" && (
<span className="muted">Loading tools...</span>
)}
{loadError && <span className="error-text">{loadError}</span>}
</div>
<div className="form-group">
<label htmlFor="config-profile">Config Profile (optional)</label>
<input
id="config-profile"
type="text"
value={configProfileId}
onChange={(e) => setConfigProfileId(e.target.value)}
placeholder="Profile ID"
disabled={submitting}
/>
</div>
{error && <p className="form-error">{error}</p>}
<div className="form-actions">
<button
type="button"
className="btn btn-secondary"
onClick={onClose}
disabled={submitting}
>
Cancel
</button>
<button
type="submit"
className="btn btn-primary"
disabled={submitting || status !== "ready"}
>
{submitting ? "Starting..." : "Start Tool"}
</button>
</div>
</form>
</div>
</div>
);
}