@tuturuuu/ui 0.9.0 → 0.11.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.
Files changed (123) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/package.json +6 -5
  3. package/src/components/ui/custom/__tests__/settings-dialog-search.test.ts +78 -0
  4. package/src/components/ui/custom/__tests__/settings-dialog-shell-compile-graph.test.ts +76 -0
  5. package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +27 -1
  6. package/src/components/ui/custom/nav-link.test.tsx +165 -0
  7. package/src/components/ui/custom/nav-link.tsx +69 -11
  8. package/src/components/ui/custom/navigation.tsx +1 -0
  9. package/src/components/ui/custom/settings/task-settings.tsx +104 -0
  10. package/src/components/ui/custom/settings-dialog-search-loader.d.ts +5 -0
  11. package/src/components/ui/custom/settings-dialog-search-loader.js +3 -0
  12. package/src/components/ui/custom/settings-dialog-search.ts +75 -0
  13. package/src/components/ui/custom/settings-dialog-shell.tsx +63 -27
  14. package/src/components/ui/custom/workspace-select-helpers.ts +23 -0
  15. package/src/components/ui/custom/workspace-select.tsx +17 -16
  16. package/src/components/ui/finance/invoices/components/subscription-attendance-summary.tsx +19 -5
  17. package/src/components/ui/finance/invoices/components/subscription-prepaid-controls.test.tsx +41 -0
  18. package/src/components/ui/finance/invoices/components/subscription-prepaid-controls.tsx +93 -0
  19. package/src/components/ui/finance/invoices/hooks/use-subscription-auto-selection.ts +82 -70
  20. package/src/components/ui/finance/invoices/hooks/use-subscription-invoice-content.ts +50 -25
  21. package/src/components/ui/finance/invoices/hooks.ts +11 -2
  22. package/src/components/ui/finance/invoices/internal-api.ts +5 -0
  23. package/src/components/ui/finance/invoices/subscription-invoice.tsx +92 -31
  24. package/src/components/ui/finance/invoices/utils.test.ts +82 -0
  25. package/src/components/ui/finance/invoices/utils.ts +240 -7
  26. package/src/components/ui/tu-do/boards/__tests__/board-share-dialog.test.tsx +16 -0
  27. package/src/components/ui/tu-do/boards/__tests__/task-board-form.test.tsx +12 -0
  28. package/src/components/ui/tu-do/boards/board-share-dialog.tsx +4 -328
  29. package/src/components/ui/tu-do/boards/board-share-settings-panel.tsx +351 -0
  30. package/src/components/ui/tu-do/boards/boardId/board-column.tsx +50 -37
  31. package/src/components/ui/tu-do/boards/boardId/enhanced-task-list.tsx +7 -0
  32. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operation-types.ts +3 -3
  33. package/src/components/ui/tu-do/boards/boardId/kanban/data/use-bulk-resources.ts +59 -5
  34. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/drag-preview.tsx +20 -1
  35. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +263 -21
  36. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +133 -14
  37. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-deadline-panels.tsx +112 -54
  38. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-skeleton.tsx +8 -2
  39. package/src/components/ui/tu-do/boards/boardId/kanban.tsx +29 -14
  40. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.test.tsx +24 -1
  41. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +7 -0
  42. package/src/components/ui/tu-do/boards/boardId/task-card/measured-task-card.tsx +7 -1
  43. package/src/components/ui/tu-do/boards/boardId/task-card/task-card-open-options.test.ts +20 -0
  44. package/src/components/ui/tu-do/boards/boardId/task-card/task-card-open-options.ts +10 -0
  45. package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +80 -8
  46. package/src/components/ui/tu-do/boards/boardId/task-list.tsx +15 -0
  47. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-grid.tsx +9 -0
  48. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-task-row.tsx +9 -0
  49. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-toolbar.tsx +9 -0
  50. package/src/components/ui/tu-do/boards/boardId/timeline-board.tsx +35 -3
  51. package/src/components/ui/tu-do/boards/form.tsx +1 -1
  52. package/src/components/ui/tu-do/hooks/__tests__/useTaskLabelManagement.test.tsx +48 -0
  53. package/src/components/ui/tu-do/hooks/__tests__/useTaskProjectManagement.test.tsx +144 -0
  54. package/src/components/ui/tu-do/hooks/useTaskDialog.ts +7 -0
  55. package/src/components/ui/tu-do/hooks/useTaskLabelManagement.ts +115 -106
  56. package/src/components/ui/tu-do/hooks/useTaskProjectManagement.ts +115 -122
  57. package/src/components/ui/tu-do/progress/task-progress-import-panel.tsx +60 -0
  58. package/src/components/ui/tu-do/progress/task-progress-leaderboards-panel.tsx +156 -0
  59. package/src/components/ui/tu-do/progress/task-progress-page.tsx +348 -0
  60. package/src/components/ui/tu-do/progress/task-progress-panels.tsx +301 -0
  61. package/src/components/ui/tu-do/providers/task-dialog-provider.tsx +26 -0
  62. package/src/components/ui/tu-do/shared/__tests__/assignee-select.test.tsx +81 -10
  63. package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +123 -1
  64. package/src/components/ui/tu-do/shared/__tests__/board-header.test.tsx +38 -0
  65. package/src/components/ui/tu-do/shared/__tests__/board-switcher.test.tsx +128 -7
  66. package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +222 -9
  67. package/src/components/ui/tu-do/shared/__tests__/task-board-loading-state.test.tsx +58 -0
  68. package/src/components/ui/tu-do/shared/__tests__/task-cache-patches.test.ts +147 -0
  69. package/src/components/ui/tu-do/shared/__tests__/use-progressive-board-loader.test.tsx +3 -0
  70. package/src/components/ui/tu-do/shared/assignee-select.tsx +77 -26
  71. package/src/components/ui/tu-do/shared/board-client.tsx +16 -4
  72. package/src/components/ui/tu-do/shared/board-header.tsx +8 -1
  73. package/src/components/ui/tu-do/shared/board-switcher.tsx +70 -38
  74. package/src/components/ui/tu-do/shared/board-user-presence-avatars.tsx +18 -12
  75. package/src/components/ui/tu-do/shared/board-views.tsx +49 -69
  76. package/src/components/ui/tu-do/shared/list-view.tsx +21 -3
  77. package/src/components/ui/tu-do/shared/task-board-loading-state.tsx +58 -4
  78. package/src/components/ui/tu-do/shared/task-cache-patches.ts +394 -0
  79. package/src/components/ui/tu-do/shared/task-dialog-manager.tsx +21 -1
  80. package/src/components/ui/tu-do/shared/task-edit-dialog/components/quick-settings-popover.tsx +5 -1
  81. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-description-editor.tsx +3 -0
  82. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-dialog-header.tsx +25 -2
  83. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-list-selector.tsx +7 -1
  84. package/src/components/ui/tu-do/shared/task-edit-dialog/description-versions.test.ts +97 -0
  85. package/src/components/ui/tu-do/shared/task-edit-dialog/description-versions.ts +210 -0
  86. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-data.ts +79 -10
  87. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-mutations.ts +76 -77
  88. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-relationships.test.tsx +63 -0
  89. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-relationships.ts +78 -69
  90. package/src/components/ui/tu-do/shared/task-edit-dialog/personal-overrides-section.tsx +28 -8
  91. package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/dependencies-section.tsx +14 -3
  92. package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/parent-section.tsx +6 -1
  93. package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/related-section.tsx +6 -1
  94. package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/subtasks-section.tsx +6 -1
  95. package/src/components/ui/tu-do/shared/task-edit-dialog/relationships/types/task-relationships.types.ts +8 -0
  96. package/src/components/ui/tu-do/shared/task-edit-dialog/task-activity-section.tsx +56 -8
  97. package/src/components/ui/tu-do/shared/task-edit-dialog/task-description-change-dialog.test.tsx +63 -0
  98. package/src/components/ui/tu-do/shared/task-edit-dialog/task-description-change-dialog.tsx +218 -0
  99. package/src/components/ui/tu-do/shared/task-edit-dialog/task-description-restore-banner.tsx +83 -0
  100. package/src/components/ui/tu-do/shared/task-edit-dialog/task-description-version-restore-dialog.test.tsx +120 -0
  101. package/src/components/ui/tu-do/shared/task-edit-dialog/task-description-version-restore-dialog.tsx +180 -0
  102. package/src/components/ui/tu-do/shared/task-edit-dialog/task-dialog-actions.tsx +8 -1
  103. package/src/components/ui/tu-do/shared/task-edit-dialog/task-properties-section.test.tsx +150 -0
  104. package/src/components/ui/tu-do/shared/task-edit-dialog/task-properties-section.tsx +61 -35
  105. package/src/components/ui/tu-do/shared/task-edit-dialog/task-relationships-properties.tsx +44 -2
  106. package/src/components/ui/tu-do/shared/task-edit-dialog/utils.test.ts +100 -0
  107. package/src/components/ui/tu-do/shared/task-edit-dialog/utils.ts +109 -0
  108. package/src/components/ui/tu-do/shared/task-edit-dialog.tsx +390 -34
  109. package/src/components/ui/tu-do/shared/task-row-actions-menu.tsx +11 -0
  110. package/src/components/ui/tu-do/shared/use-progressive-board-loader.ts +2 -0
  111. package/src/components/ui/tu-do/templates/task-template-api.ts +142 -0
  112. package/src/components/ui/tu-do/templates/task-template-card.tsx +118 -0
  113. package/src/components/ui/tu-do/templates/task-template-client.tsx +258 -0
  114. package/src/components/ui/tu-do/templates/task-template-dialogs.test.tsx +167 -0
  115. package/src/components/ui/tu-do/templates/task-template-dialogs.tsx +376 -0
  116. package/src/components/ui/tu-do/templates/task-templates-hub.test.tsx +114 -0
  117. package/src/components/ui/tu-do/templates/task-templates-hub.tsx +50 -0
  118. package/src/components/ui/tu-do/templates/task-templates-page.tsx +6 -11
  119. package/src/hooks/__tests__/useBoardPresence.test.tsx +191 -0
  120. package/src/hooks/__tests__/useBoardRealtime.test.tsx +24 -144
  121. package/src/hooks/useBoardPresence.ts +364 -0
  122. package/src/hooks/useBoardRealtimeEventHandler.ts +34 -90
  123. package/src/lib/workspace-actions.ts +2 -6
@@ -45,6 +45,115 @@ export function serializeTaskDescriptionContent(
45
45
  }
46
46
  }
47
47
 
48
+ function hasTaskDescriptionContent(content: JSONContent | null): boolean {
49
+ if (!content) return false;
50
+
51
+ if (content.text && content.text.trim().length > 0) {
52
+ return true;
53
+ }
54
+
55
+ if (
56
+ content.type &&
57
+ ['image', 'imageResize', 'youtube', 'video', 'mention', 'table'].includes(
58
+ content.type
59
+ )
60
+ ) {
61
+ return true;
62
+ }
63
+
64
+ return content.content?.some(hasTaskDescriptionContent) ?? false;
65
+ }
66
+
67
+ function isSerializedTaskDescriptionEmpty(description: string | null): boolean {
68
+ if (description === null) return true;
69
+ if (description.trim().length === 0) return true;
70
+
71
+ try {
72
+ return !hasTaskDescriptionContent(JSON.parse(description) as JSONContent);
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+
78
+ export function normalizeTaskDescriptionSnapshot(
79
+ content: JSONContent | null
80
+ ): JSONContent | null {
81
+ return hasTaskDescriptionContent(content) ? content : null;
82
+ }
83
+
84
+ export function serializeTaskDescriptionPersistenceSnapshot(
85
+ content: JSONContent | null
86
+ ): string | null {
87
+ return serializeTaskDescriptionContent(
88
+ normalizeTaskDescriptionSnapshot(content)
89
+ );
90
+ }
91
+
92
+ export type TaskDescriptionPersistenceGuardState = {
93
+ persistedDescription: string | null;
94
+ hasSeenNonEmptyEditorSnapshot: boolean;
95
+ hasConfirmedEmptyEditorSnapshot: boolean;
96
+ };
97
+
98
+ export function createTaskDescriptionPersistenceGuardState({
99
+ persistedDescription,
100
+ trustPersistedDescription = false,
101
+ }: {
102
+ persistedDescription: string | null;
103
+ trustPersistedDescription?: boolean;
104
+ }): TaskDescriptionPersistenceGuardState {
105
+ const persistedDescriptionIsEmpty =
106
+ isSerializedTaskDescriptionEmpty(persistedDescription);
107
+
108
+ return {
109
+ persistedDescription,
110
+ hasSeenNonEmptyEditorSnapshot:
111
+ trustPersistedDescription && !persistedDescriptionIsEmpty,
112
+ hasConfirmedEmptyEditorSnapshot: persistedDescriptionIsEmpty,
113
+ };
114
+ }
115
+
116
+ export function recordTaskDescriptionEditorSnapshot(
117
+ state: TaskDescriptionPersistenceGuardState,
118
+ content: JSONContent | null,
119
+ options: { canConfirmEmptySnapshot?: boolean } = {}
120
+ ): TaskDescriptionPersistenceGuardState {
121
+ const serializedDescription =
122
+ serializeTaskDescriptionPersistenceSnapshot(content);
123
+
124
+ if (serializedDescription !== null) {
125
+ return {
126
+ ...state,
127
+ hasSeenNonEmptyEditorSnapshot: true,
128
+ hasConfirmedEmptyEditorSnapshot: false,
129
+ };
130
+ }
131
+
132
+ if (options.canConfirmEmptySnapshot && state.hasSeenNonEmptyEditorSnapshot) {
133
+ return {
134
+ ...state,
135
+ hasConfirmedEmptyEditorSnapshot: true,
136
+ };
137
+ }
138
+
139
+ return state;
140
+ }
141
+
142
+ export function canPersistTaskDescriptionSnapshot({
143
+ currentSerializedDescription,
144
+ guardState,
145
+ }: {
146
+ currentSerializedDescription: string | null;
147
+ guardState: TaskDescriptionPersistenceGuardState;
148
+ }): boolean {
149
+ if (currentSerializedDescription !== null) return true;
150
+ if (isSerializedTaskDescriptionEmpty(guardState.persistedDescription)) {
151
+ return true;
152
+ }
153
+
154
+ return guardState.hasConfirmedEmptyEditorSnapshot;
155
+ }
156
+
48
157
  export function getTaskDescriptionStorageLength(
49
158
  content: JSONContent | null
50
159
  ): number {