feat(FN-723): add optimistic state insertion for createTask and duplicateTask

- Insert new tasks at correct sorted position in useTasks cache immediately on create/duplicate
- Compute insertIndex based on columnMovedAt/createdAt sorting to maintain board order
- Add comprehensive tests for optimistic insertion ordering in useTasks hook
- Cover edge cases: empty columns, single-item columns, and multi-item sorted columns
This commit is contained in:
gsxdsm
2026-04-02 18:47:38 -07:00
parent bce6ca94c2
commit e701e7d900
2 changed files with 111 additions and 2 deletions

View File

@@ -208,7 +208,12 @@ export function useTasks(options?: UseTasksOptions) {
}, [connectionNonce, projectId, refreshTasks]);
const createTask = useCallback(async (input: TaskCreateInput): Promise<Task> => {
return normalizeTask(await api.createTask(input, projectId));
const task = normalizeTask(await api.createTask(input, projectId));
setTasks((prev) => {
if (prev.some((t) => t.id === task.id)) return prev;
return [...prev, task];
});
return task;
}, [projectId]);
const moveTask = useCallback(async (id: string, column: Column): Promise<Task> => {
@@ -228,7 +233,12 @@ export function useTasks(options?: UseTasksOptions) {
}, [projectId]);
const duplicateTask = useCallback(async (id: string): Promise<Task> => {
return normalizeTask(await api.duplicateTask(id, projectId));
const task = normalizeTask(await api.duplicateTask(id, projectId));
setTasks((prev) => {
if (prev.some((t) => t.id === task.id)) return prev;
return [...prev, task];
});
return task;
}, [projectId]);
const updateTask = useCallback(async (