Skip to content

Commit c843c89

Browse files
committed
Persist new task draft across navigation
1 parent b6832ad commit c843c89

3 files changed

Lines changed: 65 additions & 17 deletions

File tree

apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useDraftStore } from "@features/message-editor/stores/draftStore";
12
import { TaskInput } from "@features/task-detail/components/TaskInput";
23
import { ArrowsOut, Plus, X } from "@phosphor-icons/react";
34
import { Flex, Text } from "@radix-ui/themes";
@@ -15,18 +16,35 @@ interface CommandCenterPanelProps {
1516
isActiveSession: boolean;
1617
}
1718

19+
function getCellSessionId(cellIndex: number): string {
20+
return `cc-cell-${cellIndex}`;
21+
}
22+
1823
function EmptyCell({ cellIndex }: { cellIndex: number }) {
1924
const [selectorOpen, setSelectorOpen] = useState(false);
20-
const [isCreating, setIsCreating] = useState(false);
25+
const isCreating = useCommandCenterStore((s) =>
26+
s.creatingCells.includes(cellIndex),
27+
);
2128
const assignTask = useCommandCenterStore((s) => s.assignTask);
29+
const startCreating = useCommandCenterStore((s) => s.startCreating);
30+
const stopCreating = useCommandCenterStore((s) => s.stopCreating);
31+
const clearDraft = useDraftStore((s) => s.actions.setDraft);
32+
33+
const sessionId = getCellSessionId(cellIndex);
2234

2335
const handleTaskCreated = useCallback(
2436
(task: Task) => {
2537
assignTask(cellIndex, task.id);
38+
clearDraft(sessionId, null);
2639
},
27-
[assignTask, cellIndex],
40+
[assignTask, cellIndex, clearDraft, sessionId],
2841
);
2942

43+
const handleCancel = useCallback(() => {
44+
stopCreating(cellIndex);
45+
clearDraft(sessionId, null);
46+
}, [stopCreating, cellIndex, clearDraft, sessionId]);
47+
3048
if (isCreating) {
3149
return (
3250
<Flex direction="column" height="100%">
@@ -46,15 +64,15 @@ function EmptyCell({ cellIndex }: { cellIndex: number }) {
4664
</Text>
4765
<button
4866
type="button"
49-
onClick={() => setIsCreating(false)}
67+
onClick={handleCancel}
5068
className="flex h-5 w-5 items-center justify-center rounded text-gray-10 transition-colors hover:bg-gray-4 hover:text-gray-12"
5169
title="Cancel"
5270
>
5371
<X size={12} />
5472
</button>
5573
</Flex>
5674
<Flex direction="column" className="min-h-0 flex-1">
57-
<TaskInput onTaskCreated={handleTaskCreated} />
75+
<TaskInput sessionId={sessionId} onTaskCreated={handleTaskCreated} />
5876
</Flex>
5977
</Flex>
6078
);
@@ -67,7 +85,7 @@ function EmptyCell({ cellIndex }: { cellIndex: number }) {
6785
cellIndex={cellIndex}
6886
open={selectorOpen}
6987
onOpenChange={setSelectorOpen}
70-
onNewTask={() => setIsCreating(true)}
88+
onNewTask={() => startCreating(cellIndex)}
7189
>
7290
<button
7391
type="button"

apps/code/src/renderer/features/command-center/stores/commandCenterStore.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface CommandCenterStoreState {
2424
cells: (string | null)[];
2525
activeTaskId: string | null;
2626
zoom: number;
27+
creatingCells: number[];
2728
}
2829

2930
interface CommandCenterStoreActions {
@@ -36,6 +37,8 @@ interface CommandCenterStoreActions {
3637
setZoom: (zoom: number) => void;
3738
zoomIn: () => void;
3839
zoomOut: () => void;
40+
startCreating: (cellIndex: number) => void;
41+
stopCreating: (cellIndex: number) => void;
3942
}
4043

4144
type CommandCenterStore = CommandCenterStoreState & CommandCenterStoreActions;
@@ -64,17 +67,22 @@ export const useCommandCenterStore = create<CommandCenterStore>()(
6467
cells: [null, null, null, null],
6568
activeTaskId: null,
6669
zoom: 1,
70+
creatingCells: [],
6771

6872
setLayout: (preset) =>
69-
set((state) => ({
70-
activeTaskId: resizeCells(state.cells, getCellCount(preset)).includes(
71-
state.activeTaskId,
72-
)
73-
? state.activeTaskId
74-
: null,
75-
layout: preset,
76-
cells: resizeCells(state.cells, getCellCount(preset)),
77-
})),
73+
set((state) => {
74+
const newCount = getCellCount(preset);
75+
return {
76+
activeTaskId: resizeCells(state.cells, newCount).includes(
77+
state.activeTaskId,
78+
)
79+
? state.activeTaskId
80+
: null,
81+
layout: preset,
82+
cells: resizeCells(state.cells, newCount),
83+
creatingCells: state.creatingCells.filter((i) => i < newCount),
84+
};
85+
}),
7886

7987
setActiveTask: (taskId) => set({ activeTaskId: taskId }),
8088

@@ -87,7 +95,11 @@ export const useCommandCenterStore = create<CommandCenterStore>()(
8795
cells[existingIndex] = null;
8896
}
8997
cells[cellIndex] = taskId;
90-
return { cells, activeTaskId: taskId };
98+
return {
99+
cells,
100+
activeTaskId: taskId,
101+
creatingCells: state.creatingCells.filter((i) => i !== cellIndex),
102+
};
91103
}),
92104

93105
removeTask: (cellIndex) =>
@@ -121,13 +133,26 @@ export const useCommandCenterStore = create<CommandCenterStore>()(
121133
set((state) => ({
122134
activeTaskId: null,
123135
cells: state.cells.map(() => null),
136+
creatingCells: [],
124137
})),
125138

126139
setZoom: (zoom) => set({ zoom: clampZoom(zoom) }),
127140
zoomIn: () =>
128141
set((state) => ({ zoom: clampZoom(state.zoom + ZOOM_STEP) })),
129142
zoomOut: () =>
130143
set((state) => ({ zoom: clampZoom(state.zoom - ZOOM_STEP) })),
144+
145+
startCreating: (cellIndex) =>
146+
set((state) => ({
147+
creatingCells: state.creatingCells.includes(cellIndex)
148+
? state.creatingCells
149+
: [...state.creatingCells, cellIndex],
150+
})),
151+
152+
stopCreating: (cellIndex) =>
153+
set((state) => ({
154+
creatingCells: state.creatingCells.filter((i) => i !== cellIndex),
155+
})),
131156
}),
132157
{
133158
name: "command-center-storage",
@@ -137,6 +162,7 @@ export const useCommandCenterStore = create<CommandCenterStore>()(
137162
cells: state.cells,
138163
activeTaskId: state.activeTaskId,
139164
zoom: state.zoom,
165+
creatingCells: state.creatingCells,
140166
}),
141167
},
142168
),

apps/code/src/renderer/features/task-detail/components/TaskInput.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ import { type WorkspaceMode, WorkspaceModeSelect } from "./WorkspaceModeSelect";
4040
const DOT_FILL = "var(--gray-6)";
4141

4242
interface TaskInputProps {
43+
sessionId?: string;
4344
onTaskCreated?: (task: import("@shared/types").Task) => void;
4445
}
4546

46-
export function TaskInput({ onTaskCreated }: TaskInputProps = {}) {
47+
export function TaskInput({
48+
sessionId = "task-input",
49+
onTaskCreated,
50+
}: TaskInputProps = {}) {
4751
const { cloudRegion } = useAuthStore();
4852
const trpcReact = useTRPC();
4953
const { view } = useNavigationStore();
@@ -441,7 +445,7 @@ export function TaskInput({ onTaskCreated }: TaskInputProps = {}) {
441445

442446
<TaskInputEditor
443447
ref={editorRef}
444-
sessionId="task-input"
448+
sessionId={sessionId}
445449
repoPath={selectedDirectory}
446450
isCreatingTask={isCreatingTask}
447451
canSubmit={canSubmit}

0 commit comments

Comments
 (0)