feat(app): sidebar, preset picker, wizard, App rewired around workspaces + LayoutEngine
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { useState } from "react";
|
||||
import { PresetPicker, PRESETS } from "./PresetPicker";
|
||||
import { openWorkspace, applyPreset } from "./socketBridge";
|
||||
|
||||
export function Wizard({ onDone, onCancel }: { onDone: (workspaceId: string) => void; onCancel: () => void }) {
|
||||
const [path, setPath] = useState(".");
|
||||
const [preset, setPreset] = useState("2x2");
|
||||
const [agents, setAgents] = useState<string[]>([]);
|
||||
const slots = PRESETS.find((p) => p.id === preset)?.slots ?? 1;
|
||||
const agentChoices = ["shell", "claude", "codex", "gemini"];
|
||||
|
||||
async function create() {
|
||||
const ws = await openWorkspace(path);
|
||||
const slotSpecs = Array.from({ length: slots }, (_, i) => {
|
||||
const a = agents[i] ?? "shell";
|
||||
return a === "shell" ? {} : { command: a };
|
||||
});
|
||||
await applyPreset(ws, preset, slotSpecs);
|
||||
onDone(ws);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ position: "fixed", inset: 0, background: "#000A", display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||||
<div style={{ width: 480, background: "#0E1116", border: "1px solid #323C49", borderRadius: 14, padding: 24, color: "#E6EDF3" }}>
|
||||
<div style={{ fontWeight: 700, fontSize: 16, marginBottom: 16 }}>New workspace</div>
|
||||
<label style={{ fontSize: 12, color: "#8B97A6" }}>Project folder</label>
|
||||
<input value={path} onChange={(e) => setPath(e.target.value)} style={{ width: "100%", margin: "6px 0 16px", padding: 8, background: "#0A0D12", color: "#E6EDF3", border: "1px solid #323C49", borderRadius: 8 }} />
|
||||
<label style={{ fontSize: 12, color: "#8B97A6" }}>Layout</label>
|
||||
<div style={{ margin: "8px 0 16px" }}><PresetPicker selected={preset} onSelect={setPreset} /></div>
|
||||
<label style={{ fontSize: 12, color: "#8B97A6" }}>Agents</label>
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, margin: "8px 0 20px" }}>
|
||||
{Array.from({ length: slots }, (_, i) => (
|
||||
<select key={i} value={agents[i] ?? "shell"} onChange={(e) => setAgents((a) => { const n = [...a]; n[i] = e.target.value; return n; })}
|
||||
style={{ padding: 8, background: "#1A2029", color: "#E6EDF3", border: "1px solid #323C49", borderRadius: 6 }}>
|
||||
{agentChoices.map((c) => <option key={c} value={c}>{c}</option>)}
|
||||
</select>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
|
||||
<button onClick={onCancel} style={{ padding: "8px 16px" }}>Cancel</button>
|
||||
<button onClick={() => void create()} style={{ padding: "8px 16px", background: "#4C8DFF", color: "#0A0D12", border: "none", borderRadius: 8, fontWeight: 700 }}>Create workspace</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user