@tuturuuu/ui 0.7.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 +88 -0
- package/biome.json +1 -1
- package/package.json +75 -73
- 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/currency-input.test.tsx +43 -0
- package/src/components/ui/currency-input.tsx +1 -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-access/workspace-access-default-role-card.tsx +60 -35
- package/src/components/ui/custom/workspace-access/workspace-access-member-row.tsx +176 -167
- package/src/components/ui/custom/workspace-access/workspace-access-members.tsx +16 -10
- package/src/components/ui/custom/workspace-access/workspace-access-page-header.tsx +75 -36
- package/src/components/ui/custom/workspace-access/workspace-access-page.tsx +39 -42
- package/src/components/ui/custom/workspace-access/workspace-access-people-filters.tsx +1 -1
- package/src/components/ui/custom/workspace-access/workspace-access-roles.tsx +113 -91
- package/src/components/ui/custom/workspace-access/workspace-access-tabs-toolbar.tsx +73 -32
- 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 +3 -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-card.tsx +21 -9
- 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/money-input.test.tsx +64 -0
- package/src/components/ui/money-input.tsx +63 -0
- 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 +104 -80
- package/src/components/ui/storefront/checkout-overlay.tsx +26 -0
- package/src/components/ui/storefront/hero-panel.tsx +2 -8
- package/src/components/ui/storefront/image-panel.tsx +6 -0
- package/src/components/ui/storefront/index.ts +11 -0
- package/src/components/ui/storefront/listing-card.tsx +84 -22
- package/src/components/ui/storefront/merch-sections.tsx +70 -0
- package/src/components/ui/storefront/product-detail.tsx +289 -0
- package/src/components/ui/storefront/product-dialog.tsx +72 -0
- package/src/components/ui/storefront/storefront-surface.test.tsx +221 -3
- package/src/components/ui/storefront/storefront-surface.tsx +288 -153
- package/src/components/ui/storefront/types.ts +27 -1
- package/src/components/ui/storefront/utils.ts +117 -27
- package/src/components/ui/text-editor/__tests__/content-migration.test.ts +32 -0
- package/src/components/ui/text-editor/__tests__/extensions.test.ts +123 -0
- package/src/components/ui/text-editor/__tests__/image-extension.test.ts +69 -1
- package/src/components/ui/text-editor/__tests__/video-extension.test.ts +47 -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/content-migration.ts +41 -18
- package/src/components/ui/text-editor/editor.tsx +69 -14
- package/src/components/ui/text-editor/extensions.ts +9 -3
- package/src/components/ui/text-editor/highlight-extension.ts +22 -0
- package/src/components/ui/text-editor/image-extension.ts +40 -18
- package/src/components/ui/text-editor/tool-bar.tsx +9 -16
- package/src/components/ui/text-editor/video-extension.ts +11 -2
- 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/__tests__/workspace-projects-client-page.test.tsx +70 -1
- 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-external-retry.test.tsx +127 -0
- package/src/components/ui/tu-do/boards/boardId/board-column.tsx +113 -46
- 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 +51 -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.test.ts +63 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +127 -38
- 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 +410 -4
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +106 -14
- 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 +186 -0
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +59 -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/boardId/timeline/timeline-display.ts +9 -0
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-grid.tsx +8 -16
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-task-row.tsx +5 -25
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-utils.test.ts +36 -1
- package/src/components/ui/tu-do/boards/boardId/timeline/timeline-utils.ts +51 -2
- package/src/components/ui/tu-do/boards/share-section.tsx +100 -0
- package/src/components/ui/tu-do/boards/workspace-projects-client-page.tsx +13 -3
- 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 +237 -3
- 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 +465 -937
- 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 +596 -82
- package/src/components/ui/tu-do/shared/cursor-overlay-multi-wrapper.tsx +53 -12
- 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-dialog-presentation.test.ts +53 -0
- package/src/components/ui/tu-do/shared/task-dialog-presentation.ts +19 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.test.tsx +57 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.tsx +136 -111
- package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-description-editor.tsx +3 -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/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 +44 -15
- 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/__tests__/useBoardRealtime.test.tsx +2 -2
- package/src/hooks/__tests__/useCursorTracking.test.tsx +212 -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/useBoardRealtime.ts +6 -3
- package/src/hooks/useBoardRealtime.types.ts +11 -0
- package/src/hooks/useBoardRealtimeEventHandler.ts +11 -0
- package/src/hooks/useCursorTracking.ts +91 -27
- package/src/hooks/useTaskUserRealtime.ts +5 -3
|
@@ -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}
|
|
@@ -39,12 +39,28 @@ dayjs.extend(utc);
|
|
|
39
39
|
dayjs.extend(timezone);
|
|
40
40
|
|
|
41
41
|
interface UseMyTasksStateProps {
|
|
42
|
+
disableAutoCreateBoard?: boolean;
|
|
43
|
+
initialBoard?: {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string | null;
|
|
46
|
+
};
|
|
47
|
+
initialListId?: string;
|
|
48
|
+
initialLists?: Array<{
|
|
49
|
+
deleted?: boolean | null;
|
|
50
|
+
id: string;
|
|
51
|
+
name: string | null;
|
|
52
|
+
position?: number | null;
|
|
53
|
+
}>;
|
|
42
54
|
wsId: string;
|
|
43
55
|
userId: string;
|
|
44
56
|
isPersonal: boolean;
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
export function useMyTasksState({
|
|
60
|
+
disableAutoCreateBoard = false,
|
|
61
|
+
initialBoard,
|
|
62
|
+
initialListId,
|
|
63
|
+
initialLists,
|
|
48
64
|
wsId,
|
|
49
65
|
userId,
|
|
50
66
|
isPersonal,
|
|
@@ -96,8 +112,16 @@ export function useMyTasksState({
|
|
|
96
112
|
// Board selector state
|
|
97
113
|
const [boardSelectorOpen, setBoardSelectorOpen] = useState(false);
|
|
98
114
|
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<string>(wsId);
|
|
99
|
-
const [selectedBoardId, setSelectedBoardId] = useState<string>(
|
|
100
|
-
|
|
115
|
+
const [selectedBoardId, setSelectedBoardId] = useState<string>(
|
|
116
|
+
initialBoard?.id ?? ''
|
|
117
|
+
);
|
|
118
|
+
const [selectedListId, setSelectedListId] = useState<string>(
|
|
119
|
+
initialListId ??
|
|
120
|
+
initialLists
|
|
121
|
+
?.filter((list) => !list.deleted)
|
|
122
|
+
.sort((a, b) => (a.position ?? 0) - (b.position ?? 0))[0]?.id ??
|
|
123
|
+
''
|
|
124
|
+
);
|
|
101
125
|
const [newBoardDialogOpen, setNewBoardDialogOpen] = useState(false);
|
|
102
126
|
const [newBoardName, setNewBoardName] = useState<string>('');
|
|
103
127
|
const [newListDialogOpen, setNewListDialogOpen] = useState(false);
|
|
@@ -276,6 +300,7 @@ export function useMyTasksState({
|
|
|
276
300
|
});
|
|
277
301
|
return payload.count ?? 0;
|
|
278
302
|
},
|
|
303
|
+
enabled: !disableAutoCreateBoard,
|
|
279
304
|
});
|
|
280
305
|
|
|
281
306
|
// Auto-create a board if the workspace has none
|
|
@@ -294,7 +319,13 @@ export function useMyTasksState({
|
|
|
294
319
|
);
|
|
295
320
|
|
|
296
321
|
useEffect(() => {
|
|
297
|
-
if (
|
|
322
|
+
if (
|
|
323
|
+
disableAutoCreateBoard ||
|
|
324
|
+
wsBoardCountLoading ||
|
|
325
|
+
wsBoardCount === undefined
|
|
326
|
+
) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
298
329
|
if (wsBoardCount > 0) return;
|
|
299
330
|
if (autoCreateAttemptedRef.current) return;
|
|
300
331
|
autoCreateAttemptedRef.current = true;
|
|
@@ -344,6 +375,7 @@ export function useMyTasksState({
|
|
|
344
375
|
queryClient,
|
|
345
376
|
defaultBoardName,
|
|
346
377
|
defaultListNames,
|
|
378
|
+
disableAutoCreateBoard,
|
|
347
379
|
]);
|
|
348
380
|
|
|
349
381
|
// Fetch boards with lists for selected workspace
|
|
@@ -422,11 +454,16 @@ export function useMyTasksState({
|
|
|
422
454
|
const availableLists = useMemo(() => {
|
|
423
455
|
if (!selectedBoardId) return [];
|
|
424
456
|
const board = boardsData.find((b: any) => b.id === selectedBoardId);
|
|
425
|
-
if (!board?.task_lists)
|
|
457
|
+
if (!board?.task_lists) {
|
|
458
|
+
if (selectedBoardId !== initialBoard?.id) return [];
|
|
459
|
+
return (initialLists ?? [])
|
|
460
|
+
.filter((list) => !list.deleted)
|
|
461
|
+
.sort((a, b) => (a.position ?? 0) - (b.position ?? 0));
|
|
462
|
+
}
|
|
426
463
|
return (board.task_lists as any[])
|
|
427
464
|
.filter((l: any) => !l.deleted)
|
|
428
465
|
.sort((a: any, b: any) => (a.position || 0) - (b.position || 0));
|
|
429
|
-
}, [selectedBoardId, boardsData]);
|
|
466
|
+
}, [selectedBoardId, boardsData, initialBoard?.id, initialLists]);
|
|
430
467
|
|
|
431
468
|
const hasValidSelectedList = useMemo(
|
|
432
469
|
() => availableLists.some((list: any) => list.id === selectedListId),
|
|
@@ -794,13 +831,23 @@ export function useMyTasksState({
|
|
|
794
831
|
const selectedDestination = useMemo(() => {
|
|
795
832
|
if (!selectedBoardId || !selectedListId) return null;
|
|
796
833
|
const board = boardsData.find((b: any) => b.id === selectedBoardId);
|
|
797
|
-
const
|
|
834
|
+
const isInitialBoard = selectedBoardId === initialBoard?.id;
|
|
835
|
+
const lists =
|
|
836
|
+
(board?.task_lists as any[]) ||
|
|
837
|
+
(isInitialBoard ? (initialLists ?? []) : []);
|
|
798
838
|
const list = lists.find((l: any) => l.id === selectedListId);
|
|
799
839
|
return {
|
|
800
|
-
boardName: board?.name || 'Unknown Board',
|
|
840
|
+
boardName: board?.name || initialBoard?.name || 'Unknown Board',
|
|
801
841
|
listName: list?.name || 'Unknown List',
|
|
802
842
|
};
|
|
803
|
-
}, [
|
|
843
|
+
}, [
|
|
844
|
+
selectedBoardId,
|
|
845
|
+
selectedListId,
|
|
846
|
+
boardsData,
|
|
847
|
+
initialBoard?.id,
|
|
848
|
+
initialBoard?.name,
|
|
849
|
+
initialLists,
|
|
850
|
+
]);
|
|
804
851
|
|
|
805
852
|
const handleClearDestination = () => {
|
|
806
853
|
setSelectedBoardId('');
|
|
@@ -41,10 +41,7 @@ export function NoteEditDialog({
|
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
43
|
<Dialog open={isOpen} onOpenChange={onOpenChange} modal={true}>
|
|
44
|
-
<DialogContent
|
|
45
|
-
showCloseButton={false}
|
|
46
|
-
className="inset-0! top-0! left-0! flex h-screen max-h-screen w-screen max-w-none! translate-x-0! translate-y-0! gap-0 rounded-none! border-0 p-0"
|
|
47
|
-
>
|
|
44
|
+
<DialogContent showCloseButton={false} presentation="fullscreen">
|
|
48
45
|
{/* Main content area - Note title and description */}
|
|
49
46
|
<div className="flex min-w-0 flex-1 flex-col bg-background transition-all duration-300">
|
|
50
47
|
{/* Enhanced Header with gradient */}
|
|
@@ -115,6 +115,31 @@ describe('BoardClient', () => {
|
|
|
115
115
|
);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
+
it('uses the shared task board loading state while the board query resolves', () => {
|
|
119
|
+
getWorkspaceTaskBoardMock.mockReturnValue(new Promise(() => {}));
|
|
120
|
+
const queryClient = new QueryClient({
|
|
121
|
+
defaultOptions: {
|
|
122
|
+
queries: {
|
|
123
|
+
retry: false,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
render(
|
|
129
|
+
<QueryClientProvider client={queryClient}>
|
|
130
|
+
<BoardClient
|
|
131
|
+
boardId="board-1"
|
|
132
|
+
workspace={{ id: 'workspace-uuid', personal: false } as any}
|
|
133
|
+
currentUserId="user-1"
|
|
134
|
+
/>
|
|
135
|
+
</QueryClientProvider>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
expect(screen.getByTestId('task-board-loading-state')).toBeInTheDocument();
|
|
139
|
+
expect(screen.getByTestId('kanban-skeleton')).toBeInTheDocument();
|
|
140
|
+
expect(screen.queryByText('Loading board...')).not.toBeInTheDocument();
|
|
141
|
+
});
|
|
142
|
+
|
|
118
143
|
it('can revalidate loaded board lists without invalidating visible task caches', async () => {
|
|
119
144
|
const queryClient = new QueryClient({
|
|
120
145
|
defaultOptions: {
|