@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.
Files changed (182) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/biome.json +1 -1
  3. package/package.json +73 -71
  4. package/src/components/ui/accordion.tsx +1 -1
  5. package/src/components/ui/breadcrumb.tsx +1 -1
  6. package/src/components/ui/calendar-app/calendar-page-shell.tsx +4 -0
  7. package/src/components/ui/calendar-app/components/calendar-connections-settings-content.tsx +239 -33
  8. package/src/components/ui/calendar-app/components/load-smart-scheduling-tasks.tsx +143 -0
  9. package/src/components/ui/calendar-app/components/priority-view.tsx +10 -3
  10. package/src/components/ui/calendar-app/components/tasks-sidebar.tsx +4 -116
  11. package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +67 -2
  12. package/src/components/ui/calendar.tsx +1 -1
  13. package/src/components/ui/carousel.tsx +1 -1
  14. package/src/components/ui/chat/chat-agent-details-external-thread-panel.test.tsx +1 -1
  15. package/src/components/ui/chat/chat-agent-details-external-thread-panel.tsx +1 -1
  16. package/src/components/ui/chat/chat-agent-details-operations-panel.test.tsx +1 -1
  17. package/src/components/ui/chat/chat-agent-details-operations-panel.tsx +1 -1
  18. package/src/components/ui/chat/chat-agent-details-setup-panel.tsx +1 -1
  19. package/src/components/ui/chat/chat-agent-details-sidebar.test.tsx +1 -1
  20. package/src/components/ui/chat/chat-agent-details-sidebar.tsx +2 -2
  21. package/src/components/ui/chat/chat-agent-details-utils.test.ts +1 -1
  22. package/src/components/ui/chat/chat-agent-details-utils.tsx +1 -1
  23. package/src/components/ui/chat/chat-agent-details-zalo-personal-panel.tsx +2 -2
  24. package/src/components/ui/checkbox.tsx +1 -1
  25. package/src/components/ui/color-picker.tsx +1 -1
  26. package/src/components/ui/command.tsx +1 -1
  27. package/src/components/ui/context-menu.tsx +5 -1
  28. package/src/components/ui/custom/__tests__/settings-dialog-shell.test.tsx +3 -0
  29. package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +19 -0
  30. package/src/components/ui/custom/combobox.test.tsx +195 -0
  31. package/src/components/ui/custom/combobox.tsx +273 -156
  32. package/src/components/ui/custom/education/modules/youtube/delete-link-button.tsx +5 -13
  33. package/src/components/ui/custom/facebook-mockup/facebook-mockup.tsx +7 -1
  34. package/src/components/ui/custom/facebook-mockup/form.tsx +1 -1
  35. package/src/components/ui/custom/facebook-mockup/image-upload-field.tsx +1 -1
  36. package/src/components/ui/custom/facebook-mockup/preview.tsx +1 -1
  37. package/src/components/ui/custom/settings-dialog-shell.tsx +2 -1
  38. package/src/components/ui/custom/theme-toggle.tsx +1 -1
  39. package/src/components/ui/custom/workspace-select.tsx +8 -3
  40. package/src/components/ui/dialog.test.tsx +52 -0
  41. package/src/components/ui/dialog.tsx +6 -2
  42. package/src/components/ui/dropdown-menu.tsx +5 -1
  43. package/src/components/ui/finance/debts/debt-loan-form.tsx +12 -5
  44. package/src/components/ui/finance/debts/debt-loan-summary.tsx +3 -2
  45. package/src/components/ui/finance/debts/debts-page.test.tsx +54 -5
  46. package/src/components/ui/finance/debts/debts-page.tsx +15 -2
  47. package/src/components/ui/finance/invoices/components/subscription-group-selector.tsx +3 -5
  48. package/src/components/ui/finance/invoices/new-invoice-page.test.tsx +25 -5
  49. package/src/components/ui/finance/invoices/new-invoice-page.tsx +7 -2
  50. package/src/components/ui/finance/invoices/standard-invoice.tsx +4 -2
  51. package/src/components/ui/finance/invoices/subscription-invoice.tsx +4 -2
  52. package/src/components/ui/finance/invoices/utils.ts +3 -1
  53. package/src/components/ui/finance/transactions/form-content-dialog.tsx +3 -0
  54. package/src/components/ui/finance/transactions/form-types.ts +1 -0
  55. package/src/components/ui/finance/transactions/form.tsx +2 -0
  56. package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +2 -0
  57. package/src/components/ui/finance/transactions/period-charts/category-breakdown-dialog.tsx +1 -1
  58. package/src/components/ui/finance/transactions/transaction-edit-dialog.tsx +1 -4
  59. package/src/components/ui/finance/transactions/transactions-create-summary.tsx +3 -0
  60. package/src/components/ui/finance/transactions/transactions-page.tsx +4 -1
  61. package/src/components/ui/finance/wallets/form.test.tsx +51 -3
  62. package/src/components/ui/finance/wallets/form.tsx +15 -4
  63. package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +4 -0
  64. package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +4 -2
  65. package/src/components/ui/finance/wallets/wallets-data-table.tsx +1 -0
  66. package/src/components/ui/finance/wallets/wallets-page.tsx +5 -2
  67. package/src/components/ui/input-otp.tsx +1 -1
  68. package/src/components/ui/legacy/calendar/all-day-event-bar.tsx +28 -39
  69. package/src/components/ui/legacy/calendar/calendar-cell.tsx +2 -0
  70. package/src/components/ui/legacy/calendar/calendar-content.tsx +10 -6
  71. package/src/components/ui/legacy/calendar/calendar-header.tsx +23 -3
  72. package/src/components/ui/legacy/calendar/calendar-loading-skeleton.tsx +135 -0
  73. package/src/components/ui/legacy/calendar/calendar-matrix.tsx +175 -237
  74. package/src/components/ui/legacy/calendar/event-card.test.tsx +177 -0
  75. package/src/components/ui/legacy/calendar/event-card.tsx +220 -131
  76. package/src/components/ui/legacy/calendar/event-modal.tsx +17 -17
  77. package/src/components/ui/legacy/calendar/event-provider-display.tsx +69 -0
  78. package/src/components/ui/legacy/calendar/smart-calendar.test.tsx +86 -4
  79. package/src/components/ui/legacy/calendar/smart-calendar.tsx +32 -2
  80. package/src/components/ui/legacy/meet/create-plan-dialog.tsx +19 -10
  81. package/src/components/ui/navigation-menu.tsx +1 -1
  82. package/src/components/ui/pagination.tsx +1 -1
  83. package/src/components/ui/radio-group.tsx +1 -1
  84. package/src/components/ui/select.tsx +5 -1
  85. package/src/components/ui/sheet.tsx +1 -1
  86. package/src/components/ui/sidebar.tsx +1 -1
  87. package/src/components/ui/storefront/cart-popover.tsx +61 -0
  88. package/src/components/ui/storefront/cart-summary-parts.tsx +290 -0
  89. package/src/components/ui/storefront/cart-summary.tsx +93 -154
  90. package/src/components/ui/storefront/checkout-overlay.tsx +4 -5
  91. package/src/components/ui/storefront/listing-card.tsx +1 -1
  92. package/src/components/ui/storefront/merch-sections.tsx +70 -0
  93. package/src/components/ui/storefront/product-detail.tsx +1 -1
  94. package/src/components/ui/storefront/storefront-surface.test.tsx +106 -11
  95. package/src/components/ui/storefront/storefront-surface.tsx +101 -166
  96. package/src/components/ui/storefront/types.ts +4 -0
  97. package/src/components/ui/storefront/utils.ts +6 -0
  98. package/src/components/ui/text-editor/__tests__/extensions.test.ts +123 -0
  99. package/src/components/ui/text-editor/background-color-extension.ts +62 -0
  100. package/src/components/ui/text-editor/color-controls.tsx +284 -0
  101. package/src/components/ui/text-editor/editor.tsx +69 -14
  102. package/src/components/ui/text-editor/extensions.ts +8 -2
  103. package/src/components/ui/text-editor/highlight-extension.ts +22 -0
  104. package/src/components/ui/text-editor/tool-bar.tsx +9 -16
  105. package/src/components/ui/toast.tsx +1 -1
  106. package/src/components/ui/tu-do/boards/__tests__/board-share-dialog.test.tsx +270 -0
  107. package/src/components/ui/tu-do/boards/board-public-link-section.tsx +231 -0
  108. package/src/components/ui/tu-do/boards/board-share-dialog.tsx +222 -109
  109. package/src/components/ui/tu-do/boards/boardId/board-column.tsx +112 -43
  110. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-clear-delete.ts +2 -0
  111. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-move.ts +5 -0
  112. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-updates.ts +3 -0
  113. package/src/components/ui/tu-do/boards/boardId/kanban/data/kanban-deadline-query.ts +50 -2
  114. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/__tests__/column-reorder.test.ts +17 -0
  115. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/column-reorder.ts +4 -1
  116. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-drag-cache.ts +38 -9
  117. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-drag-order.ts +2 -8
  118. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-sort-key.ts +47 -0
  119. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +81 -30
  120. package/src/components/ui/tu-do/boards/boardId/kanban/planner/__tests__/kanban-planner-island.test.tsx +380 -0
  121. package/src/components/ui/tu-do/boards/boardId/kanban/planner/kanban-planner-dialog.tsx +204 -0
  122. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-digest-panel.tsx +61 -0
  123. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-item-strip.tsx +54 -0
  124. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-plan-toolbar.tsx +251 -0
  125. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-scope-badge.tsx +27 -0
  126. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-section.tsx +58 -0
  127. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-share-dialog.tsx +238 -0
  128. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-target-controls.tsx +143 -0
  129. package/src/components/ui/tu-do/boards/boardId/kanban/planner/planner-utils.ts +65 -0
  130. package/src/components/ui/tu-do/boards/boardId/kanban/planner/use-kanban-planner-state.ts +234 -0
  131. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +397 -2
  132. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +103 -13
  133. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-deadline-panels.tsx +443 -19
  134. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-skeleton.tsx +94 -32
  135. package/src/components/ui/tu-do/boards/boardId/kanban.tsx +213 -106
  136. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.test.tsx +26 -4
  137. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +5 -2
  138. package/src/components/ui/tu-do/boards/boardId/task-card/measured-task-card.tsx +3 -0
  139. package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.ts +3 -0
  140. package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +191 -28
  141. package/src/components/ui/tu-do/boards/boardId/task-filter.test.tsx +152 -0
  142. package/src/components/ui/tu-do/boards/boardId/task-filter.tsx +555 -545
  143. package/src/components/ui/tu-do/boards/boardId/task-list.tsx +7 -0
  144. package/src/components/ui/tu-do/boards/share-section.tsx +100 -0
  145. package/src/components/ui/tu-do/drafts/draft-convert-dialog.tsx +10 -12
  146. package/src/components/ui/tu-do/drafts/drafts-page.tsx +33 -16
  147. package/src/components/ui/tu-do/initiatives/task-initiatives-client.tsx +56 -88
  148. package/src/components/ui/tu-do/my-tasks/my-tasks-content.tsx +26 -2
  149. package/src/components/ui/tu-do/my-tasks/use-my-tasks-state.ts +55 -8
  150. package/src/components/ui/tu-do/notes/note-edit-dialog.tsx +1 -4
  151. package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +25 -0
  152. package/src/components/ui/tu-do/shared/__tests__/board-header.test.tsx +341 -38
  153. package/src/components/ui/tu-do/shared/__tests__/board-switcher.test.tsx +253 -0
  154. package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +203 -2
  155. package/src/components/ui/tu-do/shared/__tests__/task-board-loading-state.test.tsx +17 -0
  156. package/src/components/ui/tu-do/shared/__tests__/task-legacy-route-recovery.test.tsx +16 -0
  157. package/src/components/ui/tu-do/shared/board-client.tsx +2 -7
  158. package/src/components/ui/tu-do/shared/board-config-storage.ts +7 -1
  159. package/src/components/ui/tu-do/shared/board-header.tsx +464 -975
  160. package/src/components/ui/tu-do/shared/board-layout-settings.tsx +165 -136
  161. package/src/components/ui/tu-do/shared/board-switcher.tsx +209 -217
  162. package/src/components/ui/tu-do/shared/board-views.tsx +587 -75
  163. package/src/components/ui/tu-do/shared/list-view.tsx +227 -1
  164. package/src/components/ui/tu-do/shared/recycle-bin-panel.tsx +142 -94
  165. package/src/components/ui/tu-do/shared/special-task-list-pins.ts +51 -0
  166. package/src/components/ui/tu-do/shared/task-board-loading-state.tsx +28 -0
  167. package/src/components/ui/tu-do/shared/task-edit-dialog/field-diff-viewer.tsx +3 -2
  168. package/src/components/ui/tu-do/shared/task-edit-dialog/selective-revert-panel.test.tsx +91 -0
  169. package/src/components/ui/tu-do/shared/task-edit-dialog/selective-revert-panel.tsx +123 -78
  170. package/src/components/ui/tu-do/shared/task-edit-dialog/task-activity-section.tsx +7 -1
  171. package/src/components/ui/tu-do/shared/task-edit-dialog/task-snapshot-dialog.tsx +8 -3
  172. package/src/components/ui/tu-do/shared/task-edit-dialog.tsx +2 -1
  173. package/src/components/ui/tu-do/shared/task-legacy-route-recovery.tsx +2 -9
  174. package/src/declarations.d.ts +1 -0
  175. package/src/hooks/__tests__/use-calendar-readonly.test.tsx +322 -2
  176. package/src/hooks/__tests__/use-calendar-sync.test.tsx +446 -0
  177. package/src/hooks/use-calendar-sync.tsx +247 -243
  178. package/src/hooks/use-calendar.tsx +323 -138
  179. package/src/hooks/use-task-actions.ts +24 -0
  180. package/src/hooks/use-user-workspace-config.ts +75 -0
  181. package/src/hooks/use-workspace-currency.ts +8 -3
  182. package/src/hooks/useBoardRealtimeEventHandler.ts +11 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.0](https://github.com/tutur3u/platform/compare/ui-v0.8.0...ui-v0.9.0) (2026-06-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * **calendar:** add configurable two-way sync ([76078d8](https://github.com/tutur3u/platform/commit/76078d865618b4970b430b08f0db7a1a8c30ffcb))
9
+ * **inventory:** surface storefront checkout sales ([c8e813c](https://github.com/tutur3u/platform/commit/c8e813caa23e7e77e94aa94c9f0059b95cd5ba1c))
10
+ * **storefront:** simplify cart and checkout ([a2d17e1](https://github.com/tutur3u/platform/commit/a2d17e1a024e11ffb76cbaa1a99e8f26a5a43aa0))
11
+ * **task-boards:** improve public board sharing UX ([930ceb4](https://github.com/tutur3u/platform/commit/930ceb49ef72fad22e3f412c2ff5648fd6b3c417))
12
+ * **tasks:** add board creation to task picker ([da82857](https://github.com/tutur3u/platform/commit/da828579f57ac65537fc538fb20692783c2b7751))
13
+ * **tasks:** add board-centered tasks entry ([cfb0dd6](https://github.com/tutur3u/platform/commit/cfb0dd689924f91f2b9b848e82c0feab89f62ab0))
14
+ * **tasks:** add deadline column controls ([524c621](https://github.com/tutur3u/platform/commit/524c62117dab6984ff0116e010341694ead6f8b5))
15
+ * **tasks:** add public board sharing ([b5a4a07](https://github.com/tutur3u/platform/commit/b5a4a0796dab947e8dca3970d6aa136a4863dd35))
16
+ * **tasks:** add shareable kanban task plans ([2de4e58](https://github.com/tutur3u/platform/commit/2de4e5819673e11b01cdc1f21c317f33dc196f56))
17
+ * **tasks:** compact kanban planner and share dialog ([381aa91](https://github.com/tutur3u/platform/commit/381aa91433aaed2936b04d34c44f13f364befe21))
18
+ * **tasks:** consolidate board task settings ([b1d720a](https://github.com/tutur3u/platform/commit/b1d720ac865406d6dd0b2477c5ba04e336de9929))
19
+ * **ui:** add theme-aware editor colors ([fde3ae9](https://github.com/tutur3u/platform/commit/fde3ae9930e1573b6a7273c95f90f41767e72c58))
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * **calendar:** improve synced event rendering ([9bc2bee](https://github.com/tutur3u/platform/commit/9bc2beea78fe21ccd3deb5040b63a1ae4ff39aa7))
25
+ * **calendar:** preserve events across week navigation ([aa60471](https://github.com/tutur3u/platform/commit/aa604715f132f4ed4476dd4df3795f53848c360b))
26
+ * **calendar:** stabilize optimistic event sync ([fda22e1](https://github.com/tutur3u/platform/commit/fda22e1eebec28e04af0b8a2ab22d0f148c0565d))
27
+ * **ci:** address remaining PR check failures ([7eb56d5](https://github.com/tutur3u/platform/commit/7eb56d51d8d14f6e2dd22c2d4c3514a560847333))
28
+ * **tanstack:** harden public shell migration ([849c133](https://github.com/tutur3u/platform/commit/849c1334da613437dc673a8396a373ffc7767583))
29
+ * **task-boards:** align board picker icon styling ([c145770](https://github.com/tutur3u/platform/commit/c145770c0d4cf43a96db9df2fd9f14696e4b84ad))
30
+ * **task-boards:** clean up board header icons ([16673be](https://github.com/tutur3u/platform/commit/16673be22ba40205e09134e6db8225edb7db841a))
31
+ * **tasks:** polish board activity and history diffs ([cdc1c2c](https://github.com/tutur3u/platform/commit/cdc1c2cbdcc283ee30e959435b70f03e84b999de))
32
+ * **tasks:** polish board filters planner and settings loading ([2396419](https://github.com/tutur3u/platform/commit/239641941a08e243d1295231c8e2d1089902897f))
33
+ * **tasks:** polish board header settings and share ux ([fd78ac5](https://github.com/tutur3u/platform/commit/fd78ac5e5632e8897d8e124ec8c5abd26acc820b))
34
+ * **tasks:** polish board toolbar settings and activity ([e1966bb](https://github.com/tutur3u/platform/commit/e1966bb68d4900e4d5d187153f3a8942727f2127))
35
+ * **tasks:** polish board views and loading ([0b60957](https://github.com/tutur3u/platform/commit/0b6095726b6c1aaae4f794ba6cfecde4d46f0db9))
36
+ * **tasks:** polish task board loading and defaults ([7c215d3](https://github.com/tutur3u/platform/commit/7c215d3ea6b0b710247069f8616d4b7b1029147f))
37
+ * **tasks:** refine board settings and toolbar pickers ([bec77e3](https://github.com/tutur3u/platform/commit/bec77e30804bb0ff0657831e564e8dd8efeb8722))
38
+ * **tasks:** refresh kanban special columns ([3317e1d](https://github.com/tutur3u/platform/commit/3317e1d80890afa05a4d10840131b8f2d77910ec))
39
+ * **tasks:** update board header icons ([7f79c06](https://github.com/tutur3u/platform/commit/7f79c06e4a854c1489db30a6265b6aa24583cc86))
40
+ * **ui:** stabilize fullscreen dialog surfaces ([138bc7b](https://github.com/tutur3u/platform/commit/138bc7b7761151007bb097aa15350d72a92dd638))
41
+ * **web:** prevent dashboard runtime loops ([e02ae70](https://github.com/tutur3u/platform/commit/e02ae701e6905a47b7d96d51624b0a301cb1405f))
42
+
3
43
  ## [0.8.0](https://github.com/tutur3u/platform/compare/ui-v0.7.0...ui-v0.8.0) (2026-06-17)
4
44
 
5
45
 
package/biome.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "root": false,
3
- "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
3
+ "$schema": "https://biomejs.dev/schemas/2.5.1/schema.json",
4
4
  "extends": "//"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuturuuu/ui",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,7 +14,7 @@
14
14
  "ui": "bunx shadcn-ui@latest",
15
15
  "test": "vitest run",
16
16
  "test:watch": "vitest",
17
- "type-check": "tsgo --project tsconfig.typecheck.json"
17
+ "type-check": "tsc --project tsconfig.typecheck.json"
18
18
  },
19
19
  "dependencies": {
20
20
  "@dnd-kit/core": "^6.3.1",
@@ -24,71 +24,73 @@
24
24
  "@hookform/resolvers": "^5.4.0",
25
25
  "@json-render/core": "^0.19.0",
26
26
  "@json-render/react": "^0.19.0",
27
- "@radix-ui/react-accordion": "^1.2.13",
28
- "@radix-ui/react-alert-dialog": "^1.1.16",
29
- "@radix-ui/react-aspect-ratio": "^1.1.9",
30
- "@radix-ui/react-avatar": "^1.1.12",
31
- "@radix-ui/react-checkbox": "^1.3.4",
32
- "@radix-ui/react-collapsible": "^1.1.13",
33
- "@radix-ui/react-context-menu": "^2.3.0",
34
- "@radix-ui/react-dialog": "^1.1.16",
35
- "@radix-ui/react-dropdown-menu": "^2.1.17",
36
- "@radix-ui/react-hover-card": "^1.1.16",
37
- "@radix-ui/react-label": "^2.1.9",
38
- "@radix-ui/react-menubar": "^1.1.17",
39
- "@radix-ui/react-navigation-menu": "^1.2.15",
40
- "@radix-ui/react-popover": "^1.1.16",
41
- "@radix-ui/react-progress": "^1.1.9",
42
- "@radix-ui/react-radio-group": "^1.4.0",
43
- "@radix-ui/react-scroll-area": "^1.2.11",
44
- "@radix-ui/react-select": "^2.3.0",
45
- "@radix-ui/react-separator": "^1.1.9",
46
- "@radix-ui/react-slider": "^1.4.0",
47
- "@radix-ui/react-slot": "^1.2.5",
48
- "@radix-ui/react-switch": "^1.3.0",
49
- "@radix-ui/react-tabs": "^1.1.14",
50
- "@radix-ui/react-toast": "^1.2.16",
51
- "@radix-ui/react-toggle": "^1.1.11",
52
- "@radix-ui/react-toggle-group": "^1.1.12",
53
- "@radix-ui/react-tooltip": "^1.2.9",
27
+ "@radix-ui/react-accordion": "^1.2.14",
28
+ "@radix-ui/react-alert-dialog": "^1.1.17",
29
+ "@radix-ui/react-aspect-ratio": "^1.1.10",
30
+ "@radix-ui/react-avatar": "^1.2.0",
31
+ "@radix-ui/react-checkbox": "^1.3.5",
32
+ "@radix-ui/react-collapsible": "^1.1.14",
33
+ "@radix-ui/react-context-menu": "^2.3.1",
34
+ "@radix-ui/react-dialog": "^1.1.17",
35
+ "@radix-ui/react-dropdown-menu": "^2.1.18",
36
+ "@radix-ui/react-hover-card": "^1.1.17",
37
+ "@radix-ui/react-label": "^2.1.10",
38
+ "@radix-ui/react-menubar": "^1.1.18",
39
+ "@radix-ui/react-navigation-menu": "^1.2.16",
40
+ "@radix-ui/react-popover": "^1.1.17",
41
+ "@radix-ui/react-progress": "^1.1.10",
42
+ "@radix-ui/react-radio-group": "^1.4.1",
43
+ "@radix-ui/react-scroll-area": "^1.2.12",
44
+ "@radix-ui/react-select": "^2.3.1",
45
+ "@radix-ui/react-separator": "^1.1.10",
46
+ "@radix-ui/react-slider": "^1.4.1",
47
+ "@radix-ui/react-slot": "^1.3.0",
48
+ "@radix-ui/react-switch": "^1.3.1",
49
+ "@radix-ui/react-tabs": "^1.1.15",
50
+ "@radix-ui/react-toast": "^1.2.17",
51
+ "@radix-ui/react-toggle": "^1.1.12",
52
+ "@radix-ui/react-toggle-group": "^1.1.13",
53
+ "@radix-ui/react-tooltip": "^1.2.10",
54
54
  "@streamdown/cjk": "^1.0.3",
55
55
  "@streamdown/code": "^1.1.1",
56
56
  "@streamdown/math": "^1.0.2",
57
57
  "@streamdown/mermaid": "^1.0.2",
58
58
  "@tanstack/react-hotkeys": "^0.10.0",
59
59
  "@tanstack/react-pacer": "^0.22.1",
60
- "@tanstack/react-query": "^5.101.0",
60
+ "@tanstack/react-query": "^5.101.1",
61
61
  "@tanstack/react-table": "^8.21.3",
62
- "@tanstack/react-virtual": "^3.14.2",
63
- "@tiptap/core": "3.26.1",
64
- "@tiptap/extension-collaboration": "3.26.1",
65
- "@tiptap/extension-collaboration-caret": "3.26.1",
66
- "@tiptap/extension-drag-handle-react": "3.26.1",
67
- "@tiptap/extension-highlight": "3.26.1",
68
- "@tiptap/extension-horizontal-rule": "3.26.1",
69
- "@tiptap/extension-image": "3.26.1",
70
- "@tiptap/extension-link": "3.26.1",
71
- "@tiptap/extension-list": "3.26.1",
72
- "@tiptap/extension-placeholder": "3.26.1",
73
- "@tiptap/extension-strike": "3.26.1",
74
- "@tiptap/extension-subscript": "3.26.1",
75
- "@tiptap/extension-superscript": "3.26.1",
76
- "@tiptap/extension-table": "3.26.1",
77
- "@tiptap/extension-table-cell": "3.26.1",
78
- "@tiptap/extension-table-header": "3.26.1",
79
- "@tiptap/extension-table-row": "3.26.1",
80
- "@tiptap/extension-text-align": "3.26.1",
81
- "@tiptap/extension-youtube": "3.26.1",
82
- "@tiptap/pm": "3.26.1",
83
- "@tiptap/react": "3.26.1",
84
- "@tiptap/starter-kit": "3.26.1",
62
+ "@tanstack/react-virtual": "^3.14.3",
63
+ "@tiptap/core": "3.27.1",
64
+ "@tiptap/extension-collaboration": "3.27.1",
65
+ "@tiptap/extension-collaboration-caret": "3.27.1",
66
+ "@tiptap/extension-color": "3.27.1",
67
+ "@tiptap/extension-drag-handle-react": "3.27.1",
68
+ "@tiptap/extension-highlight": "3.27.1",
69
+ "@tiptap/extension-horizontal-rule": "3.27.1",
70
+ "@tiptap/extension-image": "3.27.1",
71
+ "@tiptap/extension-link": "3.27.1",
72
+ "@tiptap/extension-list": "3.27.1",
73
+ "@tiptap/extension-placeholder": "3.27.1",
74
+ "@tiptap/extension-strike": "3.27.1",
75
+ "@tiptap/extension-subscript": "3.27.1",
76
+ "@tiptap/extension-superscript": "3.27.1",
77
+ "@tiptap/extension-table": "3.27.1",
78
+ "@tiptap/extension-table-cell": "3.27.1",
79
+ "@tiptap/extension-table-header": "3.27.1",
80
+ "@tiptap/extension-table-row": "3.27.1",
81
+ "@tiptap/extension-text-align": "3.27.1",
82
+ "@tiptap/extension-text-style": "3.27.1",
83
+ "@tiptap/extension-youtube": "3.27.1",
84
+ "@tiptap/pm": "3.27.1",
85
+ "@tiptap/react": "3.27.1",
86
+ "@tiptap/starter-kit": "3.27.1",
85
87
  "@tuturuuu/ai": "0.2.2",
86
- "@tuturuuu/apis": "0.5.0",
88
+ "@tuturuuu/apis": "0.6.0",
87
89
  "@tuturuuu/hooks": "0.0.2",
88
90
  "@tuturuuu/icons": "0.0.6",
89
- "@tuturuuu/internal-api": "0.9.0",
90
- "@tuturuuu/supabase": "0.3.4",
91
- "@tuturuuu/utils": "0.8.0",
91
+ "@tuturuuu/internal-api": "0.10.0",
92
+ "@tuturuuu/supabase": "0.4.0",
93
+ "@tuturuuu/utils": "0.9.0",
92
94
  "@types/debug": "^4.1.13",
93
95
  "browser-image-compression": "^2.0.2",
94
96
  "class-variance-authority": "^0.7.1",
@@ -100,14 +102,14 @@
100
102
  "debug": "^4.4.3",
101
103
  "embla-carousel-react": "^8.6.0",
102
104
  "eventemitter3": "^5.0.4",
103
- "framer-motion": "^12.40.0",
105
+ "framer-motion": "^12.41.0",
104
106
  "gsap": "^3.15.0",
105
- "html2canvas-pro": "^2.0.2",
107
+ "html2canvas-pro": "^2.1.1",
106
108
  "input-otp": "^1.4.2",
107
109
  "katex": "^0.17.0",
108
110
  "lodash": "4.18.1",
109
111
  "moment": "^2.30.1",
110
- "motion": "^12.40.0",
112
+ "motion": "^12.41.0",
111
113
  "next": "^16.2.9",
112
114
  "next-intl": "^4.13.0",
113
115
  "next-themes": "^0.4.6",
@@ -119,14 +121,14 @@
119
121
  "react-day-picker": "^10.0.1",
120
122
  "react-dom": "^19.2.7",
121
123
  "react-dropzone": "^15.0.0",
122
- "react-hook-form": "^7.79.0",
124
+ "react-hook-form": "^7.80.0",
123
125
  "react-markdown": "^10.1.0",
124
126
  "react-papaparse": "^4.4.0",
125
127
  "react-pdf": "^10.4.1",
126
- "react-resizable": "^4.0.1",
128
+ "react-resizable": "^4.0.2",
127
129
  "react-resizable-panels": "^4.11.0",
128
130
  "react-syntax-highlighter": "^16.1.1",
129
- "recharts": "3.8.1",
131
+ "recharts": "3.9.0",
130
132
  "sonner": "^2.0.7",
131
133
  "streamdown": "^2.5.0",
132
134
  "tailwind-scrollbar": "^4.0.2",
@@ -143,32 +145,32 @@
143
145
  "devDependencies": {
144
146
  "@tailwindcss/postcss": "^4.3.1",
145
147
  "@tailwindcss/typography": "^0.5.20",
146
- "@tanstack/react-query": "^5.101.0",
148
+ "@tanstack/react-query": "^5.101.1",
147
149
  "@tanstack/react-table": "^8.21.3",
148
150
  "@testing-library/jest-dom": "^6.9.1",
149
151
  "@testing-library/react": "^16.3.2",
150
- "@tuturuuu/types": "0.10.0",
152
+ "@tuturuuu/types": "0.11.0",
151
153
  "@tuturuuu/typescript-config": "0.1.1",
152
154
  "@types/html2canvas": "^1.0.0",
153
155
  "@types/lodash": "^4.17.24",
154
- "@types/node": "^25.9.3",
156
+ "@types/node": "^26.0.0",
155
157
  "@types/react": "^19.2.17",
156
158
  "@types/react-dom": "^19.2.3",
157
159
  "@types/react-resizable": "^4.0.0",
158
160
  "@types/react-syntax-highlighter": "^15.5.13",
159
161
  "@types/uuid": "^11.0.0",
160
- "@vitejs/plugin-react": "^6.0.2",
162
+ "@vitejs/plugin-react": "^6.0.3",
161
163
  "autoprefixer": "^10.5.0",
162
164
  "jsdom": "^29.1.1",
163
165
  "postcss": "^8.5.14",
164
166
  "postcss-load-config": "^6.0.1",
165
167
  "tailwindcss": "^4.3.1",
166
- "typescript": "^6.0.3",
167
- "uuid": "^14.0.0",
168
- "vitest": "^4.1.8"
168
+ "typescript": "7.0.1-rc",
169
+ "uuid": "^14.0.1",
170
+ "vitest": "^4.1.9"
169
171
  },
170
172
  "peerDependencies": {
171
- "@tanstack/react-query": "^5.101.0",
173
+ "@tanstack/react-query": "^5.101.1",
172
174
  "@tanstack/react-table": "^8.21.3"
173
175
  },
174
176
  "exports": {
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
4
- import { ChevronDownIcon } from '@tuturuuu/icons';
4
+ import { ChevronDownIcon } from '@tuturuuu/icons/lucide-static';
5
5
  import { cn } from '@tuturuuu/utils/format';
6
6
  import type * as React from 'react';
7
7
 
@@ -1,5 +1,5 @@
1
1
  import { Slot } from '@radix-ui/react-slot';
2
- import { ChevronRight, MoreHorizontal } from '@tuturuuu/icons';
2
+ import { ChevronRight, MoreHorizontal } from '@tuturuuu/icons/lucide-static';
3
3
  import { cn } from '@tuturuuu/utils/format';
4
4
  import type * as React from 'react';
5
5
 
@@ -5,6 +5,7 @@ import type {
5
5
  } from '@tuturuuu/types';
6
6
  import { CalendarSyncProvider } from '@tuturuuu/ui/hooks/use-calendar-sync';
7
7
  import { TaskDialogWrapper } from '@tuturuuu/ui/tu-do/shared/task-dialog-wrapper';
8
+ import type { ExtendedWorkspaceTask } from '../time-tracker/types';
8
9
  import { CalendarClientPage } from './calendar-client-page';
9
10
  import TasksSidebar from './components/tasks-sidebar';
10
11
 
@@ -14,6 +15,7 @@ interface CalendarPageShellProps {
14
15
  experimentalGoogleToken?: WorkspaceCalendarGoogleTokenClient | null;
15
16
  isPersonalWorkspace: boolean;
16
17
  locale: string;
18
+ smartSchedulingTasks?: ExtendedWorkspaceTask[];
17
19
  userId: string;
18
20
  workspace: Workspace;
19
21
  }
@@ -24,6 +26,7 @@ export function CalendarPageShell({
24
26
  experimentalGoogleToken,
25
27
  isPersonalWorkspace,
26
28
  locale,
29
+ smartSchedulingTasks = [],
27
30
  userId,
28
31
  workspace,
29
32
  }: CalendarPageShellProps) {
@@ -48,6 +51,7 @@ export function CalendarPageShell({
48
51
  resolvedWsId={workspace.id}
49
52
  locale={locale}
50
53
  userId={userId}
54
+ tasks={smartSchedulingTasks}
51
55
  />
52
56
  )}
53
57
  </div>
@@ -48,6 +48,13 @@ import { Separator } from '../../separator';
48
48
  import { Switch } from '../../switch';
49
49
  import type { CalendarConnectionsManagerState } from './use-calendar-connections-manager';
50
50
 
51
+ function isWritableProviderAccess(accessRole?: string | null) {
52
+ if (!accessRole) return true;
53
+ return ['owner', 'writer', 'write', 'editor'].includes(
54
+ accessRole.toLowerCase()
55
+ );
56
+ }
57
+
51
58
  export function CalendarConnectionsSettingsContent({
52
59
  state,
53
60
  className,
@@ -75,13 +82,26 @@ export function CalendarConnectionsSettingsContent({
75
82
  setNewCalendarName,
76
83
  setShowCreateCalendarDialog,
77
84
  showCreateCalendarDialog,
85
+ syncPreferencesData,
86
+ syncPreferencesMutation,
78
87
  systemCalendars,
79
88
  t,
80
89
  togglingIds,
81
90
  togglingTuturuuuIds,
82
91
  toggleAccountExpanded,
83
92
  toggleWorkspaceCalendarMutation,
93
+ updateConnectionSyncSettingsMutation,
84
94
  } = state;
95
+ const externalSyncOptions =
96
+ syncPreferencesData?.options.filter(
97
+ (option) => option.provider !== 'tuturuuu'
98
+ ) ?? [];
99
+ const syncSettingsUnavailable =
100
+ syncPreferencesData?.settingsAvailable === false;
101
+ const syncSettingsDisabled =
102
+ !syncPreferencesData ||
103
+ syncSettingsUnavailable ||
104
+ syncPreferencesMutation.isPending;
85
105
 
86
106
  return (
87
107
  <div className={className ? `space-y-4 ${className}` : 'space-y-4'}>
@@ -128,6 +148,126 @@ export function CalendarConnectionsSettingsContent({
128
148
  </Select>
129
149
  </div>
130
150
 
151
+ <div className="space-y-3 rounded-md border p-3">
152
+ <div>
153
+ <h4 className="font-medium text-sm">
154
+ {t('two_way_sync') || 'Two-way sync'}
155
+ </h4>
156
+ <p className="text-muted-foreground text-xs">
157
+ {t('two_way_sync_desc') ||
158
+ 'Control how Tuturuuu imports provider changes and mirrors native events outward.'}
159
+ </p>
160
+ </div>
161
+
162
+ {syncSettingsUnavailable && (
163
+ <p className="rounded-md bg-muted px-3 py-2 text-muted-foreground text-xs">
164
+ {t('calendar_sync_settings_unavailable') ||
165
+ 'Sync controls will be available after the latest calendar migration is applied.'}
166
+ </p>
167
+ )}
168
+
169
+ <div className="space-y-2">
170
+ <div className="flex items-center justify-between gap-3">
171
+ <div className="min-w-0">
172
+ <p className="font-medium text-sm">
173
+ {t('import_external_changes') || 'Import external changes'}
174
+ </p>
175
+ <p className="text-muted-foreground text-xs">
176
+ {t('import_external_changes_desc') ||
177
+ 'Bring Google and Outlook event changes into Tuturuuu.'}
178
+ </p>
179
+ </div>
180
+ <Switch
181
+ checked={syncPreferencesData?.inboundSyncEnabled ?? true}
182
+ onCheckedChange={(checked) =>
183
+ syncPreferencesMutation.mutate({
184
+ inboundSyncEnabled: checked,
185
+ })
186
+ }
187
+ disabled={syncSettingsDisabled}
188
+ />
189
+ </div>
190
+
191
+ <div className="flex items-center justify-between gap-3">
192
+ <div className="min-w-0">
193
+ <p className="font-medium text-sm">
194
+ {t('sync_tuturuuu_events_outward') ||
195
+ 'Sync Tuturuuu events outward'}
196
+ </p>
197
+ <p className="text-muted-foreground text-xs">
198
+ {t('sync_tuturuuu_events_outward_desc') ||
199
+ 'Mirror native Tuturuuu event creates and edits to a connected provider calendar.'}
200
+ </p>
201
+ </div>
202
+ <Switch
203
+ checked={syncPreferencesData?.outboundSyncEnabled ?? false}
204
+ onCheckedChange={(checked) =>
205
+ syncPreferencesMutation.mutate({
206
+ outboundSyncEnabled: checked,
207
+ })
208
+ }
209
+ disabled={
210
+ syncSettingsDisabled || externalSyncOptions.length === 0
211
+ }
212
+ />
213
+ </div>
214
+ </div>
215
+
216
+ <Select
217
+ value={syncPreferencesData?.defaultOutboundConnectionId ?? 'none'}
218
+ onValueChange={(value) =>
219
+ syncPreferencesMutation.mutate({
220
+ defaultOutboundConnectionId: value === 'none' ? null : value,
221
+ })
222
+ }
223
+ disabled={syncSettingsDisabled || externalSyncOptions.length === 0}
224
+ >
225
+ <SelectTrigger className="w-full">
226
+ <SelectValue
227
+ placeholder={
228
+ t('choose_outbound_calendar') || 'Choose outbound calendar'
229
+ }
230
+ />
231
+ </SelectTrigger>
232
+ <SelectContent>
233
+ <SelectItem value="none">
234
+ {t('no_outbound_calendar') || 'No outbound calendar'}
235
+ </SelectItem>
236
+ {externalSyncOptions.map((option) => (
237
+ <SelectItem key={option.id} value={option.connectionId}>
238
+ <div className="flex min-w-0 items-center gap-2">
239
+ <span
240
+ className="h-2.5 w-2.5 shrink-0 rounded-full"
241
+ style={{
242
+ backgroundColor: option.color ?? undefined,
243
+ }}
244
+ />
245
+ <span className="truncate">{option.label}</span>
246
+ <Badge variant="secondary" className="capitalize">
247
+ {option.provider}
248
+ </Badge>
249
+ </div>
250
+ </SelectItem>
251
+ ))}
252
+ </SelectContent>
253
+ </Select>
254
+
255
+ <div className="flex items-center justify-between gap-3 rounded-md bg-muted/40 px-3 py-2">
256
+ <div className="min-w-0">
257
+ <p className="font-medium text-xs">
258
+ {t('conflict_policy') || 'Conflict policy'}
259
+ </p>
260
+ <p className="text-muted-foreground text-xs">
261
+ {t('latest_write_wins_desc') ||
262
+ 'When both sides changed, the most recently written event wins.'}
263
+ </p>
264
+ </div>
265
+ <Badge variant="outline">
266
+ {t('latest_write_wins') || 'Latest write wins'}
267
+ </Badge>
268
+ </div>
269
+ </div>
270
+
131
271
  {/* Tuturuuu Calendars Section */}
132
272
  <div className="space-y-3">
133
273
  <div className="flex items-center justify-between">
@@ -370,40 +510,106 @@ export function CalendarConnectionsSettingsContent({
370
510
  <Separator />
371
511
  <div className="space-y-2 p-3">
372
512
  {(calendarsByAccount[account.id] || []).length > 0 ? (
373
- (calendarsByAccount[account.id] || []).map((cal) => (
374
- <div
375
- key={cal.id}
376
- className="flex items-center justify-between gap-2 rounded-md px-2 py-1.5 hover:bg-muted/50"
377
- >
378
- <div className="flex min-w-0 flex-1 items-center gap-2">
379
- <div
380
- className="h-3 w-3 shrink-0 rounded-full"
381
- style={{
382
- backgroundColor: cal.color || '#4285f4',
383
- }}
384
- />
385
- <span
386
- className="line-clamp-1 break-all text-sm"
387
- title={cal.calendar_name}
388
- >
389
- {cal.calendar_name}
390
- </span>
513
+ (calendarsByAccount[account.id] || []).map((cal) => {
514
+ const syncControlsDisabled =
515
+ !cal.connectionExists ||
516
+ !cal.is_enabled ||
517
+ syncSettingsDisabled ||
518
+ updateConnectionSyncSettingsMutation.isPending;
519
+ const canWriteToProvider = isWritableProviderAccess(
520
+ cal.accessRole
521
+ );
522
+
523
+ return (
524
+ <div
525
+ key={cal.id}
526
+ className="rounded-md px-2 py-1.5 hover:bg-muted/50"
527
+ >
528
+ <div className="flex items-center justify-between gap-2">
529
+ <div className="flex min-w-0 flex-1 items-center gap-2">
530
+ <div
531
+ className="h-3 w-3 shrink-0 rounded-full"
532
+ style={{
533
+ backgroundColor: cal.color || '#4285f4',
534
+ }}
535
+ />
536
+ <span
537
+ className="line-clamp-1 break-all text-sm"
538
+ title={cal.calendar_name}
539
+ >
540
+ {cal.calendar_name}
541
+ </span>
542
+ </div>
543
+ <Switch
544
+ checked={cal.is_enabled}
545
+ onCheckedChange={() =>
546
+ handleToggle(cal.id, cal.is_enabled, {
547
+ calendar_id: cal.calendar_id,
548
+ calendar_name: cal.calendar_name,
549
+ color: cal.color,
550
+ connectionExists: cal.connectionExists,
551
+ accountId: cal.accountId,
552
+ accessRole: cal.accessRole,
553
+ })
554
+ }
555
+ disabled={togglingIds.has(cal.id)}
556
+ />
557
+ </div>
558
+
559
+ {cal.connectionExists && (
560
+ <div className="mt-2 grid grid-cols-3 gap-2 pl-5">
561
+ <label className="flex items-center justify-between gap-2 rounded-md bg-muted/40 px-2 py-1 text-muted-foreground text-xs">
562
+ <span>{t('import') || 'Import'}</span>
563
+ <Switch
564
+ checked={cal.syncInboundEnabled}
565
+ onCheckedChange={(checked) =>
566
+ updateConnectionSyncSettingsMutation.mutate(
567
+ {
568
+ id: cal.id,
569
+ syncInboundEnabled: checked,
570
+ }
571
+ )
572
+ }
573
+ disabled={syncControlsDisabled}
574
+ />
575
+ </label>
576
+ <label className="flex items-center justify-between gap-2 rounded-md bg-muted/40 px-2 py-1 text-muted-foreground text-xs">
577
+ <span>{t('send') || 'Send'}</span>
578
+ <Switch
579
+ checked={cal.syncOutboundEnabled}
580
+ onCheckedChange={(checked) =>
581
+ updateConnectionSyncSettingsMutation.mutate(
582
+ {
583
+ id: cal.id,
584
+ syncOutboundEnabled: checked,
585
+ }
586
+ )
587
+ }
588
+ disabled={
589
+ syncControlsDisabled || !canWriteToProvider
590
+ }
591
+ />
592
+ </label>
593
+ <label className="flex items-center justify-between gap-2 rounded-md bg-muted/40 px-2 py-1 text-muted-foreground text-xs">
594
+ <span>{t('deletes') || 'Deletes'}</span>
595
+ <Switch
596
+ checked={cal.syncDeleteEnabled}
597
+ onCheckedChange={(checked) =>
598
+ updateConnectionSyncSettingsMutation.mutate(
599
+ {
600
+ id: cal.id,
601
+ syncDeleteEnabled: checked,
602
+ }
603
+ )
604
+ }
605
+ disabled={syncControlsDisabled}
606
+ />
607
+ </label>
608
+ </div>
609
+ )}
391
610
  </div>
392
- <Switch
393
- checked={cal.is_enabled}
394
- onCheckedChange={() =>
395
- handleToggle(cal.id, cal.is_enabled, {
396
- calendar_id: cal.calendar_id,
397
- calendar_name: cal.calendar_name,
398
- color: cal.color,
399
- connectionExists: cal.connectionExists,
400
- accountId: cal.accountId,
401
- })
402
- }
403
- disabled={togglingIds.has(cal.id)}
404
- />
405
- </div>
406
- ))
611
+ );
612
+ })
407
613
  ) : (
408
614
  <p className="py-2 text-center text-muted-foreground text-xs">
409
615
  {t('no_calendars_found')}