@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
package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-assignees.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { type QueryClient, useMutation } from '@tanstack/react-query';
|
|
4
|
-
import { bulkWorkspaceTasks } from '@tuturuuu/internal-api/tasks';
|
|
5
4
|
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
8
|
import type { WorkspaceMember } from './bulk-operation-types';
|
|
10
9
|
import {
|
|
10
|
+
bulkWorkspaceTasksByEffectiveWorkspace,
|
|
11
11
|
getInternalApiOptions,
|
|
12
12
|
getTaskForRelationMutation,
|
|
13
|
+
restoreFailedBoardTasks,
|
|
14
|
+
snapshotBoardTaskCaches,
|
|
15
|
+
updateBoardTaskCaches,
|
|
13
16
|
} from './bulk-operation-utils';
|
|
14
17
|
|
|
15
18
|
export function useBulkAddAssignee(
|
|
@@ -80,17 +83,17 @@ export function useBulkAddAssignee(
|
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
const result = await
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
const result = await bulkWorkspaceTasksByEffectiveWorkspace({
|
|
87
|
+
queryClient,
|
|
88
|
+
boardId,
|
|
89
|
+
defaultWorkspaceId: wsId,
|
|
90
|
+
taskIds,
|
|
91
|
+
operation: {
|
|
92
|
+
type: 'add_assignee',
|
|
93
|
+
assigneeId,
|
|
91
94
|
},
|
|
92
|
-
apiOptions
|
|
93
|
-
);
|
|
95
|
+
options: apiOptions,
|
|
96
|
+
});
|
|
94
97
|
|
|
95
98
|
if (result.successCount === 0) {
|
|
96
99
|
throw new Error(
|
|
@@ -128,8 +131,9 @@ export function useBulkAddAssignee(
|
|
|
128
131
|
},
|
|
129
132
|
onMutate: async ({ assigneeId, taskIds }) => {
|
|
130
133
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
131
|
-
|
|
132
|
-
const
|
|
134
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
135
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
136
|
+
const current = cacheSnapshot.previousTasks || [];
|
|
133
137
|
|
|
134
138
|
const missingTaskIds = taskIds.filter((id) => {
|
|
135
139
|
const task = current.find((ct) => ct.id === id);
|
|
@@ -144,42 +148,28 @@ export function useBulkAddAssignee(
|
|
|
144
148
|
avatar_url: undefined,
|
|
145
149
|
};
|
|
146
150
|
|
|
147
|
-
queryClient
|
|
148
|
-
|
|
149
|
-
(
|
|
150
|
-
if (!
|
|
151
|
-
return
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
);
|
|
151
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
152
|
+
if (!old) return old;
|
|
153
|
+
return old.map((task) => {
|
|
154
|
+
if (!missingTaskIds.includes(task.id)) return task;
|
|
155
|
+
return {
|
|
156
|
+
...task,
|
|
157
|
+
assignees: [...(task.assignees || []), assigneeData],
|
|
158
|
+
} as Task;
|
|
159
|
+
});
|
|
160
|
+
});
|
|
160
161
|
|
|
161
|
-
return {
|
|
162
|
+
return { ...cacheSnapshot, modifiedTaskIds: missingTaskIds };
|
|
162
163
|
},
|
|
163
164
|
onError: (error, variables, context) => {
|
|
164
|
-
if (context
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
queryClient.setQueryData(
|
|
174
|
-
['tasks', boardId],
|
|
175
|
-
(old: Task[] | undefined) => {
|
|
176
|
-
if (!old) return old;
|
|
177
|
-
return old.map((task) => {
|
|
178
|
-
if (!requestedTaskIdSet.has(task.id)) return task;
|
|
179
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
);
|
|
165
|
+
if (context) {
|
|
166
|
+
restoreFailedBoardTasks({
|
|
167
|
+
queryClient,
|
|
168
|
+
boardId,
|
|
169
|
+
previousTasks: context.previousTasks,
|
|
170
|
+
previousFullTasks: context.previousFullTasks,
|
|
171
|
+
failedTaskIds: variables.taskIds,
|
|
172
|
+
});
|
|
183
173
|
}
|
|
184
174
|
|
|
185
175
|
console.error('Bulk add assignee failed', error);
|
|
@@ -188,26 +178,13 @@ export function useBulkAddAssignee(
|
|
|
188
178
|
);
|
|
189
179
|
},
|
|
190
180
|
onSuccess: (data, _variables, context) => {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
queryClient.setQueryData(
|
|
200
|
-
['tasks', boardId],
|
|
201
|
-
(old: Task[] | undefined) => {
|
|
202
|
-
if (!old) return old;
|
|
203
|
-
const failedIdSet = new Set(data.failedTaskIds);
|
|
204
|
-
return old.map((task) => {
|
|
205
|
-
if (!failedIdSet.has(task.id)) return task;
|
|
206
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
}
|
|
181
|
+
restoreFailedBoardTasks({
|
|
182
|
+
queryClient,
|
|
183
|
+
boardId,
|
|
184
|
+
previousTasks: context?.previousTasks,
|
|
185
|
+
previousFullTasks: context?.previousFullTasks,
|
|
186
|
+
failedTaskIds: data.failedTaskIds,
|
|
187
|
+
});
|
|
211
188
|
|
|
212
189
|
const modifiedTaskIdSet = new Set(
|
|
213
190
|
context?.modifiedTaskIds ?? data.succeededTaskIds
|
|
@@ -217,22 +194,17 @@ export function useBulkAddAssignee(
|
|
|
217
194
|
);
|
|
218
195
|
|
|
219
196
|
if (data.updatedAssigneesByTaskId.size > 0) {
|
|
220
|
-
queryClient
|
|
221
|
-
|
|
222
|
-
(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
assignees: updatedAssignees,
|
|
232
|
-
};
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
);
|
|
197
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
198
|
+
if (!old) return old;
|
|
199
|
+
return old.map((task) => {
|
|
200
|
+
const updatedAssignees = data.updatedAssigneesByTaskId.get(task.id);
|
|
201
|
+
if (!updatedAssignees) return task;
|
|
202
|
+
return {
|
|
203
|
+
...task,
|
|
204
|
+
assignees: updatedAssignees,
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
});
|
|
236
208
|
}
|
|
237
209
|
|
|
238
210
|
for (const tid of succeededModifiedTaskIds) {
|
|
@@ -280,17 +252,17 @@ export function useBulkRemoveAssignee(
|
|
|
280
252
|
}) => {
|
|
281
253
|
const apiOptions = getInternalApiOptions();
|
|
282
254
|
|
|
283
|
-
const result = await
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
255
|
+
const result = await bulkWorkspaceTasksByEffectiveWorkspace({
|
|
256
|
+
queryClient,
|
|
257
|
+
boardId,
|
|
258
|
+
defaultWorkspaceId: wsId,
|
|
259
|
+
taskIds,
|
|
260
|
+
operation: {
|
|
261
|
+
type: 'remove_assignee',
|
|
262
|
+
assigneeId,
|
|
291
263
|
},
|
|
292
|
-
apiOptions
|
|
293
|
-
);
|
|
264
|
+
options: apiOptions,
|
|
265
|
+
});
|
|
294
266
|
|
|
295
267
|
const successCount = result.successCount;
|
|
296
268
|
const succeededTaskIds = [...result.succeededTaskIds];
|
|
@@ -314,8 +286,9 @@ export function useBulkRemoveAssignee(
|
|
|
314
286
|
},
|
|
315
287
|
onMutate: async ({ assigneeId, taskIds }) => {
|
|
316
288
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
317
|
-
|
|
318
|
-
const
|
|
289
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
290
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
291
|
+
const current = cacheSnapshot.previousTasks || [];
|
|
319
292
|
const modifiedTaskIds = taskIds.filter((id) => {
|
|
320
293
|
const task = current.find((ct) => ct.id === id);
|
|
321
294
|
return !!task?.assignees?.some(
|
|
@@ -324,45 +297,31 @@ export function useBulkRemoveAssignee(
|
|
|
324
297
|
});
|
|
325
298
|
const taskIdSet = new Set(taskIds);
|
|
326
299
|
|
|
327
|
-
queryClient
|
|
328
|
-
|
|
329
|
-
(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
);
|
|
300
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
301
|
+
if (!old) return old;
|
|
302
|
+
return old.map((task) =>
|
|
303
|
+
taskIdSet.has(task.id)
|
|
304
|
+
? {
|
|
305
|
+
...task,
|
|
306
|
+
assignees: (task.assignees || []).filter(
|
|
307
|
+
(a) => a.id !== assigneeId
|
|
308
|
+
),
|
|
309
|
+
}
|
|
310
|
+
: task
|
|
311
|
+
);
|
|
312
|
+
});
|
|
343
313
|
|
|
344
|
-
return {
|
|
314
|
+
return { ...cacheSnapshot, modifiedTaskIds };
|
|
345
315
|
},
|
|
346
316
|
onError: (error, variables, context) => {
|
|
347
|
-
if (context
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
queryClient.setQueryData(
|
|
357
|
-
['tasks', boardId],
|
|
358
|
-
(old: Task[] | undefined) => {
|
|
359
|
-
if (!old) return old;
|
|
360
|
-
return old.map((task) => {
|
|
361
|
-
if (!requestedTaskIdSet.has(task.id)) return task;
|
|
362
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
);
|
|
317
|
+
if (context) {
|
|
318
|
+
restoreFailedBoardTasks({
|
|
319
|
+
queryClient,
|
|
320
|
+
boardId,
|
|
321
|
+
previousTasks: context.previousTasks,
|
|
322
|
+
previousFullTasks: context.previousFullTasks,
|
|
323
|
+
failedTaskIds: variables.taskIds,
|
|
324
|
+
});
|
|
366
325
|
}
|
|
367
326
|
|
|
368
327
|
console.error('Bulk remove assignee failed', error);
|
|
@@ -372,26 +331,13 @@ export function useBulkRemoveAssignee(
|
|
|
372
331
|
);
|
|
373
332
|
},
|
|
374
333
|
onSuccess: (data, _variables, context) => {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
queryClient.setQueryData(
|
|
384
|
-
['tasks', boardId],
|
|
385
|
-
(old: Task[] | undefined) => {
|
|
386
|
-
if (!old) return old;
|
|
387
|
-
const failedIdSet = new Set(data.failedTaskIds);
|
|
388
|
-
return old.map((task) => {
|
|
389
|
-
if (!failedIdSet.has(task.id)) return task;
|
|
390
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
);
|
|
394
|
-
}
|
|
334
|
+
restoreFailedBoardTasks({
|
|
335
|
+
queryClient,
|
|
336
|
+
boardId,
|
|
337
|
+
previousTasks: context?.previousTasks,
|
|
338
|
+
previousFullTasks: context?.previousFullTasks,
|
|
339
|
+
failedTaskIds: data.failedTaskIds,
|
|
340
|
+
});
|
|
395
341
|
|
|
396
342
|
const modifiedTaskIdSet = new Set(
|
|
397
343
|
context?.modifiedTaskIds ?? data.succeededTaskIds
|
package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-labels.ts
CHANGED
|
@@ -7,7 +7,13 @@ import { toast } from '@tuturuuu/ui/sonner';
|
|
|
7
7
|
import type { WorkspaceLabel } from '@tuturuuu/utils/task-helper';
|
|
8
8
|
import type { BoardBroadcastFn } from '../../../../shared/board-broadcast-context';
|
|
9
9
|
import type { BulkOperationI18n } from './bulk-operation-i18n';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getInternalApiOptions,
|
|
12
|
+
restoreBoardTaskCaches,
|
|
13
|
+
restoreFailedBoardTasks,
|
|
14
|
+
snapshotBoardTaskCaches,
|
|
15
|
+
updateBoardTaskCaches,
|
|
16
|
+
} from './bulk-operation-utils';
|
|
11
17
|
|
|
12
18
|
export function useBulkAddLabel(
|
|
13
19
|
queryClient: QueryClient,
|
|
@@ -52,8 +58,9 @@ export function useBulkAddLabel(
|
|
|
52
58
|
},
|
|
53
59
|
onMutate: async ({ labelId, taskIds }) => {
|
|
54
60
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
55
|
-
|
|
56
|
-
const
|
|
61
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
62
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
63
|
+
const current = cacheSnapshot.previousTasks || [];
|
|
57
64
|
const labelMeta = workspaceLabels.find((l) => l.id === labelId);
|
|
58
65
|
|
|
59
66
|
const missingTaskIds = taskIds.filter((id) => {
|
|
@@ -61,34 +68,31 @@ export function useBulkAddLabel(
|
|
|
61
68
|
return !task?.labels?.some((l) => l.id === labelId);
|
|
62
69
|
});
|
|
63
70
|
|
|
64
|
-
queryClient
|
|
65
|
-
|
|
66
|
-
(
|
|
67
|
-
if (!
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
...task,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
);
|
|
71
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
72
|
+
if (!old) return old;
|
|
73
|
+
return old.map((task) => {
|
|
74
|
+
if (!missingTaskIds.includes(task.id)) return task;
|
|
75
|
+
return {
|
|
76
|
+
...task,
|
|
77
|
+
labels: [
|
|
78
|
+
...(task.labels || []),
|
|
79
|
+
{
|
|
80
|
+
id: labelId,
|
|
81
|
+
ws_id: wsId || labelMeta?.ws_id || '',
|
|
82
|
+
name: labelMeta?.name || i18n?.defaultLabelName() || 'Label',
|
|
83
|
+
color: labelMeta?.color || '#3b82f6',
|
|
84
|
+
created_at: new Date().toISOString(),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
} as Task;
|
|
88
|
+
});
|
|
89
|
+
});
|
|
86
90
|
|
|
87
|
-
return {
|
|
91
|
+
return { ...cacheSnapshot, modifiedTaskIds: missingTaskIds };
|
|
88
92
|
},
|
|
89
93
|
onError: (error, _, context) => {
|
|
90
|
-
if (context
|
|
91
|
-
queryClient
|
|
94
|
+
if (context) {
|
|
95
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
92
96
|
}
|
|
93
97
|
console.error('Bulk add label failed', error);
|
|
94
98
|
toast.error(
|
|
@@ -100,22 +104,13 @@ export function useBulkAddLabel(
|
|
|
100
104
|
data.failures.map((failure) => failure.taskId)
|
|
101
105
|
);
|
|
102
106
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(old: Task[] | undefined) => {
|
|
111
|
-
if (!old) return old;
|
|
112
|
-
return old.map((task) => {
|
|
113
|
-
if (!failedTaskIds.has(task.id)) return task;
|
|
114
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
}
|
|
107
|
+
restoreFailedBoardTasks({
|
|
108
|
+
queryClient,
|
|
109
|
+
boardId,
|
|
110
|
+
previousTasks: context?.previousTasks,
|
|
111
|
+
previousFullTasks: context?.previousFullTasks,
|
|
112
|
+
failedTaskIds,
|
|
113
|
+
});
|
|
119
114
|
|
|
120
115
|
const modifiedTaskIds = context?.modifiedTaskIds ?? data.taskIds;
|
|
121
116
|
const succeededModifiedTaskIds = modifiedTaskIds.filter(
|
|
@@ -199,34 +194,32 @@ export function useBulkRemoveLabel(
|
|
|
199
194
|
},
|
|
200
195
|
onMutate: async ({ labelId, taskIds }) => {
|
|
201
196
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
202
|
-
|
|
203
|
-
const
|
|
197
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
198
|
+
const cacheSnapshot = snapshotBoardTaskCaches(queryClient, boardId);
|
|
199
|
+
const current = cacheSnapshot.previousTasks || [];
|
|
204
200
|
const modifiedTaskIds = taskIds.filter((id) => {
|
|
205
201
|
const task = current.find((ct) => ct.id === id);
|
|
206
202
|
return !!task?.labels?.some((label) => label.id === labelId);
|
|
207
203
|
});
|
|
208
204
|
const taskIdSet = new Set(taskIds);
|
|
209
205
|
|
|
210
|
-
queryClient
|
|
211
|
-
|
|
212
|
-
(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
);
|
|
206
|
+
updateBoardTaskCaches(queryClient, boardId, (old) => {
|
|
207
|
+
if (!old) return old;
|
|
208
|
+
return old.map((task) =>
|
|
209
|
+
taskIdSet.has(task.id)
|
|
210
|
+
? {
|
|
211
|
+
...task,
|
|
212
|
+
labels: (task.labels || []).filter((l) => l.id !== labelId),
|
|
213
|
+
}
|
|
214
|
+
: task
|
|
215
|
+
);
|
|
216
|
+
});
|
|
224
217
|
|
|
225
|
-
return {
|
|
218
|
+
return { ...cacheSnapshot, modifiedTaskIds };
|
|
226
219
|
},
|
|
227
220
|
onError: (error, _, context) => {
|
|
228
|
-
if (context
|
|
229
|
-
queryClient
|
|
221
|
+
if (context) {
|
|
222
|
+
restoreBoardTaskCaches(queryClient, boardId, context);
|
|
230
223
|
}
|
|
231
224
|
console.error('Bulk remove label failed', error);
|
|
232
225
|
toast.error(
|
|
@@ -239,22 +232,13 @@ export function useBulkRemoveLabel(
|
|
|
239
232
|
data.failures.map((failure) => failure.taskId)
|
|
240
233
|
);
|
|
241
234
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
(old: Task[] | undefined) => {
|
|
250
|
-
if (!old) return old;
|
|
251
|
-
return old.map((task) => {
|
|
252
|
-
if (!failedTaskIds.has(task.id)) return task;
|
|
253
|
-
return previousTaskMap.get(task.id) ?? task;
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
}
|
|
235
|
+
restoreFailedBoardTasks({
|
|
236
|
+
queryClient,
|
|
237
|
+
boardId,
|
|
238
|
+
previousTasks: context?.previousTasks,
|
|
239
|
+
previousFullTasks: context?.previousFullTasks,
|
|
240
|
+
failedTaskIds,
|
|
241
|
+
});
|
|
258
242
|
|
|
259
243
|
const modifiedTaskIds = context?.modifiedTaskIds ?? data.taskIds;
|
|
260
244
|
const succeededModifiedTaskIds = modifiedTaskIds.filter(
|