diff options
Diffstat (limited to 'apps/mobile/stores/taskStore.ts')
| -rw-r--r-- | apps/mobile/stores/taskStore.ts | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/apps/mobile/stores/taskStore.ts b/apps/mobile/stores/taskStore.ts new file mode 100644 index 0000000..1a08a45 --- /dev/null +++ b/apps/mobile/stores/taskStore.ts @@ -0,0 +1,84 @@ +import { create } from 'zustand'; +import type { TaskSummary, TaskOutputEntry } from '../lib/api'; + +interface TaskState { + // Data + tasks: TaskSummary[]; + selectedTaskId: string | null; + taskOutputs: Record<string, TaskOutputEntry[]>; + + // Actions + setTasks: (tasks: TaskSummary[]) => void; + updateTask: (taskId: string, update: Partial<TaskSummary>) => void; + selectTask: (taskId: string | null) => void; + appendOutput: (taskId: string, output: TaskOutputEntry) => void; + setTaskOutputs: (taskId: string, outputs: TaskOutputEntry[]) => void; + clearTaskOutputs: (taskId: string) => void; +} + +export const useTaskStore = create<TaskState>((set) => ({ + // Initial state + tasks: [], + selectedTaskId: null, + taskOutputs: {}, + + // Actions + setTasks: (tasks) => + set({ tasks }), + + updateTask: (taskId, update) => + set((state) => ({ + tasks: state.tasks.map((task) => + task.id === taskId ? { ...task, ...update } : task + ), + })), + + selectTask: (taskId) => + set({ selectedTaskId: taskId }), + + appendOutput: (taskId, output) => + set((state) => { + const existing = state.taskOutputs[taskId] ?? []; + // Avoid duplicates by checking ID + if (existing.some((o) => o.id === output.id)) { + return state; + } + return { + taskOutputs: { + ...state.taskOutputs, + [taskId]: [...existing, output], + }, + }; + }), + + setTaskOutputs: (taskId, outputs) => + set((state) => ({ + taskOutputs: { + ...state.taskOutputs, + [taskId]: outputs, + }, + })), + + clearTaskOutputs: (taskId) => + set((state) => { + const { [taskId]: _, ...rest } = state.taskOutputs; + return { taskOutputs: rest }; + }), +})); + +// Selectors for common use cases +export const selectSelectedTask = (state: TaskState) => + state.tasks.find((t) => t.id === state.selectedTaskId); + +export const selectRunningTasks = (state: TaskState) => + state.tasks.filter((t) => + ['running', 'initializing', 'starting'].includes(t.status) + ); + +export const selectPendingTasks = (state: TaskState) => + state.tasks.filter((t) => t.status === 'pending'); + +export const selectCompletedTasks = (state: TaskState) => + state.tasks.filter((t) => + ['done', 'failed', 'merged'].includes(t.status) + ); |
