@tuturuuu/ui 0.2.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/package.json +79 -67
- package/src/components/ui/__tests__/avatar.test.tsx +8 -5
- package/src/components/ui/calendar-app/components/calendar-connections-compact.tsx +414 -0
- package/src/components/ui/calendar-app/components/calendar-connections-manager.tsx +5 -1
- package/src/components/ui/calendar-app/components/calendar-connections-settings-content.tsx +529 -0
- package/src/components/ui/calendar-app/components/calendar-connections-unified.tsx +26 -1429
- package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +711 -0
- package/src/components/ui/chart.test.tsx +29 -0
- package/src/components/ui/chart.tsx +12 -3
- package/src/components/ui/chat/chat-agent-details-operations-panel.test.tsx +396 -2
- package/src/components/ui/chat/chat-agent-details-operations-panel.tsx +36 -8
- package/src/components/ui/chat/chat-agent-details-setup-panel.tsx +14 -0
- package/src/components/ui/chat/chat-agent-details-sidebar.test.tsx +5 -0
- package/src/components/ui/chat/chat-agent-details-sidebar.tsx +21 -7
- package/src/components/ui/chat/chat-agent-details-utils.test.ts +73 -0
- package/src/components/ui/chat/chat-agent-details-utils.tsx +100 -26
- package/src/components/ui/chat/chat-agent-details-zalo-personal-panel.tsx +517 -0
- package/src/components/ui/chat/chat-workspace.tsx +31 -1
- package/src/components/ui/chat/hooks-messages.test.tsx +45 -1
- package/src/components/ui/chat/hooks-messages.ts +1 -1
- package/src/components/ui/chat/hooks-realtime.ts +13 -16
- package/src/components/ui/custom/__tests__/settings-dialog-shell.test.tsx +24 -1
- package/src/components/ui/custom/__tests__/tuturuuu-logo.test.ts +12 -3
- package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +39 -0
- package/src/components/ui/custom/common-footer.tsx +16 -1
- package/src/components/ui/custom/production-indicator.tsx +1 -1
- package/src/components/ui/custom/settings/sidebar-settings.tsx +1 -1
- package/src/components/ui/custom/settings/task-settings.tsx +18 -0
- package/src/components/ui/custom/settings-dialog-shell.tsx +38 -23
- package/src/components/ui/custom/sidebar-context-compile-graph.test.ts +60 -0
- package/src/components/ui/custom/sidebar-context.tsx +61 -61
- package/src/components/ui/custom/sidebar-remote-behavior-bridge.tsx +123 -0
- package/src/components/ui/custom/tuturuuu-logo-urls.ts +6 -0
- package/src/components/ui/custom/tuturuuu-logo.tsx +25 -7
- package/src/components/ui/custom/workspace-select-helpers.ts +20 -0
- package/src/components/ui/custom/workspace-select.tsx +33 -12
- package/src/components/ui/finance/invoices/components/invoice-checkout-summary.tsx +7 -1
- package/src/components/ui/finance/invoices/components/invoice-payment-settings.tsx +3 -0
- package/src/components/ui/finance/invoices/components/invoice-products-permission-warning.tsx +58 -0
- package/src/components/ui/finance/invoices/components/subscription-group-selector.tsx +12 -20
- package/src/components/ui/finance/invoices/hooks/use-subscription-auto-selection.ts +10 -9
- package/src/components/ui/finance/invoices/hooks/use-subscription-invoice-content.ts +10 -5
- package/src/components/ui/finance/invoices/hooks.ts +75 -20
- package/src/components/ui/finance/invoices/new-invoice-page.test.tsx +137 -0
- package/src/components/ui/finance/invoices/new-invoice-page.tsx +86 -37
- package/src/components/ui/finance/invoices/product-selection.test.tsx +8 -26
- package/src/components/ui/finance/invoices/product-selection.tsx +2 -10
- package/src/components/ui/finance/invoices/standard-invoice.tsx +88 -26
- package/src/components/ui/finance/invoices/subscription-invoice.tsx +154 -46
- package/src/components/ui/finance/invoices/utils.test.ts +50 -0
- package/src/components/ui/finance/invoices/utils.ts +75 -17
- package/src/components/ui/finance/shared/finance-display-amount.tsx +3 -1
- package/src/components/ui/finance/shared/finance-permission-warning-dialog.test.tsx +34 -0
- package/src/components/ui/finance/shared/finance-permission-warning-dialog.tsx +157 -0
- package/src/components/ui/finance/transactions/form-basic-tab.tsx +8 -0
- package/src/components/ui/finance/transactions/form-more-tab.tsx +8 -0
- package/src/components/ui/finance/transactions/form-types.ts +2 -0
- package/src/components/ui/finance/transactions/form.test.tsx +43 -0
- package/src/components/ui/finance/transactions/form.tsx +60 -0
- package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +27 -0
- package/src/components/ui/finance/transactions/transactions-create-summary.tsx +13 -1
- package/src/components/ui/finance/transactions/transactions-infinite-page.tsx +4 -0
- package/src/components/ui/finance/transactions/transactions-page.tsx +23 -1
- package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +4 -0
- package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +5 -0
- package/src/components/ui/legacy/calendar/calendar-content.tsx +9 -1
- package/src/components/ui/legacy/calendar/event-modal.tsx +146 -2
- package/src/components/ui/legacy/calendar/event-preview-popover.tsx +200 -0
- package/src/components/ui/legacy/calendar/smart-calendar.test.tsx +76 -0
- package/src/components/ui/legacy/calendar/smart-calendar.tsx +13 -1
- package/src/components/ui/legacy/meet/page.test.ts +180 -0
- package/src/components/ui/legacy/meet/page.tsx +87 -39
- package/src/components/ui/tu-do/boards/boardId/board-column.tsx +79 -25
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/__tests__/bulk-mutations-external-workspaces.test.tsx +392 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-island.test.tsx +57 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-island.tsx +106 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-clear-delete.ts +106 -161
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-assignees.ts +96 -150
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-labels.ts +63 -79
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-projects.ts +64 -83
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-updates.ts +115 -155
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operation-utils.ts +319 -2
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operations.ts +8 -1
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +63 -37
- package/src/components/ui/tu-do/boards/boardId/kanban/kanban-column-collapse.ts +16 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +46 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +5 -3
- package/src/components/ui/tu-do/boards/boardId/kanban.tsx +19 -7
- package/src/components/ui/tu-do/boards/boardId/menus/__tests__/task-menus.test.tsx +181 -2
- package/src/components/ui/tu-do/boards/boardId/menus/index.ts +1 -0
- package/src/components/ui/tu-do/boards/boardId/menus/task-scheduling-menu.tsx +463 -0
- package/src/components/ui/tu-do/boards/boardId/menus/task-scheduling-utils.ts +109 -0
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +4 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/TaskCardCheckbox.tsx +6 -3
- package/src/components/ui/tu-do/boards/boardId/task-card/TaskCardDates.tsx +26 -9
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-checkbox-style.ts +39 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.test.ts +43 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.ts +33 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-completion-checkbox-visibility.test.ts +31 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-completion-checkbox-visibility.ts +9 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-identifier-row.test.tsx +124 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-identifier-row.tsx +88 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +151 -76
- package/src/components/ui/tu-do/boards/boardId/task-card/task-scheduling-badge.tsx +174 -0
- package/src/components/ui/tu-do/providers/task-dialog-provider.tsx +34 -13
- package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +54 -1
- package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +158 -0
- package/src/components/ui/tu-do/shared/__tests__/task-dialog-manager.test.tsx +5 -2
- package/src/components/ui/tu-do/shared/board-client.tsx +12 -2
- package/src/components/ui/tu-do/shared/board-views.tsx +195 -328
- package/src/components/ui/tu-do/shared/list-view.tsx +18 -8
- package/src/components/ui/tu-do/shared/task-due-date-visibility.test.ts +72 -0
- package/src/components/ui/tu-do/shared/task-due-date-visibility.ts +38 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-mutations.ts +6 -3
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-save.ts +2 -2
- package/src/components/ui/tu-do/shared/task-row-actions-menu.tsx +33 -0
- package/src/hooks/__tests__/use-calendar-readonly.test.tsx +74 -3
- package/src/hooks/__tests__/use-task-actions.test.tsx +118 -0
- package/src/hooks/__tests__/use-user-config.test.tsx +65 -0
- package/src/hooks/__tests__/use-workspace-presence.test.tsx +1 -1
- package/src/hooks/use-calendar-sync.tsx +22 -277
- package/src/hooks/use-calendar.tsx +95 -525
- package/src/hooks/use-semantic-task-search.ts +10 -33
- package/src/hooks/use-task-actions.ts +43 -117
- package/src/hooks/use-user-config.ts +1 -1
- package/src/hooks/use-workspace-config.ts +6 -2
- package/src/hooks/use-workspace-presence.ts +1 -1
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-bar.tsx +0 -94
|
@@ -2,11 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
import { type QueryClient, useMutation } from '@tanstack/react-query';
|
|
4
4
|
import { bulkWorkspaceTasks } from '@tuturuuu/internal-api/tasks';
|
|
5
|
-
import type { Task } from '@tuturuuu/types/primitives/Task';
|
|
6
5
|
import { toast } from '@tuturuuu/ui/sonner';
|
|
7
6
|
import type { BoardBroadcastFn } from '../../../../shared/board-broadcast-context';
|
|
8
7
|
import type { BulkOperationI18n } from './bulk-operation-i18n';
|
|
9
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type BulkTaskWorkspaceGroup,
|
|
10
|
+
bulkWorkspaceTasksByEffectiveWorkspace,
|
|
11
|
+
getInternalApiOptions,
|
|
12
|
+
restoreBoardTaskCaches,
|
|
13
|
+
restoreDeletedBoardTasks,
|
|
14
|
+
restoreFailedBoardTasks,
|
|
15
|
+
snapshotBoardTaskCaches,
|
|
16
|
+
updateBoardTaskCaches,
|
|
17
|
+
} from './bulk-operation-utils';
|
|
10
18
|
|
|
11
19
|
export function useBulkClearLabels(
|
|
12
20
|
queryClient: QueryClient,
|
|
@@ -38,24 +46,22 @@ export function useBulkClearLabels(
|
|
|
38
46
|
},
|
|
39
47
|
onMutate: async ({ taskIds }) => {
|
|
40
48
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
41
|
-
|
|
49
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
50
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
42
51
|
const taskIdSet = new Set(taskIds);
|
|
43
52
|
|
|
44
|
-
queryClient
|
|
45
|
-
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
);
|
|
53
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
54
|
+
if (!old) return old;
|
|
55
|
+
return old.map((task) =>
|
|
56
|
+
taskIdSet.has(task.id) ? { ...task, labels: [] } : task
|
|
57
|
+
);
|
|
58
|
+
});
|
|
53
59
|
|
|
54
|
-
return
|
|
60
|
+
return cacheSnapshot;
|
|
55
61
|
},
|
|
56
62
|
onError: (error, _, context) => {
|
|
57
|
-
if (context
|
|
58
|
-
queryClient
|
|
63
|
+
if (context) {
|
|
64
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
59
65
|
}
|
|
60
66
|
console.error('Bulk clear labels failed', error);
|
|
61
67
|
toast.error(
|
|
@@ -68,22 +74,13 @@ export function useBulkClearLabels(
|
|
|
68
74
|
data.failures.map((failure) => failure.taskId)
|
|
69
75
|
);
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
(old: Task[] | undefined) => {
|
|
79
|
-
if (!old) return old;
|
|
80
|
-
return old.map((task) => {
|
|
81
|
-
if (!failedTaskIds.has(task.id)) return task;
|
|
82
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
}
|
|
77
|
+
restoreFailedBoardTasks({
|
|
78
|
+
queryClient,
|
|
79
|
+
boardId,
|
|
80
|
+
previousTasks: context?.previousTasks,
|
|
81
|
+
previousFullTasks: context?.previousFullTasks,
|
|
82
|
+
failedTaskIds,
|
|
83
|
+
});
|
|
87
84
|
|
|
88
85
|
const succeededTaskIds = data.taskIds.filter(
|
|
89
86
|
(taskId) => !failedTaskIds.has(taskId)
|
|
@@ -147,24 +144,22 @@ export function useBulkClearProjects(
|
|
|
147
144
|
},
|
|
148
145
|
onMutate: async ({ taskIds }) => {
|
|
149
146
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
150
|
-
|
|
147
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
148
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
151
149
|
const taskIdSet = new Set(taskIds);
|
|
152
150
|
|
|
153
|
-
queryClient
|
|
154
|
-
|
|
155
|
-
(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
);
|
|
151
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
152
|
+
if (!old) return old;
|
|
153
|
+
return old.map((task) =>
|
|
154
|
+
taskIdSet.has(task.id) ? { ...task, projects: [] } : task
|
|
155
|
+
);
|
|
156
|
+
});
|
|
162
157
|
|
|
163
|
-
return
|
|
158
|
+
return cacheSnapshot;
|
|
164
159
|
},
|
|
165
160
|
onError: (error, _, context) => {
|
|
166
|
-
if (context
|
|
167
|
-
queryClient
|
|
161
|
+
if (context) {
|
|
162
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
168
163
|
}
|
|
169
164
|
console.error('Bulk clear projects failed', error);
|
|
170
165
|
toast.error(
|
|
@@ -177,22 +172,13 @@ export function useBulkClearProjects(
|
|
|
177
172
|
data.failures.map((failure) => failure.taskId)
|
|
178
173
|
);
|
|
179
174
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
(old: Task[] | undefined) => {
|
|
188
|
-
if (!old) return old;
|
|
189
|
-
return old.map((task) => {
|
|
190
|
-
if (!failedTaskIds.has(task.id)) return task;
|
|
191
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
);
|
|
195
|
-
}
|
|
175
|
+
restoreFailedBoardTasks({
|
|
176
|
+
queryClient,
|
|
177
|
+
boardId,
|
|
178
|
+
previousTasks: context?.previousTasks,
|
|
179
|
+
previousFullTasks: context?.previousFullTasks,
|
|
180
|
+
failedTaskIds,
|
|
181
|
+
});
|
|
196
182
|
|
|
197
183
|
const succeededTaskIds = data.taskIds.filter(
|
|
198
184
|
(taskId) => !failedTaskIds.has(taskId)
|
|
@@ -237,14 +223,14 @@ export function useBulkClearAssignees(
|
|
|
237
223
|
mutationFn: async ({ taskIds }: { taskIds: string[] }) => {
|
|
238
224
|
const apiOptions = getInternalApiOptions();
|
|
239
225
|
|
|
240
|
-
const result = await
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
},
|
|
246
|
-
apiOptions
|
|
247
|
-
);
|
|
226
|
+
const result = await bulkWorkspaceTasksByEffectiveWorkspace({
|
|
227
|
+
queryClient,
|
|
228
|
+
boardId,
|
|
229
|
+
defaultWorkspaceId: wsId,
|
|
230
|
+
taskIds,
|
|
231
|
+
operation: { type: 'clear_assignees' },
|
|
232
|
+
options: apiOptions,
|
|
233
|
+
});
|
|
248
234
|
|
|
249
235
|
if (result.successCount === 0 && taskIds.length > 0) {
|
|
250
236
|
throw new Error(
|
|
@@ -256,24 +242,22 @@ export function useBulkClearAssignees(
|
|
|
256
242
|
},
|
|
257
243
|
onMutate: async ({ taskIds }) => {
|
|
258
244
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
259
|
-
|
|
245
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
246
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
260
247
|
const taskIdSet = new Set(taskIds);
|
|
261
248
|
|
|
262
|
-
queryClient
|
|
263
|
-
|
|
264
|
-
(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
);
|
|
249
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
250
|
+
if (!old) return old;
|
|
251
|
+
return old.map((task) =>
|
|
252
|
+
taskIdSet.has(task.id) ? { ...task, assignees: [] } : task
|
|
253
|
+
);
|
|
254
|
+
});
|
|
271
255
|
|
|
272
|
-
return
|
|
256
|
+
return cacheSnapshot;
|
|
273
257
|
},
|
|
274
258
|
onError: (error, _, context) => {
|
|
275
|
-
if (context
|
|
276
|
-
queryClient
|
|
259
|
+
if (context) {
|
|
260
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
277
261
|
}
|
|
278
262
|
console.error('Bulk clear assignees failed', error);
|
|
279
263
|
toast.error(
|
|
@@ -286,22 +270,13 @@ export function useBulkClearAssignees(
|
|
|
286
270
|
data.failures.map((failure) => failure.taskId)
|
|
287
271
|
);
|
|
288
272
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
(old: Task[] | undefined) => {
|
|
297
|
-
if (!old) return old;
|
|
298
|
-
return old.map((task) => {
|
|
299
|
-
if (!failedTaskIds.has(task.id)) return task;
|
|
300
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
);
|
|
304
|
-
}
|
|
273
|
+
restoreFailedBoardTasks({
|
|
274
|
+
queryClient,
|
|
275
|
+
boardId,
|
|
276
|
+
previousTasks: context?.previousTasks,
|
|
277
|
+
previousFullTasks: context?.previousFullTasks,
|
|
278
|
+
failedTaskIds,
|
|
279
|
+
});
|
|
305
280
|
|
|
306
281
|
const succeededTaskIds = data.taskIds.filter(
|
|
307
282
|
(taskId) => !failedTaskIds.has(taskId)
|
|
@@ -345,20 +320,27 @@ export function useBulkDeleteTasks(
|
|
|
345
320
|
i18n?: BulkOperationI18n
|
|
346
321
|
) {
|
|
347
322
|
return useMutation({
|
|
348
|
-
mutationFn: async ({
|
|
323
|
+
mutationFn: async ({
|
|
324
|
+
taskIds,
|
|
325
|
+
workspaceGroups,
|
|
326
|
+
}: {
|
|
327
|
+
taskIds: string[];
|
|
328
|
+
workspaceGroups?: BulkTaskWorkspaceGroup[];
|
|
329
|
+
}) => {
|
|
349
330
|
const apiOptions = getInternalApiOptions();
|
|
350
331
|
|
|
351
|
-
const result = await
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
},
|
|
332
|
+
const result = await bulkWorkspaceTasksByEffectiveWorkspace({
|
|
333
|
+
queryClient,
|
|
334
|
+
boardId,
|
|
335
|
+
defaultWorkspaceId: wsId,
|
|
336
|
+
taskIds,
|
|
337
|
+
operation: {
|
|
338
|
+
type: 'update_fields',
|
|
339
|
+
updates: { deleted: true },
|
|
359
340
|
},
|
|
360
|
-
apiOptions
|
|
361
|
-
|
|
341
|
+
options: apiOptions,
|
|
342
|
+
workspaceGroups,
|
|
343
|
+
});
|
|
362
344
|
|
|
363
345
|
if (result.successCount === 0 && taskIds.length > 0) {
|
|
364
346
|
throw new Error(`Failed to delete all ${taskIds.length} tasks`);
|
|
@@ -368,22 +350,20 @@ export function useBulkDeleteTasks(
|
|
|
368
350
|
},
|
|
369
351
|
onMutate: async ({ taskIds }) => {
|
|
370
352
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
371
|
-
|
|
353
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
354
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
372
355
|
const taskIdSet = new Set(taskIds);
|
|
373
356
|
|
|
374
|
-
queryClient
|
|
375
|
-
|
|
376
|
-
(
|
|
377
|
-
|
|
378
|
-
return old.filter((task) => !taskIdSet.has(task.id));
|
|
379
|
-
}
|
|
380
|
-
);
|
|
357
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
358
|
+
if (!old) return old;
|
|
359
|
+
return old.filter((task) => !taskIdSet.has(task.id));
|
|
360
|
+
});
|
|
381
361
|
|
|
382
|
-
return
|
|
362
|
+
return cacheSnapshot;
|
|
383
363
|
},
|
|
384
364
|
onError: (error, _, context) => {
|
|
385
|
-
if (context
|
|
386
|
-
queryClient
|
|
365
|
+
if (context) {
|
|
366
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
387
367
|
}
|
|
388
368
|
console.error('Bulk delete failed', error);
|
|
389
369
|
toast.error(
|
|
@@ -395,48 +375,13 @@ export function useBulkDeleteTasks(
|
|
|
395
375
|
data.failures.map((failure) => failure.taskId)
|
|
396
376
|
);
|
|
397
377
|
|
|
398
|
-
|
|
399
|
-
queryClient
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
);
|
|
406
|
-
const previousTasks = context.previousTasks as Task[];
|
|
407
|
-
const previousOrder = new Map(
|
|
408
|
-
previousTasks.map((task, index) => [task.id, index])
|
|
409
|
-
);
|
|
410
|
-
|
|
411
|
-
for (const previousTask of previousTasks) {
|
|
412
|
-
if (!failedTaskIds.has(previousTask.id)) {
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
existingById.set(previousTask.id, previousTask);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return Array.from(existingById.values()).sort((a, b) => {
|
|
420
|
-
const aIndex = previousOrder.get(a.id);
|
|
421
|
-
const bIndex = previousOrder.get(b.id);
|
|
422
|
-
|
|
423
|
-
if (typeof aIndex === 'number' && typeof bIndex === 'number') {
|
|
424
|
-
return aIndex - bIndex;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (typeof aIndex === 'number') {
|
|
428
|
-
return -1;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (typeof bIndex === 'number') {
|
|
432
|
-
return 1;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return 0;
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
);
|
|
439
|
-
}
|
|
378
|
+
restoreDeletedBoardTasks({
|
|
379
|
+
queryClient,
|
|
380
|
+
boardId,
|
|
381
|
+
previousTasks: context?.previousTasks,
|
|
382
|
+
previousFullTasks: context?.previousFullTasks,
|
|
383
|
+
failedTaskIds,
|
|
384
|
+
});
|
|
440
385
|
|
|
441
386
|
const succeededTaskIds = data.taskIds.filter(
|
|
442
387
|
(taskId) => !failedTaskIds.has(taskId)
|