@tuturuuu/ui 0.8.0 → 0.10.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 +69 -0
- package/biome.json +1 -1
- package/package.json +74 -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-search.test.ts +78 -0
- package/src/components/ui/custom/__tests__/settings-dialog-shell-compile-graph.test.ts +76 -0
- package/src/components/ui/custom/__tests__/settings-dialog-shell.test.tsx +3 -0
- package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +46 -1
- 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/nav-link.test.tsx +165 -0
- package/src/components/ui/custom/nav-link.tsx +69 -11
- package/src/components/ui/custom/navigation.tsx +1 -0
- package/src/components/ui/custom/settings/task-settings.tsx +104 -0
- package/src/components/ui/custom/settings-dialog-search-loader.d.ts +5 -0
- package/src/components/ui/custom/settings-dialog-search-loader.js +3 -0
- package/src/components/ui/custom/settings-dialog-search.ts +75 -0
- package/src/components/ui/custom/settings-dialog-shell.tsx +65 -28
- package/src/components/ui/custom/theme-toggle.tsx +1 -1
- package/src/components/ui/custom/workspace-select-helpers.ts +23 -0
- package/src/components/ui/custom/workspace-select.tsx +25 -19
- 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 +286 -0
- package/src/components/ui/tu-do/boards/__tests__/task-board-form.test.tsx +12 -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 +15 -226
- package/src/components/ui/tu-do/boards/board-share-settings-panel.tsx +351 -0
- package/src/components/ui/tu-do/boards/boardId/board-column.tsx +121 -39
- package/src/components/ui/tu-do/boards/boardId/enhanced-task-list.tsx +7 -0
- 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/bulk/bulk-operation-types.ts +3 -3
- 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/data/use-bulk-resources.ts +59 -5
- 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/drag-preview.tsx +20 -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 +642 -5
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +224 -15
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-deadline-panels.tsx +535 -53
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-skeleton.tsx +101 -33
- package/src/components/ui/tu-do/boards/boardId/kanban.tsx +235 -113
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.test.tsx +50 -5
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +12 -2
- package/src/components/ui/tu-do/boards/boardId/task-card/measured-task-card.tsx +10 -1
- 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-open-options.test.ts +20 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-open-options.ts +10 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +271 -36
- 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 +22 -0
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-grid.tsx +9 -0
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-task-row.tsx +9 -0
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-toolbar.tsx +9 -0
- package/src/components/ui/tu-do/boards/boardId/timeline-board.tsx +35 -3
- package/src/components/ui/tu-do/boards/form.tsx +1 -1
- 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/hooks/__tests__/useTaskLabelManagement.test.tsx +48 -0
- package/src/components/ui/tu-do/hooks/__tests__/useTaskProjectManagement.test.tsx +144 -0
- package/src/components/ui/tu-do/hooks/useTaskDialog.ts +7 -0
- package/src/components/ui/tu-do/hooks/useTaskLabelManagement.ts +115 -106
- package/src/components/ui/tu-do/hooks/useTaskProjectManagement.ts +115 -122
- 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/progress/task-progress-import-panel.tsx +60 -0
- package/src/components/ui/tu-do/progress/task-progress-leaderboards-panel.tsx +156 -0
- package/src/components/ui/tu-do/progress/task-progress-page.tsx +348 -0
- package/src/components/ui/tu-do/progress/task-progress-panels.tsx +301 -0
- package/src/components/ui/tu-do/providers/task-dialog-provider.tsx +26 -0
- package/src/components/ui/tu-do/shared/__tests__/assignee-select.test.tsx +81 -10
- package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +141 -1
- package/src/components/ui/tu-do/shared/__tests__/board-header.test.tsx +377 -36
- package/src/components/ui/tu-do/shared/__tests__/board-switcher.test.tsx +374 -0
- package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +419 -5
- package/src/components/ui/tu-do/shared/__tests__/task-board-loading-state.test.tsx +38 -0
- package/src/components/ui/tu-do/shared/__tests__/task-cache-patches.test.ts +147 -0
- package/src/components/ui/tu-do/shared/__tests__/task-legacy-route-recovery.test.tsx +16 -0
- package/src/components/ui/tu-do/shared/__tests__/use-progressive-board-loader.test.tsx +3 -0
- package/src/components/ui/tu-do/shared/assignee-select.tsx +77 -26
- package/src/components/ui/tu-do/shared/board-client.tsx +15 -10
- package/src/components/ui/tu-do/shared/board-config-storage.ts +7 -1
- package/src/components/ui/tu-do/shared/board-header.tsx +471 -975
- package/src/components/ui/tu-do/shared/board-layout-settings.tsx +165 -136
- package/src/components/ui/tu-do/shared/board-switcher.tsx +244 -220
- package/src/components/ui/tu-do/shared/board-user-presence-avatars.tsx +18 -12
- package/src/components/ui/tu-do/shared/board-views.tsx +577 -85
- package/src/components/ui/tu-do/shared/list-view.tsx +246 -2
- 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-cache-patches.ts +394 -0
- package/src/components/ui/tu-do/shared/task-dialog-manager.tsx +21 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/quick-settings-popover.tsx +5 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-dialog-header.tsx +25 -2
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-list-selector.tsx +7 -1
- 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/hooks/use-task-data.ts +79 -10
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-mutations.ts +76 -77
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-relationships.test.tsx +63 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-relationships.ts +78 -69
- package/src/components/ui/tu-do/shared/task-edit-dialog/personal-overrides-section.tsx +28 -8
- package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/dependencies-section.tsx +14 -3
- package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/parent-section.tsx +6 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/related-section.tsx +6 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/subtasks-section.tsx +6 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/types/task-relationships.types.ts +8 -0
- 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-dialog-actions.tsx +8 -1
- package/src/components/ui/tu-do/shared/task-edit-dialog/task-properties-section.test.tsx +150 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/task-properties-section.tsx +61 -35
- package/src/components/ui/tu-do/shared/task-edit-dialog/task-relationships-properties.tsx +44 -2
- 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 +11 -1
- package/src/components/ui/tu-do/shared/task-legacy-route-recovery.tsx +2 -9
- package/src/components/ui/tu-do/shared/task-row-actions-menu.tsx +11 -0
- package/src/components/ui/tu-do/shared/use-progressive-board-loader.ts +2 -0
- 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/__tests__/useBoardPresence.test.tsx +191 -0
- package/src/hooks/__tests__/useBoardRealtime.test.tsx +24 -144
- 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/useBoardPresence.ts +364 -0
- package/src/hooks/useBoardRealtimeEventHandler.ts +45 -90
- package/src/lib/workspace-actions.ts +2 -6
|
@@ -6,7 +6,17 @@ import {
|
|
|
6
6
|
import type { Task } from '@tuturuuu/types/primitives/Task';
|
|
7
7
|
import { toast } from '@tuturuuu/ui/sonner';
|
|
8
8
|
import { useState } from 'react';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getActiveBoardRefresh,
|
|
11
|
+
useBoardBroadcast,
|
|
12
|
+
} from '../shared/board-broadcast-context';
|
|
13
|
+
import {
|
|
14
|
+
getTaskFromVisibleCaches,
|
|
15
|
+
patchTaskInVisibleCaches,
|
|
16
|
+
restoreTasksFromVisibleCacheSnapshot,
|
|
17
|
+
restoreVisibleTaskCaches,
|
|
18
|
+
snapshotVisibleTaskCaches,
|
|
19
|
+
} from '../shared/task-cache-patches';
|
|
10
20
|
|
|
11
21
|
function getInternalApiOptions() {
|
|
12
22
|
if (typeof window === 'undefined') {
|
|
@@ -89,10 +99,14 @@ export function useTaskProjectManagement({
|
|
|
89
99
|
|
|
90
100
|
// CRITICAL: Get current task state from cache instead of stale prop
|
|
91
101
|
// This ensures we read the most up-to-date state after optimistic updates
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
const canonicalTaskId = taskId ?? task.id;
|
|
103
|
+
const currentTask =
|
|
104
|
+
getTaskFromVisibleCaches({
|
|
105
|
+
queryClient,
|
|
106
|
+
boardId,
|
|
107
|
+
taskId: canonicalTaskId,
|
|
108
|
+
fallback: task,
|
|
109
|
+
}) ?? task;
|
|
96
110
|
|
|
97
111
|
// Check if we're in multi-select mode with multiple tasks selected
|
|
98
112
|
const shouldBulkUpdate =
|
|
@@ -107,11 +121,17 @@ export function useTaskProjectManagement({
|
|
|
107
121
|
|
|
108
122
|
// Cancel any outgoing refetches
|
|
109
123
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
124
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
110
125
|
|
|
111
126
|
// Snapshot the previous value BEFORE optimistic update
|
|
112
127
|
const previousTasks = queryClient.getQueryData(['tasks', boardId]) as
|
|
113
128
|
| Task[]
|
|
114
129
|
| undefined;
|
|
130
|
+
const cacheSnapshot = snapshotVisibleTaskCaches(
|
|
131
|
+
queryClient,
|
|
132
|
+
boardId,
|
|
133
|
+
tasksToUpdate
|
|
134
|
+
);
|
|
115
135
|
|
|
116
136
|
// Determine action: remove if ALL selected tasks have the project, add otherwise
|
|
117
137
|
// Use currentTask from cache, not stale task prop
|
|
@@ -133,6 +153,13 @@ export function useTaskProjectManagement({
|
|
|
133
153
|
const fromBoardCache = previousTasks?.find((ct) => ct.id === taskId);
|
|
134
154
|
if (fromBoardCache) return fromBoardCache;
|
|
135
155
|
|
|
156
|
+
const fromVisibleCaches = getTaskFromVisibleCaches({
|
|
157
|
+
queryClient,
|
|
158
|
+
boardId,
|
|
159
|
+
taskId,
|
|
160
|
+
});
|
|
161
|
+
if (fromVisibleCaches) return fromVisibleCaches;
|
|
162
|
+
|
|
136
163
|
// Fallback to individual task cache (for tasks not in board view)
|
|
137
164
|
if (taskId === currentTask.id) return currentTask;
|
|
138
165
|
|
|
@@ -156,54 +183,44 @@ export function useTaskProjectManagement({
|
|
|
156
183
|
|
|
157
184
|
// Get project details from workspace projects for optimistic update
|
|
158
185
|
const project = workspaceProjects.find((p) => p.id === projectId);
|
|
186
|
+
const fallbackProject = project
|
|
187
|
+
? {
|
|
188
|
+
id: project.id,
|
|
189
|
+
name: project.name,
|
|
190
|
+
status: project.status ?? 'unknown',
|
|
191
|
+
}
|
|
192
|
+
: {
|
|
193
|
+
id: projectId,
|
|
194
|
+
name: 'Unknown',
|
|
195
|
+
status: 'unknown',
|
|
196
|
+
};
|
|
159
197
|
|
|
160
198
|
// Optimistically update the cache - only update tasks that actually change
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// CRITICAL: Also update the individual task cache if taskId is provided
|
|
185
|
-
// This ensures the chip menu's task cache stays in sync with the board cache
|
|
186
|
-
if (taskId) {
|
|
187
|
-
queryClient.setQueryData(['task', taskId], (old: Task | undefined) => {
|
|
188
|
-
if (!old) return old;
|
|
189
|
-
if (active && tasksToRemoveFrom.includes(taskId)) {
|
|
190
|
-
// Remove the project
|
|
191
|
-
return {
|
|
192
|
-
...old,
|
|
193
|
-
projects:
|
|
194
|
-
old.projects?.filter((p: any) => p.id !== projectId) || [],
|
|
195
|
-
};
|
|
196
|
-
} else if (!active && tasksNeedingProject.includes(taskId)) {
|
|
197
|
-
// Add the project
|
|
199
|
+
for (const tid of active ? tasksToRemoveFrom : tasksNeedingProject) {
|
|
200
|
+
patchTaskInVisibleCaches({
|
|
201
|
+
queryClient,
|
|
202
|
+
boardId,
|
|
203
|
+
taskId: tid,
|
|
204
|
+
updater: (cachedTask) => {
|
|
205
|
+
if (active) {
|
|
206
|
+
return {
|
|
207
|
+
...cachedTask,
|
|
208
|
+
projects:
|
|
209
|
+
cachedTask.projects?.filter(
|
|
210
|
+
(entry) => entry.id !== projectId
|
|
211
|
+
) || [],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (cachedTask.projects?.some((entry) => entry.id === projectId)) {
|
|
216
|
+
return cachedTask;
|
|
217
|
+
}
|
|
218
|
+
|
|
198
219
|
return {
|
|
199
|
-
...
|
|
200
|
-
projects: [
|
|
201
|
-
...(old.projects || []),
|
|
202
|
-
project || { id: projectId, name: 'Unknown', status: 'unknown' },
|
|
203
|
-
],
|
|
220
|
+
...cachedTask,
|
|
221
|
+
projects: [...(cachedTask.projects || []), fallbackProject],
|
|
204
222
|
};
|
|
205
|
-
}
|
|
206
|
-
return old;
|
|
223
|
+
},
|
|
207
224
|
});
|
|
208
225
|
}
|
|
209
226
|
|
|
@@ -281,34 +298,19 @@ export function useTaskProjectManagement({
|
|
|
281
298
|
(taskId) => !succeededTaskIds.includes(taskId)
|
|
282
299
|
);
|
|
283
300
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (!current) return current;
|
|
290
|
-
return current.map((task) => {
|
|
291
|
-
if (!failedTaskIds.includes(task.id)) {
|
|
292
|
-
return task;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return previousTaskMap.get(task.id) || task;
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
);
|
|
299
|
-
|
|
300
|
-
if (taskId && failedTaskIds.includes(taskId)) {
|
|
301
|
-
const previousTask = previousTaskMap.get(taskId);
|
|
302
|
-
if (previousTask) {
|
|
303
|
-
queryClient.setQueryData(['task', taskId], previousTask);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
301
|
+
restoreTasksFromVisibleCacheSnapshot({
|
|
302
|
+
queryClient,
|
|
303
|
+
snapshot: cacheSnapshot,
|
|
304
|
+
taskIds: failedTaskIds,
|
|
305
|
+
});
|
|
307
306
|
|
|
308
307
|
// Broadcast relation changes for all affected tasks
|
|
309
308
|
for (const tid of succeededTaskIds) {
|
|
310
309
|
broadcast?.('task:relations-changed', { taskId: tid });
|
|
311
310
|
}
|
|
311
|
+
if (succeededTaskIds.length > 0) {
|
|
312
|
+
getActiveBoardRefresh()?.({ invalidateTasks: false });
|
|
313
|
+
}
|
|
312
314
|
|
|
313
315
|
if (failedTaskIds.length > 0) {
|
|
314
316
|
toast.warning(
|
|
@@ -329,17 +331,7 @@ export function useTaskProjectManagement({
|
|
|
329
331
|
// Don't auto-clear selection - let user manually clear with "Clear" button
|
|
330
332
|
} catch (e: any) {
|
|
331
333
|
// Rollback on error
|
|
332
|
-
|
|
333
|
-
queryClient.setQueryData(['tasks', boardId], previousTasks);
|
|
334
|
-
if (taskId) {
|
|
335
|
-
const previousTask = previousTasks.find(
|
|
336
|
-
(entry) => entry.id === taskId
|
|
337
|
-
);
|
|
338
|
-
if (previousTask) {
|
|
339
|
-
queryClient.setQueryData(['task', taskId], previousTask);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
334
|
+
restoreVisibleTaskCaches(queryClient, cacheSnapshot);
|
|
343
335
|
console.error('Failed to toggle project:', e);
|
|
344
336
|
toast.error('Error', {
|
|
345
337
|
description: 'Failed to update project. Please try again.',
|
|
@@ -355,52 +347,55 @@ export function useTaskProjectManagement({
|
|
|
355
347
|
const newProject =
|
|
356
348
|
await createProjectMutation.mutateAsync(newProjectName);
|
|
357
349
|
const canonicalTaskId = taskId ?? task.id;
|
|
350
|
+
const projectForCache = {
|
|
351
|
+
id: newProject.id,
|
|
352
|
+
name: newProject.name,
|
|
353
|
+
status: newProject.status ?? 'unknown',
|
|
354
|
+
};
|
|
358
355
|
|
|
359
356
|
// Auto-apply the newly created project to this task
|
|
360
357
|
let linkSucceeded = false;
|
|
361
|
-
let
|
|
358
|
+
let cacheSnapshot:
|
|
359
|
+
| ReturnType<typeof snapshotVisibleTaskCaches>
|
|
360
|
+
| undefined;
|
|
362
361
|
try {
|
|
363
362
|
// Cancel any outgoing refetches
|
|
364
363
|
await queryClient.cancelQueries({ queryKey: ['tasks', boardId] });
|
|
364
|
+
await queryClient.cancelQueries({ queryKey: ['tasks-full', boardId] });
|
|
365
365
|
|
|
366
366
|
// Snapshot the previous value
|
|
367
|
-
|
|
367
|
+
cacheSnapshot = snapshotVisibleTaskCaches(queryClient, boardId, [
|
|
368
|
+
canonicalTaskId,
|
|
369
|
+
]);
|
|
368
370
|
|
|
369
371
|
// Optimistically update the cache
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
return t;
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
// CRITICAL: Also update individual task cache if taskId is provided
|
|
387
|
-
if (canonicalTaskId) {
|
|
388
|
-
queryClient.setQueryData(
|
|
389
|
-
['task', canonicalTaskId],
|
|
390
|
-
(old: Task | undefined) => {
|
|
391
|
-
if (!old) return old;
|
|
392
|
-
return {
|
|
393
|
-
...old,
|
|
394
|
-
projects: [...(old.projects || []), newProject],
|
|
395
|
-
};
|
|
372
|
+
patchTaskInVisibleCaches({
|
|
373
|
+
queryClient,
|
|
374
|
+
boardId,
|
|
375
|
+
taskId: canonicalTaskId,
|
|
376
|
+
updater: (cachedTask) => {
|
|
377
|
+
if (
|
|
378
|
+
cachedTask.projects?.some(
|
|
379
|
+
(project) => project.id === newProject.id
|
|
380
|
+
)
|
|
381
|
+
) {
|
|
382
|
+
return cachedTask;
|
|
396
383
|
}
|
|
397
|
-
|
|
398
|
-
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
...cachedTask,
|
|
387
|
+
projects: [...(cachedTask.projects || []), projectForCache],
|
|
388
|
+
};
|
|
389
|
+
},
|
|
390
|
+
});
|
|
399
391
|
|
|
400
392
|
const taskState =
|
|
401
|
-
(
|
|
402
|
-
|
|
403
|
-
|
|
393
|
+
getTaskFromVisibleCaches({
|
|
394
|
+
queryClient,
|
|
395
|
+
boardId,
|
|
396
|
+
taskId: canonicalTaskId,
|
|
397
|
+
fallback: task,
|
|
398
|
+
}) ?? task;
|
|
404
399
|
const nextProjectIds = [
|
|
405
400
|
...new Set([
|
|
406
401
|
...(taskState.projects ?? []).map((entry) => entry.id),
|
|
@@ -418,21 +413,19 @@ export function useTaskProjectManagement({
|
|
|
418
413
|
);
|
|
419
414
|
linkSucceeded = true;
|
|
420
415
|
} catch (applyErr: any) {
|
|
421
|
-
|
|
416
|
+
if (cacheSnapshot) {
|
|
417
|
+
restoreVisibleTaskCaches(queryClient, cacheSnapshot);
|
|
418
|
+
}
|
|
422
419
|
toast.error(
|
|
423
420
|
'The project was created but could not be attached to the task. Refresh and try manually.'
|
|
424
421
|
);
|
|
425
|
-
if (canonicalTaskId) {
|
|
426
|
-
queryClient.invalidateQueries({
|
|
427
|
-
queryKey: ['task', canonicalTaskId],
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
422
|
console.error('Failed to auto-apply new project', applyErr);
|
|
431
423
|
}
|
|
432
424
|
|
|
433
425
|
// Only show success toast and reset form if link succeeded
|
|
434
426
|
if (linkSucceeded) {
|
|
435
427
|
broadcast?.('task:relations-changed', { taskId: canonicalTaskId });
|
|
428
|
+
getActiveBoardRefresh()?.({ invalidateTasks: false });
|
|
436
429
|
|
|
437
430
|
// Reset form and close dialog
|
|
438
431
|
setNewProjectName('');
|
|
@@ -13,6 +13,15 @@ import {
|
|
|
13
13
|
Trash2,
|
|
14
14
|
User,
|
|
15
15
|
} from '@tuturuuu/icons';
|
|
16
|
+
import {
|
|
17
|
+
createWorkspaceTaskInitiative,
|
|
18
|
+
deleteWorkspaceTaskInitiative,
|
|
19
|
+
linkWorkspaceTaskInitiativeProject,
|
|
20
|
+
listWorkspaceTaskInitiatives,
|
|
21
|
+
listWorkspaceTaskProjects,
|
|
22
|
+
unlinkWorkspaceTaskInitiativeProject,
|
|
23
|
+
updateWorkspaceTaskInitiative,
|
|
24
|
+
} from '@tuturuuu/internal-api/tasks';
|
|
16
25
|
import { Badge } from '@tuturuuu/ui/badge';
|
|
17
26
|
import { Button } from '@tuturuuu/ui/button';
|
|
18
27
|
import {
|
|
@@ -98,6 +107,12 @@ const STATUS_BADGE_CLASS: Record<InitiativeStatus, string> = {
|
|
|
98
107
|
cancelled: 'bg-dynamic-red/15 text-dynamic-red border-transparent',
|
|
99
108
|
};
|
|
100
109
|
|
|
110
|
+
function getBrowserInternalApiOptions() {
|
|
111
|
+
return typeof window !== 'undefined'
|
|
112
|
+
? { baseUrl: window.location.origin }
|
|
113
|
+
: undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
101
116
|
export function TaskInitiativesClient({
|
|
102
117
|
wsId,
|
|
103
118
|
initialInitiatives,
|
|
@@ -136,16 +151,8 @@ export function TaskInitiativesClient({
|
|
|
136
151
|
refetch: refetchInitiatives,
|
|
137
152
|
} = useQuery<TaskInitiative[]>({
|
|
138
153
|
queryKey: ['workspace', wsId, 'task-initiatives'],
|
|
139
|
-
queryFn:
|
|
140
|
-
|
|
141
|
-
`/api/v1/workspaces/${wsId}/task-initiatives`,
|
|
142
|
-
{ cache: 'no-store' }
|
|
143
|
-
);
|
|
144
|
-
if (!response.ok) {
|
|
145
|
-
throw new Error(t('errors.fetch_initiatives'));
|
|
146
|
-
}
|
|
147
|
-
return response.json();
|
|
148
|
-
},
|
|
154
|
+
queryFn: () =>
|
|
155
|
+
listWorkspaceTaskInitiatives(wsId, getBrowserInternalApiOptions()),
|
|
149
156
|
initialData: initialInitiatives,
|
|
150
157
|
staleTime: 30_000,
|
|
151
158
|
});
|
|
@@ -157,20 +164,12 @@ export function TaskInitiativesClient({
|
|
|
157
164
|
} = useQuery<TaskProjectOption[]>({
|
|
158
165
|
queryKey: ['workspace', wsId, 'task-projects-for-initiatives'],
|
|
159
166
|
queryFn: async () => {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const rawProjects = await response.json();
|
|
167
|
-
return (
|
|
168
|
-
rawProjects as Array<{
|
|
169
|
-
id: string;
|
|
170
|
-
name: string;
|
|
171
|
-
status?: string | null;
|
|
172
|
-
}>
|
|
173
|
-
).map((project) => ({
|
|
167
|
+
const rawProjects = await listWorkspaceTaskProjects(
|
|
168
|
+
wsId,
|
|
169
|
+
getBrowserInternalApiOptions()
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
return rawProjects.map((project) => ({
|
|
174
173
|
id: project.id,
|
|
175
174
|
name: project.name,
|
|
176
175
|
status: project.status ?? null,
|
|
@@ -218,19 +217,13 @@ export function TaskInitiativesClient({
|
|
|
218
217
|
description?: string;
|
|
219
218
|
status: InitiativeStatus;
|
|
220
219
|
}) => {
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
220
|
+
const payload = { name, description: description ?? '', status };
|
|
221
|
+
|
|
222
|
+
return createWorkspaceTaskInitiative(
|
|
223
|
+
wsId,
|
|
224
|
+
payload,
|
|
225
|
+
getBrowserInternalApiOptions()
|
|
228
226
|
);
|
|
229
|
-
if (!response.ok) {
|
|
230
|
-
const errorData = await response.json().catch(() => ({}));
|
|
231
|
-
throw new Error(errorData.error || t('errors.create_initiative'));
|
|
232
|
-
}
|
|
233
|
-
return response.json();
|
|
234
227
|
},
|
|
235
228
|
onSuccess: () => {
|
|
236
229
|
toast.success(t('success.initiative_created'));
|
|
@@ -257,19 +250,14 @@ export function TaskInitiativesClient({
|
|
|
257
250
|
description?: string;
|
|
258
251
|
status: InitiativeStatus;
|
|
259
252
|
}) => {
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
253
|
+
const payload = { name, description: description ?? '', status };
|
|
254
|
+
|
|
255
|
+
return updateWorkspaceTaskInitiative(
|
|
256
|
+
wsId,
|
|
257
|
+
initiativeId,
|
|
258
|
+
payload,
|
|
259
|
+
getBrowserInternalApiOptions()
|
|
267
260
|
);
|
|
268
|
-
if (!response.ok) {
|
|
269
|
-
const errorData = await response.json().catch(() => ({}));
|
|
270
|
-
throw new Error(errorData.error || t('errors.update_initiative'));
|
|
271
|
-
}
|
|
272
|
-
return response.json();
|
|
273
261
|
},
|
|
274
262
|
onSuccess: () => {
|
|
275
263
|
toast.success(t('success.initiative_updated'));
|
|
@@ -286,18 +274,12 @@ export function TaskInitiativesClient({
|
|
|
286
274
|
});
|
|
287
275
|
|
|
288
276
|
const deleteInitiativeMutation = useMutation({
|
|
289
|
-
mutationFn:
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
);
|
|
296
|
-
if (!response.ok) {
|
|
297
|
-
const errorData = await response.json().catch(() => ({}));
|
|
298
|
-
throw new Error(errorData.error || t('errors.delete_initiative'));
|
|
299
|
-
}
|
|
300
|
-
},
|
|
277
|
+
mutationFn: (initiativeId: string) =>
|
|
278
|
+
deleteWorkspaceTaskInitiative(
|
|
279
|
+
wsId,
|
|
280
|
+
initiativeId,
|
|
281
|
+
getBrowserInternalApiOptions()
|
|
282
|
+
),
|
|
301
283
|
onSuccess: () => {
|
|
302
284
|
toast.success(t('success.initiative_deleted'));
|
|
303
285
|
refetchInitiatives();
|
|
@@ -314,21 +296,13 @@ export function TaskInitiativesClient({
|
|
|
314
296
|
}: {
|
|
315
297
|
initiativeId: string;
|
|
316
298
|
projectId: string;
|
|
317
|
-
}) =>
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
);
|
|
326
|
-
if (!response.ok) {
|
|
327
|
-
const errorData = await response.json().catch(() => ({}));
|
|
328
|
-
throw new Error(errorData.error || t('errors.link_project'));
|
|
329
|
-
}
|
|
330
|
-
return response.json();
|
|
331
|
-
},
|
|
299
|
+
}) =>
|
|
300
|
+
linkWorkspaceTaskInitiativeProject(
|
|
301
|
+
wsId,
|
|
302
|
+
initiativeId,
|
|
303
|
+
projectId,
|
|
304
|
+
getBrowserInternalApiOptions()
|
|
305
|
+
),
|
|
332
306
|
onSuccess: (_data, variables) => {
|
|
333
307
|
toast.success(t('success.project_linked'));
|
|
334
308
|
setProjectToLink('');
|
|
@@ -362,19 +336,13 @@ export function TaskInitiativesClient({
|
|
|
362
336
|
}: {
|
|
363
337
|
initiativeId: string;
|
|
364
338
|
projectId: string;
|
|
365
|
-
}) =>
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
)
|
|
372
|
-
if (!response.ok) {
|
|
373
|
-
const errorData = await response.json().catch(() => ({}));
|
|
374
|
-
throw new Error(errorData.error || t('errors.unlink_project'));
|
|
375
|
-
}
|
|
376
|
-
return response.json();
|
|
377
|
-
},
|
|
339
|
+
}) =>
|
|
340
|
+
unlinkWorkspaceTaskInitiativeProject(
|
|
341
|
+
wsId,
|
|
342
|
+
initiativeId,
|
|
343
|
+
projectId,
|
|
344
|
+
getBrowserInternalApiOptions()
|
|
345
|
+
),
|
|
378
346
|
onSuccess: (_data, variables) => {
|
|
379
347
|
toast.success(t('success.project_unlinked'));
|
|
380
348
|
if (variables) {
|
|
@@ -20,12 +20,30 @@ import { TaskPreviewDialog } from './task-preview-dialog';
|
|
|
20
20
|
import { useMyTasksState } from './use-my-tasks-state';
|
|
21
21
|
|
|
22
22
|
interface MyTasksContentProps {
|
|
23
|
+
disableAutoCreateBoard?: boolean;
|
|
24
|
+
embedded?: boolean;
|
|
25
|
+
initialBoard?: {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string | null;
|
|
28
|
+
};
|
|
29
|
+
initialListId?: string;
|
|
30
|
+
initialLists?: Array<{
|
|
31
|
+
deleted?: boolean | null;
|
|
32
|
+
id: string;
|
|
33
|
+
name: string | null;
|
|
34
|
+
position?: number | null;
|
|
35
|
+
}>;
|
|
23
36
|
wsId: string;
|
|
24
37
|
userId: string;
|
|
25
38
|
isPersonal: boolean;
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
export default function MyTasksContent({
|
|
42
|
+
disableAutoCreateBoard = false,
|
|
43
|
+
embedded = false,
|
|
44
|
+
initialBoard,
|
|
45
|
+
initialListId,
|
|
46
|
+
initialLists,
|
|
29
47
|
wsId,
|
|
30
48
|
userId,
|
|
31
49
|
isPersonal,
|
|
@@ -40,13 +58,17 @@ export default function MyTasksContent({
|
|
|
40
58
|
'enter'
|
|
41
59
|
);
|
|
42
60
|
const state = useMyTasksState({
|
|
61
|
+
...(disableAutoCreateBoard ? { disableAutoCreateBoard } : {}),
|
|
62
|
+
...(initialBoard ? { initialBoard } : {}),
|
|
63
|
+
...(initialListId ? { initialListId } : {}),
|
|
64
|
+
...(initialLists ? { initialLists } : {}),
|
|
43
65
|
wsId,
|
|
44
66
|
userId,
|
|
45
67
|
isPersonal,
|
|
46
68
|
});
|
|
47
69
|
|
|
48
70
|
return (
|
|
49
|
-
<div className=
|
|
71
|
+
<div className={embedded ? 'space-y-4' : 'space-y-4 md:space-y-6'}>
|
|
50
72
|
{/* Header with greeting + summary cards */}
|
|
51
73
|
<MyTasksHeader
|
|
52
74
|
overdueCount={state.filteredTasks.overdueTasks?.length ?? 0}
|
|
@@ -55,7 +77,9 @@ export default function MyTasksContent({
|
|
|
55
77
|
/>
|
|
56
78
|
|
|
57
79
|
{/* Command Bar */}
|
|
58
|
-
<div
|
|
80
|
+
<div
|
|
81
|
+
className={embedded ? 'mx-auto max-w-5xl' : 'mx-auto mb-32 max-w-5xl'}
|
|
82
|
+
>
|
|
59
83
|
<CommandBar
|
|
60
84
|
value={state.commandBarInput}
|
|
61
85
|
onValueChange={state.setCommandBarInput}
|