@tulip-systems/core 0.5.2 → 0.5.4

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 (423) hide show
  1. package/dist/auth/client.d.mts +3 -3
  2. package/dist/auth/client.mjs +2 -2
  3. package/dist/components/client.d.mts +2 -2
  4. package/dist/components/common/icons.d.mts +2 -2
  5. package/dist/components/common/icons.d.mts.map +1 -1
  6. package/dist/components/common/status.d.mts +3 -3
  7. package/dist/components/common/status.d.mts.map +1 -1
  8. package/dist/components/editor/components/content.client.d.mts +2 -2
  9. package/dist/components/editor/components/content.client.d.mts.map +1 -1
  10. package/dist/components/editor/components/editor.client.d.mts +6 -6
  11. package/dist/components/editor/components/editor.client.d.mts.map +1 -1
  12. package/dist/components/editor/components/editor.client.mjs +2 -2
  13. package/dist/components/editor/components/editor.client.mjs.map +1 -1
  14. package/dist/components/editor/components/menu.client.d.mts +3 -3
  15. package/dist/components/editor/components/menu.client.d.mts.map +1 -1
  16. package/dist/components/editor/components/menu.client.mjs +3 -0
  17. package/dist/components/editor/components/menu.client.mjs.map +1 -1
  18. package/dist/components/editor/extensions/file-handler/extension.d.mts +21 -0
  19. package/dist/components/editor/extensions/file-handler/extension.d.mts.map +1 -0
  20. package/dist/components/editor/extensions/file-handler/extension.mjs +40 -0
  21. package/dist/components/editor/extensions/file-handler/extension.mjs.map +1 -0
  22. package/dist/components/editor/extensions/file-handler/strategy.d.mts +29 -0
  23. package/dist/components/editor/extensions/file-handler/strategy.d.mts.map +1 -0
  24. package/dist/components/editor/extensions/file-handler/strategy.mjs +111 -0
  25. package/dist/components/editor/extensions/file-handler/strategy.mjs.map +1 -0
  26. package/dist/components/editor/extensions/file-handler/utils.mjs +50 -0
  27. package/dist/components/editor/extensions/file-handler/utils.mjs.map +1 -0
  28. package/dist/components/editor/extensions/image/extension.d.mts +8 -0
  29. package/dist/components/editor/extensions/image/extension.d.mts.map +1 -0
  30. package/dist/components/editor/extensions/image/extension.mjs +51 -0
  31. package/dist/components/editor/extensions/image/extension.mjs.map +1 -0
  32. package/dist/components/editor/extensions/skeleton/extension.mjs +41 -0
  33. package/dist/components/editor/extensions/skeleton/extension.mjs.map +1 -0
  34. package/dist/components/editor/extensions/skeleton/renderer.mjs +25 -0
  35. package/dist/components/editor/extensions/skeleton/renderer.mjs.map +1 -0
  36. package/dist/components/editor/lib/constants.d.mts +31 -28
  37. package/dist/components/editor/lib/constants.d.mts.map +1 -1
  38. package/dist/components/editor/lib/constants.mjs +17 -5
  39. package/dist/components/editor/lib/constants.mjs.map +1 -1
  40. package/dist/components/editor/lib/extensions.d.mts +7 -3
  41. package/dist/components/editor/lib/extensions.d.mts.map +1 -1
  42. package/dist/components/editor/lib/extensions.mjs.map +1 -1
  43. package/dist/components/editor/lib/helpers.d.mts.map +1 -1
  44. package/dist/components/editor/lib/helpers.mjs +38 -3
  45. package/dist/components/editor/lib/helpers.mjs.map +1 -1
  46. package/dist/components/editor/lib/variants.mjs +10 -2
  47. package/dist/components/editor/lib/variants.mjs.map +1 -1
  48. package/dist/components/header/back-button.client.d.mts +2 -2
  49. package/dist/components/header/back-button.client.d.mts.map +1 -1
  50. package/dist/components/header/bottom-bar.client.d.mts +3 -3
  51. package/dist/components/header/bottom-bar.client.d.mts.map +1 -1
  52. package/dist/components/header/breadcrumbs.client.d.mts +7 -7
  53. package/dist/components/header/breadcrumbs.client.d.mts.map +1 -1
  54. package/dist/components/header/header.client.d.mts +2 -2
  55. package/dist/components/header/header.client.d.mts.map +1 -1
  56. package/dist/components/header/mobile-nav-switcher.client.d.mts +2 -2
  57. package/dist/components/header/mobile-nav-switcher.client.d.mts.map +1 -1
  58. package/dist/components/header/top-bar.client.d.mts +4 -4
  59. package/dist/components/header/top-bar.client.d.mts.map +1 -1
  60. package/dist/components/layouts/admin-content.client.d.mts +2 -2
  61. package/dist/components/layouts/admin-content.client.d.mts.map +1 -1
  62. package/dist/components/layouts/admin-layout.d.mts +2 -2
  63. package/dist/components/layouts/admin-layout.d.mts.map +1 -1
  64. package/dist/components/layouts/admin-loading.d.mts +2 -2
  65. package/dist/components/layouts/admin-loading.d.mts.map +1 -1
  66. package/dist/components/layouts/empty-page.d.mts +4 -4
  67. package/dist/components/layouts/empty-page.d.mts.map +1 -1
  68. package/dist/components/layouts/error-page.d.mts +23 -0
  69. package/dist/components/layouts/error-page.d.mts.map +1 -0
  70. package/dist/components/layouts/error-page.mjs +58 -0
  71. package/dist/components/layouts/error-page.mjs.map +1 -0
  72. package/dist/components/layouts/list-layout.d.mts +2 -2
  73. package/dist/components/layouts/list-layout.d.mts.map +1 -1
  74. package/dist/components/layouts/not-allowed-page.d.mts +22 -0
  75. package/dist/components/layouts/not-allowed-page.d.mts.map +1 -0
  76. package/dist/components/layouts/not-allowed-page.mjs +25 -0
  77. package/dist/components/layouts/not-allowed-page.mjs.map +1 -0
  78. package/dist/components/layouts/not-found-page.d.mts +3 -3
  79. package/dist/components/layouts/not-found-page.d.mts.map +1 -1
  80. package/dist/components/layouts/providers.client.d.mts +2 -2
  81. package/dist/components/layouts/providers.client.d.mts.map +1 -1
  82. package/dist/components/layouts/root-layout.server.d.mts +2 -2
  83. package/dist/components/layouts/root-layout.server.d.mts.map +1 -1
  84. package/dist/components/layouts/root-loading.d.mts +2 -2
  85. package/dist/components/layouts/root-loading.d.mts.map +1 -1
  86. package/dist/components/layouts/tab-layout.d.mts +2 -2
  87. package/dist/components/layouts/tab-layout.d.mts.map +1 -1
  88. package/dist/components/lists/data-list.d.mts +5 -5
  89. package/dist/components/lists/data-list.d.mts.map +1 -1
  90. package/dist/components/lists/data-stack.d.mts +8 -8
  91. package/dist/components/lists/data-stack.d.mts.map +1 -1
  92. package/dist/components/navigation/admin-sidebar-paths.client.d.mts +21 -11
  93. package/dist/components/navigation/admin-sidebar-paths.client.d.mts.map +1 -1
  94. package/dist/components/navigation/admin-sidebar-paths.client.mjs +7 -5
  95. package/dist/components/navigation/admin-sidebar-paths.client.mjs.map +1 -1
  96. package/dist/components/ui/accordion.d.mts +5 -5
  97. package/dist/components/ui/accordion.d.mts.map +1 -1
  98. package/dist/components/ui/alert-dialog.d.mts +12 -12
  99. package/dist/components/ui/alert-dialog.d.mts.map +1 -1
  100. package/dist/components/ui/alert.d.mts +6 -6
  101. package/dist/components/ui/alert.d.mts.map +1 -1
  102. package/dist/components/ui/aspect-ratio.d.mts +2 -2
  103. package/dist/components/ui/aspect-ratio.d.mts.map +1 -1
  104. package/dist/components/ui/avatar.client.d.mts +4 -4
  105. package/dist/components/ui/avatar.client.d.mts.map +1 -1
  106. package/dist/components/ui/badge.d.mts +4 -4
  107. package/dist/components/ui/badge.d.mts.map +1 -1
  108. package/dist/components/ui/breadcrumb.d.mts +8 -8
  109. package/dist/components/ui/breadcrumb.d.mts.map +1 -1
  110. package/dist/components/ui/button.d.mts +5 -5
  111. package/dist/components/ui/button.d.mts.map +1 -1
  112. package/dist/components/ui/calendar.d.mts +3 -3
  113. package/dist/components/ui/calendar.d.mts.map +1 -1
  114. package/dist/components/ui/card.d.mts +7 -7
  115. package/dist/components/ui/card.d.mts.map +1 -1
  116. package/dist/components/ui/carousel.d.mts +6 -6
  117. package/dist/components/ui/carousel.d.mts.map +1 -1
  118. package/dist/components/ui/chart.client.d.mts +5 -5
  119. package/dist/components/ui/chart.client.d.mts.map +1 -1
  120. package/dist/components/ui/checkbox.d.mts +2 -2
  121. package/dist/components/ui/checkbox.d.mts.map +1 -1
  122. package/dist/components/ui/collapsible.client.d.mts +4 -4
  123. package/dist/components/ui/collapsible.client.d.mts.map +1 -1
  124. package/dist/components/ui/color-picker.client.d.mts +2 -2
  125. package/dist/components/ui/color-picker.client.d.mts.map +1 -1
  126. package/dist/components/ui/combobox-dropdown.client.d.mts +2 -2
  127. package/dist/components/ui/combobox-dropdown.client.d.mts.map +1 -1
  128. package/dist/components/ui/combobox.client.d.mts +2 -2
  129. package/dist/components/ui/combobox.client.d.mts.map +1 -1
  130. package/dist/components/ui/command.d.mts +10 -10
  131. package/dist/components/ui/command.d.mts.map +1 -1
  132. package/dist/components/ui/context-menu.d.mts +16 -16
  133. package/dist/components/ui/context-menu.d.mts.map +1 -1
  134. package/dist/components/ui/date-picker.client.d.mts +2 -2
  135. package/dist/components/ui/date-picker.client.d.mts.map +1 -1
  136. package/dist/components/ui/dialog.client.d.mts +11 -11
  137. package/dist/components/ui/dialog.client.d.mts.map +1 -1
  138. package/dist/components/ui/drawer.client.d.mts +11 -11
  139. package/dist/components/ui/drawer.client.d.mts.map +1 -1
  140. package/dist/components/ui/dropdown-menu.d.mts +16 -16
  141. package/dist/components/ui/form.client.d.mts +7 -7
  142. package/dist/components/ui/form.client.d.mts.map +1 -1
  143. package/dist/components/ui/hover-card.client.d.mts +4 -4
  144. package/dist/components/ui/hover-card.client.d.mts.map +1 -1
  145. package/dist/components/ui/input-recipient.d.mts +2 -2
  146. package/dist/components/ui/input.d.mts +2 -2
  147. package/dist/components/ui/label.d.mts +2 -2
  148. package/dist/components/ui/navigation-menu.d.mts +11 -11
  149. package/dist/components/ui/pagination.d.mts +8 -8
  150. package/dist/components/ui/popover.d.mts +5 -5
  151. package/dist/components/ui/progress.client.d.mts +2 -2
  152. package/dist/components/ui/progress.client.d.mts.map +1 -1
  153. package/dist/components/ui/radio-group.d.mts +3 -3
  154. package/dist/components/ui/resizable.client.d.mts +4 -4
  155. package/dist/components/ui/resizable.client.d.mts.map +1 -1
  156. package/dist/components/ui/scroll-area.d.mts +3 -3
  157. package/dist/components/ui/select.client.d.mts +11 -11
  158. package/dist/components/ui/select.client.d.mts.map +1 -1
  159. package/dist/components/ui/separator.d.mts +2 -2
  160. package/dist/components/ui/sheet.client.d.mts +9 -9
  161. package/dist/components/ui/sheet.client.d.mts.map +1 -1
  162. package/dist/components/ui/sidebar.client.d.mts +26 -26
  163. package/dist/components/ui/sidebar.client.d.mts.map +1 -1
  164. package/dist/components/ui/skeleton.d.mts +2 -2
  165. package/dist/components/ui/slider.d.mts +2 -2
  166. package/dist/components/ui/sonner.client.d.mts +2 -2
  167. package/dist/components/ui/switch.d.mts +2 -2
  168. package/dist/components/ui/tabs.d.mts +5 -5
  169. package/dist/components/ui/textarea.d.mts +2 -2
  170. package/dist/components/ui/time-input.client.d.mts +2 -2
  171. package/dist/components/ui/toggle-group.client.d.mts +3 -3
  172. package/dist/components/ui/toggle.d.mts +2 -2
  173. package/dist/components/ui/toggle.d.mts.map +1 -1
  174. package/dist/components/ui/tooltip.client.d.mts +5 -5
  175. package/dist/components/ui/tooltip.client.d.mts.map +1 -1
  176. package/dist/components/ui/tooltip.client.mjs +1 -1
  177. package/dist/components/ui/tooltip.client.mjs.map +1 -1
  178. package/dist/components.d.mts +4 -1
  179. package/dist/components.mjs +5 -2
  180. package/dist/data-tables.d.mts +2 -2
  181. package/dist/data-tables.mjs +2 -2
  182. package/dist/inline-edit/client.d.mts +2 -3
  183. package/dist/inline-edit/client.mjs +1 -2
  184. package/dist/lib/client.d.mts +2 -2
  185. package/dist/lib/client.mjs +2 -2
  186. package/dist/lib/hooks/use-action.d.mts +2 -2
  187. package/dist/lib/hooks/use-indicator.d.mts +11 -3
  188. package/dist/lib/hooks/use-indicator.d.mts.map +1 -1
  189. package/dist/lib/hooks/use-indicator.mjs +19 -8
  190. package/dist/lib/hooks/use-indicator.mjs.map +1 -1
  191. package/dist/modules/auth/components/allowed.client.d.mts +21 -7
  192. package/dist/modules/auth/components/allowed.client.d.mts.map +1 -1
  193. package/dist/modules/auth/components/allowed.client.mjs +8 -2
  194. package/dist/modules/auth/components/allowed.client.mjs.map +1 -1
  195. package/dist/modules/auth/components/auth-layout.server.d.mts +2 -2
  196. package/dist/modules/auth/components/auth-layout.server.d.mts.map +1 -1
  197. package/dist/modules/auth/components/auth-loading.d.mts +2 -2
  198. package/dist/modules/auth/components/auth-loading.d.mts.map +1 -1
  199. package/dist/modules/auth/components/create-first-user-page.client.d.mts +2 -2
  200. package/dist/modules/auth/components/create-first-user-page.client.d.mts.map +1 -1
  201. package/dist/modules/auth/components/forget-password-page.client.d.mts +2 -2
  202. package/dist/modules/auth/components/forget-password-page.client.d.mts.map +1 -1
  203. package/dist/modules/auth/components/guard-first-user.server.d.mts +2 -2
  204. package/dist/modules/auth/components/guard-first-user.server.d.mts.map +1 -1
  205. package/dist/modules/auth/components/guard.server.d.mts +2 -2
  206. package/dist/modules/auth/components/guard.server.d.mts.map +1 -1
  207. package/dist/modules/auth/components/login-page.client.d.mts +2 -2
  208. package/dist/modules/auth/components/login-page.client.d.mts.map +1 -1
  209. package/dist/modules/auth/components/reset-password-page.client.d.mts +2 -2
  210. package/dist/modules/auth/components/reset-password-page.client.d.mts.map +1 -1
  211. package/dist/modules/auth/components/update-password-command.d.mts +2 -2
  212. package/dist/modules/auth/components/update-password-command.d.mts.map +1 -1
  213. package/dist/modules/auth/db/schema.d.mts +73 -73
  214. package/dist/modules/auth/db/schema.d.mts.map +1 -1
  215. package/dist/modules/auth/handler/client.client.d.mts +143 -143
  216. package/dist/modules/auth/handler/client.client.d.mts.map +1 -1
  217. package/dist/modules/auth/handler/init.d.mts +131 -131
  218. package/dist/modules/auth/handler/init.d.mts.map +1 -1
  219. package/dist/modules/auth/hooks/use-permission.d.mts +48 -4
  220. package/dist/modules/auth/hooks/use-permission.d.mts.map +1 -1
  221. package/dist/modules/auth/hooks/use-permission.mjs +51 -4
  222. package/dist/modules/auth/hooks/use-permission.mjs.map +1 -1
  223. package/dist/modules/auth/lib/helpers.server.mjs +1 -1
  224. package/dist/modules/auth/lib/validators.d.mts +2 -2
  225. package/dist/modules/auth/lib/validators.d.mts.map +1 -1
  226. package/dist/modules/commands/components/alert-dialog-command.client.d.mts +10 -10
  227. package/dist/modules/commands/components/click-command.client.d.mts +2 -2
  228. package/dist/modules/commands/components/command-trigger.client.d.mts +6 -6
  229. package/dist/modules/commands/components/dialog-command.client.d.mts +8 -8
  230. package/dist/modules/commands/components/dropdown-command.client.d.mts +5 -5
  231. package/dist/modules/commands/components/empty-command.client.d.mts +2 -2
  232. package/dist/modules/commands/components/form-dialog-command.client.d.mts +11 -11
  233. package/dist/modules/commands/hooks/use-command-menu.client.d.mts.map +1 -1
  234. package/dist/modules/commands/hooks/use-command-menu.client.mjs +0 -5
  235. package/dist/modules/commands/hooks/use-command-menu.client.mjs.map +1 -1
  236. package/dist/modules/commands/hooks/use-command-mutation.client.d.mts +2 -2
  237. package/dist/modules/commands/menus/context-menu.client.d.mts +2 -2
  238. package/dist/modules/commands/menus/dropdown-menu.client.d.mts +3 -3
  239. package/dist/modules/commands/menus/inline-menu.client.d.mts +3 -3
  240. package/dist/modules/commands/menus/responsive-menu.client.d.mts +3 -3
  241. package/dist/modules/commands/utils/archive-command.client.d.mts +3 -3
  242. package/dist/modules/commands/utils/delete-command.client.d.mts +3 -3
  243. package/dist/modules/config/db/helpers.d.mts +5 -5
  244. package/dist/modules/config/db/helpers.d.mts.map +1 -1
  245. package/dist/modules/data-tables/components/cell/common.client.d.mts +5 -5
  246. package/dist/modules/data-tables/components/column-header.d.mts +2 -2
  247. package/dist/modules/data-tables/components/filters/combobox.client.d.mts +2 -2
  248. package/dist/modules/data-tables/components/filters/slider.client.d.mts +2 -2
  249. package/dist/modules/data-tables/components/header.d.mts +4 -4
  250. package/dist/modules/data-tables/components/layout.d.mts +2 -2
  251. package/dist/modules/data-tables/components/search-input.client.d.mts +2 -2
  252. package/dist/modules/data-tables/components/skeleton.d.mts +2 -2
  253. package/dist/modules/data-tables/components/table.d.mts +7 -7
  254. package/dist/modules/data-tables/components/toolbar.d.mts +3 -3
  255. package/dist/modules/data-tables/hooks/use-context.client.d.mts +2 -2
  256. package/dist/modules/data-tables/lib/filters/parsers.d.mts +6 -1
  257. package/dist/modules/data-tables/lib/filters/parsers.d.mts.map +1 -1
  258. package/dist/modules/data-tables/lib/filters/parsers.mjs +6 -1
  259. package/dist/modules/data-tables/lib/filters/parsers.mjs.map +1 -1
  260. package/dist/modules/data-tables/tables/data-table/components/table.d.mts +2 -2
  261. package/dist/modules/data-tables/tables/inline-table/components/cells/common.d.mts +2 -2
  262. package/dist/modules/data-tables/tables/inline-table/components/cells/drag-handle.client.d.mts +2 -2
  263. package/dist/modules/data-tables/tables/inline-table/components/inputs/advanced-select.client.d.mts +2 -2
  264. package/dist/modules/data-tables/tables/inline-table/components/inputs/combobox.client.d.mts +2 -2
  265. package/dist/modules/data-tables/tables/inline-table/components/inputs/input.client.d.mts +3 -3
  266. package/dist/modules/data-tables/tables/inline-table/components/inputs/read-only.d.mts +2 -2
  267. package/dist/modules/data-tables/tables/inline-table/components/inputs/select.client.d.mts +2 -2
  268. package/dist/modules/data-tables/tables/inline-table/components/table.d.mts +2 -2
  269. package/dist/modules/data-tables/tables/inline-table/hooks/context.client.d.mts +2 -2
  270. package/dist/modules/inline-edit/components/combobox-dropdown.client.d.mts +6 -4
  271. package/dist/modules/inline-edit/components/combobox-dropdown.client.d.mts.map +1 -1
  272. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs +11 -6
  273. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs.map +1 -1
  274. package/dist/modules/inline-edit/components/combobox.client.d.mts +6 -4
  275. package/dist/modules/inline-edit/components/combobox.client.d.mts.map +1 -1
  276. package/dist/modules/inline-edit/components/combobox.client.mjs +7 -5
  277. package/dist/modules/inline-edit/components/combobox.client.mjs.map +1 -1
  278. package/dist/modules/inline-edit/components/date-input.client.d.mts +5 -3
  279. package/dist/modules/inline-edit/components/date-input.client.d.mts.map +1 -1
  280. package/dist/modules/inline-edit/components/date-input.client.mjs +26 -13
  281. package/dist/modules/inline-edit/components/date-input.client.mjs.map +1 -1
  282. package/dist/modules/inline-edit/components/date-picker.client.d.mts +6 -4
  283. package/dist/modules/inline-edit/components/date-picker.client.d.mts.map +1 -1
  284. package/dist/modules/inline-edit/components/date-picker.client.mjs +12 -7
  285. package/dist/modules/inline-edit/components/date-picker.client.mjs.map +1 -1
  286. package/dist/modules/inline-edit/components/editor.client.d.mts +6 -4
  287. package/dist/modules/inline-edit/components/editor.client.d.mts.map +1 -1
  288. package/dist/modules/inline-edit/components/editor.client.mjs +11 -6
  289. package/dist/modules/inline-edit/components/editor.client.mjs.map +1 -1
  290. package/dist/modules/inline-edit/components/input-recipient.client.d.mts +6 -4
  291. package/dist/modules/inline-edit/components/input-recipient.client.d.mts.map +1 -1
  292. package/dist/modules/inline-edit/components/input-recipient.client.mjs +11 -6
  293. package/dist/modules/inline-edit/components/input-recipient.client.mjs.map +1 -1
  294. package/dist/modules/inline-edit/components/input-toggle.client.d.mts +6 -4
  295. package/dist/modules/inline-edit/components/input-toggle.client.d.mts.map +1 -1
  296. package/dist/modules/inline-edit/components/input-toggle.client.mjs +9 -7
  297. package/dist/modules/inline-edit/components/input-toggle.client.mjs.map +1 -1
  298. package/dist/modules/inline-edit/components/input.client.d.mts +13 -10
  299. package/dist/modules/inline-edit/components/input.client.d.mts.map +1 -1
  300. package/dist/modules/inline-edit/components/input.client.mjs +35 -19
  301. package/dist/modules/inline-edit/components/input.client.mjs.map +1 -1
  302. package/dist/modules/inline-edit/components/select.client.d.mts +10 -9
  303. package/dist/modules/inline-edit/components/select.client.d.mts.map +1 -1
  304. package/dist/modules/inline-edit/components/select.client.mjs +14 -7
  305. package/dist/modules/inline-edit/components/select.client.mjs.map +1 -1
  306. package/dist/modules/inline-edit/components/switch.client.d.mts +5 -3
  307. package/dist/modules/inline-edit/components/switch.client.d.mts.map +1 -1
  308. package/dist/modules/inline-edit/components/switch.client.mjs +8 -6
  309. package/dist/modules/inline-edit/components/switch.client.mjs.map +1 -1
  310. package/dist/modules/inline-edit/components/toggle.client.d.mts +6 -4
  311. package/dist/modules/inline-edit/components/toggle.client.d.mts.map +1 -1
  312. package/dist/modules/inline-edit/components/toggle.client.mjs +9 -7
  313. package/dist/modules/inline-edit/components/toggle.client.mjs.map +1 -1
  314. package/dist/modules/inline-edit/hooks/context.client.d.mts +2 -2
  315. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts +35 -3
  316. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts.map +1 -1
  317. package/dist/modules/inline-edit/hooks/use-inline.client.mjs +71 -9
  318. package/dist/modules/inline-edit/hooks/use-inline.client.mjs.map +1 -1
  319. package/dist/modules/inline-edit/lib/variants.d.mts +1 -0
  320. package/dist/modules/inline-edit/lib/variants.d.mts.map +1 -1
  321. package/dist/modules/inline-edit/lib/variants.mjs +12 -4
  322. package/dist/modules/inline-edit/lib/variants.mjs.map +1 -1
  323. package/dist/modules/router/handler/init.server.d.mts +4 -4
  324. package/dist/modules/router/handler/init.server.mjs +1 -1
  325. package/dist/modules/router/lib/query-client.server.d.mts +2 -2
  326. package/dist/modules/storage/components/dropzone-context.client.d.mts +2 -2
  327. package/dist/modules/storage/components/dropzone.client.d.mts +5 -5
  328. package/dist/modules/storage/components/image-grid.client.d.mts +3 -3
  329. package/dist/modules/storage/components/image-grid.client.mjs +2 -2
  330. package/dist/modules/storage/components/image-grid.client.mjs.map +1 -1
  331. package/dist/modules/storage/components/upload-zone-context.client.d.mts +3 -11
  332. package/dist/modules/storage/components/upload-zone-context.client.d.mts.map +1 -1
  333. package/dist/modules/storage/components/upload-zone-context.client.mjs.map +1 -1
  334. package/dist/modules/storage/components/upload-zone.client.d.mts +10 -33
  335. package/dist/modules/storage/components/upload-zone.client.d.mts.map +1 -1
  336. package/dist/modules/storage/components/upload-zone.client.mjs +19 -93
  337. package/dist/modules/storage/components/upload-zone.client.mjs.map +1 -1
  338. package/dist/modules/storage/config/filters.d.mts +1 -0
  339. package/dist/modules/storage/config/filters.d.mts.map +1 -1
  340. package/dist/modules/storage/config/filters.mjs +1 -0
  341. package/dist/modules/storage/config/filters.mjs.map +1 -1
  342. package/dist/modules/storage/lib/create-upload.client.d.mts +56 -0
  343. package/dist/modules/storage/lib/create-upload.client.d.mts.map +1 -0
  344. package/dist/modules/storage/lib/create-upload.client.mjs +98 -0
  345. package/dist/modules/storage/lib/create-upload.client.mjs.map +1 -0
  346. package/dist/modules/storage/lib/helpers.d.mts +1 -1
  347. package/dist/modules/storage/lib/router.server.d.mts +3239 -2319
  348. package/dist/modules/storage/lib/router.server.d.mts.map +1 -1
  349. package/dist/modules/storage/lib/router.server.mjs +5 -2
  350. package/dist/modules/storage/lib/router.server.mjs.map +1 -1
  351. package/dist/modules/storage/lib/schema.d.mts +124 -90
  352. package/dist/modules/storage/lib/schema.d.mts.map +1 -1
  353. package/dist/modules/storage/lib/schema.mjs +2 -1
  354. package/dist/modules/storage/lib/schema.mjs.map +1 -1
  355. package/dist/modules/storage/lib/service.server.d.mts +28 -39
  356. package/dist/modules/storage/lib/service.server.d.mts.map +1 -1
  357. package/dist/modules/storage/lib/service.server.mjs +6 -6
  358. package/dist/modules/storage/lib/service.server.mjs.map +1 -1
  359. package/dist/modules/storage/lib/validators.d.mts +166 -86
  360. package/dist/modules/storage/lib/validators.d.mts.map +1 -1
  361. package/dist/modules/storage/lib/validators.mjs +2 -1
  362. package/dist/modules/storage/lib/validators.mjs.map +1 -1
  363. package/dist/router/server.mjs +1 -1
  364. package/dist/storage/client.d.mts +2 -1
  365. package/dist/storage/client.mjs +2 -8
  366. package/dist/storage.d.mts +2 -2
  367. package/dist/storage.mjs +1 -1
  368. package/package.json +4 -3
  369. package/src/components/editor/components/editor.client.tsx +7 -2
  370. package/src/components/editor/components/menu.client.tsx +26 -0
  371. package/src/components/editor/extensions/file-handler/extension.ts +69 -0
  372. package/src/components/editor/extensions/file-handler/strategy.ts +167 -0
  373. package/src/components/editor/extensions/file-handler/utils.ts +51 -0
  374. package/src/components/editor/extensions/image/extension.ts +55 -0
  375. package/src/components/editor/extensions/skeleton/extension.ts +35 -0
  376. package/src/components/editor/extensions/skeleton/renderer.tsx +14 -0
  377. package/src/components/editor/lib/constants.ts +16 -2
  378. package/src/components/editor/lib/extensions.ts +4 -1
  379. package/src/components/editor/lib/helpers.ts +39 -3
  380. package/src/components/editor/lib/utils.ts +32 -0
  381. package/src/components/editor/lib/variants.ts +72 -1
  382. package/src/components/entry.ts +4 -1
  383. package/src/components/layouts/error-page.tsx +61 -0
  384. package/src/components/layouts/not-allowed-page.tsx +1 -1
  385. package/src/components/navigation/admin-sidebar-paths.client.tsx +18 -2
  386. package/src/components/ui/tooltip.client.tsx +1 -1
  387. package/src/lib/hooks/use-indicator.tsx +27 -18
  388. package/src/modules/auth/components/allowed.client.tsx +35 -7
  389. package/src/modules/auth/hooks/use-permission.ts +88 -2
  390. package/src/modules/commands/hooks/use-command-menu.client.tsx +4 -7
  391. package/src/modules/data-tables/lib/filters/parsers.ts +14 -0
  392. package/src/modules/inline-edit/components/combobox-dropdown.client.tsx +21 -12
  393. package/src/modules/inline-edit/components/combobox.client.tsx +13 -6
  394. package/src/modules/inline-edit/components/date-input.client.tsx +29 -13
  395. package/src/modules/inline-edit/components/date-picker.client.tsx +13 -9
  396. package/src/modules/inline-edit/components/editor.client.tsx +14 -14
  397. package/src/modules/inline-edit/components/input-recipient.client.tsx +15 -8
  398. package/src/modules/inline-edit/components/input-toggle.client.tsx +16 -9
  399. package/src/modules/inline-edit/components/input.client.tsx +38 -24
  400. package/src/modules/inline-edit/components/select.client.tsx +16 -9
  401. package/src/modules/inline-edit/components/switch.client.tsx +10 -6
  402. package/src/modules/inline-edit/components/toggle.client.tsx +13 -9
  403. package/src/modules/inline-edit/entry.client.ts +0 -1
  404. package/src/modules/inline-edit/hooks/use-inline.client.tsx +139 -20
  405. package/src/modules/inline-edit/lib/variants.ts +7 -0
  406. package/src/modules/storage/components/image-grid.client.tsx +2 -2
  407. package/src/modules/storage/components/upload-zone-context.client.tsx +3 -4
  408. package/src/modules/storage/components/upload-zone.client.tsx +17 -116
  409. package/src/modules/storage/config/filters.ts +1 -0
  410. package/src/modules/storage/entry.client.ts +2 -1
  411. package/src/modules/storage/lib/create-upload.client.ts +134 -0
  412. package/src/modules/storage/lib/router.server.ts +1 -0
  413. package/src/modules/storage/lib/schema.ts +1 -0
  414. package/src/modules/storage/lib/service.server.ts +10 -4
  415. package/src/modules/storage/lib/validators.ts +1 -0
  416. package/dist/modules/auth/lib/utils.mjs +0 -21
  417. package/dist/modules/auth/lib/utils.mjs.map +0 -1
  418. package/dist/modules/inline-edit/components/deprecated-editor.client.d.mts +0 -21
  419. package/dist/modules/inline-edit/components/deprecated-editor.client.d.mts.map +0 -1
  420. package/dist/modules/inline-edit/components/deprecated-editor.client.mjs +0 -37
  421. package/dist/modules/inline-edit/components/deprecated-editor.client.mjs.map +0 -1
  422. package/dist/storage/client.mjs.map +0 -1
  423. package/src/modules/inline-edit/components/deprecated-editor.client.tsx +0 -48
@@ -4,7 +4,6 @@ import { HardBreakOptions } from "@tiptap/extension-hard-break";
4
4
  import { HeadingOptions } from "@tiptap/extension-heading";
5
5
  import { HighlightOptions } from "@tiptap/extension-highlight";
6
6
  import { HorizontalRuleOptions } from "@tiptap/extension-horizontal-rule";
7
- import { ImageOptions } from "@tiptap/extension-image";
8
7
  import { ItalicOptions } from "@tiptap/extension-italic";
9
8
  import { LinkOptions } from "@tiptap/extension-link";
10
9
  import {
@@ -20,6 +19,8 @@ import { UnderlineOptions } from "@tiptap/extension-underline";
20
19
  import { DropcursorOptions, TrailingNodeOptions, UndoRedoOptions } from "@tiptap/extensions";
21
20
  import { Extension } from "@tiptap/react";
22
21
  import deepmerge from "deepmerge";
22
+ import { FileHandlerOptions } from "../extensions/file-handler/extension";
23
+ import { ImageOptions } from "../extensions/image/extension";
23
24
  import {
24
25
  EDITOR_EXTENSIONS,
25
26
  EDITOR_EXTENSIONS_CONFIG,
@@ -48,6 +49,8 @@ export type EditorExtensionsConfig = {
48
49
  paragraph: Partial<ParagraphOptions> | boolean;
49
50
  text: Partial<TextStyleOptions> | boolean;
50
51
  image: Partial<ImageOptions> | boolean;
52
+ fileHandler: Partial<FileHandlerOptions> | boolean;
53
+ skeleton: boolean;
51
54
  /**
52
55
  * Marks
53
56
  */
@@ -1,17 +1,53 @@
1
+ import Blockquote from "@tiptap/extension-blockquote";
2
+ import Bold from "@tiptap/extension-bold";
3
+ import Document from "@tiptap/extension-document";
4
+ import HardBreak from "@tiptap/extension-hard-break";
5
+ import Heading from "@tiptap/extension-heading";
6
+ import HorizontalRule from "@tiptap/extension-horizontal-rule";
7
+ import Italic from "@tiptap/extension-italic";
8
+ import Link from "@tiptap/extension-link";
9
+ import { BulletList, ListItem, ListKeymap, OrderedList } from "@tiptap/extension-list";
10
+ import Paragraph from "@tiptap/extension-paragraph";
11
+ import Strike from "@tiptap/extension-strike";
12
+ import Text from "@tiptap/extension-text";
13
+ import Underline from "@tiptap/extension-underline";
14
+ import { Dropcursor, Gapcursor, TrailingNode, UndoRedo } from "@tiptap/extensions";
1
15
  import { generateHTML, generateJSON } from "@tiptap/html";
2
- import { EDITOR_EXTENSIONS_VALUES } from "./constants";
3
16
  import { EditorJSONContent } from "./types";
4
17
 
18
+ const EXTENSIONS_FOR_GENERATION = [
19
+ Blockquote,
20
+ BulletList,
21
+ Document,
22
+ HardBreak,
23
+ Heading,
24
+ HorizontalRule,
25
+ ListItem,
26
+ OrderedList,
27
+ Paragraph,
28
+ Text,
29
+ Bold,
30
+ Italic,
31
+ Link,
32
+ Strike,
33
+ Underline,
34
+ Dropcursor,
35
+ Gapcursor,
36
+ UndoRedo,
37
+ ListKeymap,
38
+ TrailingNode,
39
+ ];
40
+
5
41
  /**
6
42
  * Convert text to editor content
7
43
  */
8
44
  export function convertHTMLToEditorContent(html: string): EditorJSONContent {
9
- return generateJSON(html, EDITOR_EXTENSIONS_VALUES);
45
+ return generateJSON(html, EXTENSIONS_FOR_GENERATION);
10
46
  }
11
47
 
12
48
  /**
13
49
  * Convert editor content to text
14
50
  */
15
51
  export function convertEditorContentToHTML(content: EditorJSONContent): string {
16
- return generateHTML(content, EDITOR_EXTENSIONS_VALUES);
52
+ return generateHTML(content, EXTENSIONS_FOR_GENERATION);
17
53
  }
@@ -1,3 +1,5 @@
1
+ import type { Node as PMNode } from "@tiptap/pm/model";
2
+
1
3
  type ShortcutKeyResult = {
2
4
  symbol: string;
3
5
  readable: string;
@@ -199,3 +201,33 @@ export const filterFiles = <T extends FileInput>(
199
201
 
200
202
  return [validFiles, errors];
201
203
  };
204
+
205
+ /**
206
+ * Helper for iterating through the nodes in a document that changed compared
207
+ * to the given previous document. Useful for avoiding duplicate work on each transaction.
208
+ * Source: https://github.com/ProseMirror/prosemirror-tables/blob/master/src/fixtables.js
209
+ */
210
+ export function changedDescendants(
211
+ old: PMNode,
212
+ cur: PMNode,
213
+ offset: number,
214
+ f: (node: PMNode, pos: number) => void,
215
+ ) {
216
+ const oldSize = old.childCount,
217
+ curSize = cur.childCount;
218
+ outer: for (let i = 0, j = 0; i < curSize; i++) {
219
+ const child = cur.child(i);
220
+ for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) {
221
+ if (old.child(scan) == child) {
222
+ j = scan + 1;
223
+ offset += child.nodeSize;
224
+ continue outer;
225
+ }
226
+ }
227
+ f(child, offset);
228
+ if (j < oldSize && old.child(j).sameMarkup(child))
229
+ changedDescendants(old.child(j), child, offset + 1, f);
230
+ else child.nodesBetween(0, child.content.size, f, offset + 1);
231
+ offset += child.nodeSize;
232
+ }
233
+ }
@@ -1,5 +1,76 @@
1
+ import { cn } from "@/lib/utils/cn";
1
2
  import { cva } from "class-variance-authority";
2
3
 
4
+ /**
5
+ * Prose variants
6
+ */
3
7
  export const editorProseVariants = cva(
4
- "prose dark:prose-invert prose-a:text-primary prose-li:marker:text-primary",
8
+ cn(
9
+ "prose dark:prose-invert",
10
+ "prose-a:text-primary",
11
+ "prose-headings:scroll-mt-20",
12
+ "prose-h1:mt-6 prose-h1:mb-3",
13
+ "prose-h2:mt-6 prose-h2:mb-3",
14
+ "prose-h3:mt-5 prose-h3:mb-2",
15
+ "prose-h4:mt-4 prose-h4:mb-2",
16
+ "prose-ul:my-3 prose-ol:my-3",
17
+ "prose-ul:pl-6 prose-ol:pl-6",
18
+ "prose-li:my-1",
19
+ "prose-li:marker:text-primary",
20
+ "prose-li:p-0",
21
+ "prose-img:my-0 prose-img:rounded-lg",
22
+ "prose-blockquote:my-4 prose-blockquote:py-1",
23
+ "prose-hr:my-6",
24
+ "prose-pre:my-4",
25
+ ),
26
+ );
27
+
28
+ /**
29
+ * Image variants
30
+ */
31
+ export const editorImageVariants = cva(
32
+ cn(
33
+ // wrapper (TipTap sets display:block inline → override with !)
34
+ "[&_[data-resize-wrapper]]:!inline-block",
35
+ "[&_[data-resize-wrapper]]:!relative",
36
+ "[&_[data-resize-wrapper]]:max-w-full",
37
+ "[&_[data-resize-wrapper]]:overflow-hidden",
38
+
39
+ // handle base
40
+ "[&_[data-resize-handle]]:absolute",
41
+ "[&_[data-resize-handle]]:z-10",
42
+ "[&_[data-resize-handle]]:rounded-full",
43
+ "[&_[data-resize-handle]]:bg-muted/40",
44
+ "[&_[data-resize-handle]]:w-1.5",
45
+ "[&_[data-resize-handle]]:cursor-ew-resize",
46
+ "[&_[data-resize-handle]]:opacity-0",
47
+ "[&_[data-resize-handle]]:transition-opacity",
48
+
49
+ // show on hover / active
50
+ "[&:hover_[data-resize-handle]]:opacity-100",
51
+ "[&_[data-resize-state='true']_[data-resize-handle]]:opacity-100",
52
+
53
+ // ✅ override TipTap inline: top:0; bottom:0;
54
+ "[&_[data-resize-handle]]:!top-1/2",
55
+ "[&_[data-resize-handle]]:!bottom-auto",
56
+ "[&_[data-resize-handle]]:!-translate-y-1/2",
57
+
58
+ // ✅ half height (also must beat inline)
59
+ "[&_[data-resize-handle]]:!h-1/2",
60
+
61
+ // ✅ spacing from edge (beat inline left:0 / right:0)
62
+ "[&_[data-resize-handle='left']]:!left-2",
63
+ "[&_[data-resize-handle='right']]:!right-2",
64
+
65
+ // ✅ override inline visibility:hidden on the resize container while pending
66
+ "[&_[data-resize-container]:has(img[data-pending='true'])]:[visibility:visible!important]",
67
+ "[&_[data-resize-container]:has(img[data-pending='true'])]:[pointer-events:auto!important]",
68
+
69
+ // Pending img should behave like a skeleton block (even before wrapper exists)
70
+ "[&_img[data-pending='true']]:bg-primary/10",
71
+ "[&_img[data-pending='true']]:animate-pulse",
72
+ "[&_img[data-pending='true']]:rounded-md",
73
+ "[&_img[data-pending='true']]:opacity-0",
74
+ "[&_img[data-pending='true']]:min-h-[500px]",
75
+ ),
5
76
  );
@@ -3,15 +3,18 @@
3
3
  */
4
4
  export * from "./common/icons";
5
5
  export * from "./common/status";
6
- export * from "./editor/lib/types";
6
+ export * from "./editor/extensions/file-handler/strategy";
7
7
  export * from "./editor/lib/helpers";
8
+ export * from "./editor/lib/types";
8
9
 
9
10
  /**
10
11
  * Components Layouts
11
12
  */
12
13
  export * from "./layouts/admin-loading";
13
14
  export * from "./layouts/empty-page";
15
+ export * from "./layouts/error-page";
14
16
  export * from "./layouts/list-layout";
17
+ export * from "./layouts/not-allowed-page";
15
18
  export * from "./layouts/not-found-page";
16
19
  export * from "./layouts/root-loading";
17
20
  export * from "./layouts/tab-layout";
@@ -0,0 +1,61 @@
1
+ import { cn } from "@/lib/utils/cn";
2
+ import { ServerError } from "@/modules/router/lib/error.server";
3
+ import { CommonORPCErrorCode } from "@orpc/client";
4
+ import { BugIcon } from "lucide-react";
5
+ import { ComponentProps } from "react";
6
+ import { NotAllowedPage } from "./not-allowed-page";
7
+ import { NotFoundSection } from "./not-found-section";
8
+
9
+ /**
10
+ * ErrorPage
11
+ */
12
+ export function ErrorPage({ className, ...props }: ComponentProps<"div">) {
13
+ return (
14
+ <div {...props} className={cn("relative z-0 grid h-dvh w-full place-items-center", className)}>
15
+ <div className="flex flex-col items-center gap-12 text-center">
16
+ <span className="text-destructive flex flex-col items-center gap-2">
17
+ <BugIcon className="size-20 xl:size-32" />
18
+ <h1 className="text-2xl font-bold lg:text-3xl">Oeps, er is iets fout gegaan.</h1>
19
+ </span>
20
+ </div>
21
+ </div>
22
+ );
23
+ }
24
+
25
+ /**
26
+ * ErrorPage
27
+ * - If the error is a ServerError and the code is "UNAUTHORIZED", show the NotAllowedPage
28
+ * - If the error is a ServerError and the code is "NOT_FOUND", show the NotFoundSection
29
+ * - Else show the ErrorPage
30
+ */
31
+ export function AdminErrorPage(props: { error: Error }) {
32
+ const serverErrorCode: CommonORPCErrorCode =
33
+ props.error instanceof ServerError ? props.error.code : undefined;
34
+
35
+ /**
36
+ * If the error is a ServerError and the code is "UNAUTHORIZED", show the NotAllowedPage
37
+ */
38
+ if (serverErrorCode === "UNAUTHORIZED") {
39
+ return (
40
+ <div className="p-content h-dvh">
41
+ <NotAllowedPage className="h-full" />
42
+ </div>
43
+ );
44
+ }
45
+
46
+ /**
47
+ * If the error is a ServerError and the code is "UNAUTHORIZED", show the NotAllowedPage
48
+ */
49
+ if (serverErrorCode === "NOT_FOUND") {
50
+ return (
51
+ <div className="relative z-0 grid h-dvh w-full place-items-center">
52
+ <NotFoundSection href="/admin" />
53
+ </div>
54
+ );
55
+ }
56
+
57
+ /**
58
+ * Else show the ErrorPage
59
+ */
60
+ return <ErrorPage />;
61
+ }
@@ -14,7 +14,7 @@ export type NotAllowedPageProps = HTMLAttributes<HTMLDivElement> & {
14
14
  };
15
15
  };
16
16
 
17
- export default function NotAllowedPage({
17
+ export function NotAllowedPage({
18
18
  title,
19
19
  description,
20
20
  callToAction,
@@ -51,8 +51,24 @@ export function Paths({ children, ...props }: React.ComponentProps<typeof Sideba
51
51
  /**
52
52
  * Path Group
53
53
  */
54
- export function PathGroup(props: React.ComponentProps<"div">) {
55
- return <SidebarGroup {...props} />;
54
+ export type PathGroupProps = React.ComponentProps<"div"> & {
55
+ /**
56
+ * Permission to check with the any strategy for displaying the group
57
+ * @example { project: ["view", "create"], client: ["view"], drive: ["view"] }
58
+ */
59
+ permission?: Permission[];
60
+ };
61
+
62
+ export function PathGroup({ permission, ...props }: PathGroupProps) {
63
+ if (!permission) {
64
+ return <SidebarGroup {...props} />;
65
+ }
66
+
67
+ return (
68
+ <Allowed permission={permission} strategy="any">
69
+ <SidebarGroup {...props} />
70
+ </Allowed>
71
+ );
56
72
  }
57
73
 
58
74
  /**
@@ -48,7 +48,7 @@ function TooltipContent({
48
48
  {...props}
49
49
  >
50
50
  {children}
51
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
51
+ <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]" />
52
52
  </TooltipPrimitive.Content>
53
53
  </TooltipPrimitive.Portal>
54
54
  );
@@ -9,25 +9,9 @@ import { createContext, useContext, useEffect, useState, useTransition } from "r
9
9
  export type IndicatorStatus = "idle" | "pending" | "success" | "error";
10
10
 
11
11
  /**
12
- * Indicator context
12
+ * Use local indicator
13
13
  */
14
- type IndicatorContextType = {
15
- status: IndicatorStatus;
16
- setStatus: React.Dispatch<React.SetStateAction<IndicatorStatus>>;
17
- startTransition: React.TransitionStartFunction;
18
- };
19
-
20
- export const IndicatorContext = createContext<IndicatorContextType>({} as IndicatorContextType);
21
-
22
- /**
23
- * Inline edit indicator context
24
- */
25
- export const useIndicator = () => useContext(IndicatorContext);
26
-
27
- /**
28
- * Indicator context provider
29
- */
30
- export function IndicatorContextProvider({ children }: { children: React.ReactNode }) {
14
+ export function useLocalIndicator() {
31
15
  /**
32
16
  * Start transition
33
17
  */
@@ -54,6 +38,31 @@ export function IndicatorContextProvider({ children }: { children: React.ReactNo
54
38
  if (status === "error") setTimeout(() => setStatus("idle"), 2000);
55
39
  }, [status]);
56
40
 
41
+ return { status, setStatus, startTransition };
42
+ }
43
+
44
+ /**
45
+ * Indicator context
46
+ */
47
+ type IndicatorContextType = {
48
+ status: IndicatorStatus;
49
+ setStatus: React.Dispatch<React.SetStateAction<IndicatorStatus>>;
50
+ startTransition: React.TransitionStartFunction;
51
+ };
52
+
53
+ export const IndicatorContext = createContext<IndicatorContextType>({} as IndicatorContextType);
54
+
55
+ /**
56
+ * Inline edit indicator context
57
+ */
58
+ export const useIndicator = () => useContext(IndicatorContext);
59
+
60
+ /**
61
+ * Indicator context provider
62
+ */
63
+ export function IndicatorContextProvider({ children }: { children: React.ReactNode }) {
64
+ const { status, setStatus, startTransition } = useLocalIndicator();
65
+
57
66
  return (
58
67
  <IndicatorContext.Provider value={{ status, setStatus, startTransition }}>
59
68
  {children}
@@ -1,20 +1,48 @@
1
1
  "use client";
2
2
 
3
3
  import { JSX } from "react";
4
- import { usePermission } from "../hooks/use-permission";
5
- import { type Permission } from "../lib/permissions";
4
+ import { usePermission, UsePermissionProps } from "../hooks/use-permission";
6
5
 
7
6
  /**
8
- * Allowed
7
+ * Allowed types
9
8
  */
10
- type AllowedProps = {
11
- permission: Permission;
9
+ export type AllowedStrategy = "all" | "any";
10
+
11
+ /**
12
+ * Allowed props
13
+ */
14
+ export type AllowedProps = UsePermissionProps & {
15
+ // /**
16
+ // * Permission to check
17
+ // * @example { project: ["view", "create"] }
18
+ // */
19
+ // permission: Permission;
20
+
21
+ // /**
22
+ // * Strategy to use when checking multiple permissions
23
+ // * - "all": all permissions must be allowed
24
+ // * - "any": at least one permission must be allowed
25
+ // * @default "all"
26
+ // */
27
+ // strategy?: AllowedStrategy;
28
+
29
+ /**
30
+ * Fallback component to render if the user doesn't have the permission
31
+ * @default null
32
+ */
12
33
  fallback?: JSX.Element | string;
34
+
35
+ /**
36
+ * Children to render if the user has the permission
37
+ */
13
38
  children: React.ReactNode;
14
39
  };
15
40
 
16
- export function Allowed({ permission, fallback, children }: AllowedProps) {
17
- const { data } = usePermission(permission);
41
+ /**
42
+ * Allowed
43
+ */
44
+ export function Allowed({ permission, strategy, fallback, children }: AllowedProps) {
45
+ const { data } = usePermission({ permission, strategy } as UsePermissionProps);
18
46
 
19
47
  if (data?.success) return <>{children}</>;
20
48
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useSuspenseQueries } from "@tanstack/react-query";
3
+ import { useSuspenseQueries, useSuspenseQuery } from "@tanstack/react-query";
4
4
  import { authClient } from "../handler/client.client";
5
5
  import { type Permission } from "../lib/permissions";
6
6
  import { useSession } from "./use-session";
@@ -8,7 +8,93 @@ import { useSession } from "./use-session";
8
8
  /**
9
9
  * UsePermission
10
10
  */
11
- export function usePermission(permission?: Permission) {
11
+ export type UsePermissionProps =
12
+ | {
13
+ /**
14
+ * Strategy to use when checking multiple permissions
15
+ * - "all": all permissions must be allowed
16
+ * - "any": at least one permission must be allowed
17
+ * @default "all"
18
+ */
19
+ strategy?: "all";
20
+
21
+ /**
22
+ * Permission to check
23
+ * @example { project: ["view", "create"] }
24
+ */
25
+ permission?: Permission;
26
+ }
27
+ | {
28
+ /**
29
+ * Strategy to use when checking multiple permissions
30
+ * - "all": all permissions must be allowed
31
+ * - "any": at least one permission must be allowed
32
+ * @default "all"
33
+ */
34
+ strategy?: "any";
35
+
36
+ /**
37
+ * Permission to check
38
+ * @example [{ project: ["view", "create"] }, { client: ["view"] }, { drive: ["view"] }]
39
+ */
40
+ permission?: Permission[];
41
+ };
42
+
43
+ export function usePermission({ permission, strategy = "all" }: UsePermissionProps) {
44
+ const sessionQuery = useSession();
45
+
46
+ return useSuspenseQuery({
47
+ queryKey: ["permission", { permission, strategy }],
48
+ queryFn: async () => {
49
+ // If no permission is provided, allow by default
50
+ if (!permission) return { permission, success: true };
51
+
52
+ // If no user is logged in, deny by default
53
+ if (!sessionQuery.data) return { permission, success: false };
54
+ const userId = sessionQuery.data?.user.id;
55
+ if (!userId) return { permission, success: false };
56
+
57
+ // If the strategy is "any", check if the user has any of the permissions
58
+ const permissions = Array.isArray(permission) ? permission : [permission];
59
+
60
+ // Check if the user has the permission
61
+ const results = await Promise.all(
62
+ permissions.map((permission) => authClient.admin.hasPermission({ permission, userId })),
63
+ );
64
+
65
+ const data = results.map(({ data }) => data).filter((data) => !!data);
66
+ const errors = results.filter(({ error }) => !!error).map(({ error }) => error);
67
+
68
+ // If there is an error, log it and return false
69
+ if (errors.length > 0) {
70
+ console.error(...errors);
71
+ return { permission, success: false };
72
+ }
73
+
74
+ // Determine if the user has the permission based on the strategy
75
+ const success =
76
+ strategy === "all"
77
+ ? data.every(({ success }) => success)
78
+ : data.some(({ success }) => success);
79
+
80
+ // Return the result
81
+ return {
82
+ permission,
83
+ success,
84
+ };
85
+ },
86
+ staleTime: 5 * 60 * 1000, // 5 minutes
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Check multiple permissions in parallel
92
+ * @param permission
93
+ * @param strategy
94
+ * @returns
95
+ * @deprecated Use `usePermission` with strategy "any" or "all" instead
96
+ */
97
+ export function usePermissions(permission?: Permission) {
12
98
  const sessionQuery = useSession();
13
99
 
14
100
  const keys = Object.entries(permission ?? {}).flatMap(([resource, permissions]) =>
@@ -1,8 +1,5 @@
1
1
  "use client";
2
2
 
3
- import { Permission } from "@/modules/auth/entry";
4
- import { usePermission } from "@/modules/auth/hooks/use-permission";
5
- import { mergePermissions } from "@/modules/auth/lib/utils";
6
3
  import {
7
4
  type BulkCommandDefRenderParams,
8
5
  type CommandDef,
@@ -115,8 +112,8 @@ export function useSingleCommandMenu<TData, TMeta>({
115
112
  commands,
116
113
  meta,
117
114
  }: SingleCommandMenuProps<TData, TMeta> & { data: TData }) {
118
- const permissions = commands.map((command) => command.permission).filter(Boolean) as Permission[];
119
- usePermission(mergePermissions(permissions));
115
+ // const permissions = commands.map((command) => command.permission).filter(Boolean) as Permission[];
116
+ // usePermission(mergePermissions(permissions));
120
117
 
121
118
  // filter out commands that don't have valid conditions
122
119
  const validCommands = commands.filter((command) =>
@@ -142,8 +139,8 @@ export function useBulkCommandMenu<TData, TMeta>({
142
139
  commands,
143
140
  meta,
144
141
  }: BulkCommandMenuProps<TData, TMeta>) {
145
- const permissions = commands.map((command) => command.permission).filter(Boolean) as Permission[];
146
- usePermission(mergePermissions(permissions));
142
+ // const permissions = commands.map((command) => command.permission).filter(Boolean) as Permission[];
143
+ // usePermission(mergePermissions(permissions));
147
144
 
148
145
  /**
149
146
  * Filter out commands that don't have valid conditions
@@ -65,6 +65,20 @@ export const parseFilterBoolean = <TSchema extends z.ZodType<boolean>>(
65
65
  encode: (decoded) => (decoded ? "true" : "false"),
66
66
  });
67
67
 
68
+ /**
69
+ * Filter datetime value
70
+ */
71
+ export type ParseFilterDatetimeSchema = z.ZodDate;
72
+
73
+ export const parseFilterDatetime = <TSchema extends ParseFilterDatetimeSchema>(
74
+ schema: TSchema,
75
+ ): ParseFilter<TSchema> => ({
76
+ schema: schema.nullable(),
77
+ decode: (encoded) => (encoded ? new Date(encoded) : null) as unknown as z.input<TSchema>,
78
+ encode: (decoded) => (decoded ? decoded.toISOString() : ""),
79
+ });
80
+
81
+
68
82
  /**
69
83
  * Filter range value
70
84
  */
@@ -9,14 +9,19 @@ import { cn } from "@/lib/utils/cn";
9
9
  import { useInlineEdit, type useInlineEditOptions } from "../hooks/use-inline.client";
10
10
  import { inlineEditVariants, InlineEditVariantsProps } from "../lib/variants";
11
11
 
12
- export type InlineEditComboboxDropdownProps<TValue extends ComboboxDropdownItem> =
13
- useInlineEditOptions<string> &
14
- InlineEditVariantsProps &
15
- Omit<ComboboxDropdownProps<TValue>, "onSelect"> & {
16
- onSelect?: ComboboxDropdownProps<TValue>["onSelect"];
17
- };
12
+ export type InlineEditComboboxDropdownProps<
13
+ TValue extends ComboboxDropdownItem,
14
+ Required extends boolean = false,
15
+ > = useInlineEditOptions<string, Required> &
16
+ InlineEditVariantsProps &
17
+ Omit<ComboboxDropdownProps<TValue>, "onSelect"> & {
18
+ onSelect?: ComboboxDropdownProps<TValue>["onSelect"];
19
+ };
18
20
 
19
- export function InlineComboboxDropdown<TValue extends ComboboxDropdownItem>({
21
+ export function InlineComboboxDropdown<
22
+ TValue extends ComboboxDropdownItem,
23
+ Required extends boolean,
24
+ >({
20
25
  selectedItem,
21
26
  variant,
22
27
  className,
@@ -24,13 +29,17 @@ export function InlineComboboxDropdown<TValue extends ComboboxDropdownItem>({
24
29
  initialValue,
25
30
  action,
26
31
  permission,
32
+ updateStrategy,
33
+ isRequired,
27
34
  disabled,
28
35
  ...props
29
- }: InlineEditComboboxDropdownProps<TValue>) {
30
- const { setValue, handleUpdate, isAllowed } = useInlineEdit({
36
+ }: InlineEditComboboxDropdownProps<TValue, Required>) {
37
+ const { handleChange, handleBlur, isAllowed, status } = useInlineEdit({
31
38
  initialValue,
32
39
  action,
33
40
  permission,
41
+ updateStrategy,
42
+ isRequired,
34
43
  });
35
44
 
36
45
  const initialSelectedItem = props.items.find((item) => item.id === initialValue);
@@ -38,12 +47,12 @@ export function InlineComboboxDropdown<TValue extends ComboboxDropdownItem>({
38
47
  return (
39
48
  <ComboboxDropdown
40
49
  {...props}
41
- className={cn(inlineEditVariants({ variant }), className)}
50
+ className={cn(inlineEditVariants({ variant, status }), className)}
42
51
  disabled={disabled || !isAllowed}
43
52
  selectedItem={selectedItem ?? initialSelectedItem}
44
53
  onSelect={(event) => {
45
- setValue(event.id);
46
- handleUpdate(event.id);
54
+ handleChange(event.id ?? null);
55
+ handleBlur(event.id ?? null);
47
56
  onSelect?.(event);
48
57
  }}
49
58
  />