@tuturuuu/ui 0.8.0 → 0.9.0
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 +40 -0
- package/biome.json +1 -1
- package/package.json +73 -71
- package/src/components/ui/accordion.tsx +1 -1
- package/src/components/ui/breadcrumb.tsx +1 -1
- package/src/components/ui/calendar-app/calendar-page-shell.tsx +4 -0
- package/src/components/ui/calendar-app/components/calendar-connections-settings-content.tsx +239 -33
- package/src/components/ui/calendar-app/components/load-smart-scheduling-tasks.tsx +143 -0
- package/src/components/ui/calendar-app/components/priority-view.tsx +10 -3
- package/src/components/ui/calendar-app/components/tasks-sidebar.tsx +4 -116
- package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +67 -2
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/carousel.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-external-thread-panel.test.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-external-thread-panel.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-operations-panel.test.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-operations-panel.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-setup-panel.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-sidebar.test.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-sidebar.tsx +2 -2
- package/src/components/ui/chat/chat-agent-details-utils.test.ts +1 -1
- package/src/components/ui/chat/chat-agent-details-utils.tsx +1 -1
- package/src/components/ui/chat/chat-agent-details-zalo-personal-panel.tsx +2 -2
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/color-picker.tsx +1 -1
- package/src/components/ui/command.tsx +1 -1
- package/src/components/ui/context-menu.tsx +5 -1
- package/src/components/ui/custom/__tests__/settings-dialog-shell.test.tsx +3 -0
- package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +19 -0
- package/src/components/ui/custom/combobox.test.tsx +195 -0
- package/src/components/ui/custom/combobox.tsx +273 -156
- package/src/components/ui/custom/education/modules/youtube/delete-link-button.tsx +5 -13
- package/src/components/ui/custom/facebook-mockup/facebook-mockup.tsx +7 -1
- package/src/components/ui/custom/facebook-mockup/form.tsx +1 -1
- package/src/components/ui/custom/facebook-mockup/image-upload-field.tsx +1 -1
- package/src/components/ui/custom/facebook-mockup/preview.tsx +1 -1
- package/src/components/ui/custom/settings-dialog-shell.tsx +2 -1
- package/src/components/ui/custom/theme-toggle.tsx +1 -1
- package/src/components/ui/custom/workspace-select.tsx +8 -3
- package/src/components/ui/dialog.test.tsx +52 -0
- package/src/components/ui/dialog.tsx +6 -2
- package/src/components/ui/dropdown-menu.tsx +5 -1
- package/src/components/ui/finance/debts/debt-loan-form.tsx +12 -5
- package/src/components/ui/finance/debts/debt-loan-summary.tsx +3 -2
- package/src/components/ui/finance/debts/debts-page.test.tsx +54 -5
- package/src/components/ui/finance/debts/debts-page.tsx +15 -2
- package/src/components/ui/finance/invoices/components/subscription-group-selector.tsx +3 -5
- package/src/components/ui/finance/invoices/new-invoice-page.test.tsx +25 -5
- package/src/components/ui/finance/invoices/new-invoice-page.tsx +7 -2
- package/src/components/ui/finance/invoices/standard-invoice.tsx +4 -2
- package/src/components/ui/finance/invoices/subscription-invoice.tsx +4 -2
- package/src/components/ui/finance/invoices/utils.ts +3 -1
- package/src/components/ui/finance/transactions/form-content-dialog.tsx +3 -0
- package/src/components/ui/finance/transactions/form-types.ts +1 -0
- package/src/components/ui/finance/transactions/form.tsx +2 -0
- package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +2 -0
- package/src/components/ui/finance/transactions/period-charts/category-breakdown-dialog.tsx +1 -1
- package/src/components/ui/finance/transactions/transaction-edit-dialog.tsx +1 -4
- package/src/components/ui/finance/transactions/transactions-create-summary.tsx +3 -0
- package/src/components/ui/finance/transactions/transactions-page.tsx +4 -1
- package/src/components/ui/finance/wallets/form.test.tsx +51 -3
- package/src/components/ui/finance/wallets/form.tsx +15 -4
- package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +4 -0
- package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +4 -2
- package/src/components/ui/finance/wallets/wallets-data-table.tsx +1 -0
- package/src/components/ui/finance/wallets/wallets-page.tsx +5 -2
- package/src/components/ui/input-otp.tsx +1 -1
- package/src/components/ui/legacy/calendar/all-day-event-bar.tsx +28 -39
- package/src/components/ui/legacy/calendar/calendar-cell.tsx +2 -0
- package/src/components/ui/legacy/calendar/calendar-content.tsx +10 -6
- package/src/components/ui/legacy/calendar/calendar-header.tsx +23 -3
- package/src/components/ui/legacy/calendar/calendar-loading-skeleton.tsx +135 -0
- package/src/components/ui/legacy/calendar/calendar-matrix.tsx +175 -237
- package/src/components/ui/legacy/calendar/event-card.test.tsx +177 -0
- package/src/components/ui/legacy/calendar/event-card.tsx +220 -131
- package/src/components/ui/legacy/calendar/event-modal.tsx +17 -17
- package/src/components/ui/legacy/calendar/event-provider-display.tsx +69 -0
- package/src/components/ui/legacy/calendar/smart-calendar.test.tsx +86 -4
- package/src/components/ui/legacy/calendar/smart-calendar.tsx +32 -2
- package/src/components/ui/legacy/meet/create-plan-dialog.tsx +19 -10
- package/src/components/ui/navigation-menu.tsx +1 -1
- package/src/components/ui/pagination.tsx +1 -1
- package/src/components/ui/radio-group.tsx +1 -1
- package/src/components/ui/select.tsx +5 -1
- package/src/components/ui/sheet.tsx +1 -1
- package/src/components/ui/sidebar.tsx +1 -1
- package/src/components/ui/storefront/cart-popover.tsx +61 -0
- package/src/components/ui/storefront/cart-summary-parts.tsx +290 -0
- package/src/components/ui/storefront/cart-summary.tsx +93 -154
- package/src/components/ui/storefront/checkout-overlay.tsx +4 -5
- package/src/components/ui/storefront/listing-card.tsx +1 -1
- package/src/components/ui/storefront/merch-sections.tsx +70 -0
- package/src/components/ui/storefront/product-detail.tsx +1 -1
- package/src/components/ui/storefront/storefront-surface.test.tsx +106 -11
- package/src/components/ui/storefront/storefront-surface.tsx +101 -166
- package/src/components/ui/storefront/types.ts +4 -0
- package/src/components/ui/storefront/utils.ts +6 -0
- package/src/components/ui/text-editor/__tests__/extensions.test.ts +123 -0
- package/src/components/ui/text-editor/background-color-extension.ts +62 -0
- package/src/components/ui/text-editor/color-controls.tsx +284 -0
- package/src/components/ui/text-editor/editor.tsx +69 -14
- package/src/components/ui/text-editor/extensions.ts +8 -2
- package/src/components/ui/text-editor/highlight-extension.ts +22 -0
- package/src/components/ui/text-editor/tool-bar.tsx +9 -16
- package/src/components/ui/toast.tsx +1 -1
- package/src/components/ui/tu-do/boards/__tests__/board-share-dialog.test.tsx +270 -0
- package/src/components/ui/tu-do/boards/board-public-link-section.tsx +231 -0
- package/src/components/ui/tu-do/boards/board-share-dialog.tsx +222 -109
- package/src/components/ui/tu-do/boards/boardId/board-column.tsx +112 -43
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-clear-delete.ts +2 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-move.ts +5 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-updates.ts +3 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/data/kanban-deadline-query.ts +50 -2
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/__tests__/column-reorder.test.ts +17 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/column-reorder.ts +4 -1
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-drag-cache.ts +38 -9
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-drag-order.ts +2 -8
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-sort-key.ts +47 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +81 -30
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/__tests__/kanban-planner-island.test.tsx +380 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/kanban-planner-dialog.tsx +204 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-digest-panel.tsx +61 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-item-strip.tsx +54 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-plan-toolbar.tsx +251 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-scope-badge.tsx +27 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-section.tsx +58 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-share-dialog.tsx +238 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-target-controls.tsx +143 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-utils.ts +65 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/planner/use-kanban-planner-state.ts +234 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +397 -2
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +103 -13
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-deadline-panels.tsx +443 -19
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-skeleton.tsx +94 -32
- package/src/components/ui/tu-do/boards/boardId/kanban.tsx +213 -106
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.test.tsx +26 -4
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +5 -2
- package/src/components/ui/tu-do/boards/boardId/task-card/measured-task-card.tsx +3 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.ts +3 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +191 -28
- package/src/components/ui/tu-do/boards/boardId/task-filter.test.tsx +152 -0
- package/src/components/ui/tu-do/boards/boardId/task-filter.tsx +555 -545
- package/src/components/ui/tu-do/boards/boardId/task-list.tsx +7 -0
- package/src/components/ui/tu-do/boards/share-section.tsx +100 -0
- package/src/components/ui/tu-do/drafts/draft-convert-dialog.tsx +10 -12
- package/src/components/ui/tu-do/drafts/drafts-page.tsx +33 -16
- package/src/components/ui/tu-do/initiatives/task-initiatives-client.tsx +56 -88
- package/src/components/ui/tu-do/my-tasks/my-tasks-content.tsx +26 -2
- package/src/components/ui/tu-do/my-tasks/use-my-tasks-state.ts +55 -8
- package/src/components/ui/tu-do/notes/note-edit-dialog.tsx +1 -4
- package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +25 -0
- package/src/components/ui/tu-do/shared/__tests__/board-header.test.tsx +341 -38
- package/src/components/ui/tu-do/shared/__tests__/board-switcher.test.tsx +253 -0
- package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +203 -2
- package/src/components/ui/tu-do/shared/__tests__/task-board-loading-state.test.tsx +17 -0
- package/src/components/ui/tu-do/shared/__tests__/task-legacy-route-recovery.test.tsx +16 -0
- package/src/components/ui/tu-do/shared/board-client.tsx +2 -7
- package/src/components/ui/tu-do/shared/board-config-storage.ts +7 -1
- package/src/components/ui/tu-do/shared/board-header.tsx +464 -975
- package/src/components/ui/tu-do/shared/board-layout-settings.tsx +165 -136
- package/src/components/ui/tu-do/shared/board-switcher.tsx +209 -217
- package/src/components/ui/tu-do/shared/board-views.tsx +587 -75
- package/src/components/ui/tu-do/shared/list-view.tsx +227 -1
- package/src/components/ui/tu-do/shared/recycle-bin-panel.tsx +142 -94
- package/src/components/ui/tu-do/shared/special-task-list-pins.ts +51 -0
- package/src/components/ui/tu-do/shared/task-board-loading-state.tsx +28 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/field-diff-viewer.tsx +3 -2
- package/src/components/ui/tu-do/shared/task-edit-dialog/selective-revert-panel.test.tsx +91 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/selective-revert-panel.tsx +123 -78
- package/src/components/ui/tu-do/shared/task-edit-dialog/task-activity-section.tsx +7 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/task-snapshot-dialog.tsx +8 -3
- package/src/components/ui/tu-do/shared/task-edit-dialog.tsx +2 -1
- package/src/components/ui/tu-do/shared/task-legacy-route-recovery.tsx +2 -9
- package/src/declarations.d.ts +1 -0
- package/src/hooks/__tests__/use-calendar-readonly.test.tsx +322 -2
- package/src/hooks/__tests__/use-calendar-sync.test.tsx +446 -0
- package/src/hooks/use-calendar-sync.tsx +247 -243
- package/src/hooks/use-calendar.tsx +323 -138
- package/src/hooks/use-task-actions.ts +24 -0
- package/src/hooks/use-user-workspace-config.ts +75 -0
- package/src/hooks/use-workspace-currency.ts +8 -3
- package/src/hooks/useBoardRealtimeEventHandler.ts +11 -0
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from '@tuturuuu/utils/task-list-status';
|
|
16
16
|
import { addDays } from 'date-fns';
|
|
17
17
|
import { useCallback } from 'react';
|
|
18
|
+
import { invalidateKanbanDeadlineTasks } from '../components/ui/tu-do/boards/boardId/kanban/data/kanban-deadline-query';
|
|
18
19
|
import { useBoardBroadcast } from '../components/ui/tu-do/shared/board-broadcast-context';
|
|
19
20
|
import {
|
|
20
21
|
dispatchTaskSoundCue,
|
|
@@ -81,6 +82,9 @@ export function useTaskActions({
|
|
|
81
82
|
}: UseTaskActionsProps) {
|
|
82
83
|
const queryClient = useQueryClient();
|
|
83
84
|
const broadcast = useBoardBroadcast();
|
|
85
|
+
const invalidateDeadlineTasks = useCallback(() => {
|
|
86
|
+
void invalidateKanbanDeadlineTasks(queryClient, boardId);
|
|
87
|
+
}, [boardId, queryClient]);
|
|
84
88
|
|
|
85
89
|
const resolveWorkspaceIdForTask = useCallback(
|
|
86
90
|
async (taskRecord?: Task) => {
|
|
@@ -272,6 +276,7 @@ export function useTaskActions({
|
|
|
272
276
|
description: `Task marked as ${targetCompletionList.status === 'done' ? 'done' : 'closed'} and moved to ${targetCompletionList.name}`,
|
|
273
277
|
});
|
|
274
278
|
dispatchTaskActionSound('complete');
|
|
279
|
+
invalidateDeadlineTasks();
|
|
275
280
|
} catch (error) {
|
|
276
281
|
console.error('Failed to complete external task:', error);
|
|
277
282
|
toast.error('Error', {
|
|
@@ -337,6 +342,7 @@ export function useTaskActions({
|
|
|
337
342
|
closed_at: movedTask?.closed_at,
|
|
338
343
|
},
|
|
339
344
|
});
|
|
345
|
+
invalidateDeadlineTasks();
|
|
340
346
|
|
|
341
347
|
toast.success('Task completed', {
|
|
342
348
|
description: `Task marked as done and moved to ${targetCompletionList.name}`,
|
|
@@ -395,6 +401,7 @@ export function useTaskActions({
|
|
|
395
401
|
},
|
|
396
402
|
});
|
|
397
403
|
dispatchTaskActionSound(newClosedState ? 'complete' : 'update');
|
|
404
|
+
invalidateDeadlineTasks();
|
|
398
405
|
} catch (error) {
|
|
399
406
|
// Rollback on error
|
|
400
407
|
if (previousTasks) {
|
|
@@ -422,6 +429,7 @@ export function useTaskActions({
|
|
|
422
429
|
getWorkspaceId,
|
|
423
430
|
markLocallyMutatedTask,
|
|
424
431
|
mergeLocallyMutatedTask,
|
|
432
|
+
invalidateDeadlineTasks,
|
|
425
433
|
]);
|
|
426
434
|
|
|
427
435
|
const handleMoveToCompletion = useCallback(async () => {
|
|
@@ -452,6 +460,7 @@ export function useTaskActions({
|
|
|
452
460
|
description: `Task marked as ${targetCompletionList.status === 'done' ? 'done' : 'closed'} and moved to ${targetCompletionList.name}`,
|
|
453
461
|
});
|
|
454
462
|
dispatchTaskActionSound('complete');
|
|
463
|
+
invalidateDeadlineTasks();
|
|
455
464
|
return;
|
|
456
465
|
}
|
|
457
466
|
|
|
@@ -514,6 +523,7 @@ export function useTaskActions({
|
|
|
514
523
|
}
|
|
515
524
|
}
|
|
516
525
|
if (successCount === 0) throw new Error('Failed to move any tasks');
|
|
526
|
+
invalidateDeadlineTasks();
|
|
517
527
|
|
|
518
528
|
if (failedTaskIds.length > 0) {
|
|
519
529
|
toast.warning('Partial completion update', {
|
|
@@ -561,6 +571,7 @@ export function useTaskActions({
|
|
|
561
571
|
getWorkspaceId,
|
|
562
572
|
markLocallyMutatedTask,
|
|
563
573
|
rollbackTaskIds,
|
|
574
|
+
invalidateDeadlineTasks,
|
|
564
575
|
]);
|
|
565
576
|
|
|
566
577
|
const handleMoveToClose = useCallback(async () => {
|
|
@@ -590,6 +601,7 @@ export function useTaskActions({
|
|
|
590
601
|
description: 'Task marked as closed',
|
|
591
602
|
});
|
|
592
603
|
dispatchTaskActionSound('complete');
|
|
604
|
+
invalidateDeadlineTasks();
|
|
593
605
|
return;
|
|
594
606
|
}
|
|
595
607
|
|
|
@@ -648,6 +660,7 @@ export function useTaskActions({
|
|
|
648
660
|
}
|
|
649
661
|
}
|
|
650
662
|
if (successCount === 0) throw new Error('Failed to move any tasks');
|
|
663
|
+
invalidateDeadlineTasks();
|
|
651
664
|
|
|
652
665
|
if (failedTaskIds.length > 0) {
|
|
653
666
|
toast.warning('Partial close update', {
|
|
@@ -692,6 +705,7 @@ export function useTaskActions({
|
|
|
692
705
|
getWorkspaceId,
|
|
693
706
|
markLocallyMutatedTask,
|
|
694
707
|
rollbackTaskIds,
|
|
708
|
+
invalidateDeadlineTasks,
|
|
695
709
|
]);
|
|
696
710
|
|
|
697
711
|
const handleDelete = useCallback(async () => {
|
|
@@ -764,6 +778,7 @@ export function useTaskActions({
|
|
|
764
778
|
}
|
|
765
779
|
|
|
766
780
|
if (successCount === 0) throw new Error('Failed to delete any tasks');
|
|
781
|
+
invalidateDeadlineTasks();
|
|
767
782
|
|
|
768
783
|
if (failedTaskIds.length > 0) {
|
|
769
784
|
toast.warning('Partial delete update', {
|
|
@@ -812,6 +827,7 @@ export function useTaskActions({
|
|
|
812
827
|
broadcast,
|
|
813
828
|
getWorkspaceId,
|
|
814
829
|
restoreDeletedTaskIds,
|
|
830
|
+
invalidateDeadlineTasks,
|
|
815
831
|
]);
|
|
816
832
|
|
|
817
833
|
const handleRemoveAllAssignees = useCallback(async () => {
|
|
@@ -1010,6 +1026,7 @@ export function useTaskActions({
|
|
|
1010
1026
|
description: `Task moved to ${targetList.name || 'selected list'}`,
|
|
1011
1027
|
});
|
|
1012
1028
|
dispatchTaskActionSound(getMoveSoundCue(targetList));
|
|
1029
|
+
invalidateDeadlineTasks();
|
|
1013
1030
|
} catch (error) {
|
|
1014
1031
|
console.error('Failed to move external task:', error);
|
|
1015
1032
|
toast.error('Error', {
|
|
@@ -1115,6 +1132,7 @@ export function useTaskActions({
|
|
|
1115
1132
|
}
|
|
1116
1133
|
}
|
|
1117
1134
|
if (successCount === 0) throw new Error('Failed to move any tasks');
|
|
1135
|
+
invalidateDeadlineTasks();
|
|
1118
1136
|
|
|
1119
1137
|
if (failedTaskIds.length > 0) {
|
|
1120
1138
|
toast.warning('Partial move update', {
|
|
@@ -1161,6 +1179,7 @@ export function useTaskActions({
|
|
|
1161
1179
|
markLocallyMutatedTask,
|
|
1162
1180
|
resolveWorkspaceIdForTask,
|
|
1163
1181
|
rollbackTaskIds,
|
|
1182
|
+
invalidateDeadlineTasks,
|
|
1164
1183
|
]
|
|
1165
1184
|
);
|
|
1166
1185
|
|
|
@@ -1243,6 +1262,7 @@ export function useTaskActions({
|
|
|
1243
1262
|
task: { id: tid, end_date: newDate },
|
|
1244
1263
|
});
|
|
1245
1264
|
}
|
|
1265
|
+
invalidateDeadlineTasks();
|
|
1246
1266
|
|
|
1247
1267
|
if (failedTaskIds.length > 0) {
|
|
1248
1268
|
toast.warning('Partial due date update', {
|
|
@@ -1283,6 +1303,7 @@ export function useTaskActions({
|
|
|
1283
1303
|
boardId,
|
|
1284
1304
|
task,
|
|
1285
1305
|
broadcast,
|
|
1306
|
+
invalidateDeadlineTasks,
|
|
1286
1307
|
]
|
|
1287
1308
|
);
|
|
1288
1309
|
|
|
@@ -1575,6 +1596,7 @@ export function useTaskActions({
|
|
|
1575
1596
|
// Use the centralized bulk update function from useBulkOperations
|
|
1576
1597
|
try {
|
|
1577
1598
|
await bulkUpdateCustomDueDate(date || null);
|
|
1599
|
+
invalidateDeadlineTasks();
|
|
1578
1600
|
} catch (error) {
|
|
1579
1601
|
console.error('Bulk custom date update failed', error);
|
|
1580
1602
|
toast.error('Failed to update due date for selected tasks');
|
|
@@ -1610,6 +1632,7 @@ export function useTaskActions({
|
|
|
1610
1632
|
broadcast?.('task:upsert', {
|
|
1611
1633
|
task: { id: task.id, end_date: newDate },
|
|
1612
1634
|
});
|
|
1635
|
+
invalidateDeadlineTasks();
|
|
1613
1636
|
|
|
1614
1637
|
toast.success('Due date updated', {
|
|
1615
1638
|
description: newDate
|
|
@@ -1639,6 +1662,7 @@ export function useTaskActions({
|
|
|
1639
1662
|
queryClient,
|
|
1640
1663
|
boardId,
|
|
1641
1664
|
broadcast,
|
|
1665
|
+
invalidateDeadlineTasks,
|
|
1642
1666
|
]
|
|
1643
1667
|
);
|
|
1644
1668
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import {
|
|
5
|
+
getUserWorkspaceConfig,
|
|
6
|
+
updateUserWorkspaceConfig,
|
|
7
|
+
} from '@tuturuuu/internal-api/users';
|
|
8
|
+
|
|
9
|
+
export function getUserWorkspaceConfigQueryKey(
|
|
10
|
+
workspaceId: string,
|
|
11
|
+
configId: string
|
|
12
|
+
) {
|
|
13
|
+
return ['user-workspace-config', workspaceId, configId] as const;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useUserWorkspaceConfig(
|
|
17
|
+
workspaceId: string,
|
|
18
|
+
configId: string,
|
|
19
|
+
defaultValue: string | null = null,
|
|
20
|
+
options?: {
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
staleTime?: number;
|
|
23
|
+
}
|
|
24
|
+
) {
|
|
25
|
+
return useQuery({
|
|
26
|
+
queryKey: getUserWorkspaceConfigQueryKey(workspaceId, configId),
|
|
27
|
+
queryFn: async () => {
|
|
28
|
+
const data = await getUserWorkspaceConfig(workspaceId, configId);
|
|
29
|
+
return data.value ?? defaultValue;
|
|
30
|
+
},
|
|
31
|
+
enabled: options?.enabled !== false && Boolean(workspaceId && configId),
|
|
32
|
+
staleTime: options?.staleTime ?? 5 * 60 * 1000,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function useUpdateUserWorkspaceConfig() {
|
|
37
|
+
const queryClient = useQueryClient();
|
|
38
|
+
|
|
39
|
+
return useMutation({
|
|
40
|
+
mutationFn: async ({
|
|
41
|
+
configId,
|
|
42
|
+
value,
|
|
43
|
+
workspaceId,
|
|
44
|
+
}: {
|
|
45
|
+
configId: string;
|
|
46
|
+
value: string | null;
|
|
47
|
+
workspaceId: string;
|
|
48
|
+
}) => updateUserWorkspaceConfig(workspaceId, configId, value),
|
|
49
|
+
onMutate: async ({ configId, value, workspaceId }) => {
|
|
50
|
+
const queryKey = getUserWorkspaceConfigQueryKey(workspaceId, configId);
|
|
51
|
+
await queryClient.cancelQueries({ queryKey });
|
|
52
|
+
|
|
53
|
+
const previousValue = queryClient.getQueryData<string | null>(queryKey);
|
|
54
|
+
queryClient.setQueryData(queryKey, value);
|
|
55
|
+
|
|
56
|
+
return { configId, previousValue, workspaceId };
|
|
57
|
+
},
|
|
58
|
+
onError: (_error, _variables, context) => {
|
|
59
|
+
if (!context) return;
|
|
60
|
+
|
|
61
|
+
queryClient.setQueryData(
|
|
62
|
+
getUserWorkspaceConfigQueryKey(context.workspaceId, context.configId),
|
|
63
|
+
context.previousValue ?? null
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
onSettled: (_data, _error, variables) => {
|
|
67
|
+
queryClient.invalidateQueries({
|
|
68
|
+
queryKey: getUserWorkspaceConfigQueryKey(
|
|
69
|
+
variables.workspaceId,
|
|
70
|
+
variables.configId
|
|
71
|
+
),
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getCurrencyLocale,
|
|
3
|
+
resolveSupportedCurrency,
|
|
3
4
|
type SupportedCurrency,
|
|
4
5
|
} from '@tuturuuu/utils/currencies';
|
|
5
6
|
|
|
@@ -8,14 +9,18 @@ import { useWorkspaceConfig } from './use-workspace-config';
|
|
|
8
9
|
// Re-export for convenience
|
|
9
10
|
export type { SupportedCurrency } from '@tuturuuu/utils/currencies';
|
|
10
11
|
|
|
11
|
-
export const useWorkspaceCurrency = (
|
|
12
|
+
export const useWorkspaceCurrency = (
|
|
13
|
+
wsId: string,
|
|
14
|
+
fallbackCurrency = 'USD'
|
|
15
|
+
) => {
|
|
16
|
+
const fallback = resolveSupportedCurrency(fallbackCurrency);
|
|
12
17
|
const { data, isLoading, error } = useWorkspaceConfig<SupportedCurrency>(
|
|
13
18
|
wsId,
|
|
14
19
|
'DEFAULT_CURRENCY',
|
|
15
|
-
|
|
20
|
+
fallback
|
|
16
21
|
);
|
|
17
22
|
|
|
18
|
-
const currency = (data
|
|
23
|
+
const currency = resolveSupportedCurrency(data, fallback);
|
|
19
24
|
|
|
20
25
|
return {
|
|
21
26
|
currency,
|
|
@@ -188,6 +188,16 @@ function invalidateTaskMembershipQueries(
|
|
|
188
188
|
void queryClient.invalidateQueries({
|
|
189
189
|
queryKey: ['task-list-counts', boardId],
|
|
190
190
|
});
|
|
191
|
+
void queryClient.invalidateQueries({
|
|
192
|
+
predicate: (query) => {
|
|
193
|
+
const queryKey = query.queryKey;
|
|
194
|
+
return (
|
|
195
|
+
Array.isArray(queryKey) &&
|
|
196
|
+
queryKey[0] === 'kanban-deadline-tasks' &&
|
|
197
|
+
queryKey[2] === boardId
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
});
|
|
191
201
|
void queryClient.invalidateQueries({ queryKey: ['my-tasks'] });
|
|
192
202
|
void queryClient.invalidateQueries({ queryKey: ['my-completed-tasks'] });
|
|
193
203
|
}
|
|
@@ -342,6 +352,7 @@ export function useBoardRealtimeEventHandler({
|
|
|
342
352
|
patchMyTasksCaches(queryClient, taskData);
|
|
343
353
|
if (
|
|
344
354
|
'list_id' in taskData ||
|
|
355
|
+
'end_date' in taskData ||
|
|
345
356
|
'completed' in taskData ||
|
|
346
357
|
'completed_at' in taskData ||
|
|
347
358
|
'closed_at' in taskData ||
|