@questpie/admin 2.0.0 → 3.0.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 (1091) hide show
  1. package/README.md +119 -122
  2. package/dist/augmentation.d.mts +110 -11
  3. package/dist/client/blocks/block-renderer.d.mts +5 -12
  4. package/dist/client/blocks/block-renderer.mjs +89 -55
  5. package/dist/client/blocks/index.d.mts +2 -4
  6. package/dist/client/blocks/types.d.mts +3 -4
  7. package/dist/client/blocks/types.mjs +1 -2
  8. package/dist/client/builder/admin-types.d.mts +11 -44
  9. package/dist/client/builder/admin.d.mts +34 -45
  10. package/dist/client/builder/admin.mjs +35 -44
  11. package/dist/client/builder/field/field.d.mts +27 -205
  12. package/dist/client/builder/field/field.mjs +22 -68
  13. package/dist/client/builder/index.d.mts +23 -28
  14. package/dist/client/builder/page/page.d.mts +15 -27
  15. package/dist/client/builder/page/page.mjs +21 -17
  16. package/dist/client/builder/registry.d.mts +14 -34
  17. package/dist/client/builder/types/action-registry.mjs +148 -14
  18. package/dist/client/builder/types/action-types.d.mts +8 -35
  19. package/dist/client/builder/types/collection-types.mjs +1 -2
  20. package/dist/client/builder/types/common.d.mts +6 -20
  21. package/dist/client/builder/types/field-types.d.mts +4 -5
  22. package/dist/client/builder/types/field-types.mjs +1 -2
  23. package/dist/client/builder/types/ui-config.d.mts +3 -5
  24. package/dist/client/builder/types/widget-types.d.mts +19 -20
  25. package/dist/client/builder/validation.d.mts +33 -3
  26. package/dist/client/builder/validation.mjs +169 -150
  27. package/dist/client/builder/view/view.d.mts +26 -106
  28. package/dist/client/builder/view/view.mjs +14 -96
  29. package/dist/client/builder/widget/widget.d.mts +16 -22
  30. package/dist/client/builder/widget/widget.mjs +11 -16
  31. package/dist/client/components/actions/action-button.mjs +207 -97
  32. package/dist/client/components/actions/action-dialog.mjs +471 -176
  33. package/dist/client/components/actions/confirmation-dialog.mjs +166 -47
  34. package/dist/client/components/actions/header-actions.mjs +164 -71
  35. package/dist/client/components/admin-link.d.mts +8 -9
  36. package/dist/client/components/admin-link.mjs +127 -48
  37. package/dist/client/components/auth/auth-guard.d.mts +6 -7
  38. package/dist/client/components/auth/auth-guard.mjs +9 -9
  39. package/dist/client/components/auth/auth-loading.d.mts +3 -4
  40. package/dist/client/components/auth/auth-loading.mjs +38 -10
  41. package/dist/client/components/blocks/block-canvas.mjs +111 -42
  42. package/dist/client/components/blocks/block-editor-context.mjs +90 -23
  43. package/dist/client/components/blocks/block-editor-layout.mjs +176 -59
  44. package/dist/client/components/blocks/block-editor-provider.mjs +219 -139
  45. package/dist/client/components/blocks/block-fields-renderer.mjs +212 -42
  46. package/dist/client/components/blocks/block-insert-button.mjs +168 -51
  47. package/dist/client/components/blocks/block-item-menu.mjs +312 -110
  48. package/dist/client/components/blocks/block-item.mjs +372 -125
  49. package/dist/client/components/blocks/block-library-sidebar.mjs +209 -114
  50. package/dist/client/components/blocks/block-tree.mjs +73 -15
  51. package/dist/client/components/blocks/block-type-icon.mjs +65 -20
  52. package/dist/client/components/blocks/utils/tree-utils.mjs +1 -2
  53. package/dist/client/components/component-renderer.d.mts +11 -22
  54. package/dist/client/components/component-renderer.mjs +151 -38
  55. package/dist/client/components/error-boundary.mjs +77 -25
  56. package/dist/client/components/fields/array-field.mjs +474 -199
  57. package/dist/client/components/fields/asset-preview-field.mjs +143 -44
  58. package/dist/client/components/fields/blocks-field/blocks-field.mjs +143 -35
  59. package/dist/client/components/fields/boolean-field.mjs +62 -32
  60. package/dist/client/components/fields/date-field.mjs +46 -12
  61. package/dist/client/components/fields/datetime-field.mjs +42 -11
  62. package/dist/client/components/fields/email-field.mjs +57 -28
  63. package/dist/client/components/fields/field-utils.mjs +1 -2
  64. package/dist/client/components/fields/field-wrapper.mjs +107 -32
  65. package/dist/client/components/fields/json-field.mjs +323 -110
  66. package/dist/client/components/fields/locale-badge.mjs +16 -8
  67. package/dist/client/components/fields/number-field.mjs +63 -30
  68. package/dist/client/components/fields/object-array-field.mjs +666 -272
  69. package/dist/client/components/fields/object-field.mjs +656 -98
  70. package/dist/client/components/fields/relation/displays/cards-display.mjs +225 -111
  71. package/dist/client/components/fields/relation/displays/chips-display.mjs +150 -77
  72. package/dist/client/components/fields/relation/displays/grid-display.mjs +186 -91
  73. package/dist/client/components/fields/relation/displays/list-display.mjs +230 -111
  74. package/dist/client/components/fields/relation/displays/table-display.mjs +241 -66
  75. package/dist/client/components/fields/relation/displays/types.mjs +2 -3
  76. package/dist/client/components/fields/relation/relation-items-display.mjs +131 -35
  77. package/dist/client/components/fields/relation-field.mjs +70 -15
  78. package/dist/client/components/fields/relation-picker.mjs +93 -98
  79. package/dist/client/components/fields/relation-select.mjs +42 -29
  80. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +90 -41
  81. package/dist/client/components/fields/rich-text-editor/extensions.mjs +33 -7
  82. package/dist/client/components/fields/rich-text-editor/image-popover.mjs +48 -23
  83. package/dist/client/components/fields/rich-text-editor/index.mjs +491 -158
  84. package/dist/client/components/fields/rich-text-editor/link-popover.mjs +13 -14
  85. package/dist/client/components/fields/rich-text-editor/presets.mjs +1 -2
  86. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +96 -53
  87. package/dist/client/components/fields/rich-text-editor/table-controls.mjs +416 -107
  88. package/dist/client/components/fields/rich-text-editor/toolbar.mjs +476 -215
  89. package/dist/client/components/fields/rich-text-editor/types.mjs +1 -2
  90. package/dist/client/components/fields/rich-text-editor/utils.mjs +1 -2
  91. package/dist/client/components/fields/rich-text-field.mjs +55 -17
  92. package/dist/client/components/fields/select-field.mjs +79 -44
  93. package/dist/client/components/fields/text-field.mjs +62 -29
  94. package/dist/client/components/fields/textarea-field.mjs +61 -29
  95. package/dist/client/components/fields/time-field.mjs +39 -11
  96. package/dist/client/components/fields/upload-field.mjs +253 -129
  97. package/dist/client/components/filter-builder/columns-tab.mjs +287 -93
  98. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +437 -138
  99. package/dist/client/components/filter-builder/filters-tab.mjs +409 -126
  100. package/dist/client/components/filter-builder/saved-views-tab.mjs +259 -106
  101. package/dist/client/components/history-sidebar.mjs +496 -0
  102. package/dist/client/components/layout/field-layout-renderer.mjs +301 -0
  103. package/dist/client/components/locale-switcher.mjs +231 -108
  104. package/dist/client/components/media/media-grid.mjs +259 -84
  105. package/dist/client/components/media/media-picker-dialog.mjs +500 -192
  106. package/dist/client/components/preview/live-preview-mode.mjs +416 -124
  107. package/dist/client/components/preview/preview-pane.mjs +353 -144
  108. package/dist/client/components/primitives/asset-preview.mjs +665 -257
  109. package/dist/client/components/primitives/checkbox-input.mjs +37 -11
  110. package/dist/client/components/primitives/date-input.mjs +392 -149
  111. package/dist/client/components/primitives/dropzone.mjs +314 -185
  112. package/dist/client/components/primitives/number-input.mjs +14 -10
  113. package/dist/client/components/primitives/select-multi.mjs +519 -185
  114. package/dist/client/components/primitives/select-single.mjs +416 -126
  115. package/dist/client/components/primitives/text-input.mjs +10 -5
  116. package/dist/client/components/primitives/textarea-input.mjs +10 -5
  117. package/dist/client/components/primitives/time-input.mjs +118 -45
  118. package/dist/client/components/primitives/toggle-input.mjs +31 -11
  119. package/dist/client/components/primitives/types.mjs +1 -2
  120. package/dist/client/components/sheets/resource-sheet.mjs +72 -64
  121. package/dist/client/components/ui/accordion.mjs +156 -37
  122. package/dist/client/components/ui/alert.mjs +70 -17
  123. package/dist/client/components/ui/badge.mjs +57 -16
  124. package/dist/client/components/ui/button.mjs +49 -14
  125. package/dist/client/components/ui/card.mjs +194 -39
  126. package/dist/client/components/ui/checkbox.mjs +71 -16
  127. package/dist/client/components/ui/command.mjs +220 -50
  128. package/dist/client/components/ui/dialog.mjs +265 -52
  129. package/dist/client/components/ui/drawer.mjs +260 -57
  130. package/dist/client/components/ui/dropdown-menu.mjs +293 -67
  131. package/dist/client/components/ui/empty-state.mjs +72 -26
  132. package/dist/client/components/ui/field.mjs +332 -56
  133. package/dist/client/components/ui/input-group.mjs +174 -41
  134. package/dist/client/components/ui/input.mjs +38 -9
  135. package/dist/client/components/ui/kbd.mjs +37 -8
  136. package/dist/client/components/ui/label.mjs +38 -8
  137. package/dist/client/components/ui/popover.mjs +162 -35
  138. package/dist/client/components/ui/responsive-dialog.mjs +277 -71
  139. package/dist/client/components/ui/search-input.mjs +101 -36
  140. package/dist/client/components/ui/select.mjs +297 -57
  141. package/dist/client/components/ui/separator.mjs +39 -9
  142. package/dist/client/components/ui/sheet.mjs +253 -51
  143. package/dist/client/components/ui/sidebar.mjs +700 -182
  144. package/dist/client/components/ui/skeleton.mjs +33 -8
  145. package/dist/client/components/ui/sonner.d.mts +2 -3
  146. package/dist/client/components/ui/sonner.mjs +45 -15
  147. package/dist/client/components/ui/spinner.mjs +44 -10
  148. package/dist/client/components/ui/switch.mjs +47 -12
  149. package/dist/client/components/ui/table.mjs +260 -50
  150. package/dist/client/components/ui/tabs.mjs +140 -29
  151. package/dist/client/components/ui/textarea.mjs +33 -8
  152. package/dist/client/components/ui/toolbar.mjs +105 -23
  153. package/dist/client/components/ui/tooltip.mjs +130 -29
  154. package/dist/client/components/widgets/chart-widget.mjs +456 -156
  155. package/dist/client/components/widgets/progress-widget.mjs +150 -60
  156. package/dist/client/components/widgets/quick-actions-widget.mjs +175 -87
  157. package/dist/client/components/widgets/recent-items-widget.mjs +157 -62
  158. package/dist/client/components/widgets/stats-widget.mjs +153 -42
  159. package/dist/client/components/widgets/table-widget.mjs +198 -64
  160. package/dist/client/components/widgets/timeline-widget.mjs +193 -82
  161. package/dist/client/components/widgets/value-widget.mjs +257 -56
  162. package/dist/client/components/widgets/widget-skeletons.mjs +390 -108
  163. package/dist/client/contexts/breadcrumb-context.mjs +44 -16
  164. package/dist/client/{context → contexts}/focus-context.d.mts +6 -7
  165. package/dist/client/{context → contexts}/focus-context.mjs +134 -62
  166. package/dist/client/hooks/typed-hooks.d.mts +38 -12
  167. package/dist/client/hooks/typed-hooks.mjs +758 -142
  168. package/dist/client/hooks/use-action.mjs +197 -69
  169. package/dist/client/hooks/use-admin-config.mjs +39 -10
  170. package/dist/client/hooks/use-admin-preferences.mjs +118 -15
  171. package/dist/client/hooks/use-admin-routes.mjs +60 -27
  172. package/dist/client/hooks/use-audit-history.mjs +157 -0
  173. package/dist/client/hooks/use-auth.d.mts +14 -15
  174. package/dist/client/hooks/use-auth.mjs +8 -9
  175. package/dist/client/hooks/use-collection-fields.mjs +58 -19
  176. package/dist/client/hooks/use-collection-meta.mjs +45 -13
  177. package/dist/client/hooks/use-collection-schema.mjs +34 -11
  178. package/dist/client/hooks/use-collection-validation.mjs +39 -25
  179. package/dist/client/hooks/use-collection.d.mts +18 -8
  180. package/dist/client/hooks/use-collection.mjs +560 -101
  181. package/dist/client/hooks/use-current-user.d.mts +6 -3
  182. package/dist/client/hooks/use-current-user.mjs +2 -2
  183. package/dist/client/hooks/use-field-hooks.mjs +73 -65
  184. package/dist/client/hooks/use-field-options.d.mts +1 -34
  185. package/dist/client/hooks/use-field-options.mjs +233 -148
  186. package/dist/client/hooks/use-global-fields.mjs +47 -16
  187. package/dist/client/hooks/use-global-meta.mjs +57 -11
  188. package/dist/client/hooks/use-global-schema.mjs +31 -11
  189. package/dist/client/hooks/use-global.d.mts +13 -2
  190. package/dist/client/hooks/use-global.mjs +244 -34
  191. package/dist/client/hooks/use-locks.mjs +331 -124
  192. package/dist/client/hooks/use-media-query.d.mts +1 -2
  193. package/dist/client/hooks/use-media-query.mjs +38 -19
  194. package/dist/client/hooks/use-prefill-params.mjs +2 -2
  195. package/dist/client/hooks/use-questpie-query-options.mjs +33 -11
  196. package/dist/client/hooks/use-reactive-fields.d.mts +6 -3
  197. package/dist/client/hooks/use-reactive-fields.mjs +130 -93
  198. package/dist/client/hooks/use-realtime-highlight.mjs +115 -53
  199. package/dist/client/hooks/use-saved-views.mjs +109 -34
  200. package/dist/client/hooks/use-search-param-toggle.d.mts +12 -0
  201. package/dist/client/hooks/use-search-param-toggle.mjs +115 -0
  202. package/dist/client/hooks/use-search.mjs +147 -36
  203. package/dist/client/hooks/use-server-actions.mjs +191 -0
  204. package/dist/client/hooks/use-server-validation.mjs +164 -72
  205. package/dist/client/hooks/use-server-widget-data.d.mts +2 -3
  206. package/dist/client/hooks/use-server-widget-data.mjs +36 -11
  207. package/dist/client/hooks/use-setup-status.d.mts +3 -4
  208. package/dist/client/hooks/use-setup-status.mjs +28 -16
  209. package/dist/client/hooks/use-sidebar-search-param.d.mts +9 -0
  210. package/dist/client/hooks/use-sidebar-search-param.mjs +104 -0
  211. package/dist/client/hooks/use-transition-stage.mjs +125 -0
  212. package/dist/client/hooks/use-upload-collection.mjs +1 -2
  213. package/dist/client/hooks/use-upload.mjs +189 -125
  214. package/dist/client/hooks/use-validation-error-map.mjs +10 -6
  215. package/dist/client/hooks/use-view-state.mjs +380 -162
  216. package/dist/client/i18n/hooks.mjs +191 -67
  217. package/dist/client/i18n/intl-cache.mjs +1 -2
  218. package/dist/client/i18n/messages.mjs +1 -2
  219. package/dist/client/i18n/simple.d.mts +1 -2
  220. package/dist/client/i18n/simple.mjs +1 -2
  221. package/dist/client/i18n/types.d.mts +1 -2
  222. package/dist/client/lib/cookies.mjs +9 -0
  223. package/dist/client/lib/events.mjs +5 -0
  224. package/dist/client/lib/render-profiler.mjs +51 -0
  225. package/dist/client/lib/utils.mjs +1 -6
  226. package/dist/client/preview/block-scope-context.d.mts +5 -6
  227. package/dist/client/preview/block-scope-context.mjs +50 -27
  228. package/dist/client/preview/index.d.mts +2 -2
  229. package/dist/client/preview/preview-banner.d.mts +3 -4
  230. package/dist/client/preview/preview-banner.mjs +74 -35
  231. package/dist/client/preview/preview-field.d.mts +9 -10
  232. package/dist/client/preview/preview-field.mjs +163 -61
  233. package/dist/client/preview/types.d.mts +1 -2
  234. package/dist/client/preview/types.mjs +1 -2
  235. package/dist/client/preview/use-collection-preview.d.mts +1 -2
  236. package/dist/client/preview/use-collection-preview.mjs +105 -56
  237. package/dist/client/runtime/content-locales-provider.mjs +87 -36
  238. package/dist/client/runtime/index.d.mts +1 -3
  239. package/dist/client/runtime/index.mjs +1 -3
  240. package/dist/client/runtime/locale-scope.mjs +69 -29
  241. package/dist/client/runtime/provider.d.mts +18 -9922
  242. package/dist/client/runtime/provider.mjs +250 -86
  243. package/dist/client/runtime/routes.d.mts +7 -7
  244. package/dist/client/runtime/routes.mjs +4 -20
  245. package/dist/client/runtime/translations-provider.mjs +114 -53
  246. package/dist/client/scope/picker.d.mts +3 -4
  247. package/dist/client/scope/picker.mjs +324 -90
  248. package/dist/client/scope/provider.d.mts +4 -5
  249. package/dist/client/scope/provider.mjs +30 -22
  250. package/dist/client/scope/types.d.mts +1 -2
  251. package/dist/client/styles/index.css +301 -225
  252. package/dist/client/utils/auto-expand-fields.mjs +23 -5
  253. package/dist/client/utils/build-field-definitions-from-schema.mjs +10 -7
  254. package/dist/client/utils/dependency-tracker.mjs +61 -0
  255. package/dist/client/utils/detect-relations.mjs +1 -2
  256. package/dist/client/utils/locale-to-flag.d.mts +8 -7
  257. package/dist/client/utils/locale-to-flag.mjs +1 -2
  258. package/dist/client/utils/routes.mjs +1 -2
  259. package/dist/client/views/auth/accept-invite-form.d.mts +3 -4
  260. package/dist/client/views/auth/accept-invite-form.mjs +414 -121
  261. package/dist/client/views/auth/auth-layout.d.mts +7 -8
  262. package/dist/client/views/auth/auth-layout.mjs +93 -30
  263. package/dist/client/views/auth/forgot-password-form.d.mts +4 -5
  264. package/dist/client/views/auth/forgot-password-form.mjs +332 -100
  265. package/dist/client/views/auth/invite-form.mjs +447 -105
  266. package/dist/client/views/auth/login-form.d.mts +4 -5
  267. package/dist/client/views/auth/login-form.mjs +340 -120
  268. package/dist/client/views/auth/reset-password-form.d.mts +4 -5
  269. package/dist/client/views/auth/reset-password-form.mjs +458 -131
  270. package/dist/client/views/auth/setup-form.d.mts +4 -5
  271. package/dist/client/views/auth/setup-form.mjs +481 -141
  272. package/dist/client/views/collection/auto-form-fields.mjs +686 -266
  273. package/dist/client/views/collection/bulk-action-toolbar.mjs +392 -203
  274. package/dist/client/views/collection/cells/complex-cells.mjs +635 -216
  275. package/dist/client/views/collection/cells/primitive-cells.mjs +332 -102
  276. package/dist/client/views/collection/cells/relation-cells.mjs +227 -72
  277. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +456 -136
  278. package/dist/client/views/collection/cells/shared/cell-helpers.mjs +49 -2
  279. package/dist/client/views/collection/cells/shared/relation-chip.mjs +109 -25
  280. package/dist/client/views/collection/cells/upload-cells.mjs +16 -8
  281. package/dist/client/views/collection/columns/build-columns.mjs +51 -12
  282. package/dist/client/views/collection/columns/column-defaults.mjs +17 -2
  283. package/dist/client/views/collection/field-context.mjs +10 -11
  284. package/dist/client/views/collection/field-renderer.mjs +237 -40
  285. package/dist/client/views/collection/form-view.mjs +1108 -445
  286. package/dist/client/views/collection/table-view.mjs +300 -163
  287. package/dist/client/views/collection/view-skeletons.mjs +181 -87
  288. package/dist/client/views/common/global-search.mjs +557 -233
  289. package/dist/client/views/dashboard/dashboard-grid.mjs +707 -211
  290. package/dist/client/views/dashboard/dashboard-widget.mjs +145 -58
  291. package/dist/client/views/dashboard/widget-card.mjs +315 -102
  292. package/dist/client/views/globals/global-form-view.mjs +1256 -131
  293. package/dist/client/views/layout/admin-layout-provider.d.mts +18 -21
  294. package/dist/client/views/layout/admin-layout-provider.mjs +135 -32
  295. package/dist/client/views/layout/admin-layout.d.mts +14 -32
  296. package/dist/client/views/layout/admin-layout.mjs +254 -96
  297. package/dist/client/views/layout/admin-router.d.mts +10 -42
  298. package/dist/client/views/layout/admin-router.mjs +1086 -426
  299. package/dist/client/views/layout/admin-sidebar.d.mts +10 -16
  300. package/dist/client/views/layout/admin-sidebar.mjs +1211 -382
  301. package/dist/client/views/layout/admin-topbar.mjs +220 -112
  302. package/dist/client/views/pages/accept-invite-page.d.mts +5 -6
  303. package/dist/client/views/pages/accept-invite-page.mjs +302 -96
  304. package/dist/client/views/pages/dashboard-page.d.mts +7 -16
  305. package/dist/client/views/pages/dashboard-page.mjs +62 -23
  306. package/dist/client/views/pages/forgot-password-page.d.mts +7 -10
  307. package/dist/client/views/pages/forgot-password-page.mjs +112 -40
  308. package/dist/client/views/pages/invite-page.d.mts +6 -7
  309. package/dist/client/views/pages/invite-page.mjs +121 -46
  310. package/dist/client/views/pages/login-page.d.mts +8 -15
  311. package/dist/client/views/pages/login-page.mjs +152 -57
  312. package/dist/client/views/pages/reset-password-page.d.mts +7 -10
  313. package/dist/client/views/pages/reset-password-page.mjs +209 -57
  314. package/dist/client/views/pages/setup-page.d.mts +7 -10
  315. package/dist/client/views/pages/setup-page.mjs +108 -43
  316. package/dist/client-module.d.mts +3 -0
  317. package/dist/client-module.mjs +3 -0
  318. package/dist/client.d.mts +55 -48
  319. package/dist/client.mjs +26 -28
  320. package/dist/components/rich-text/rich-text-renderer.d.mts +3 -4
  321. package/dist/components/rich-text/rich-text-renderer.mjs +97 -70
  322. package/dist/index.d.mts +36 -39
  323. package/dist/index.mjs +26 -28
  324. package/dist/plugin.d.mts +2 -0
  325. package/dist/plugin.mjs +3 -0
  326. package/dist/server/adapters/nextjs.d.mts +13 -14
  327. package/dist/server/adapters/nextjs.mjs +12 -13
  328. package/dist/server/adapters/tanstack.d.mts +10 -11
  329. package/dist/server/adapters/tanstack.mjs +11 -12
  330. package/dist/server/augmentation/actions.d.mts +279 -0
  331. package/dist/server/augmentation/common.d.mts +76 -0
  332. package/dist/server/augmentation/dashboard.d.mts +547 -0
  333. package/dist/server/augmentation/form-layout.d.mts +303 -0
  334. package/dist/server/augmentation/index.d.mts +44 -0
  335. package/dist/server/augmentation/index.mjs +10 -0
  336. package/dist/server/augmentation/sidebar.d.mts +181 -0
  337. package/dist/server/augmentation/views.d.mts +237 -0
  338. package/dist/server/augmentation.d.mts +7 -1523
  339. package/dist/server/block/index.d.mts +4 -3
  340. package/dist/server/codegen/admin-client-template.mjs +93 -0
  341. package/dist/server/codegen/projection-validator.mjs +67 -0
  342. package/dist/server/fields/blocks.d.mts +10 -78
  343. package/dist/server/fields/blocks.mjs +74 -115
  344. package/dist/server/fields/index.d.mts +6 -39
  345. package/dist/server/fields/index.mjs +6 -7
  346. package/dist/server/fields/rich-text.d.mts +10 -77
  347. package/dist/server/fields/rich-text.mjs +59 -100
  348. package/dist/server/i18n/index.mjs +8 -9
  349. package/dist/server/i18n/messages/cs.mjs +3 -3
  350. package/dist/server/i18n/messages/de.mjs +3 -3
  351. package/dist/server/i18n/messages/en.mjs +217 -3
  352. package/dist/server/i18n/messages/es.mjs +3 -3
  353. package/dist/server/i18n/messages/fr.mjs +3 -3
  354. package/dist/server/i18n/messages/index.mjs +1 -2
  355. package/dist/server/i18n/messages/pl.mjs +3 -3
  356. package/dist/server/i18n/messages/pt.mjs +3 -3
  357. package/dist/server/i18n/messages/sk.mjs +202 -3
  358. package/dist/server/modules/admin/.generated/module.d.mts +52 -0
  359. package/dist/server/modules/admin/.generated/module.mjs +78 -0
  360. package/dist/server/modules/admin/.generated/registries.d.mts +22 -0
  361. package/dist/server/{auth-helpers.d.mts → modules/admin/auth-helpers.d.mts} +13 -14
  362. package/dist/server/{auth-helpers.mjs → modules/admin/auth-helpers.mjs} +15 -16
  363. package/dist/server/{block → modules/admin/block}/block-builder.d.mts +96 -32
  364. package/dist/server/{block → modules/admin/block}/block-builder.mjs +113 -15
  365. package/dist/server/modules/admin/block/index.d.mts +3 -0
  366. package/dist/server/{block → modules/admin/block}/introspection.d.mts +10 -5
  367. package/dist/server/{block → modules/admin/block}/introspection.mjs +18 -7
  368. package/dist/server/{block → modules/admin/block}/prefetch.d.mts +17 -17
  369. package/dist/server/{block → modules/admin/block}/prefetch.mjs +17 -16
  370. package/dist/server/modules/admin/client/.generated/module.d.mts +94 -0
  371. package/dist/server/modules/admin/client/.generated/module.mjs +91 -0
  372. package/dist/server/modules/admin/client/components/badge.d.mts +1 -0
  373. package/dist/server/modules/admin/client/components/icon.d.mts +1 -0
  374. package/dist/server/modules/admin/client/fields/array.d.mts +6 -0
  375. package/dist/server/modules/admin/client/fields/array.mjs +12 -0
  376. package/dist/server/modules/admin/client/fields/assetPreview.d.mts +6 -0
  377. package/dist/server/modules/admin/client/fields/assetPreview.mjs +18 -0
  378. package/dist/server/modules/admin/client/fields/blocks.d.mts +6 -0
  379. package/dist/server/modules/admin/client/fields/blocks.mjs +12 -0
  380. package/dist/server/modules/admin/client/fields/boolean.d.mts +6 -0
  381. package/dist/server/modules/admin/client/fields/boolean.mjs +12 -0
  382. package/dist/server/modules/admin/client/fields/date.d.mts +6 -0
  383. package/dist/server/modules/admin/client/fields/date.mjs +12 -0
  384. package/dist/server/modules/admin/client/fields/datetime.d.mts +6 -0
  385. package/dist/server/modules/admin/client/fields/datetime.mjs +12 -0
  386. package/dist/server/modules/admin/client/fields/email.d.mts +6 -0
  387. package/dist/server/modules/admin/client/fields/email.mjs +12 -0
  388. package/dist/server/modules/admin/client/fields/json.d.mts +6 -0
  389. package/dist/server/modules/admin/client/fields/json.mjs +11 -0
  390. package/dist/server/modules/admin/client/fields/number.d.mts +6 -0
  391. package/dist/server/modules/admin/client/fields/number.mjs +12 -0
  392. package/dist/server/modules/admin/client/fields/object.d.mts +6 -0
  393. package/dist/server/modules/admin/client/fields/object.mjs +12 -0
  394. package/dist/server/modules/admin/client/fields/relation.d.mts +6 -0
  395. package/dist/server/modules/admin/client/fields/relation.mjs +12 -0
  396. package/dist/server/modules/admin/client/fields/richText.d.mts +6 -0
  397. package/dist/server/modules/admin/client/fields/richText.mjs +11 -0
  398. package/dist/server/modules/admin/client/fields/select.d.mts +6 -0
  399. package/dist/server/modules/admin/client/fields/select.mjs +12 -0
  400. package/dist/server/modules/admin/client/fields/text.d.mts +6 -0
  401. package/dist/server/modules/admin/client/fields/text.mjs +12 -0
  402. package/dist/server/modules/admin/client/fields/textarea.d.mts +6 -0
  403. package/dist/server/modules/admin/client/fields/textarea.mjs +12 -0
  404. package/dist/server/modules/admin/client/fields/time.d.mts +6 -0
  405. package/dist/server/modules/admin/client/fields/time.mjs +12 -0
  406. package/dist/server/modules/admin/client/fields/upload.d.mts +6 -0
  407. package/dist/server/modules/admin/client/fields/upload.mjs +12 -0
  408. package/dist/server/modules/admin/client/fields/url.d.mts +6 -0
  409. package/dist/server/modules/admin/client/fields/url.mjs +12 -0
  410. package/dist/server/modules/admin/client/index.d.mts +1 -0
  411. package/dist/server/modules/admin/client/pages/dashboard.d.mts +6 -0
  412. package/dist/server/modules/admin/client/pages/dashboard.mjs +11 -0
  413. package/dist/server/modules/admin/client/pages/forgotPassword.d.mts +6 -0
  414. package/dist/server/modules/admin/client/pages/forgotPassword.mjs +11 -0
  415. package/dist/server/modules/admin/client/pages/login.d.mts +6 -0
  416. package/dist/server/modules/admin/client/pages/login.mjs +11 -0
  417. package/dist/server/modules/admin/client/pages/resetPassword.d.mts +6 -0
  418. package/dist/server/modules/admin/client/pages/resetPassword.mjs +11 -0
  419. package/dist/server/modules/admin/client/pages/setup.d.mts +6 -0
  420. package/dist/server/modules/admin/client/pages/setup.mjs +11 -0
  421. package/dist/server/modules/admin/client/views/collection-form.mjs +10 -0
  422. package/dist/server/modules/admin/client/views/collection-table.mjs +10 -0
  423. package/dist/server/modules/admin/client/views/global-form.mjs +10 -0
  424. package/dist/server/modules/admin/client/widgets/chart.d.mts +6 -0
  425. package/dist/server/modules/admin/client/widgets/chart.mjs +7 -0
  426. package/dist/server/modules/admin/client/widgets/progress.d.mts +6 -0
  427. package/dist/server/modules/admin/client/widgets/progress.mjs +7 -0
  428. package/dist/server/modules/admin/client/widgets/quickActions.d.mts +6 -0
  429. package/dist/server/modules/admin/client/widgets/quickActions.mjs +7 -0
  430. package/dist/server/modules/admin/client/widgets/recentItems.d.mts +6 -0
  431. package/dist/server/modules/admin/client/widgets/recentItems.mjs +7 -0
  432. package/dist/server/modules/admin/client/widgets/stats.d.mts +6 -0
  433. package/dist/server/modules/admin/client/widgets/stats.mjs +7 -0
  434. package/dist/server/modules/admin/client/widgets/table.d.mts +6 -0
  435. package/dist/server/modules/admin/client/widgets/table.mjs +7 -0
  436. package/dist/server/modules/admin/client/widgets/timeline.d.mts +6 -0
  437. package/dist/server/modules/admin/client/widgets/timeline.mjs +7 -0
  438. package/dist/server/modules/admin/client/widgets/value.d.mts +6 -0
  439. package/dist/server/modules/admin/client/widgets/value.mjs +7 -0
  440. package/dist/server/modules/admin/collections/account.d.mts +77 -0
  441. package/dist/server/modules/admin/collections/account.mjs +23 -0
  442. package/dist/server/modules/admin/collections/admin-locks.d.mts +90 -0
  443. package/dist/server/modules/admin/collections/admin-locks.mjs +16 -0
  444. package/dist/server/modules/admin/collections/admin-preferences.d.mts +69 -0
  445. package/dist/server/modules/admin/collections/admin-preferences.mjs +16 -0
  446. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +83 -0
  447. package/dist/server/modules/admin/collections/admin-saved-views.mjs +16 -0
  448. package/dist/server/modules/admin/collections/apikey.d.mts +99 -0
  449. package/dist/server/modules/admin/collections/apikey.mjs +15 -0
  450. package/dist/server/modules/admin/collections/assets.d.mts +72 -0
  451. package/dist/server/modules/admin/collections/assets.mjs +71 -0
  452. package/dist/server/modules/admin/collections/session.d.mts +69 -0
  453. package/dist/server/modules/admin/collections/session.mjs +15 -0
  454. package/dist/server/modules/admin/collections/user.d.mts +85 -0
  455. package/dist/server/modules/admin/collections/user.mjs +204 -0
  456. package/dist/server/modules/admin/collections/verification.d.mts +63 -0
  457. package/dist/server/modules/admin/collections/verification.mjs +15 -0
  458. package/dist/server/modules/admin/components/badge.d.mts +10 -0
  459. package/dist/server/modules/admin/components/badge.mjs +10 -0
  460. package/dist/server/modules/admin/components/icon.d.mts +9 -0
  461. package/dist/server/modules/admin/components/icon.mjs +11 -0
  462. package/dist/server/modules/admin/config/admin.mjs +34 -0
  463. package/dist/server/modules/admin/dto/admin-config.dto.mjs +102 -0
  464. package/dist/server/modules/admin/factories.mjs +172 -0
  465. package/dist/server/modules/admin/index.d.mts +1060 -16846
  466. package/dist/server/modules/admin/index.mjs +17 -240
  467. package/dist/server/modules/admin/modules.mjs +11 -0
  468. package/dist/server/modules/admin/plugin.mjs +13 -0
  469. package/dist/server/modules/admin/routes/admin-config.d.mts +28 -0
  470. package/dist/server/modules/admin/routes/admin-config.mjs +552 -0
  471. package/dist/server/modules/admin/{functions → routes}/execute-action.d.mts +17 -32
  472. package/dist/server/modules/admin/{functions → routes}/execute-action.mjs +146 -44
  473. package/dist/server/modules/admin/routes/locales.d.mts +18 -0
  474. package/dist/server/modules/admin/routes/locales.mjs +69 -0
  475. package/dist/server/modules/admin/{functions → routes}/preview.d.mts +25 -15
  476. package/dist/server/modules/admin/{functions → routes}/preview.mjs +84 -97
  477. package/dist/server/modules/admin/{functions → routes}/reactive.d.mts +19 -44
  478. package/dist/server/modules/admin/{functions → routes}/reactive.mjs +89 -117
  479. package/dist/server/modules/admin/routes/route-helpers.d.mts +23 -0
  480. package/dist/server/modules/admin/routes/route-helpers.mjs +76 -0
  481. package/dist/server/modules/admin/{functions → routes}/setup.d.mts +11 -32
  482. package/dist/server/modules/admin/routes/setup.mjs +114 -0
  483. package/dist/server/modules/admin/routes/translations.d.mts +26 -0
  484. package/dist/server/modules/admin/routes/translations.mjs +114 -0
  485. package/dist/server/modules/admin/routes/widget-data.d.mts +32 -0
  486. package/dist/server/modules/admin/routes/widget-data.mjs +62 -0
  487. package/dist/server/modules/admin/views/form.d.mts +8 -0
  488. package/dist/server/modules/admin/views/form.mjs +7 -0
  489. package/dist/server/modules/admin/views/global-form.d.mts +8 -0
  490. package/dist/server/modules/admin/views/global-form.mjs +7 -0
  491. package/dist/server/modules/admin/views/table.d.mts +8 -0
  492. package/dist/server/modules/admin/views/table.mjs +7 -0
  493. package/dist/server/modules/admin-preferences/collections/{admin-preferences.collection.mjs → admin-preferences.mjs} +13 -24
  494. package/dist/server/modules/admin-preferences/collections/locks.collection.mjs +18 -42
  495. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +99 -0
  496. package/dist/server/modules/admin-preferences/collections/saved-views.mjs +38 -0
  497. package/dist/server/modules/audit/.generated/module.d.mts +60 -0
  498. package/dist/server/modules/audit/.generated/module.mjs +30 -0
  499. package/dist/server/modules/audit/collections/audit-log.d.mts +214 -0
  500. package/dist/server/modules/audit/collections/audit-log.mjs +107 -0
  501. package/dist/server/modules/audit/config/admin.mjs +21 -0
  502. package/dist/server/modules/audit/config/app.mjs +262 -0
  503. package/dist/server/modules/audit/index.d.mts +2 -0
  504. package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +13 -0
  505. package/dist/server/modules/audit/jobs/audit-cleanup.mjs +28 -0
  506. package/dist/server/plugin.d.mts +26 -0
  507. package/dist/server/plugin.mjs +385 -0
  508. package/dist/server/proxy-factories.d.mts +85 -0
  509. package/dist/server/proxy-factories.mjs +302 -0
  510. package/dist/server/registry-helpers.d.mts +83 -0
  511. package/dist/server/registry-helpers.mjs +104 -0
  512. package/dist/server.d.mts +30 -18
  513. package/dist/server.mjs +19 -16
  514. package/dist/shared/preview-utils.d.mts +2 -3
  515. package/dist/shared/preview-utils.mjs +2 -3
  516. package/dist/shared/types/saved-views.types.d.mts +2 -2
  517. package/package.json +50 -40
  518. package/skills/questpie-admin/SKILL.md +397 -0
  519. package/skills/questpie-admin/blocks/SKILL.md +305 -0
  520. package/skills/questpie-admin/custom-ui/SKILL.md +307 -0
  521. package/skills/questpie-admin/views/SKILL.md +442 -0
  522. package/dist/_virtual/rolldown_runtime.mjs +0 -18
  523. package/dist/augmentation.d.mts.map +0 -1
  524. package/dist/client/blocks/block-registry.d.mts +0 -199
  525. package/dist/client/blocks/block-registry.d.mts.map +0 -1
  526. package/dist/client/blocks/block-registry.mjs +0 -88
  527. package/dist/client/blocks/block-registry.mjs.map +0 -1
  528. package/dist/client/blocks/block-renderer.d.mts.map +0 -1
  529. package/dist/client/blocks/block-renderer.mjs.map +0 -1
  530. package/dist/client/blocks/prefetch.d.mts +0 -45
  531. package/dist/client/blocks/prefetch.d.mts.map +0 -1
  532. package/dist/client/blocks/prefetch.mjs +0 -26
  533. package/dist/client/blocks/prefetch.mjs.map +0 -1
  534. package/dist/client/blocks/types.d.mts.map +0 -1
  535. package/dist/client/blocks/types.mjs.map +0 -1
  536. package/dist/client/builder/admin-builder.d.mts +0 -112
  537. package/dist/client/builder/admin-builder.d.mts.map +0 -1
  538. package/dist/client/builder/admin-builder.mjs +0 -185
  539. package/dist/client/builder/admin-builder.mjs.map +0 -1
  540. package/dist/client/builder/admin-types.d.mts.map +0 -1
  541. package/dist/client/builder/admin.d.mts.map +0 -1
  542. package/dist/client/builder/admin.mjs.map +0 -1
  543. package/dist/client/builder/defaults/components.mjs +0 -20
  544. package/dist/client/builder/defaults/components.mjs.map +0 -1
  545. package/dist/client/builder/defaults/core.d.mts +0 -354
  546. package/dist/client/builder/defaults/core.d.mts.map +0 -1
  547. package/dist/client/builder/defaults/core.mjs +0 -49
  548. package/dist/client/builder/defaults/core.mjs.map +0 -1
  549. package/dist/client/builder/defaults/fields.mjs +0 -328
  550. package/dist/client/builder/defaults/fields.mjs.map +0 -1
  551. package/dist/client/builder/defaults/pages.mjs +0 -58
  552. package/dist/client/builder/defaults/pages.mjs.map +0 -1
  553. package/dist/client/builder/defaults/starter.d.mts +0 -351
  554. package/dist/client/builder/defaults/starter.d.mts.map +0 -1
  555. package/dist/client/builder/defaults/starter.mjs +0 -28
  556. package/dist/client/builder/defaults/starter.mjs.map +0 -1
  557. package/dist/client/builder/defaults/views.mjs +0 -27
  558. package/dist/client/builder/defaults/views.mjs.map +0 -1
  559. package/dist/client/builder/defaults/widgets.mjs +0 -31
  560. package/dist/client/builder/defaults/widgets.mjs.map +0 -1
  561. package/dist/client/builder/field/field.d.mts.map +0 -1
  562. package/dist/client/builder/field/field.mjs.map +0 -1
  563. package/dist/client/builder/index.d.mts.map +0 -1
  564. package/dist/client/builder/page/page.d.mts.map +0 -1
  565. package/dist/client/builder/page/page.mjs.map +0 -1
  566. package/dist/client/builder/proxies.d.mts +0 -2
  567. package/dist/client/builder/proxies.mjs +0 -24
  568. package/dist/client/builder/proxies.mjs.map +0 -1
  569. package/dist/client/builder/qa.d.mts +0 -50
  570. package/dist/client/builder/qa.d.mts.map +0 -1
  571. package/dist/client/builder/qa.mjs +0 -42
  572. package/dist/client/builder/qa.mjs.map +0 -1
  573. package/dist/client/builder/registry.d.mts.map +0 -1
  574. package/dist/client/builder/types/action-registry.d.mts +0 -2
  575. package/dist/client/builder/types/action-registry.mjs.map +0 -1
  576. package/dist/client/builder/types/action-types.d.mts.map +0 -1
  577. package/dist/client/builder/types/collection-types.d.mts +0 -199
  578. package/dist/client/builder/types/collection-types.d.mts.map +0 -1
  579. package/dist/client/builder/types/collection-types.mjs.map +0 -1
  580. package/dist/client/builder/types/common.d.mts.map +0 -1
  581. package/dist/client/builder/types/field-types.d.mts.map +0 -1
  582. package/dist/client/builder/types/field-types.mjs.map +0 -1
  583. package/dist/client/builder/types/global-types.d.mts +0 -22
  584. package/dist/client/builder/types/global-types.d.mts.map +0 -1
  585. package/dist/client/builder/types/ui-config.d.mts.map +0 -1
  586. package/dist/client/builder/types/views.d.mts +0 -89
  587. package/dist/client/builder/types/views.d.mts.map +0 -1
  588. package/dist/client/builder/types/widget-types.d.mts.map +0 -1
  589. package/dist/client/builder/validation.mjs.map +0 -1
  590. package/dist/client/builder/view/view.d.mts.map +0 -1
  591. package/dist/client/builder/view/view.mjs.map +0 -1
  592. package/dist/client/builder/widget/widget.d.mts.map +0 -1
  593. package/dist/client/builder/widget/widget.mjs.map +0 -1
  594. package/dist/client/components/actions/action-button.d.mts +0 -2
  595. package/dist/client/components/actions/action-button.mjs.map +0 -1
  596. package/dist/client/components/actions/action-dialog.d.mts +0 -2
  597. package/dist/client/components/actions/action-dialog.mjs.map +0 -1
  598. package/dist/client/components/actions/confirmation-dialog.d.mts +0 -2
  599. package/dist/client/components/actions/confirmation-dialog.mjs.map +0 -1
  600. package/dist/client/components/actions/header-actions.d.mts +0 -2
  601. package/dist/client/components/actions/header-actions.mjs.map +0 -1
  602. package/dist/client/components/actions/index.d.mts +0 -4
  603. package/dist/client/components/admin-link.d.mts.map +0 -1
  604. package/dist/client/components/admin-link.mjs.map +0 -1
  605. package/dist/client/components/auth/auth-guard.d.mts.map +0 -1
  606. package/dist/client/components/auth/auth-guard.mjs.map +0 -1
  607. package/dist/client/components/auth/auth-loading.d.mts.map +0 -1
  608. package/dist/client/components/auth/auth-loading.mjs.map +0 -1
  609. package/dist/client/components/auth/index.d.mts +0 -2
  610. package/dist/client/components/blocks/block-canvas.mjs.map +0 -1
  611. package/dist/client/components/blocks/block-editor-context.mjs.map +0 -1
  612. package/dist/client/components/blocks/block-editor-layout.mjs.map +0 -1
  613. package/dist/client/components/blocks/block-editor-provider.mjs.map +0 -1
  614. package/dist/client/components/blocks/block-fields-renderer.mjs.map +0 -1
  615. package/dist/client/components/blocks/block-insert-button.mjs.map +0 -1
  616. package/dist/client/components/blocks/block-item-menu.mjs.map +0 -1
  617. package/dist/client/components/blocks/block-item.mjs.map +0 -1
  618. package/dist/client/components/blocks/block-library-sidebar.mjs.map +0 -1
  619. package/dist/client/components/blocks/block-tree.mjs.map +0 -1
  620. package/dist/client/components/blocks/block-type-icon.mjs.map +0 -1
  621. package/dist/client/components/blocks/utils/tree-utils.mjs.map +0 -1
  622. package/dist/client/components/component-renderer.d.mts.map +0 -1
  623. package/dist/client/components/component-renderer.mjs.map +0 -1
  624. package/dist/client/components/error-boundary.mjs.map +0 -1
  625. package/dist/client/components/fields/array-field.d.mts +0 -44
  626. package/dist/client/components/fields/array-field.d.mts.map +0 -1
  627. package/dist/client/components/fields/array-field.mjs.map +0 -1
  628. package/dist/client/components/fields/asset-preview-field.d.mts +0 -52
  629. package/dist/client/components/fields/asset-preview-field.d.mts.map +0 -1
  630. package/dist/client/components/fields/asset-preview-field.mjs.map +0 -1
  631. package/dist/client/components/fields/blocks-field/blocks-field.d.mts +0 -41
  632. package/dist/client/components/fields/blocks-field/blocks-field.d.mts.map +0 -1
  633. package/dist/client/components/fields/blocks-field/blocks-field.mjs.map +0 -1
  634. package/dist/client/components/fields/blocks-field/index.d.mts +0 -1
  635. package/dist/client/components/fields/boolean-field.d.mts +0 -30
  636. package/dist/client/components/fields/boolean-field.d.mts.map +0 -1
  637. package/dist/client/components/fields/boolean-field.mjs.map +0 -1
  638. package/dist/client/components/fields/custom-field.d.mts +0 -3
  639. package/dist/client/components/fields/date-field.d.mts +0 -22
  640. package/dist/client/components/fields/date-field.d.mts.map +0 -1
  641. package/dist/client/components/fields/date-field.mjs.map +0 -1
  642. package/dist/client/components/fields/datetime-field.d.mts +0 -23
  643. package/dist/client/components/fields/datetime-field.d.mts.map +0 -1
  644. package/dist/client/components/fields/datetime-field.mjs.map +0 -1
  645. package/dist/client/components/fields/email-field.d.mts +0 -19
  646. package/dist/client/components/fields/email-field.d.mts.map +0 -1
  647. package/dist/client/components/fields/email-field.mjs.map +0 -1
  648. package/dist/client/components/fields/embedded-collection.d.mts +0 -3
  649. package/dist/client/components/fields/field-types.d.mts +0 -571
  650. package/dist/client/components/fields/field-types.d.mts.map +0 -1
  651. package/dist/client/components/fields/field-utils.d.mts +0 -1
  652. package/dist/client/components/fields/field-utils.mjs.map +0 -1
  653. package/dist/client/components/fields/field-wrapper.d.mts +0 -3
  654. package/dist/client/components/fields/field-wrapper.mjs.map +0 -1
  655. package/dist/client/components/fields/index.d.mts +0 -33
  656. package/dist/client/components/fields/json-field.d.mts +0 -84
  657. package/dist/client/components/fields/json-field.d.mts.map +0 -1
  658. package/dist/client/components/fields/json-field.mjs.map +0 -1
  659. package/dist/client/components/fields/locale-badge.d.mts +0 -1
  660. package/dist/client/components/fields/locale-badge.mjs.map +0 -1
  661. package/dist/client/components/fields/number-field.d.mts +0 -23
  662. package/dist/client/components/fields/number-field.d.mts.map +0 -1
  663. package/dist/client/components/fields/number-field.mjs.map +0 -1
  664. package/dist/client/components/fields/object-array-field.d.mts +0 -2
  665. package/dist/client/components/fields/object-array-field.mjs.map +0 -1
  666. package/dist/client/components/fields/object-field.d.mts +0 -32
  667. package/dist/client/components/fields/object-field.d.mts.map +0 -1
  668. package/dist/client/components/fields/object-field.mjs.map +0 -1
  669. package/dist/client/components/fields/relation/displays/cards-display.d.mts +0 -2
  670. package/dist/client/components/fields/relation/displays/cards-display.mjs.map +0 -1
  671. package/dist/client/components/fields/relation/displays/chips-display.d.mts +0 -2
  672. package/dist/client/components/fields/relation/displays/chips-display.mjs.map +0 -1
  673. package/dist/client/components/fields/relation/displays/grid-display.d.mts +0 -2
  674. package/dist/client/components/fields/relation/displays/grid-display.mjs.map +0 -1
  675. package/dist/client/components/fields/relation/displays/index.d.mts +0 -6
  676. package/dist/client/components/fields/relation/displays/list-display.d.mts +0 -2
  677. package/dist/client/components/fields/relation/displays/list-display.mjs.map +0 -1
  678. package/dist/client/components/fields/relation/displays/table-display.d.mts +0 -2
  679. package/dist/client/components/fields/relation/displays/table-display.mjs.map +0 -1
  680. package/dist/client/components/fields/relation/displays/types.d.mts +0 -22
  681. package/dist/client/components/fields/relation/displays/types.d.mts.map +0 -1
  682. package/dist/client/components/fields/relation/displays/types.mjs.map +0 -1
  683. package/dist/client/components/fields/relation/index.d.mts +0 -3
  684. package/dist/client/components/fields/relation/relation-items-display.d.mts +0 -5
  685. package/dist/client/components/fields/relation/relation-items-display.mjs.map +0 -1
  686. package/dist/client/components/fields/relation-field.d.mts +0 -134
  687. package/dist/client/components/fields/relation-field.d.mts.map +0 -1
  688. package/dist/client/components/fields/relation-field.mjs.map +0 -1
  689. package/dist/client/components/fields/relation-picker.d.mts +0 -4
  690. package/dist/client/components/fields/relation-picker.mjs.map +0 -1
  691. package/dist/client/components/fields/relation-select.d.mts +0 -3
  692. package/dist/client/components/fields/relation-select.mjs.map +0 -1
  693. package/dist/client/components/fields/reverse-relation-field.d.mts +0 -2
  694. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs.map +0 -1
  695. package/dist/client/components/fields/rich-text-editor/extensions.mjs.map +0 -1
  696. package/dist/client/components/fields/rich-text-editor/image-popover.mjs.map +0 -1
  697. package/dist/client/components/fields/rich-text-editor/index.d.mts +0 -4
  698. package/dist/client/components/fields/rich-text-editor/index.mjs.map +0 -1
  699. package/dist/client/components/fields/rich-text-editor/link-popover.mjs.map +0 -1
  700. package/dist/client/components/fields/rich-text-editor/presets.d.mts +0 -11
  701. package/dist/client/components/fields/rich-text-editor/presets.d.mts.map +0 -1
  702. package/dist/client/components/fields/rich-text-editor/presets.mjs.map +0 -1
  703. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs.map +0 -1
  704. package/dist/client/components/fields/rich-text-editor/table-controls.mjs.map +0 -1
  705. package/dist/client/components/fields/rich-text-editor/toolbar.mjs.map +0 -1
  706. package/dist/client/components/fields/rich-text-editor/types.d.mts +0 -78
  707. package/dist/client/components/fields/rich-text-editor/types.d.mts.map +0 -1
  708. package/dist/client/components/fields/rich-text-editor/types.mjs.map +0 -1
  709. package/dist/client/components/fields/rich-text-editor/utils.mjs.map +0 -1
  710. package/dist/client/components/fields/rich-text-editor/variants.d.mts +0 -2
  711. package/dist/client/components/fields/rich-text-field.d.mts +0 -14
  712. package/dist/client/components/fields/rich-text-field.d.mts.map +0 -1
  713. package/dist/client/components/fields/rich-text-field.mjs.map +0 -1
  714. package/dist/client/components/fields/select-field.d.mts +0 -25
  715. package/dist/client/components/fields/select-field.d.mts.map +0 -1
  716. package/dist/client/components/fields/select-field.mjs.map +0 -1
  717. package/dist/client/components/fields/status-field.d.mts +0 -2
  718. package/dist/client/components/fields/text-field.d.mts +0 -22
  719. package/dist/client/components/fields/text-field.d.mts.map +0 -1
  720. package/dist/client/components/fields/text-field.mjs.map +0 -1
  721. package/dist/client/components/fields/textarea-field.d.mts +0 -22
  722. package/dist/client/components/fields/textarea-field.d.mts.map +0 -1
  723. package/dist/client/components/fields/textarea-field.mjs.map +0 -1
  724. package/dist/client/components/fields/time-field.d.mts +0 -20
  725. package/dist/client/components/fields/time-field.d.mts.map +0 -1
  726. package/dist/client/components/fields/time-field.mjs.map +0 -1
  727. package/dist/client/components/fields/upload-field.d.mts +0 -97
  728. package/dist/client/components/fields/upload-field.d.mts.map +0 -1
  729. package/dist/client/components/fields/upload-field.mjs.map +0 -1
  730. package/dist/client/components/filter-builder/columns-tab.d.mts +0 -1
  731. package/dist/client/components/filter-builder/columns-tab.mjs.map +0 -1
  732. package/dist/client/components/filter-builder/filter-builder-sheet.d.mts +0 -1
  733. package/dist/client/components/filter-builder/filter-builder-sheet.mjs.map +0 -1
  734. package/dist/client/components/filter-builder/filters-tab.d.mts +0 -1
  735. package/dist/client/components/filter-builder/filters-tab.mjs.map +0 -1
  736. package/dist/client/components/filter-builder/index.d.mts +0 -5
  737. package/dist/client/components/filter-builder/saved-views-tab.d.mts +0 -1
  738. package/dist/client/components/filter-builder/saved-views-tab.mjs.map +0 -1
  739. package/dist/client/components/index.d.mts +0 -80
  740. package/dist/client/components/locale-switcher.d.mts +0 -2
  741. package/dist/client/components/locale-switcher.mjs.map +0 -1
  742. package/dist/client/components/media/media-grid.mjs.map +0 -1
  743. package/dist/client/components/media/media-picker-dialog.mjs.map +0 -1
  744. package/dist/client/components/preview/live-preview-mode.mjs.map +0 -1
  745. package/dist/client/components/preview/preview-pane.mjs.map +0 -1
  746. package/dist/client/components/primitives/asset-preview.mjs.map +0 -1
  747. package/dist/client/components/primitives/checkbox-input.mjs.map +0 -1
  748. package/dist/client/components/primitives/date-input.mjs.map +0 -1
  749. package/dist/client/components/primitives/dropzone.mjs.map +0 -1
  750. package/dist/client/components/primitives/number-input.mjs.map +0 -1
  751. package/dist/client/components/primitives/select-multi.mjs.map +0 -1
  752. package/dist/client/components/primitives/select-single.mjs.map +0 -1
  753. package/dist/client/components/primitives/text-input.mjs.map +0 -1
  754. package/dist/client/components/primitives/textarea-input.mjs.map +0 -1
  755. package/dist/client/components/primitives/time-input.mjs.map +0 -1
  756. package/dist/client/components/primitives/toggle-input.mjs.map +0 -1
  757. package/dist/client/components/primitives/types.d.mts +0 -14
  758. package/dist/client/components/primitives/types.d.mts.map +0 -1
  759. package/dist/client/components/primitives/types.mjs.map +0 -1
  760. package/dist/client/components/sheets/index.d.mts +0 -1
  761. package/dist/client/components/sheets/resource-sheet.d.mts +0 -1
  762. package/dist/client/components/sheets/resource-sheet.mjs.map +0 -1
  763. package/dist/client/components/ui/accordion.d.mts +0 -2
  764. package/dist/client/components/ui/accordion.mjs.map +0 -1
  765. package/dist/client/components/ui/alert.mjs.map +0 -1
  766. package/dist/client/components/ui/avatar.d.mts +0 -3
  767. package/dist/client/components/ui/badge.d.mts +0 -3
  768. package/dist/client/components/ui/badge.mjs.map +0 -1
  769. package/dist/client/components/ui/button.d.mts +0 -3
  770. package/dist/client/components/ui/button.mjs.map +0 -1
  771. package/dist/client/components/ui/card.d.mts +0 -2
  772. package/dist/client/components/ui/card.mjs.map +0 -1
  773. package/dist/client/components/ui/checkbox.d.mts +0 -2
  774. package/dist/client/components/ui/checkbox.mjs.map +0 -1
  775. package/dist/client/components/ui/combobox.d.mts +0 -3
  776. package/dist/client/components/ui/command.mjs.map +0 -1
  777. package/dist/client/components/ui/dialog.d.mts +0 -3
  778. package/dist/client/components/ui/dialog.mjs.map +0 -1
  779. package/dist/client/components/ui/drawer.mjs.map +0 -1
  780. package/dist/client/components/ui/dropdown-menu.d.mts +0 -3
  781. package/dist/client/components/ui/dropdown-menu.mjs.map +0 -1
  782. package/dist/client/components/ui/empty-state.mjs.map +0 -1
  783. package/dist/client/components/ui/field.d.mts +0 -3
  784. package/dist/client/components/ui/field.mjs.map +0 -1
  785. package/dist/client/components/ui/input-group.d.mts +0 -4
  786. package/dist/client/components/ui/input-group.mjs.map +0 -1
  787. package/dist/client/components/ui/input.d.mts +0 -2
  788. package/dist/client/components/ui/input.mjs.map +0 -1
  789. package/dist/client/components/ui/kbd.mjs.map +0 -1
  790. package/dist/client/components/ui/label.d.mts +0 -2
  791. package/dist/client/components/ui/label.mjs.map +0 -1
  792. package/dist/client/components/ui/popover.d.mts +0 -3
  793. package/dist/client/components/ui/popover.mjs.map +0 -1
  794. package/dist/client/components/ui/responsive-dialog.mjs.map +0 -1
  795. package/dist/client/components/ui/scroll-area.d.mts +0 -2
  796. package/dist/client/components/ui/search-input.mjs.map +0 -1
  797. package/dist/client/components/ui/select.d.mts +0 -3
  798. package/dist/client/components/ui/select.mjs.map +0 -1
  799. package/dist/client/components/ui/separator.d.mts +0 -2
  800. package/dist/client/components/ui/separator.mjs.map +0 -1
  801. package/dist/client/components/ui/sheet.d.mts +0 -3
  802. package/dist/client/components/ui/sheet.mjs.map +0 -1
  803. package/dist/client/components/ui/sidebar.d.mts +0 -8
  804. package/dist/client/components/ui/sidebar.mjs.map +0 -1
  805. package/dist/client/components/ui/skeleton.d.mts +0 -1
  806. package/dist/client/components/ui/skeleton.mjs.map +0 -1
  807. package/dist/client/components/ui/sonner.d.mts.map +0 -1
  808. package/dist/client/components/ui/sonner.mjs.map +0 -1
  809. package/dist/client/components/ui/spinner.d.mts +0 -1
  810. package/dist/client/components/ui/spinner.mjs.map +0 -1
  811. package/dist/client/components/ui/switch.d.mts +0 -2
  812. package/dist/client/components/ui/switch.mjs.map +0 -1
  813. package/dist/client/components/ui/table.d.mts +0 -2
  814. package/dist/client/components/ui/table.mjs.map +0 -1
  815. package/dist/client/components/ui/tabs.d.mts +0 -3
  816. package/dist/client/components/ui/tabs.mjs.map +0 -1
  817. package/dist/client/components/ui/textarea.d.mts +0 -2
  818. package/dist/client/components/ui/textarea.mjs.map +0 -1
  819. package/dist/client/components/ui/toolbar.mjs.map +0 -1
  820. package/dist/client/components/ui/tooltip.d.mts +0 -2
  821. package/dist/client/components/ui/tooltip.mjs.map +0 -1
  822. package/dist/client/components/widgets/chart-widget.d.mts +0 -57
  823. package/dist/client/components/widgets/chart-widget.d.mts.map +0 -1
  824. package/dist/client/components/widgets/chart-widget.mjs.map +0 -1
  825. package/dist/client/components/widgets/progress-widget.d.mts +0 -41
  826. package/dist/client/components/widgets/progress-widget.d.mts.map +0 -1
  827. package/dist/client/components/widgets/progress-widget.mjs.map +0 -1
  828. package/dist/client/components/widgets/quick-actions-widget.d.mts +0 -29
  829. package/dist/client/components/widgets/quick-actions-widget.d.mts.map +0 -1
  830. package/dist/client/components/widgets/quick-actions-widget.mjs.map +0 -1
  831. package/dist/client/components/widgets/recent-items-widget.d.mts +0 -51
  832. package/dist/client/components/widgets/recent-items-widget.d.mts.map +0 -1
  833. package/dist/client/components/widgets/recent-items-widget.mjs.map +0 -1
  834. package/dist/client/components/widgets/stats-widget.d.mts +0 -55
  835. package/dist/client/components/widgets/stats-widget.d.mts.map +0 -1
  836. package/dist/client/components/widgets/stats-widget.mjs.map +0 -1
  837. package/dist/client/components/widgets/table-widget.d.mts +0 -31
  838. package/dist/client/components/widgets/table-widget.d.mts.map +0 -1
  839. package/dist/client/components/widgets/table-widget.mjs.map +0 -1
  840. package/dist/client/components/widgets/timeline-widget.d.mts +0 -51
  841. package/dist/client/components/widgets/timeline-widget.d.mts.map +0 -1
  842. package/dist/client/components/widgets/timeline-widget.mjs.map +0 -1
  843. package/dist/client/components/widgets/value-widget.d.mts +0 -39
  844. package/dist/client/components/widgets/value-widget.d.mts.map +0 -1
  845. package/dist/client/components/widgets/value-widget.mjs.map +0 -1
  846. package/dist/client/components/widgets/widget-skeletons.mjs.map +0 -1
  847. package/dist/client/context/focus-context.d.mts.map +0 -1
  848. package/dist/client/context/focus-context.mjs.map +0 -1
  849. package/dist/client/contexts/breadcrumb-context.mjs.map +0 -1
  850. package/dist/client/hooks/typed-hooks.d.mts.map +0 -1
  851. package/dist/client/hooks/typed-hooks.mjs.map +0 -1
  852. package/dist/client/hooks/use-action.mjs.map +0 -1
  853. package/dist/client/hooks/use-admin-config.mjs.map +0 -1
  854. package/dist/client/hooks/use-admin-preferences.mjs.map +0 -1
  855. package/dist/client/hooks/use-admin-routes.mjs.map +0 -1
  856. package/dist/client/hooks/use-auth.d.mts.map +0 -1
  857. package/dist/client/hooks/use-auth.mjs.map +0 -1
  858. package/dist/client/hooks/use-collection-fields.mjs.map +0 -1
  859. package/dist/client/hooks/use-collection-meta.mjs.map +0 -1
  860. package/dist/client/hooks/use-collection-schema.mjs.map +0 -1
  861. package/dist/client/hooks/use-collection-validation.mjs.map +0 -1
  862. package/dist/client/hooks/use-collection.d.mts.map +0 -1
  863. package/dist/client/hooks/use-collection.mjs.map +0 -1
  864. package/dist/client/hooks/use-current-user.d.mts.map +0 -1
  865. package/dist/client/hooks/use-current-user.mjs.map +0 -1
  866. package/dist/client/hooks/use-field-hooks.mjs.map +0 -1
  867. package/dist/client/hooks/use-field-options.d.mts.map +0 -1
  868. package/dist/client/hooks/use-field-options.mjs.map +0 -1
  869. package/dist/client/hooks/use-global-fields.mjs.map +0 -1
  870. package/dist/client/hooks/use-global-meta.mjs.map +0 -1
  871. package/dist/client/hooks/use-global-schema.mjs.map +0 -1
  872. package/dist/client/hooks/use-global.d.mts.map +0 -1
  873. package/dist/client/hooks/use-global.mjs.map +0 -1
  874. package/dist/client/hooks/use-locks.mjs.map +0 -1
  875. package/dist/client/hooks/use-media-query.d.mts.map +0 -1
  876. package/dist/client/hooks/use-media-query.mjs.map +0 -1
  877. package/dist/client/hooks/use-prefill-params.mjs.map +0 -1
  878. package/dist/client/hooks/use-questpie-query-options.mjs.map +0 -1
  879. package/dist/client/hooks/use-reactive-fields.d.mts.map +0 -1
  880. package/dist/client/hooks/use-reactive-fields.mjs.map +0 -1
  881. package/dist/client/hooks/use-realtime-highlight.mjs.map +0 -1
  882. package/dist/client/hooks/use-saved-views.mjs.map +0 -1
  883. package/dist/client/hooks/use-search.mjs.map +0 -1
  884. package/dist/client/hooks/use-server-validation.mjs.map +0 -1
  885. package/dist/client/hooks/use-server-widget-data.d.mts.map +0 -1
  886. package/dist/client/hooks/use-server-widget-data.mjs.map +0 -1
  887. package/dist/client/hooks/use-setup-status.d.mts.map +0 -1
  888. package/dist/client/hooks/use-setup-status.mjs.map +0 -1
  889. package/dist/client/hooks/use-upload-collection.mjs.map +0 -1
  890. package/dist/client/hooks/use-upload.d.mts +0 -23
  891. package/dist/client/hooks/use-upload.d.mts.map +0 -1
  892. package/dist/client/hooks/use-upload.mjs.map +0 -1
  893. package/dist/client/hooks/use-validation-error-map.mjs.map +0 -1
  894. package/dist/client/hooks/use-view-state.mjs.map +0 -1
  895. package/dist/client/i18n/hooks.mjs.map +0 -1
  896. package/dist/client/i18n/intl-cache.mjs.map +0 -1
  897. package/dist/client/i18n/messages.mjs.map +0 -1
  898. package/dist/client/i18n/simple.d.mts.map +0 -1
  899. package/dist/client/i18n/simple.mjs.map +0 -1
  900. package/dist/client/i18n/types.d.mts.map +0 -1
  901. package/dist/client/lib/utils.d.mts +0 -1
  902. package/dist/client/lib/utils.mjs.map +0 -1
  903. package/dist/client/preview/block-scope-context.d.mts.map +0 -1
  904. package/dist/client/preview/block-scope-context.mjs.map +0 -1
  905. package/dist/client/preview/preview-banner.d.mts.map +0 -1
  906. package/dist/client/preview/preview-banner.mjs.map +0 -1
  907. package/dist/client/preview/preview-field.d.mts.map +0 -1
  908. package/dist/client/preview/preview-field.mjs.map +0 -1
  909. package/dist/client/preview/types.d.mts.map +0 -1
  910. package/dist/client/preview/types.mjs.map +0 -1
  911. package/dist/client/preview/use-collection-preview.d.mts.map +0 -1
  912. package/dist/client/preview/use-collection-preview.mjs.map +0 -1
  913. package/dist/client/runtime/content-locales-provider.mjs.map +0 -1
  914. package/dist/client/runtime/locale-scope.mjs.map +0 -1
  915. package/dist/client/runtime/provider.d.mts.map +0 -1
  916. package/dist/client/runtime/provider.mjs.map +0 -1
  917. package/dist/client/runtime/routes.d.mts.map +0 -1
  918. package/dist/client/runtime/routes.mjs.map +0 -1
  919. package/dist/client/runtime/translations-provider.d.mts +0 -2
  920. package/dist/client/runtime/translations-provider.mjs.map +0 -1
  921. package/dist/client/scope/picker.d.mts.map +0 -1
  922. package/dist/client/scope/picker.mjs.map +0 -1
  923. package/dist/client/scope/provider.d.mts.map +0 -1
  924. package/dist/client/scope/provider.mjs.map +0 -1
  925. package/dist/client/scope/types.d.mts.map +0 -1
  926. package/dist/client/utils/auto-expand-fields.mjs.map +0 -1
  927. package/dist/client/utils/build-field-definitions-from-schema.mjs.map +0 -1
  928. package/dist/client/utils/detect-relations.mjs.map +0 -1
  929. package/dist/client/utils/locale-to-flag.d.mts.map +0 -1
  930. package/dist/client/utils/locale-to-flag.mjs.map +0 -1
  931. package/dist/client/utils/routes.mjs.map +0 -1
  932. package/dist/client/views/auth/accept-invite-form.d.mts.map +0 -1
  933. package/dist/client/views/auth/accept-invite-form.mjs.map +0 -1
  934. package/dist/client/views/auth/auth-layout.d.mts.map +0 -1
  935. package/dist/client/views/auth/auth-layout.mjs.map +0 -1
  936. package/dist/client/views/auth/forgot-password-form.d.mts.map +0 -1
  937. package/dist/client/views/auth/forgot-password-form.mjs.map +0 -1
  938. package/dist/client/views/auth/index.d.mts +0 -7
  939. package/dist/client/views/auth/invite-form.d.mts +0 -1
  940. package/dist/client/views/auth/invite-form.mjs.map +0 -1
  941. package/dist/client/views/auth/login-form.d.mts.map +0 -1
  942. package/dist/client/views/auth/login-form.mjs.map +0 -1
  943. package/dist/client/views/auth/reset-password-form.d.mts.map +0 -1
  944. package/dist/client/views/auth/reset-password-form.mjs.map +0 -1
  945. package/dist/client/views/auth/setup-form.d.mts.map +0 -1
  946. package/dist/client/views/auth/setup-form.mjs.map +0 -1
  947. package/dist/client/views/collection/auto-form-fields.d.mts +0 -4
  948. package/dist/client/views/collection/auto-form-fields.mjs.map +0 -1
  949. package/dist/client/views/collection/bulk-action-toolbar.mjs.map +0 -1
  950. package/dist/client/views/collection/cells/complex-cells.d.mts +0 -46
  951. package/dist/client/views/collection/cells/complex-cells.d.mts.map +0 -1
  952. package/dist/client/views/collection/cells/complex-cells.mjs.map +0 -1
  953. package/dist/client/views/collection/cells/index.d.mts +0 -7
  954. package/dist/client/views/collection/cells/primitive-cells.d.mts +0 -76
  955. package/dist/client/views/collection/cells/primitive-cells.d.mts.map +0 -1
  956. package/dist/client/views/collection/cells/primitive-cells.mjs.map +0 -1
  957. package/dist/client/views/collection/cells/relation-cells.d.mts +0 -21
  958. package/dist/client/views/collection/cells/relation-cells.d.mts.map +0 -1
  959. package/dist/client/views/collection/cells/relation-cells.mjs.map +0 -1
  960. package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +0 -1
  961. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs.map +0 -1
  962. package/dist/client/views/collection/cells/shared/cell-helpers.d.mts +0 -2
  963. package/dist/client/views/collection/cells/shared/cell-helpers.mjs.map +0 -1
  964. package/dist/client/views/collection/cells/shared/relation-chip.d.mts +0 -1
  965. package/dist/client/views/collection/cells/shared/relation-chip.mjs.map +0 -1
  966. package/dist/client/views/collection/cells/upload-cells.d.mts +0 -25
  967. package/dist/client/views/collection/cells/upload-cells.d.mts.map +0 -1
  968. package/dist/client/views/collection/cells/upload-cells.mjs.map +0 -1
  969. package/dist/client/views/collection/columns/build-columns.d.mts +0 -2
  970. package/dist/client/views/collection/columns/build-columns.mjs.map +0 -1
  971. package/dist/client/views/collection/columns/column-defaults.d.mts +0 -2
  972. package/dist/client/views/collection/columns/column-defaults.mjs.map +0 -1
  973. package/dist/client/views/collection/columns/index.d.mts +0 -3
  974. package/dist/client/views/collection/columns/types.d.mts +0 -2
  975. package/dist/client/views/collection/field-context.mjs.map +0 -1
  976. package/dist/client/views/collection/field-renderer.mjs.map +0 -1
  977. package/dist/client/views/collection/form-view.d.mts +0 -112
  978. package/dist/client/views/collection/form-view.d.mts.map +0 -1
  979. package/dist/client/views/collection/form-view.mjs.map +0 -1
  980. package/dist/client/views/collection/index.d.mts +0 -9
  981. package/dist/client/views/collection/table-view.d.mts +0 -102
  982. package/dist/client/views/collection/table-view.d.mts.map +0 -1
  983. package/dist/client/views/collection/table-view.mjs.map +0 -1
  984. package/dist/client/views/collection/view-skeletons.mjs.map +0 -1
  985. package/dist/client/views/common/global-search.d.mts +0 -1
  986. package/dist/client/views/common/global-search.mjs.map +0 -1
  987. package/dist/client/views/common/index.d.mts +0 -1
  988. package/dist/client/views/dashboard/dashboard-grid.mjs.map +0 -1
  989. package/dist/client/views/dashboard/dashboard-widget.mjs.map +0 -1
  990. package/dist/client/views/dashboard/widget-card.mjs.map +0 -1
  991. package/dist/client/views/globals/global-form-view.d.mts +0 -74
  992. package/dist/client/views/globals/global-form-view.d.mts.map +0 -1
  993. package/dist/client/views/globals/global-form-view.mjs.map +0 -1
  994. package/dist/client/views/index.d.mts +0 -28
  995. package/dist/client/views/layout/admin-layout-provider.d.mts.map +0 -1
  996. package/dist/client/views/layout/admin-layout-provider.mjs.map +0 -1
  997. package/dist/client/views/layout/admin-layout.d.mts.map +0 -1
  998. package/dist/client/views/layout/admin-layout.mjs.map +0 -1
  999. package/dist/client/views/layout/admin-root.d.mts +0 -7
  1000. package/dist/client/views/layout/admin-router.d.mts.map +0 -1
  1001. package/dist/client/views/layout/admin-router.mjs.map +0 -1
  1002. package/dist/client/views/layout/admin-sidebar.d.mts.map +0 -1
  1003. package/dist/client/views/layout/admin-sidebar.mjs.map +0 -1
  1004. package/dist/client/views/layout/admin-topbar.mjs.map +0 -1
  1005. package/dist/client/views/layout/index.d.mts +0 -5
  1006. package/dist/client/views/pages/accept-invite-page.d.mts.map +0 -1
  1007. package/dist/client/views/pages/accept-invite-page.mjs.map +0 -1
  1008. package/dist/client/views/pages/dashboard-page.d.mts.map +0 -1
  1009. package/dist/client/views/pages/dashboard-page.mjs.map +0 -1
  1010. package/dist/client/views/pages/forgot-password-page.d.mts.map +0 -1
  1011. package/dist/client/views/pages/forgot-password-page.mjs.map +0 -1
  1012. package/dist/client/views/pages/index.d.mts +0 -7
  1013. package/dist/client/views/pages/invite-page.d.mts.map +0 -1
  1014. package/dist/client/views/pages/invite-page.mjs.map +0 -1
  1015. package/dist/client/views/pages/login-page.d.mts.map +0 -1
  1016. package/dist/client/views/pages/login-page.mjs.map +0 -1
  1017. package/dist/client/views/pages/reset-password-page.d.mts.map +0 -1
  1018. package/dist/client/views/pages/reset-password-page.mjs.map +0 -1
  1019. package/dist/client/views/pages/setup-page.d.mts.map +0 -1
  1020. package/dist/client/views/pages/setup-page.mjs.map +0 -1
  1021. package/dist/client.d.mts.map +0 -1
  1022. package/dist/components/rich-text/rich-text-renderer.d.mts.map +0 -1
  1023. package/dist/components/rich-text/rich-text-renderer.mjs.map +0 -1
  1024. package/dist/server/adapters/nextjs.d.mts.map +0 -1
  1025. package/dist/server/adapters/nextjs.mjs.map +0 -1
  1026. package/dist/server/adapters/tanstack.d.mts.map +0 -1
  1027. package/dist/server/adapters/tanstack.mjs.map +0 -1
  1028. package/dist/server/augmentation.d.mts.map +0 -1
  1029. package/dist/server/auth-helpers.d.mts.map +0 -1
  1030. package/dist/server/auth-helpers.mjs.map +0 -1
  1031. package/dist/server/block/block-builder.d.mts.map +0 -1
  1032. package/dist/server/block/block-builder.mjs.map +0 -1
  1033. package/dist/server/block/introspection.d.mts.map +0 -1
  1034. package/dist/server/block/introspection.mjs.map +0 -1
  1035. package/dist/server/block/prefetch.d.mts.map +0 -1
  1036. package/dist/server/block/prefetch.mjs.map +0 -1
  1037. package/dist/server/fields/blocks.d.mts.map +0 -1
  1038. package/dist/server/fields/blocks.mjs.map +0 -1
  1039. package/dist/server/fields/index.d.mts.map +0 -1
  1040. package/dist/server/fields/index.mjs.map +0 -1
  1041. package/dist/server/fields/rich-text.d.mts.map +0 -1
  1042. package/dist/server/fields/rich-text.mjs.map +0 -1
  1043. package/dist/server/i18n/index.d.mts +0 -16
  1044. package/dist/server/i18n/index.d.mts.map +0 -1
  1045. package/dist/server/i18n/index.mjs.map +0 -1
  1046. package/dist/server/i18n/messages/cs.mjs.map +0 -1
  1047. package/dist/server/i18n/messages/de.mjs.map +0 -1
  1048. package/dist/server/i18n/messages/en.mjs.map +0 -1
  1049. package/dist/server/i18n/messages/es.mjs.map +0 -1
  1050. package/dist/server/i18n/messages/fr.mjs.map +0 -1
  1051. package/dist/server/i18n/messages/index.mjs.map +0 -1
  1052. package/dist/server/i18n/messages/pl.mjs.map +0 -1
  1053. package/dist/server/i18n/messages/pt.mjs.map +0 -1
  1054. package/dist/server/i18n/messages/sk.mjs.map +0 -1
  1055. package/dist/server/index.d.mts +0 -20
  1056. package/dist/server/modules/admin/functions/admin-config.mjs +0 -348
  1057. package/dist/server/modules/admin/functions/admin-config.mjs.map +0 -1
  1058. package/dist/server/modules/admin/functions/execute-action.d.mts.map +0 -1
  1059. package/dist/server/modules/admin/functions/execute-action.mjs.map +0 -1
  1060. package/dist/server/modules/admin/functions/locales.mjs +0 -80
  1061. package/dist/server/modules/admin/functions/locales.mjs.map +0 -1
  1062. package/dist/server/modules/admin/functions/preview.d.mts.map +0 -1
  1063. package/dist/server/modules/admin/functions/preview.mjs.map +0 -1
  1064. package/dist/server/modules/admin/functions/reactive.d.mts.map +0 -1
  1065. package/dist/server/modules/admin/functions/reactive.mjs.map +0 -1
  1066. package/dist/server/modules/admin/functions/setup.d.mts.map +0 -1
  1067. package/dist/server/modules/admin/functions/setup.mjs +0 -131
  1068. package/dist/server/modules/admin/functions/setup.mjs.map +0 -1
  1069. package/dist/server/modules/admin/functions/translations.mjs +0 -125
  1070. package/dist/server/modules/admin/functions/translations.mjs.map +0 -1
  1071. package/dist/server/modules/admin/functions/widget-data.d.mts +0 -33
  1072. package/dist/server/modules/admin/functions/widget-data.d.mts.map +0 -1
  1073. package/dist/server/modules/admin/functions/widget-data.mjs +0 -70
  1074. package/dist/server/modules/admin/functions/widget-data.mjs.map +0 -1
  1075. package/dist/server/modules/admin/index.d.mts.map +0 -1
  1076. package/dist/server/modules/admin/index.mjs.map +0 -1
  1077. package/dist/server/modules/admin-preferences/collections/admin-preferences.collection.d.mts +0 -3
  1078. package/dist/server/modules/admin-preferences/collections/admin-preferences.collection.mjs.map +0 -1
  1079. package/dist/server/modules/admin-preferences/collections/locks.collection.d.mts +0 -3
  1080. package/dist/server/modules/admin-preferences/collections/locks.collection.mjs.map +0 -1
  1081. package/dist/server/modules/admin-preferences/collections/saved-views.collection.d.mts +0 -1490
  1082. package/dist/server/modules/admin-preferences/collections/saved-views.collection.d.mts.map +0 -1
  1083. package/dist/server/modules/admin-preferences/collections/saved-views.collection.mjs +0 -57
  1084. package/dist/server/modules/admin-preferences/collections/saved-views.collection.mjs.map +0 -1
  1085. package/dist/server/patch.d.mts +0 -100
  1086. package/dist/server/patch.d.mts.map +0 -1
  1087. package/dist/server/patch.mjs +0 -1062
  1088. package/dist/server/patch.mjs.map +0 -1
  1089. package/dist/shared/preview-utils.d.mts.map +0 -1
  1090. package/dist/shared/preview-utils.mjs.map +0 -1
  1091. package/dist/shared/types/saved-views.types.d.mts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"table-view.mjs","names":["config: ListViewConfig","options: any","whereConditions: Record<string, any>","availableFields: AvailableField[]","selectCol: ColumnDef<any>","t","orderedColumns: ColumnDef<any>[]","React","config","items","user","pageNum: number"],"sources":["../../../../src/client/views/collection/table-view.tsx"],"sourcesContent":["/**\n * Table View - Default list view component\n *\n * Renders collection items in a table with columns, sorting, filtering, and search.\n * This is the default list view registered in the admin view registry.\n */\n\nimport { Icon } from \"@iconify/react\";\nimport {\n\ttype ColumnDef,\n\tflexRender,\n\tgetCoreRowModel,\n\tgetSortedRowModel,\n\ttype RowSelectionState,\n\ttype SortingState,\n\tuseReactTable,\n} from \"@tanstack/react-table\";\nimport * as React from \"react\";\nimport { Suspense, useMemo, useState } from \"react\";\nimport type { ActionsConfig } from \"../../builder/types/action-types\";\nimport type {\n\tCollectionBuilderState,\n\tListViewConfig,\n} from \"../../builder/types/collection-types\";\nimport { ActionDialog } from \"../../components/actions/action-dialog\";\nimport { HeaderActions } from \"../../components/actions/header-actions\";\nimport { FilterBuilderSheet } from \"../../components/filter-builder/filter-builder-sheet\";\nimport type {\n\tAvailableField,\n\tViewConfiguration,\n} from \"../../components/filter-builder/types\";\nimport { LocaleSwitcher } from \"../../components/locale-switcher\";\nimport { flattenOptions } from \"../../components/primitives/types\";\nimport { Button } from \"../../components/ui/button\";\nimport { Checkbox } from \"../../components/ui/checkbox\";\nimport { EmptyState } from \"../../components/ui/empty-state\";\nimport { SearchInput } from \"../../components/ui/search-input\";\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectItem,\n\tSelectTrigger,\n\tSelectValue,\n} from \"../../components/ui/select\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRow,\n} from \"../../components/ui/table\";\nimport {\n\tToolbar,\n\tToolbarSection,\n\tToolbarSeparator,\n} from \"../../components/ui/toolbar\";\nimport { useActions } from \"../../hooks/use-action\";\nimport {\n\tuseCollectionDelete,\n\tuseCollectionList,\n} from \"../../hooks/use-collection\";\nimport { useCollectionFields } from \"../../hooks/use-collection-fields\";\nimport { useSuspenseCollectionMeta } from \"../../hooks/use-collection-meta\";\nimport { useSessionState } from \"../../hooks/use-current-user\";\nimport { getLockUser, useLocks } from \"../../hooks/use-locks\";\nimport { useRealtimeHighlight } from \"../../hooks/use-realtime-highlight\";\nimport {\n\tuseDeleteSavedView,\n\tuseSavedViews,\n\tuseSaveView,\n} from \"../../hooks/use-saved-views\";\nimport { useDebouncedValue, useSearch } from \"../../hooks/use-search\";\nimport { useViewState } from \"../../hooks/use-view-state\";\nimport { useResolveText, useTranslation } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport {\n\tselectRealtime,\n\tuseAdminStore,\n\tuseSafeContentLocales,\n\tuseScopedLocale,\n} from \"../../runtime\";\nimport {\n\tautoExpandFields,\n\thasFieldsToExpand,\n} from \"../../utils/auto-expand-fields\";\n\nimport { BulkActionToolbar } from \"./bulk-action-toolbar\";\nimport {\n\tbuildColumns,\n\tcomputeDefaultColumns,\n\tgetAllAvailableFields,\n} from \"./columns\";\nimport { TableViewSkeleton } from \"./view-skeletons\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Table view configuration from registry.\n *\n * Re-exports ListViewConfig for type consistency between builder and component.\n */\nexport type TableViewConfig = ListViewConfig;\n\nfunction mapListSchemaToConfig(list?: {\n\tview?: string;\n\tcolumns?: string[];\n\tdefaultSort?: { field: string; direction: \"asc\" | \"desc\" };\n\tsearchable?: string[];\n\tfilterable?: string[];\n\tactions?: unknown;\n}): ListViewConfig | undefined {\n\tif (!list) return undefined;\n\n\tconst config: ListViewConfig = {};\n\tif (list.columns?.length) config.columns = list.columns;\n\tif (list.defaultSort) config.defaultSort = list.defaultSort as any;\n\tif (list.searchable?.length) {\n\t\tconfig.searchFields = list.searchable as any;\n\t\tconfig.searchable = true;\n\t}\n\n\treturn config;\n}\n\n/**\n * Props for TableView component\n */\nexport interface TableViewProps {\n\t/**\n\t * Collection name\n\t */\n\tcollection: string;\n\n\t/**\n\t * Collection configuration from admin builder\n\t * Accepts CollectionBuilderState or any compatible config object\n\t */\n\tconfig?: Partial<CollectionBuilderState> | Record<string, any>;\n\n\t/**\n\t * View-specific configuration from registry\n\t */\n\tviewConfig?: TableViewConfig;\n\n\t/**\n\t * Navigate function for routing\n\t */\n\tnavigate: (path: string) => void;\n\n\t/**\n\t * Base path for admin routes (e.g., \"/admin\")\n\t */\n\tbasePath?: string;\n\n\t/**\n\t * Show search functionality\n\t * @default true\n\t */\n\tshowSearch?: boolean;\n\n\t/**\n\t * Show filter functionality\n\t * @default true\n\t */\n\tshowFilters?: boolean;\n\n\t/**\n\t * Show toolbar\n\t * @default true\n\t */\n\tshowToolbar?: boolean;\n\n\t/**\n\t * Enable realtime invalidation for this table.\n\t * Falls back to AdminProvider realtime config when undefined.\n\t */\n\trealtime?: boolean;\n\n\t/**\n\t * Custom header actions (in addition to configured actions)\n\t * @deprecated Use actions config instead\n\t */\n\theaderActions?: React.ReactNode;\n\n\t/**\n\t * Custom empty state\n\t */\n\temptyState?: React.ReactNode;\n\n\t/**\n\t * Actions configuration (header, row, bulk)\n\t * If not provided, defaults will be used\n\t */\n\tactionsConfig?: ActionsConfig;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * TableView - Default table-based list view for collections\n *\n * Uses Suspense for data loading to eliminate race conditions.\n * Critical data (collectionMeta, user session, preferences) is loaded\n * before rendering, ensuring stable initial state.\n *\n * Features:\n * - Auto-generates columns from collection config\n * - Search and filter functionality\n * - Sortable columns\n * - Saved views support\n * - Auto-expands upload/relation fields\n *\n * @example\n * ```tsx\n * // Used automatically via registry when navigating to /admin/collections/:name\n * // Can also be used directly:\n * <TableView\n * collection=\"posts\"\n * config={postsConfig}\n * navigate={navigate}\n * basePath=\"/admin\"\n * />\n * ```\n */\nexport default function TableView(props: TableViewProps): React.ReactElement {\n\treturn (\n\t\t<Suspense fallback={<TableViewSkeleton />}>\n\t\t\t<TableViewInner {...props} />\n\t\t</Suspense>\n\t);\n}\n\n/**\n * Inner component that uses Suspense queries.\n * This component will suspend until all critical data is loaded.\n */\nfunction TableViewInner({\n\tcollection,\n\tconfig,\n\tviewConfig,\n\tnavigate,\n\tbasePath = \"/admin\",\n\tshowSearch = true,\n\tshowFilters = true,\n\tshowToolbar = true,\n\trealtime,\n\theaderActions,\n\temptyState,\n\tactionsConfig,\n}: TableViewProps): React.ReactElement {\n\tconst globalRealtimeConfig = useAdminStore(selectRealtime);\n\tconst { fields: resolvedFields, schema } = useCollectionFields(collection, {\n\t\tfallbackFields: (config as any)?.fields,\n\t});\n\tconst schemaListConfig = mapListSchemaToConfig(schema?.admin?.list as any);\n\tconst resolvedListConfig =\n\t\tviewConfig ??\n\t\t(config?.list as any)?.[\"~config\"] ??\n\t\tconfig?.list ??\n\t\tschemaListConfig;\n\t// Default to global realtime.enabled if not explicitly set\n\tconst resolvedRealtime =\n\t\trealtime ??\n\t\t((resolvedListConfig as any)?.realtime as boolean | undefined) ??\n\t\tglobalRealtimeConfig.enabled;\n\n\t// Use actionsConfig from prop or from config.list view config\n\t// Actions are now stored in the list view config, not at collection level\n\tconst resolvedActionsConfig =\n\t\tactionsConfig ?? (resolvedListConfig as any)?.actions;\n\n\t// Get user session for preferences (suspense-enabled)\n\tconst { user } = useSessionState();\n\n\t// Fetch collection metadata from backend (suspense-enabled)\n\t// This will suspend until data is loaded, eliminating race conditions\n\tconst { data: collectionMeta } = useSuspenseCollectionMeta(collection);\n\n\t// i18n translations\n\tconst { t } = useTranslation();\n\tconst resolveText = useResolveText();\n\n\t// Locale switching (scoped or global)\n\tconst { locale: contentLocale, setLocale: setContentLocale } =\n\t\tuseScopedLocale();\n\tconst contentLocales = useSafeContentLocales();\n\tconst localeOptions = contentLocales?.locales ?? [];\n\n\t// Use actions hook for helpers and dialog state\n\tconst {\n\t\thelpers: actionHelpers,\n\t\tactions,\n\t\tdialogAction,\n\t\tdialogItem,\n\t\topenDialog,\n\t\tcloseDialog,\n\t} = useActions({\n\t\tcollection,\n\t\tactionsConfig: resolvedActionsConfig,\n\t});\n\n\t// Build columns from config - buildAllColumns enables showing any field user selects\n\tconst columns = useMemo(\n\t\t() =>\n\t\t\tbuildColumns({\n\t\t\t\tconfig: {\n\t\t\t\t\tfields: resolvedFields,\n\t\t\t\t\tlist: resolvedListConfig,\n\t\t\t\t},\n\t\t\t\tfallbackColumns: [\"id\"],\n\t\t\t\tbuildAllColumns: true, // Build all columns so user can toggle any field\n\t\t\t\tmeta: collectionMeta, // Use meta to determine title field\n\t\t\t}),\n\t\t[resolvedFields, resolvedListConfig, collectionMeta],\n\t);\n\n\t// Auto-detect fields to expand (uploads, relations)\n\tconst expandedFields = useMemo(\n\t\t() =>\n\t\t\tautoExpandFields({\n\t\t\t\tfields: resolvedFields,\n\t\t\t\tlist: resolvedListConfig as any,\n\t\t\t\trelations: collectionMeta?.relations,\n\t\t\t}),\n\t\t[resolvedFields, resolvedListConfig, collectionMeta?.relations],\n\t);\n\n\t// Filter builder sheet state\n\tconst [isSheetOpen, setIsSheetOpen] = useState(false);\n\tconst [searchTerm, setSearchTerm] = useState(\"\");\n\n\t// Default columns using configured columns from .list() or auto-detection\n\t// When .list({ columns: [...] }) is defined, those become the defaults\n\tconst defaultColumns = useMemo(\n\t\t() =>\n\t\t\tcomputeDefaultColumns(resolvedFields, {\n\t\t\t\tmeta: collectionMeta,\n\t\t\t\tconfiguredColumns: resolvedListConfig?.columns as any,\n\t\t\t}),\n\t\t[resolvedFields, resolvedListConfig?.columns, collectionMeta],\n\t);\n\n\t// View state (filters, sort, visible columns, realtime) - with database persistence\n\t// Uses Suspense internally for loading preferences\n\tconst viewState = useViewState(\n\t\tdefaultColumns,\n\t\t{ realtime: resolvedRealtime },\n\t\tcollection,\n\t\tuser?.id,\n\t);\n\tconst effectiveRealtime = viewState.config.realtime ?? resolvedRealtime;\n\n\t// Build query options from view state (filters, sort)\n\tconst queryOptions = useMemo(() => {\n\t\tconst options: any = {};\n\n\t\t// Add field expansion if needed\n\t\tif (hasFieldsToExpand(expandedFields)) {\n\t\t\toptions.with = expandedFields;\n\t\t}\n\n\t\t// Apply filters from view state\n\t\tif (viewState.config.filters.length > 0) {\n\t\t\tconst whereConditions: Record<string, any> = { ...options.where };\n\t\t\tconst relationNames = collectionMeta?.relations ?? [];\n\n\t\t\tconst isEmptyValue = (val: unknown) => {\n\t\t\t\tif (val === undefined || val === null) return true;\n\t\t\t\tif (typeof val === \"string\") return val.trim().length === 0;\n\t\t\t\tif (Array.isArray(val)) return val.length === 0;\n\t\t\t\treturn false;\n\t\t\t};\n\n\t\t\tconst normalizeSelectValue = (val: unknown, fieldOptions: any) => {\n\t\t\t\tconst optionsList = fieldOptions?.options;\n\t\t\t\tif (!optionsList) return val;\n\t\t\t\tconst map = new Map(\n\t\t\t\t\tflattenOptions(optionsList).map((opt) => [\n\t\t\t\t\t\tString(opt.value),\n\t\t\t\t\t\topt.value,\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\tconst mapValue = (item: unknown) => map.get(String(item)) ?? item;\n\t\t\t\tif (Array.isArray(val)) return val.map(mapValue);\n\t\t\t\tif (val === undefined || val === null) return val;\n\t\t\t\treturn mapValue(val);\n\t\t\t};\n\n\t\t\tconst coerceValue = (val: unknown, fieldDef?: any) => {\n\t\t\t\tif (!fieldDef) return val;\n\t\t\t\tconst fieldType = fieldDef?.name ?? \"text\";\n\t\t\t\tconst fieldOptions = fieldDef?.[\"~options\"] ?? {};\n\n\t\t\t\tif (fieldType === \"number\" && typeof val === \"string\") {\n\t\t\t\t\tconst parsed = Number(val);\n\t\t\t\t\treturn Number.isNaN(parsed) ? val : parsed;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t(fieldType === \"checkbox\" || fieldType === \"switch\") &&\n\t\t\t\t\ttypeof val === \"string\"\n\t\t\t\t) {\n\t\t\t\t\tif (val === \"true\") return true;\n\t\t\t\t\tif (val === \"false\") return false;\n\t\t\t\t}\n\t\t\t\tif (fieldType === \"select\") {\n\t\t\t\t\treturn normalizeSelectValue(val, fieldOptions);\n\t\t\t\t}\n\n\t\t\t\treturn val;\n\t\t\t};\n\n\t\t\tconst toArray = (val: unknown): unknown[] => {\n\t\t\t\tif (Array.isArray(val)) return val;\n\t\t\t\tif (val === undefined || val === null || val === \"\") return [];\n\t\t\t\treturn [val];\n\t\t\t};\n\n\t\t\tconst buildRelationCondition = (\n\t\t\t\toperator: string,\n\t\t\t\tval: unknown,\n\t\t\t\trelationType: \"single\" | \"multiple\",\n\t\t\t) => {\n\t\t\t\tconst isMultiple = relationType === \"multiple\";\n\t\t\t\tconst ids = toArray(val);\n\n\t\t\t\tswitch (operator) {\n\t\t\t\t\tcase \"equals\":\n\t\t\t\t\t\treturn isMultiple ? { some: { id: val } } : { is: { id: val } };\n\t\t\t\t\tcase \"not_equals\":\n\t\t\t\t\t\treturn isMultiple ? { none: { id: val } } : { isNot: { id: val } };\n\t\t\t\t\tcase \"in\":\n\t\t\t\t\t\treturn isMultiple\n\t\t\t\t\t\t\t? { some: { id: { in: ids } } }\n\t\t\t\t\t\t\t: { is: { id: { in: ids } } };\n\t\t\t\t\tcase \"not_in\":\n\t\t\t\t\t\treturn isMultiple\n\t\t\t\t\t\t\t? { none: { id: { in: ids } } }\n\t\t\t\t\t\t\t: { isNot: { id: { in: ids } } };\n\t\t\t\t\tcase \"some\":\n\t\t\t\t\t\treturn { some: { id: { in: ids } } };\n\t\t\t\t\tcase \"every\":\n\t\t\t\t\t\treturn { every: { id: { in: ids } } };\n\t\t\t\t\tcase \"none\":\n\t\t\t\t\t\treturn { none: { id: { in: ids } } };\n\t\t\t\t\tcase \"is_empty\":\n\t\t\t\t\t\treturn isMultiple ? { none: {} } : { isNot: {} };\n\t\t\t\t\tcase \"is_not_empty\":\n\t\t\t\t\t\treturn isMultiple ? { some: {} } : { is: {} };\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tfor (const filter of viewState.config.filters) {\n\t\t\t\tconst { field, operator, value } = filter;\n\t\t\t\tif (!field || field === \"_title\") continue;\n\n\t\t\t\tconst fieldDef = resolvedFields?.[field] as any;\n\t\t\t\tconst fieldType = fieldDef?.name ?? \"text\";\n\t\t\t\tconst fieldOptions = fieldDef?.[\"~options\"] ?? {};\n\t\t\t\tconst relationName =\n\t\t\t\t\tfieldType === \"relation\"\n\t\t\t\t\t\t? ((fieldOptions.relationName as string | undefined) ?? field)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst hasRelation =\n\t\t\t\t\trelationName &&\n\t\t\t\t\t(relationNames.length === 0 || relationNames.includes(relationName));\n\t\t\t\tconst isRelationField = fieldType === \"relation\" && !!hasRelation;\n\n\t\t\t\tconst requiresValue =\n\t\t\t\t\toperator !== \"is_empty\" && operator !== \"is_not_empty\";\n\t\t\t\tif (requiresValue && isEmptyValue(value)) continue;\n\n\t\t\t\tconst normalizedValue = coerceValue(value, fieldDef);\n\n\t\t\t\tif (isRelationField && relationName) {\n\t\t\t\t\tconst relationType =\n\t\t\t\t\t\tfieldOptions.type === \"multiple\" ? \"multiple\" : \"single\";\n\t\t\t\t\tconst condition = buildRelationCondition(\n\t\t\t\t\t\toperator,\n\t\t\t\t\t\tnormalizedValue,\n\t\t\t\t\t\trelationType,\n\t\t\t\t\t);\n\t\t\t\t\tif (condition) {\n\t\t\t\t\t\twhereConditions[relationName] = condition;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tswitch (operator) {\n\t\t\t\t\tcase \"equals\":\n\t\t\t\t\t\twhereConditions[field] = normalizedValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"not_equals\":\n\t\t\t\t\t\twhereConditions[field] = { ne: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"contains\":\n\t\t\t\t\t\twhereConditions[field] = { contains: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"not_contains\":\n\t\t\t\t\t\twhereConditions[field] = {\n\t\t\t\t\t\t\tnotIlike: `%${normalizedValue}%`,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"starts_with\":\n\t\t\t\t\t\twhereConditions[field] = { startsWith: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"ends_with\":\n\t\t\t\t\t\twhereConditions[field] = { endsWith: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"greater_than\":\n\t\t\t\t\t\twhereConditions[field] = { gt: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"less_than\":\n\t\t\t\t\t\twhereConditions[field] = { lt: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"greater_than_or_equal\":\n\t\t\t\t\t\twhereConditions[field] = { gte: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"less_than_or_equal\":\n\t\t\t\t\t\twhereConditions[field] = { lte: normalizedValue };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"in\": {\n\t\t\t\t\t\tconst values = Array.isArray(normalizedValue)\n\t\t\t\t\t\t\t? normalizedValue\n\t\t\t\t\t\t\t: [normalizedValue];\n\t\t\t\t\t\twhereConditions[field] = { in: values };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"not_in\": {\n\t\t\t\t\t\tconst values = Array.isArray(normalizedValue)\n\t\t\t\t\t\t\t? normalizedValue\n\t\t\t\t\t\t\t: [normalizedValue];\n\t\t\t\t\t\twhereConditions[field] = { notIn: values };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"is_empty\":\n\t\t\t\t\t\twhereConditions[field] = { isNull: true };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"is_not_empty\":\n\t\t\t\t\t\twhereConditions[field] = { isNotNull: true };\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toptions.where = whereConditions;\n\t\t}\n\n\t\t// Apply sort from view state\n\t\tif (viewState.config.sortConfig) {\n\t\t\tconst { field, direction } = viewState.config.sortConfig;\n\t\t\toptions.orderBy = { [field]: direction };\n\t\t}\n\n\t\t// Apply pagination from view state\n\t\tconst pageSize = viewState.config.pagination?.pageSize ?? 25;\n\t\tconst page = viewState.config.pagination?.page ?? 1;\n\t\toptions.limit = pageSize;\n\t\toptions.offset = (page - 1) * pageSize;\n\n\t\treturn options;\n\t}, [\n\t\texpandedFields,\n\t\tviewState.config.filters,\n\t\tviewState.config.sortConfig,\n\t\tviewState.config.pagination?.page,\n\t\tviewState.config.pagination?.pageSize,\n\t\tresolvedFields,\n\t\tcollectionMeta?.relations,\n\t]);\n\n\t// Debounce search term for API requests (300ms)\n\tconst debouncedSearchTerm = useDebouncedValue(searchTerm, 300);\n\tconst isSearching = debouncedSearchTerm.trim().length > 0;\n\n\t// Search API for FTS-powered search\n\t// Returns full records with search metadata (_search.score, _search.highlights)\n\tconst {\n\t\tdata: searchData,\n\t\tisLoading: searchLoading,\n\t\tisFetching: searchFetching,\n\t} = useSearch(\n\t\t{\n\t\t\tcollection,\n\t\t\tquery: debouncedSearchTerm,\n\t\t\tlimit: 100,\n\t\t\thighlights: true,\n\t\t},\n\t\t{ enabled: isSearching },\n\t);\n\n\t// Data fetching with filters and sort applied (normal browsing)\n\tconst { data: listData, isLoading: listLoading } = useCollectionList(\n\t\tcollection as any,\n\t\tqueryOptions,\n\t\t{ enabled: !isSearching },\n\t\t{ realtime: effectiveRealtime },\n\t);\n\n\t// Merge data sources - search returns full records directly now\n\tconst isLoading = isSearching ? searchLoading : listLoading;\n\tconst isSearchActive = isSearching && searchFetching;\n\n\t// Saved views hooks\n\tconst { data: savedViewsData, isLoading: savedViewsLoading } =\n\t\tuseSavedViews(collection);\n\tconst saveViewMutation = useSaveView(collection);\n\tconst deleteViewMutation = useDeleteSavedView(collection);\n\n\t// Delete mutation for bulk actions\n\tconst deleteMutation = useCollectionDelete(collection as any);\n\n\t// Build available fields from config for column picker\n\t// All fields are available in Options, but defaults come from .list() config\n\tconst availableFields: AvailableField[] = useMemo(() => {\n\t\treturn getAllAvailableFields(resolvedFields, { meta: collectionMeta });\n\t}, [resolvedFields, collectionMeta]);\n\n\t// Filter columns based on visibleColumns from view state\n\t// Includes checkbox selection column as first column\n\tconst visibleColumnDefs = useMemo(() => {\n\t\t// Checkbox selection column (first column, sticky)\n\t\tconst selectCol: ColumnDef<any> = {\n\t\t\tid: \"_select\",\n\t\t\theader: ({ table: t }) => {\n\t\t\t\tconst isAllSelected = t.getIsAllPageRowsSelected();\n\t\t\t\tconst isSomeSelected = t.getIsSomePageRowsSelected();\n\t\t\t\treturn (\n\t\t\t\t\t// biome-ignore lint/a11y/noStaticElementInteractions: <explanation>\n\t\t\t\t\t<div\n\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\tonKeyDown={(e) => e.stopPropagation()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Checkbox\n\t\t\t\t\t\t\tchecked={isAllSelected}\n\t\t\t\t\t\t\tindeterminate={!isAllSelected && isSomeSelected}\n\t\t\t\t\t\t\tonCheckedChange={(checked) =>\n\t\t\t\t\t\t\t\tt.toggleAllPageRowsSelected(!!checked)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\taria-label=\"Select all\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t},\n\t\t\tcell: ({ row }) => {\n\t\t\t\tconst isSelected = row.getIsSelected();\n\t\t\t\tconst canSelect = row.getCanSelect();\n\t\t\t\treturn (\n\t\t\t\t\t// biome-ignore lint/a11y/noStaticElementInteractions: <explanation>\n\t\t\t\t\t<div\n\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\tonKeyDown={(e) => e.stopPropagation()}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Checkbox\n\t\t\t\t\t\t\tchecked={isSelected}\n\t\t\t\t\t\t\tdisabled={!canSelect}\n\t\t\t\t\t\t\tonCheckedChange={(checked) => row.toggleSelected(!!checked)}\n\t\t\t\t\t\t\taria-label=\"Select row\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t},\n\t\t\tsize: 40,\n\t\t\tenableSorting: false,\n\t\t\tenableHiding: false,\n\t\t};\n\n\t\t// Determine title column name from meta\n\t\tconst titleFieldName = collectionMeta?.title?.fieldName;\n\t\tconst titleType = collectionMeta?.title?.type;\n\t\tconst titleColName =\n\t\t\ttitleType === \"field\" && titleFieldName ? titleFieldName : \"_title\";\n\n\t\t// Start with checkbox column\n\t\tconst orderedColumns: ColumnDef<any>[] = [selectCol];\n\n\t\t// Always add title column first (after checkbox) if it exists\n\t\tconst titleCol = columns.find(\n\t\t\t(c) =>\n\t\t\t\t(c as any).accessorKey === titleColName ||\n\t\t\t\t(c as any).id === titleColName,\n\t\t);\n\t\tif (titleCol) {\n\t\t\torderedColumns.push(titleCol as ColumnDef<any>);\n\t\t}\n\n\t\t// Determine which columns to show\n\t\t// If visibleColumns is empty, show ALL columns (default behavior)\n\t\tconst columnsToShow =\n\t\t\tviewState.config.visibleColumns.length > 0\n\t\t\t\t? viewState.config.visibleColumns\n\t\t\t\t: columns\n\t\t\t\t\t\t.map((c) => (c as any).accessorKey || (c as any).id)\n\t\t\t\t\t\t.filter(Boolean);\n\n\t\t// Add remaining visible columns (excluding title since it's already added)\n\t\tfor (const colName of columnsToShow) {\n\t\t\t// Skip title column - already added first\n\t\t\tif (colName === titleColName) continue;\n\n\t\t\tconst col = columns.find(\n\t\t\t\t(c) => (c as any).accessorKey === colName || (c as any).id === colName,\n\t\t\t);\n\t\t\tif (col) {\n\t\t\t\torderedColumns.push(col as ColumnDef<any>);\n\t\t\t}\n\t\t}\n\n\t\treturn orderedColumns;\n\t}, [columns, viewState.config.visibleColumns, collectionMeta]);\n\n\t// Table sorting state - sync with view state\n\tconst [sorting, setSorting] = React.useState<SortingState>(() => {\n\t\tif (viewState.config.sortConfig) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: viewState.config.sortConfig.field,\n\t\t\t\t\tdesc: viewState.config.sortConfig.direction === \"desc\",\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t});\n\n\t// Row selection state\n\tconst [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});\n\n\t// Sync table sorting with view state\n\tconst handleSortingChange = React.useCallback(\n\t\t(updater: SortingState | ((old: SortingState) => SortingState)) => {\n\t\t\tconst newSorting =\n\t\t\t\ttypeof updater === \"function\" ? updater(sorting) : updater;\n\t\t\tsetSorting(newSorting);\n\t\t\tif (newSorting.length > 0) {\n\t\t\t\tviewState.setSort({\n\t\t\t\t\tfield: newSorting[0].id,\n\t\t\t\t\tdirection: newSorting[0].desc ? \"desc\" : \"asc\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tviewState.setSort(null);\n\t\t\t}\n\t\t},\n\t\t[sorting, viewState],\n\t);\n\n\t// Get items from appropriate data source\n\t// Search returns full records directly with _search metadata\n\t// List returns normal CRUD results\n\tconst items = useMemo(() => {\n\t\tif (isSearching) {\n\t\t\treturn searchData?.docs ?? [];\n\t\t}\n\t\treturn listData?.docs ?? [];\n\t}, [isSearching, searchData?.docs, listData?.docs]);\n\n\t// Track realtime changes and highlight affected rows\n\tconst { isHighlighted } = useRealtimeHighlight(items, {\n\t\tenabled: effectiveRealtime && !isSearching,\n\t});\n\n\t// Track who is editing which documents\n\tconst { getLock, isLocked: isDocLocked } = useLocks({\n\t\tresourceType: \"collection\",\n\t\tresource: collection,\n\t\trealtime: effectiveRealtime,\n\t});\n\n\t// Search results are already sorted by score, list results are server-sorted\n\tconst filteredItems = items;\n\n\tconst table = useReactTable({\n\t\tdata: filteredItems as any[],\n\t\tcolumns: visibleColumnDefs,\n\t\tgetCoreRowModel: getCoreRowModel(),\n\t\tgetSortedRowModel: getSortedRowModel(),\n\t\tonSortingChange: handleSortingChange,\n\t\tenableRowSelection: true,\n\t\tonRowSelectionChange: setRowSelection,\n\t\tgetRowId: (row: any) => row.id, // Use item ID as row ID for selection\n\t\tstate: {\n\t\t\tsorting,\n\t\t\trowSelection,\n\t\t},\n\t});\n\n\t// Handlers\n\tconst handleSaveView = (name: string, config: ViewConfiguration) => {\n\t\tsaveViewMutation.mutate({\n\t\t\tname,\n\t\t\tconfiguration: config,\n\t\t});\n\t};\n\n\tconst handleDeleteView = (viewId: string) => {\n\t\tdeleteViewMutation.mutate(viewId);\n\t};\n\n\tconst handleRowClick = (item: any) => {\n\t\tnavigate(`${basePath}/collections/${collection}/${item.id}`);\n\t};\n\n\t// Bulk delete handler\n\tconst handleBulkDelete = React.useCallback(\n\t\tasync (ids: string[]) => {\n\t\t\t// Delete items in parallel\n\t\t\tconst results = await Promise.allSettled(\n\t\t\t\tids.map((id) => deleteMutation.mutateAsync({ id })),\n\t\t\t);\n\n\t\t\tconst successCount = results.filter(\n\t\t\t\t(r) => r.status === \"fulfilled\",\n\t\t\t).length;\n\t\t\tconst failCount = results.filter((r) => r.status === \"rejected\").length;\n\n\t\t\tif (failCount === 0) {\n\t\t\t\tactionHelpers.toast.success(\n\t\t\t\t\tt(\"collection.bulkDeleteSuccess\", { count: successCount }),\n\t\t\t\t);\n\t\t\t} else if (successCount === 0) {\n\t\t\t\tactionHelpers.toast.error(t(\"collection.bulkDeleteError\"));\n\t\t\t} else {\n\t\t\t\tactionHelpers.toast.warning(\n\t\t\t\t\tt(\"collection.bulkDeletePartial\", {\n\t\t\t\t\t\tsuccess: successCount,\n\t\t\t\t\t\tfailed: failCount,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[deleteMutation, actionHelpers, t],\n\t);\n\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<div className=\"container\">\n\t\t\t\t<div className=\"flex h-64 items-center justify-center text-muted-foreground\">\n\t\t\t\t\t<Icon icon=\"ph:spinner-gap\" className=\"size-6 animate-spin\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"container\">\n\t\t\t<div className=\"space-y-4\">\n\t\t\t\t{/* Header - Title & Actions */}\n\t\t\t\t<div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t\t\t\t<h1 className=\"text-2xl md:text-3xl font-extrabold tracking-tight truncate\">\n\t\t\t\t\t\t\t\t{resolveText(\n\t\t\t\t\t\t\t\t\t(config as any)?.label ?? schema?.admin?.config?.label,\n\t\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</h1>\n\t\t\t\t\t\t\t{localeOptions.length > 0 && (\n\t\t\t\t\t\t\t\t<LocaleSwitcher\n\t\t\t\t\t\t\t\t\tlocales={localeOptions}\n\t\t\t\t\t\t\t\t\tvalue={contentLocale}\n\t\t\t\t\t\t\t\t\tonChange={setContentLocale}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{((config as any)?.description ??\n\t\t\t\t\t\tschema?.admin?.config?.description) ? (\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm mt-1 line-clamp-2\">\n\t\t\t\t\t\t\t\t{resolveText(\n\t\t\t\t\t\t\t\t\t(config as any)?.description ??\n\t\t\t\t\t\t\t\t\t\tschema?.admin?.config?.description,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex items-center gap-2 shrink-0\">\n\t\t\t\t\t\t{headerActions}\n\t\t\t\t\t\t{(actions.header.primary?.length ||\n\t\t\t\t\t\t\tactions.header.secondary?.length) && (\n\t\t\t\t\t\t\t<HeaderActions\n\t\t\t\t\t\t\t\tactions={actions.header}\n\t\t\t\t\t\t\t\tcollection={collection}\n\t\t\t\t\t\t\t\thelpers={actionHelpers}\n\t\t\t\t\t\t\t\tonOpenDialog={(action) => openDialog(action)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Toolbar */}\n\t\t\t\t{showToolbar && (\n\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t<Toolbar>\n\t\t\t\t\t\t\t{/* Search */}\n\t\t\t\t\t\t\t{showSearch && (\n\t\t\t\t\t\t\t\t<ToolbarSection className=\"flex-1\">\n\t\t\t\t\t\t\t\t\t<SearchInput\n\t\t\t\t\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => setSearchTerm(e.target.value)}\n\t\t\t\t\t\t\t\t\t\tonClear={() => setSearchTerm(\"\")}\n\t\t\t\t\t\t\t\t\t\tplaceholder={t(\"common.search\")}\n\t\t\t\t\t\t\t\t\t\tcontainerClassName=\"border-none bg-transparent dark:bg-transparent\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</ToolbarSection>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* Separator + Options */}\n\t\t\t\t\t\t\t{showFilters && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t{showSearch && <ToolbarSeparator />}\n\t\t\t\t\t\t\t\t\t<ToolbarSection>\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => setIsSheetOpen(true)}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"gap-2\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\t\t\ticon=\"ph:sliders-horizontal\"\n\t\t\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{t(\"viewOptions.title\")}\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</ToolbarSection>\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Toolbar>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Floating toolbar - shows when rows selected OR filters active */}\n\t\t\t\t<BulkActionToolbar\n\t\t\t\t\ttable={table}\n\t\t\t\t\tactions={actions.bulk}\n\t\t\t\t\tcollection={collection}\n\t\t\t\t\thelpers={actionHelpers}\n\t\t\t\t\ttotalCount={isSearching ? searchData?.total : listData?.totalDocs}\n\t\t\t\t\tpageCount={filteredItems.length}\n\t\t\t\t\tonOpenDialog={(action, items) => openDialog(action, items)}\n\t\t\t\t\tonBulkDelete={handleBulkDelete}\n\t\t\t\t\tfilterCount={viewState.config.filters.length}\n\t\t\t\t\tonOpenFilters={() => setIsSheetOpen(true)}\n\t\t\t\t\tonClearFilters={() =>\n\t\t\t\t\t\tviewState.setConfig({ ...viewState.config, filters: [] })\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t{/* Table */}\n\t\t\t\t<div className=\"bg-card/5 backdrop-blur-sm border border-border/40 overflow-hidden\">\n\t\t\t\t\t<Table>\n\t\t\t\t\t\t<TableHeader>\n\t\t\t\t\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t\t\t\t\t<TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n\t\t\t\t\t\t\t\t\t{headerGroup.headers.map((header, headerIndex) => {\n\t\t\t\t\t\t\t\t\t\t// First column (checkbox) is sticky at left=0, width ~36px\n\t\t\t\t\t\t\t\t\t\t// Second column (title) is sticky at left=36px\n\t\t\t\t\t\t\t\t\t\tconst stickyLeft =\n\t\t\t\t\t\t\t\t\t\t\theaderIndex === 0\n\t\t\t\t\t\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t\t\t\t\t\t: headerIndex === 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 36\n\t\t\t\t\t\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t\t\t\t\t// Only show border on the last sticky column (title)\n\t\t\t\t\t\t\t\t\t\tconst showStickyBorder = headerIndex === 1;\n\t\t\t\t\t\t\t\t\t\t// Checkbox column gets compact styling\n\t\t\t\t\t\t\t\t\t\tconst isCheckboxCol = headerIndex === 0;\n\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<TableHead\n\t\t\t\t\t\t\t\t\t\t\t\tkey={header.id}\n\t\t\t\t\t\t\t\t\t\t\t\tstickyLeft={stickyLeft}\n\t\t\t\t\t\t\t\t\t\t\t\tshowStickyBorder={showStickyBorder}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\t\tisCheckboxCol ? \"w-9 min-w-9 px-1.5\" : undefined\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{header.isPlaceholder ? null : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theader.column.getCanSort()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"cursor-pointer select-none flex items-center gap-2 hover:text-foreground transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={header.column.getToggleSortingHandler()}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{flexRender(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theader.column.columnDef.header,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theader.getContext(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{header.column.getIsSorted() && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{header.column.getIsSorted() === \"asc\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"↑\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"↓\"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</TableHeader>\n\t\t\t\t\t\t<TableBody>\n\t\t\t\t\t\t\t{table.getRowModel().rows?.length ? (\n\t\t\t\t\t\t\t\ttable.getRowModel().rows.map((row) => (\n\t\t\t\t\t\t\t\t\t<TableRow\n\t\t\t\t\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\t\t\t\t\tdata-state={row.getIsSelected() && \"selected\"}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\"group\",\n\t\t\t\t\t\t\t\t\t\t\tisHighlighted(row.id) && \"animate-realtime-pulse\",\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{row.getVisibleCells().map((cell, cellIndex) => {\n\t\t\t\t\t\t\t\t\t\t\t// First column (checkbox) is sticky at left=0, width ~36px\n\t\t\t\t\t\t\t\t\t\t\t// Second column (title) is sticky at left=36px\n\t\t\t\t\t\t\t\t\t\t\tconst stickyLeft =\n\t\t\t\t\t\t\t\t\t\t\t\tcellIndex === 0 ? 0 : cellIndex === 1 ? 36 : undefined;\n\t\t\t\t\t\t\t\t\t\t\t// Only show border on the last sticky column (title)\n\t\t\t\t\t\t\t\t\t\t\tconst showStickyBorder = cellIndex === 1;\n\t\t\t\t\t\t\t\t\t\t\t// Checkbox column gets compact styling\n\t\t\t\t\t\t\t\t\t\t\tconst isCheckboxCol = cellIndex === 0;\n\n\t\t\t\t\t\t\t\t\t\t\t// Title column (index 1) is clickable\n\t\t\t\t\t\t\t\t\t\t\tconst isTitleCol = cellIndex === 1;\n\n\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t<TableCell\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={cell.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\tstickyLeft={stickyLeft}\n\t\t\t\t\t\t\t\t\t\t\t\t\tshowStickyBorder={showStickyBorder}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisCheckboxCol ? \"w-9 min-w-9 px-1.5\" : undefined\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{isTitleCol ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleRowClick(row.original)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-left underline underline-offset-2 decoration-muted-foreground/50 hover:decoration-foreground transition-colors cursor-pointer\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{flexRender(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcell.column.columnDef.cell,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcell.getContext(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isDocLocked(row.id) &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst lock = getLock(row.id);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst user = lock ? getLockUser(lock) : null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"inline-flex items-center gap-1 text-xs text-muted-foreground bg-muted/50 px-1.5 py-0.5 rounded-full\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tuser?.name ??\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tuser?.email ??\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Someone is editing\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{user?.image ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsrc={user.image}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-4 rounded-full\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ticon=\"ph:pencil-simple\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-3\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"max-w-20 truncate\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{user?.name?.split(\" \")[0] ?? \"Editing\"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t})()}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tflexRender(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcell.column.columnDef.cell,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcell.getContext(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t\t\t<TableCell colSpan={visibleColumnDefs.length} className=\"p-0\">\n\t\t\t\t\t\t\t\t\t\t{emptyState || (\n\t\t\t\t\t\t\t\t\t\t\t<EmptyState\n\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"NO_RESULTS\"\n\t\t\t\t\t\t\t\t\t\t\t\tdescription={\n\t\t\t\t\t\t\t\t\t\t\t\t\tisSearching\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? t(\"collectionSearch.noResults\")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"No items found in this collection\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\theight=\"h-48\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</TableBody>\n\t\t\t\t\t</Table>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Footer - Pagination */}\n\t\t\t\t{!isSearching && (\n\t\t\t\t\t<div className=\"flex items-center justify-between gap-4 py-2\">\n\t\t\t\t\t\t{/* Left side - item count and page size */}\n\t\t\t\t\t\t<div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t{filteredItems.length > 0\n\t\t\t\t\t\t\t\t\t? `${((viewState.config.pagination?.page ?? 1) - 1) * (viewState.config.pagination?.pageSize ?? 25) + 1}-${Math.min(((viewState.config.pagination?.page ?? 1) - 1) * (viewState.config.pagination?.pageSize ?? 25) + (viewState.config.pagination?.pageSize ?? 25), listData?.totalDocs ?? filteredItems.length)}`\n\t\t\t\t\t\t\t\t\t: \"0\"}{\" \"}\n\t\t\t\t\t\t\t\tof {listData?.totalDocs ?? 0}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">Show</span>\n\t\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t\tvalue={String(viewState.config.pagination?.pageSize ?? 25)}\n\t\t\t\t\t\t\t\t\tonValueChange={(value) =>\n\t\t\t\t\t\t\t\t\t\tviewState.setPageSize(Number(value))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"h-8 w-[70px]\">\n\t\t\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t<SelectContent side=\"top\">\n\t\t\t\t\t\t\t\t\t\t{[10, 25, 50, 100].map((size) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem key={size} value={String(size)}>\n\t\t\t\t\t\t\t\t\t\t\t\t{size}\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Right side - pagination controls */}\n\t\t\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tclassName=\"size-8 p-0\"\n\t\t\t\t\t\t\t\tdisabled={(viewState.config.pagination?.page ?? 1) <= 1}\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tviewState.setPage(\n\t\t\t\t\t\t\t\t\t\t(viewState.config.pagination?.page ?? 1) - 1,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:caret-left\" className=\"size-4\" />\n\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t{/* Page numbers */}\n\t\t\t\t\t\t\t{Array.from(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlength: Math.min(5, listData?.totalPages ?? 1),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t(_, i) => {\n\t\t\t\t\t\t\t\t\tconst currentPage = viewState.config.pagination?.page ?? 1;\n\t\t\t\t\t\t\t\t\tconst totalPages = listData?.totalPages ?? 1;\n\t\t\t\t\t\t\t\t\tlet pageNum: number;\n\n\t\t\t\t\t\t\t\t\tif (totalPages <= 5) {\n\t\t\t\t\t\t\t\t\t\tpageNum = i + 1;\n\t\t\t\t\t\t\t\t\t} else if (currentPage <= 3) {\n\t\t\t\t\t\t\t\t\t\tpageNum = i + 1;\n\t\t\t\t\t\t\t\t\t} else if (currentPage >= totalPages - 2) {\n\t\t\t\t\t\t\t\t\t\tpageNum = totalPages - 4 + i;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpageNum = currentPage - 2 + i;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tkey={pageNum}\n\t\t\t\t\t\t\t\t\t\t\tvariant={currentPage === pageNum ? \"secondary\" : \"ghost\"}\n\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-8 p-0 min-w-[32px]\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => viewState.setPage(pageNum)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{pageNum}\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tclassName=\"size-8 p-0\"\n\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\t(viewState.config.pagination?.page ?? 1) >=\n\t\t\t\t\t\t\t\t\t(listData?.totalPages ?? 1)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tviewState.setPage(\n\t\t\t\t\t\t\t\t\t\t(viewState.config.pagination?.page ?? 1) + 1,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:caret-right\" className=\"size-4\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Search mode footer */}\n\t\t\t\t{isSearching && (\n\t\t\t\t\t<div className=\"text-sm text-muted-foreground flex items-center gap-2 py-2\">\n\t\t\t\t\t\t{isSearchActive && (\n\t\t\t\t\t\t\t<Icon icon=\"ph:spinner-gap\" className=\"size-3 animate-spin\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{filteredItems.length} item{filteredItems.length !== 1 ? \"s\" : \"\"}\n\t\t\t\t\t\t{searchData?.total !== undefined && (\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t({searchData.total} match{searchData.total !== 1 ? \"es\" : \"\"}{\" \"}\n\t\t\t\t\t\t\t\tfound)\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Filter Builder Sheet */}\n\t\t\t\t<FilterBuilderSheet\n\t\t\t\t\tcollection={collection}\n\t\t\t\t\tavailableFields={availableFields}\n\t\t\t\t\tdefaultColumns={defaultColumns}\n\t\t\t\t\tcurrentConfig={viewState.config}\n\t\t\t\t\tonConfigChange={viewState.setConfig}\n\t\t\t\t\tisOpen={isSheetOpen}\n\t\t\t\t\tonOpenChange={setIsSheetOpen}\n\t\t\t\t\tsavedViews={savedViewsData?.docs ?? []}\n\t\t\t\t\tsavedViewsLoading={savedViewsLoading}\n\t\t\t\t\tonSaveView={handleSaveView}\n\t\t\t\t\tonDeleteView={handleDeleteView}\n\t\t\t\t/>\n\n\t\t\t\t{/* Action Dialog */}\n\t\t\t\t{dialogAction && (\n\t\t\t\t\t<ActionDialog\n\t\t\t\t\t\topen={!!dialogAction}\n\t\t\t\t\t\tonOpenChange={(open) => !open && closeDialog()}\n\t\t\t\t\t\taction={dialogAction}\n\t\t\t\t\t\tcollection={collection}\n\t\t\t\t\t\titem={dialogItem}\n\t\t\t\t\t\thelpers={actionHelpers}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"view-skeletons.mjs","names":[],"sources":["../../../../src/client/views/collection/view-skeletons.tsx"],"sourcesContent":["/**\n * View Skeletons\n *\n * Loading skeletons for collection views (table, form).\n * Used with Suspense boundaries to show loading state.\n */\n\nimport { Skeleton } from \"../../components/ui/skeleton\";\n\nfunction TableSkeletonRow({ isLast = false }: { isLast?: boolean }) {\n\treturn (\n\t\t<div className={`flex items-center gap-4 p-4 ${isLast ? \"\" : \"border-b\"}`}>\n\t\t\t<Skeleton className=\"h-4 w-4\" />\n\t\t\t<Skeleton className=\"h-4 w-48\" />\n\t\t\t<Skeleton className=\"h-4 w-20\" />\n\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t<Skeleton className=\"h-4 w-16 ml-auto\" />\n\t\t</div>\n\t);\n}\n\nfunction FormFieldSkeleton() {\n\treturn (\n\t\t<div className=\"space-y-2\">\n\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t<Skeleton className=\"h-10 w-full\" />\n\t\t</div>\n\t);\n}\n\nfunction ToolbarIconSkeleton() {\n\treturn <Skeleton className=\"h-8 w-8\" />;\n}\n\nfunction ContentLineSkeleton({ width }: { width: string }) {\n\treturn <Skeleton className={`h-4 ${width}`} />;\n}\n\n/**\n * Skeleton for TableView\n *\n * Shows a loading state that mimics the table layout.\n */\nexport function TableViewSkeleton() {\n\treturn (\n\t\t<div className=\"container\">\n\t\t\t<div className=\"space-y-4\">\n\t\t\t\t{/* Header */}\n\t\t\t\t<div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n\t\t\t\t\t<div className=\"space-y-1\">\n\t\t\t\t\t\t<Skeleton className=\"h-8 w-48\" />\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-64\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<Skeleton className=\"h-9 w-32\" />\n\t\t\t\t</div>\n\n\t\t\t\t{/* Toolbar */}\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<Skeleton className=\"h-9 w-64\" />\n\t\t\t\t\t<Skeleton className=\"h-9 w-24\" />\n\t\t\t\t\t<Skeleton className=\"h-9 w-24\" />\n\t\t\t\t</div>\n\n\t\t\t\t{/* Table */}\n\t\t\t\t<div className=\"rounded-md border\">\n\t\t\t\t\t{/* Header row */}\n\t\t\t\t\t<div className=\"flex items-center gap-4 p-4 border-b bg-muted/50\">\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-4\" />\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-32\" />\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-20 ml-auto\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* Data rows */}\n\t\t\t\t\t<TableSkeletonRow />\n\t\t\t\t\t<TableSkeletonRow />\n\t\t\t\t\t<TableSkeletonRow />\n\t\t\t\t\t<TableSkeletonRow />\n\t\t\t\t\t<TableSkeletonRow isLast />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n/**\n * Skeleton for FormView\n *\n * Shows a loading state that mimics the form layout.\n */\nexport function FormViewSkeleton() {\n\treturn (\n\t\t<div className=\"container max-w-4xl py-6\">\n\t\t\t<div className=\"space-y-6\">\n\t\t\t\t{/* Header */}\n\t\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t\t\t<Skeleton className=\"h-8 w-8 rounded-md\" /> {/* Back button */}\n\t\t\t\t\t\t<Skeleton className=\"h-8 w-48\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t<Skeleton className=\"h-9 w-20\" />\n\t\t\t\t\t\t<Skeleton className=\"h-9 w-24\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Form fields */}\n\t\t\t\t<div className=\"space-y-6\">\n\t\t\t\t\t<FormFieldSkeleton />\n\t\t\t\t\t<FormFieldSkeleton />\n\t\t\t\t\t<FormFieldSkeleton />\n\t\t\t\t\t<FormFieldSkeleton />\n\n\t\t\t\t\t{/* Textarea field */}\n\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-32\" />\n\t\t\t\t\t\t<Skeleton className=\"h-32 w-full\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n/**\n * Skeleton for RichTextEditor\n *\n * Shows a loading state that mimics the rich text editor.\n */\nexport function RichTextEditorSkeleton() {\n\treturn (\n\t\t<div className=\"space-y-2\">\n\t\t\t{/* Toolbar */}\n\t\t\t<div className=\"flex items-center gap-1 p-2 border rounded-t-md bg-muted/30\">\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t\t<ToolbarIconSkeleton />\n\t\t\t</div>\n\t\t\t{/* Content area */}\n\t\t\t<div className=\"border border-t-0 rounded-b-md p-4 min-h-[200px]\">\n\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t<ContentLineSkeleton width=\"w-full\" />\n\t\t\t\t\t<ContentLineSkeleton width=\"w-3/4\" />\n\t\t\t\t\t<ContentLineSkeleton width=\"w-5/6\" />\n\t\t\t\t\t<ContentLineSkeleton width=\"w-2/3\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;;AASA,SAAS,iBAAiB,EAAE,SAAS,SAA+B;AACnE,QACC,qBAAC;EAAI,WAAW,+BAA+B,SAAS,KAAK;;GAC5D,oBAAC,YAAS,WAAU,YAAY;GAChC,oBAAC,YAAS,WAAU,aAAa;GACjC,oBAAC,YAAS,WAAU,aAAa;GACjC,oBAAC,YAAS,WAAU,aAAa;GACjC,oBAAC,YAAS,WAAU,qBAAqB;;GACpC;;AAIR,SAAS,oBAAoB;AAC5B,QACC,qBAAC;EAAI,WAAU;aACd,oBAAC,YAAS,WAAU,aAAa,EACjC,oBAAC,YAAS,WAAU,gBAAgB;GAC/B;;;;;;;AAiBR,SAAgB,oBAAoB;AACnC,QACC,oBAAC;EAAI,WAAU;YACd,qBAAC;GAAI,WAAU;;IAEd,qBAAC;KAAI,WAAU;gBACd,qBAAC;MAAI,WAAU;iBACd,oBAAC,YAAS,WAAU,aAAa,EACjC,oBAAC,YAAS,WAAU,aAAa;OAC5B,EACN,oBAAC,YAAS,WAAU,aAAa;MAC5B;IAGN,qBAAC;KAAI,WAAU;;MACd,oBAAC,YAAS,WAAU,aAAa;MACjC,oBAAC,YAAS,WAAU,aAAa;MACjC,oBAAC,YAAS,WAAU,aAAa;;MAC5B;IAGN,qBAAC;KAAI,WAAU;;MAEd,qBAAC;OAAI,WAAU;;QACd,oBAAC,YAAS,WAAU,YAAY;QAChC,oBAAC,YAAS,WAAU,aAAa;QACjC,oBAAC,YAAS,WAAU,aAAa;QACjC,oBAAC,YAAS,WAAU,aAAa;QACjC,oBAAC,YAAS,WAAU,qBAAqB;;QACpC;MAEN,oBAAC,qBAAmB;MACpB,oBAAC,qBAAmB;MACpB,oBAAC,qBAAmB;MACpB,oBAAC,qBAAmB;MACpB,oBAAC,oBAAiB,eAAS;;MACtB;;IACD;GACD;;;;;;;AASR,SAAgB,mBAAmB;AAClC,QACC,oBAAC;EAAI,WAAU;YACd,qBAAC;GAAI,WAAU;cAEd,qBAAC;IAAI,WAAU;eACd,qBAAC;KAAI,WAAU;;MACd,oBAAC,YAAS,WAAU,uBAAuB;;MAC3C,oBAAC,YAAS,WAAU,aAAa;;MAC5B,EACN,qBAAC;KAAI,WAAU;gBACd,oBAAC,YAAS,WAAU,aAAa,EACjC,oBAAC,YAAS,WAAU,aAAa;MAC5B;KACD,EAGN,qBAAC;IAAI,WAAU;;KACd,oBAAC,sBAAoB;KACrB,oBAAC,sBAAoB;KACrB,oBAAC,sBAAoB;KACrB,oBAAC,sBAAoB;KAGrB,qBAAC;MAAI,WAAU;iBACd,oBAAC,YAAS,WAAU,aAAa,EACjC,oBAAC,YAAS,WAAU,gBAAgB;OAC/B;;KACD;IACD;GACD"}
@@ -1 +0,0 @@
1
- import "react/jsx-runtime";
@@ -1 +0,0 @@
1
- {"version":3,"file":"global-search.mjs","names":["items: SearchItem[]"],"sources":["../../../../src/client/views/common/global-search.tsx"],"sourcesContent":["/**\n * Global Search\n *\n * Fast navigation to collections, globals, quick actions, AND actual records.\n * Uses ResponsiveDialog for desktop (Dialog) and mobile (fullscreen Drawer).\n *\n * Features:\n * - Navigation items: Collections, globals, create actions (client-side filter)\n * - Record search: Full-text search across ALL collections (server-side)\n * - Keyboard navigation: ↑↓ arrows, Enter to select, Esc to close\n * - Highlights: Shows search term highlighted in record titles\n */\n\nimport { Icon } from \"@iconify/react\";\nimport type * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ComponentReference } from \"#questpie/admin/server\";\nimport { resolveIconElement } from \"../../components/component-renderer\";\nimport { Kbd } from \"../../components/ui/kbd\";\nimport {\n\tResponsiveDialog,\n\tResponsiveDialogContent,\n} from \"../../components/ui/responsive-dialog\";\nimport { useAdminConfig } from \"../../hooks/use-admin-config\";\nimport { useDebouncedValue, useGlobalSearch } from \"../../hooks/use-search\";\nimport { useResolveText, useTranslation } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { selectBasePath, useAdminStore } from \"../../runtime\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface SearchItem {\n\tid: string;\n\ttype: \"collection\" | \"global\" | \"action\" | \"record\";\n\tlabel: string;\n\tsublabel?: string;\n\thref: string;\n\ticon?:\n\t\t| ComponentReference\n\t\t| React.ComponentType<{ className?: string }>\n\t\t| string;\n\tkeywords?: string[];\n\thighlights?: { title?: string };\n}\n\nexport interface GlobalSearchProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tnavigate: (path: string) => void;\n\tbasePath?: string;\n}\n\n// ============================================================================\n// Default Icon Names (for resolveIconElement)\n// ============================================================================\n\nconst DEFAULT_FOLDER_ICON = \"ph:folder\";\nconst DEFAULT_GEAR_ICON = \"ph:gear\";\nconst DEFAULT_PLUS_ICON = \"ph:plus\";\nconst DEFAULT_FILE_ICON = \"ph:file\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Extract typed props from server config entries (collections/globals).\n * Server config entries come as plain objects without strict typing.\n */\nfunction getConfigProps(config: unknown) {\n\tconst c = config as Record<string, any>;\n\treturn {\n\t\tlabel: c?.label as string | undefined,\n\t\ticon: c?.icon as ComponentReference | undefined,\n\t\thidden: c?.hidden as boolean | undefined,\n\t};\n}\n\n/**\n * Simple fuzzy search - matches if query words appear anywhere in text\n */\nfunction fuzzyMatch(text: string, query: string): boolean {\n\tconst textLower = text.toLowerCase();\n\tconst queryWords = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n\treturn queryWords.every((word) => textLower.includes(word));\n}\n\n/**\n * Search and filter items based on query\n */\nfunction filterItems(items: SearchItem[], query: string): SearchItem[] {\n\tif (!query.trim()) return items;\n\n\treturn items.filter((item) => {\n\t\t// Match against label\n\t\tif (fuzzyMatch(item.label, query)) return true;\n\n\t\t// Match against keywords\n\t\tif (item.keywords?.some((kw) => fuzzyMatch(kw, query))) return true;\n\n\t\treturn false;\n\t});\n}\n\n// ============================================================================\n// Search Group Component\n// ============================================================================\n\ninterface SearchGroupProps {\n\ttitle: string;\n\titems: SearchItem[];\n\tselectedIndex: number;\n\tstartIndex: number;\n\tonSelect: (item: SearchItem) => void;\n\tonHover: (index: number) => void;\n}\n\nfunction SearchGroup({\n\ttitle,\n\titems,\n\tselectedIndex,\n\tstartIndex,\n\tonSelect,\n\tonHover,\n}: SearchGroupProps) {\n\tconst resolveText = useResolveText();\n\n\tif (items.length === 0) return null;\n\n\treturn (\n\t\t<div className=\"mb-4 last:mb-0\">\n\t\t\t<h3 className=\"mb-2 px-2 font-mono text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground\">\n\t\t\t\t{resolveText(title)}\n\t\t\t</h3>\n\t\t\t<div className=\"space-y-0.5\">\n\t\t\t\t{items.map((item, idx) => {\n\t\t\t\t\tconst globalIndex = startIndex + idx;\n\t\t\t\t\tconst isSelected = globalIndex === selectedIndex;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => onSelect(item)}\n\t\t\t\t\t\t\tonMouseEnter={() => onHover(globalIndex)}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex w-full items-center gap-3 px-3 py-2.5 text-sm outline-none transition-colors rounded-md\",\n\t\t\t\t\t\t\t\tisSelected\n\t\t\t\t\t\t\t\t\t? \"bg-accent text-accent-foreground\"\n\t\t\t\t\t\t\t\t\t: \"hover:bg-accent/50 hover:text-accent-foreground\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{item.icon && (\n\t\t\t\t\t\t\t\t<span className=\"h-4 w-4 text-muted-foreground shrink-0 flex items-center justify-center\">\n\t\t\t\t\t\t\t\t\t{resolveIconElement(item.icon, { className: \"h-4 w-4\" })}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<div className=\"flex flex-col items-start min-w-0\">\n\t\t\t\t\t\t\t\t{item.highlights?.title ? (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclassName=\"truncate\"\n\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/security/noDangerouslySetInnerHtml: highlights from server\n\t\t\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: item.highlights.title }}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{resolveText(item.label)}</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{item.sublabel && (\n\t\t\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground truncate\">\n\t\t\t\t\t\t\t\t\t\t{item.sublabel}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function GlobalSearch({\n\tisOpen,\n\tonClose,\n\tnavigate,\n\tbasePath: basePathProp,\n}: GlobalSearchProps) {\n\tconst { t } = useTranslation();\n\tconst resolveText = useResolveText();\n\n\t// Get admin config from server\n\tconst { data: serverConfig } = useAdminConfig();\n\tconst storeBasePath = useAdminStore(selectBasePath);\n\tconst basePath = basePathProp ?? storeBasePath ?? \"/admin\";\n\n\t// Search state\n\tconst [query, setQuery] = useState(\"\");\n\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\n\t// Debounce query for record search (300ms)\n\tconst debouncedQuery = useDebouncedValue(query, 300);\n\n\t// Fetch records from search API\n\tconst { data: searchResults, isLoading: isSearching } = useGlobalSearch({\n\t\tquery: debouncedQuery,\n\t\tlimit: 10,\n\t\tenabled: debouncedQuery.trim().length >= 2,\n\t});\n\n\t// Build navigation items from server config\n\t// Note: Server already filters by access rules, we only need to filter by hidden flag\n\tconst navItems = useMemo(() => {\n\t\tconst items: SearchItem[] = [];\n\t\tconst collections = serverConfig?.collections ?? {};\n\t\tconst globals = serverConfig?.globals ?? {};\n\n\t\t// Add visible collections (not hidden in admin)\n\t\tfor (const [name, config] of Object.entries(collections)) {\n\t\t\tconst { label: rawLabel, icon, hidden } = getConfigProps(config);\n\t\t\t// Skip hidden collections\n\t\t\tif (hidden) continue;\n\n\t\t\tconst label = resolveText(rawLabel, name);\n\t\t\titems.push({\n\t\t\t\tid: `col-${name}`,\n\t\t\t\ttype: \"collection\",\n\t\t\t\tlabel,\n\t\t\t\thref: `${basePath}/collections/${name}`,\n\t\t\t\ticon: icon ?? DEFAULT_FOLDER_ICON,\n\t\t\t\tkeywords: [name, \"collection\", \"list\"],\n\t\t\t});\n\t\t}\n\n\t\t// Add visible globals (not hidden in admin)\n\t\tfor (const [name, config] of Object.entries(globals)) {\n\t\t\tconst { label: rawLabel, icon, hidden } = getConfigProps(config);\n\t\t\t// Skip hidden globals\n\t\t\tif (hidden) continue;\n\n\t\t\tconst label = resolveText(rawLabel, name);\n\t\t\titems.push({\n\t\t\t\tid: `glob-${name}`,\n\t\t\t\ttype: \"global\",\n\t\t\t\tlabel,\n\t\t\t\thref: `${basePath}/globals/${name}`,\n\t\t\t\ticon: icon ?? DEFAULT_GEAR_ICON,\n\t\t\t\tkeywords: [name, \"global\", \"settings\", \"config\"],\n\t\t\t});\n\t\t}\n\n\t\t// Add quick actions (create new) only for visible collections\n\t\tfor (const [name, config] of Object.entries(collections)) {\n\t\t\tconst {\n\t\t\t\tlabel: rawLabel,\n\t\t\t\ticon: collectionIcon,\n\t\t\t\thidden,\n\t\t\t} = getConfigProps(config);\n\t\t\t// Skip hidden collections\n\t\t\tif (hidden) continue;\n\n\t\t\tconst label = resolveText(rawLabel, name);\n\t\t\titems.push({\n\t\t\t\tid: `action-create-${name}`,\n\t\t\t\ttype: \"action\",\n\t\t\t\tlabel: t(\"globalSearch.createNew\", { name: label }),\n\t\t\t\thref: `${basePath}/collections/${name}/create`,\n\t\t\t\ticon: collectionIcon ?? DEFAULT_PLUS_ICON,\n\t\t\t\tkeywords: [\"create\", \"new\", \"add\", name],\n\t\t\t});\n\t\t}\n\n\t\treturn items;\n\t}, [serverConfig, basePath, resolveText, t]);\n\n\t// Filter navigation items based on query (client-side)\n\tconst filteredNavItems = useMemo(\n\t\t() => filterItems(navItems, query),\n\t\t[navItems, query],\n\t);\n\n\t// Convert search results to SearchItem format\n\tconst recordItems = useMemo(() => {\n\t\tif (!searchResults?.docs) return [];\n\n\t\tconst collections = serverConfig?.collections ?? {};\n\n\t\treturn searchResults.docs.map((doc): SearchItem => {\n\t\t\tconst collectionName = doc._collection;\n\t\t\tconst collectionConfig = collections[collectionName];\n\t\t\tconst { label: rawLabel, icon: configIcon } =\n\t\t\t\tgetConfigProps(collectionConfig);\n\t\t\tconst collectionLabel = resolveText(rawLabel, collectionName);\n\t\t\tconst icon = configIcon ?? DEFAULT_FILE_ICON;\n\n\t\t\treturn {\n\t\t\t\tid: `record-${collectionName}-${doc.id}`,\n\t\t\t\ttype: \"record\",\n\t\t\t\tlabel: doc._search?.indexedTitle || doc.id,\n\t\t\t\tsublabel: collectionLabel,\n\t\t\t\thref: `${basePath}/collections/${collectionName}/${doc.id}`,\n\t\t\t\ticon,\n\t\t\t\thighlights: doc._search?.highlights,\n\t\t\t};\n\t\t});\n\t}, [searchResults, serverConfig, basePath, resolveText]);\n\n\t// Group navigation items by type\n\tconst groupedNavItems = useMemo(() => {\n\t\treturn {\n\t\t\tcollections: filteredNavItems.filter((i) => i.type === \"collection\"),\n\t\t\tglobals: filteredNavItems.filter((i) => i.type === \"global\"),\n\t\t\tactions: filteredNavItems.filter((i) => i.type === \"action\"),\n\t\t};\n\t}, [filteredNavItems]);\n\n\t// Calculate total count and indices\n\tconst allItems = useMemo(() => {\n\t\treturn [\n\t\t\t...groupedNavItems.collections,\n\t\t\t...groupedNavItems.globals,\n\t\t\t...groupedNavItems.actions,\n\t\t\t...recordItems,\n\t\t];\n\t}, [groupedNavItems, recordItems]);\n\n\tconst totalCount = allItems.length;\n\tconst collectionsStartIndex = 0;\n\tconst globalsStartIndex = groupedNavItems.collections.length;\n\tconst actionsStartIndex =\n\t\tgroupedNavItems.collections.length + groupedNavItems.globals.length;\n\tconst recordsStartIndex =\n\t\tgroupedNavItems.collections.length +\n\t\tgroupedNavItems.globals.length +\n\t\tgroupedNavItems.actions.length;\n\n\t// Reset selected index when query changes\n\tuseEffect(() => {\n\t\tsetSelectedIndex(0);\n\t}, [query]);\n\n\t// Reset state when dialog opens\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tsetQuery(\"\");\n\t\t\tsetSelectedIndex(0);\n\t\t\t// Focus input after a small delay to ensure dialog is rendered\n\t\t\tsetTimeout(() => inputRef.current?.focus(), 50);\n\t\t}\n\t}, [isOpen]);\n\n\t// Handle selection\n\tconst handleSelect = useCallback(\n\t\t(item: SearchItem) => {\n\t\t\tnavigate(item.href);\n\t\t\tonClose();\n\t\t},\n\t\t[navigate, onClose],\n\t);\n\n\t// Handle keyboard navigation\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tswitch (e.key) {\n\t\t\t\tcase \"ArrowDown\":\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tsetSelectedIndex((i) => Math.min(i + 1, totalCount - 1));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ArrowUp\":\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tsetSelectedIndex((i) => Math.max(i - 1, 0));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"Enter\":\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (allItems[selectedIndex]) {\n\t\t\t\t\t\thandleSelect(allItems[selectedIndex]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"Escape\":\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tonClose();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t\t[allItems, selectedIndex, totalCount, handleSelect, onClose],\n\t);\n\n\tconst handleHover = useCallback((index: number) => {\n\t\tsetSelectedIndex(index);\n\t}, []);\n\n\tconst hasNavResults =\n\t\tgroupedNavItems.collections.length > 0 ||\n\t\tgroupedNavItems.globals.length > 0 ||\n\t\tgroupedNavItems.actions.length > 0;\n\n\tconst hasRecordResults = recordItems.length > 0;\n\tconst hasResults = hasNavResults || hasRecordResults;\n\n\treturn (\n\t\t<ResponsiveDialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n\t\t\t<ResponsiveDialogContent className=\"p-0 gap-0 max-w-2xl\">\n\t\t\t\t{/* Search Input */}\n\t\t\t\t<div className=\"flex items-center border-b px-3\">\n\t\t\t\t\t<Icon\n\t\t\t\t\t\ticon=\"ph:magnifying-glass\"\n\t\t\t\t\t\tclassName=\"mr-2 h-5 w-5 text-muted-foreground shrink-0\"\n\t\t\t\t\t/>\n\t\t\t\t\t<input\n\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\tclassName=\"flex h-14 w-full rounded-none bg-transparent py-3 text-base outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n\t\t\t\t\t\tplaceholder={t(\"globalSearch.placeholder\")}\n\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\tonChange={(e) => setQuery(e.target.value)}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"flex items-center gap-1 shrink-0\">\n\t\t\t\t\t\t{isSearching && (\n\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\ticon=\"ph:spinner\"\n\t\t\t\t\t\t\t\tclassName=\"h-4 w-4 animate-spin text-muted-foreground\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Kbd>ESC</Kbd>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Results */}\n\t\t\t\t<div className=\"max-h-[60vh] overflow-y-auto p-2\">\n\t\t\t\t\t{hasResults ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{/* Navigation Groups */}\n\t\t\t\t\t\t\t<SearchGroup\n\t\t\t\t\t\t\t\ttitle={t(\"globalSearch.collections\")}\n\t\t\t\t\t\t\t\titems={groupedNavItems.collections}\n\t\t\t\t\t\t\t\tselectedIndex={selectedIndex}\n\t\t\t\t\t\t\t\tstartIndex={collectionsStartIndex}\n\t\t\t\t\t\t\t\tonSelect={handleSelect}\n\t\t\t\t\t\t\t\tonHover={handleHover}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<SearchGroup\n\t\t\t\t\t\t\t\ttitle={t(\"globalSearch.globals\")}\n\t\t\t\t\t\t\t\titems={groupedNavItems.globals}\n\t\t\t\t\t\t\t\tselectedIndex={selectedIndex}\n\t\t\t\t\t\t\t\tstartIndex={globalsStartIndex}\n\t\t\t\t\t\t\t\tonSelect={handleSelect}\n\t\t\t\t\t\t\t\tonHover={handleHover}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<SearchGroup\n\t\t\t\t\t\t\t\ttitle={t(\"globalSearch.quickActions\")}\n\t\t\t\t\t\t\t\titems={groupedNavItems.actions}\n\t\t\t\t\t\t\t\tselectedIndex={selectedIndex}\n\t\t\t\t\t\t\t\tstartIndex={actionsStartIndex}\n\t\t\t\t\t\t\t\tonSelect={handleSelect}\n\t\t\t\t\t\t\t\tonHover={handleHover}\n\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t{/* Record Results */}\n\t\t\t\t\t\t\t{hasRecordResults && (\n\t\t\t\t\t\t\t\t<SearchGroup\n\t\t\t\t\t\t\t\t\ttitle={t(\"globalSearch.records\")}\n\t\t\t\t\t\t\t\t\titems={recordItems}\n\t\t\t\t\t\t\t\t\tselectedIndex={selectedIndex}\n\t\t\t\t\t\t\t\t\tstartIndex={recordsStartIndex}\n\t\t\t\t\t\t\t\t\tonSelect={handleSelect}\n\t\t\t\t\t\t\t\t\tonHover={handleHover}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"py-8 text-center text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t{isSearching ? (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-center gap-2\">\n\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:spinner\" className=\"h-4 w-4 animate-spin\" />\n\t\t\t\t\t\t\t\t\t<span>{t(\"globalSearch.searching\")}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tt(\"globalSearch.noResults\")\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{/* Footer with keyboard hints */}\n\t\t\t\t<div className=\"border-t px-3 py-2 flex items-center justify-end gap-4 text-xs text-muted-foreground\">\n\t\t\t\t\t<span className=\"flex items-center gap-1\">\n\t\t\t\t\t\t<Kbd className=\"text-[10px] px-1\">↑</Kbd>\n\t\t\t\t\t\t<Kbd className=\"text-[10px] px-1\">↓</Kbd>\n\t\t\t\t\t\t<span>{t(\"globalSearch.navigate\")}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"flex items-center gap-1\">\n\t\t\t\t\t\t<Kbd className=\"text-[10px] px-1.5\">↵</Kbd>\n\t\t\t\t\t\t<span>{t(\"globalSearch.select\")}</span>\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</ResponsiveDialogContent>\n\t\t</ResponsiveDialog>\n\t);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- import "./global-search.mjs";
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-grid.mjs","names":["gridClasses: Record<number, string>","spanClasses: Record<number, string>"],"sources":["../../../../src/client/views/dashboard/dashboard-grid.tsx"],"sourcesContent":["/**\n * DashboardGrid Component\n *\n * Renders a grid of dashboard widgets based on configuration.\n * Supports:\n * - Responsive layouts with container queries\n * - Widget spanning\n * - Dashboard sections (grouped widgets)\n * - Dashboard tabs (tabbed widget groups)\n * - Recursive nesting of sections/tabs\n */\n\nimport { Icon } from \"@iconify/react\";\nimport type * as React from \"react\";\nimport type {\n\tAnyWidgetConfig,\n\tDashboardAction,\n\tDashboardConfig,\n\tDashboardLayoutItem,\n\tDashboardSection,\n\tDashboardTabConfig,\n\tDashboardTabs,\n\tWidgetComponentProps,\n\tWidgetConfig,\n} from \"../../builder\";\nimport { resolveIconElement } from \"../../components/component-renderer\";\nimport {\n\tAccordion,\n\tAccordionContent,\n\tAccordionItem,\n\tAccordionTrigger,\n} from \"../../components/ui/accordion\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n\tCard,\n\tCardContent,\n\tCardHeader,\n\tCardTitle,\n} from \"../../components/ui/card\";\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n} from \"../../components/ui/dropdown-menu\";\nimport {\n\tTabs,\n\tTabsContent,\n\tTabsList,\n\tTabsTrigger,\n} from \"../../components/ui/tabs\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { DashboardWidget } from \"./dashboard-widget\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardGridProps {\n\t/**\n\t * Dashboard configuration\n\t */\n\tconfig: DashboardConfig;\n\n\t/**\n\t * Base path for navigation links (default: \"/admin\")\n\t */\n\tbasePath?: string;\n\n\t/**\n\t * Navigate function for item clicks\n\t */\n\tnavigate?: (path: string) => void;\n\n\t/**\n\t * Custom widget registry for overrides\n\t */\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n\n\t/**\n\t * Additional CSS class\n\t */\n\tclassName?: string;\n}\n\n// ============================================================================\n// Grid Classes - Using Container Queries\n// ============================================================================\n\n/**\n * Grid column classes for different column counts\n * Uses container queries (@container) for responsive behavior\n */\nconst gridClasses: Record<number, string> = {\n\t1: \"grid-cols-1\",\n\t2: \"grid-cols-1 @xs:grid-cols-2\",\n\t3: \"grid-cols-1 @xs:grid-cols-2 @md:grid-cols-3\",\n\t4: \"grid-cols-1 @xs:grid-cols-2 @md:grid-cols-3 @lg:grid-cols-4\",\n\t5: \"grid-cols-1 @xs:grid-cols-2 @sm:grid-cols-3 @md:grid-cols-4 @lg:grid-cols-5\",\n\t6: \"grid-cols-1 @xs:grid-cols-2 @sm:grid-cols-3 @md:grid-cols-4 @lg:grid-cols-5 @xl:grid-cols-6\",\n\t12: \"grid-cols-1 @xs:grid-cols-2 @sm:grid-cols-4 @md:grid-cols-6 @lg:grid-cols-12\",\n};\n\n/**\n * Span classes for widget column spanning\n * - span:1 widgets can be 2x2 on @xs (half width each)\n * - span:2+ widgets are full width on mobile/tablet, then expand at larger breakpoints\n */\nconst spanClasses: Record<number, string> = {\n\t1: \"col-span-1\",\n\t2: \"col-span-full @sm:col-span-2\",\n\t3: \"col-span-full @sm:col-span-2 @md:col-span-3\",\n\t4: \"col-span-full @sm:col-span-2 @md:col-span-3 @lg:col-span-4\",\n\t5: \"col-span-full @sm:col-span-2 @md:col-span-3 @lg:col-span-5\",\n\t6: \"col-span-full @sm:col-span-2 @md:col-span-3 @lg:col-span-6\",\n\t12: \"col-span-full\",\n};\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get grid columns class based on column count\n */\nfunction getGridClass(columns: number): string {\n\treturn gridClasses[columns] || gridClasses[4];\n}\n\n/**\n * Get column span class for a widget.\n * Returns responsive span classes that gracefully collapse on smaller screens.\n * For custom responsive behavior, use className prop directly.\n */\nfunction getSpanClass(span: number | undefined): string {\n\tif (!span || span <= 1) return \"col-span-1\";\n\tif (spanClasses[span]) return spanClasses[span];\n\n\t// Generate responsive classes for spans not in the map (7-11)\n\t// Progressive collapse: full span at lg+, 3 at md, 2 at xs, 1 on mobile\n\tif (span >= 7 && span <= 11) {\n\t\treturn `col-span-1 @xs:col-span-2 @md:col-span-3 @lg:col-span-${span}`;\n\t}\n\n\t// Fallback for any other value\n\treturn `col-span-${Math.min(span, 12)}`;\n}\n\n/**\n * Check if item is a widget config\n */\nfunction isWidgetConfig(item: DashboardLayoutItem): item is WidgetConfig {\n\treturn (\n\t\ttypeof item === \"object\" &&\n\t\t\"type\" in item &&\n\t\titem.type !== \"section\" &&\n\t\titem.type !== \"tabs\"\n\t);\n}\n\n/**\n * Check if item is a section config\n */\nfunction isSectionConfig(item: DashboardLayoutItem): item is DashboardSection {\n\treturn typeof item === \"object\" && \"type\" in item && item.type === \"section\";\n}\n\n/**\n * Check if item is a tabs config\n */\nfunction isTabsConfig(item: DashboardLayoutItem): item is DashboardTabs {\n\treturn typeof item === \"object\" && \"type\" in item && item.type === \"tabs\";\n}\n\n/**\n * Generate a unique key for a layout item\n */\nfunction getLayoutItemKey(item: DashboardLayoutItem, index: number): string {\n\tif (isWidgetConfig(item)) {\n\t\treturn `widget-${item.id || item.type}-${index}`;\n\t}\n\tif (isSectionConfig(item)) {\n\t\treturn `section-${index}`;\n\t}\n\tif (isTabsConfig(item)) {\n\t\tconst tabIds = item.tabs.map((t) => t.id).join(\"-\");\n\t\treturn `tabs-${tabIds || index}`;\n\t}\n\treturn `item-${index}`;\n}\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\ninterface DashboardHeaderProps {\n\ttitle?: string;\n\tdescription?: string;\n\tactions?: DashboardAction[];\n\tnavigate?: (path: string) => void;\n\tresolveText: (text: any) => string;\n}\n\nfunction DashboardHeader({\n\ttitle,\n\tdescription,\n\tactions,\n\tnavigate,\n\tresolveText,\n}: DashboardHeaderProps) {\n\tif (!title && !description && !actions?.length) return null;\n\n\tconst handleActionClick = (action: DashboardAction) => {\n\t\tif (action.onClick) {\n\t\t\taction.onClick();\n\t\t} else if (action.href && navigate) {\n\t\t\tnavigate(action.href);\n\t\t}\n\t};\n\n\t// Split actions: primary (first with variant=primary or first action) shown as button\n\t// Rest go into dropdown on mobile, all visible on desktop\n\tconst primaryAction =\n\t\tactions?.find((a) => a.variant === \"primary\") || actions?.[0];\n\tconst secondaryActions = actions?.filter((a) => a !== primaryAction) || [];\n\n\treturn (\n\t\t<div className=\"mb-8 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t{title && (\n\t\t\t\t\t<h1 className=\"text-2xl md:text-3xl font-extrabold tracking-tight\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h1>\n\t\t\t\t)}\n\t\t\t\t{description && (\n\t\t\t\t\t<p className=\"mt-1 text-muted-foreground\">{description}</p>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{actions && actions.length > 0 && (\n\t\t\t\t<div className=\"flex items-center gap-2 shrink-0\">\n\t\t\t\t\t{/* Primary action always visible */}\n\t\t\t\t\t{primaryAction && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tkey={primaryAction.id}\n\t\t\t\t\t\t\tvariant={\n\t\t\t\t\t\t\t\tprimaryAction.variant === \"primary\"\n\t\t\t\t\t\t\t\t\t? \"default\"\n\t\t\t\t\t\t\t\t\t: primaryAction.variant || \"default\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonClick={() => handleActionClick(primaryAction)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{resolveIconElement(primaryAction.icon, {\n\t\t\t\t\t\t\t\t\"data-icon\": \"inline-start\",\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t{resolveText(primaryAction.label)}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Secondary actions: visible on md+, hidden on mobile */}\n\t\t\t\t\t{secondaryActions.map((action) => {\n\t\t\t\t\t\tconst iconElement = resolveIconElement(action.icon, {\n\t\t\t\t\t\t\t\"data-icon\": \"inline-start\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst variant = action.variant || \"default\";\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tkey={action.id}\n\t\t\t\t\t\t\t\tvariant={variant === \"primary\" ? \"default\" : variant}\n\t\t\t\t\t\t\t\tonClick={() => handleActionClick(action)}\n\t\t\t\t\t\t\t\tclassName=\"hidden md:inline-flex\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{iconElement}\n\t\t\t\t\t\t\t\t{resolveText(action.label)}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\n\t\t\t\t\t{/* Dropdown for secondary actions on mobile */}\n\t\t\t\t\t{secondaryActions.length > 0 && (\n\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t<DropdownMenuTrigger\n\t\t\t\t\t\t\t\trender={\n\t\t\t\t\t\t\t\t\t<Button variant=\"outline\" size=\"icon\" className=\"md:hidden\">\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:dots-three-vertical\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t{secondaryActions.map((action) => (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\tkey={action.id}\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleActionClick(action)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{resolveIconElement(action.icon, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: \"size-4 mr-2\",\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t{resolveText(action.label)}\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ============================================================================\n// Layout Item Renderer\n// ============================================================================\n\ninterface LayoutItemRendererProps {\n\titem: DashboardLayoutItem;\n\tindex: number;\n\tcolumns: number;\n\tbasePath: string;\n\tnavigate?: (path: string) => void;\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n\tresolveText: (text: any) => string;\n\tdashboardRealtime?: boolean;\n}\n\nfunction LayoutItemRenderer({\n\titem,\n\tindex,\n\tcolumns,\n\tbasePath,\n\tnavigate,\n\twidgetRegistry,\n\tresolveText,\n\tdashboardRealtime,\n}: LayoutItemRendererProps) {\n\t// Widget\n\tif (isWidgetConfig(item)) {\n\t\tconst spanClass = getSpanClass(item.span);\n\t\tconst widgetConfig =\n\t\t\tdashboardRealtime !== undefined && item.realtime === undefined\n\t\t\t\t? ({ ...item, realtime: dashboardRealtime } as AnyWidgetConfig)\n\t\t\t\t: item;\n\t\treturn (\n\t\t\t<div className={cn(\"min-h-0 h-full\", spanClass, item.className)}>\n\t\t\t\t<DashboardWidget\n\t\t\t\t\tconfig={widgetConfig}\n\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Section\n\tif (isSectionConfig(item)) {\n\t\treturn (\n\t\t\t<SectionRenderer\n\t\t\t\tkey={`section-${index}`}\n\t\t\t\tsection={item}\n\t\t\t\tbasePath={basePath}\n\t\t\t\tnavigate={navigate}\n\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\tresolveText={resolveText}\n\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// Tabs\n\tif (isTabsConfig(item)) {\n\t\treturn (\n\t\t\t<TabsRenderer\n\t\t\t\tkey={`tabs-${index}`}\n\t\t\t\ttabs={item}\n\t\t\t\tbasePath={basePath}\n\t\t\t\tnavigate={navigate}\n\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\tresolveText={resolveText}\n\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn null;\n}\n\n// ============================================================================\n// Section Renderer\n// ============================================================================\n\ninterface SectionRendererProps {\n\tsection: DashboardSection;\n\tbasePath: string;\n\tnavigate?: (path: string) => void;\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n\tresolveText: (text: any) => string;\n\tdashboardRealtime?: boolean;\n}\n\nfunction SectionRenderer({\n\tsection,\n\tbasePath,\n\tnavigate,\n\twidgetRegistry,\n\tresolveText,\n\tdashboardRealtime,\n}: SectionRendererProps) {\n\tconst {\n\t\tlabel,\n\t\tdescription,\n\t\twrapper = \"flat\",\n\t\tdefaultCollapsed = false,\n\t\tlayout = \"grid\",\n\t\tcolumns = 4,\n\t\tgap,\n\t\titems,\n\t\tclassName,\n\t} = section;\n\n\tconst sectionLabel = label ? resolveText(label) : undefined;\n\tconst sectionDescription = description ? resolveText(description) : undefined;\n\n\t// Render items grid with container queries\n\tconst itemsContent = (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"@container\",\n\t\t\t\tlayout === \"grid\" && \"grid gap-4 items-stretch\",\n\t\t\t\tlayout === \"grid\" && getGridClass(columns),\n\t\t\t\tlayout === \"stack\" && \"flex flex-col gap-4\",\n\t\t\t)}\n\t\t\tstyle={gap ? { gap: `${gap * 0.25}rem` } : undefined}\n\t\t>\n\t\t\t{items.map((item, index) => (\n\t\t\t\t<LayoutItemRenderer\n\t\t\t\t\tkey={getLayoutItemKey(item, index)}\n\t\t\t\t\titem={item}\n\t\t\t\t\tindex={index}\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\t\tresolveText={resolveText}\n\t\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t);\n\n\t// Flat wrapper (just label + content)\n\tif (wrapper === \"flat\") {\n\t\treturn (\n\t\t\t<div className={cn(\"col-span-full\", className)}>\n\t\t\t\t{(sectionLabel || sectionDescription) && (\n\t\t\t\t\t<div className=\"mb-4\">\n\t\t\t\t\t\t{sectionLabel && (\n\t\t\t\t\t\t\t<h2 className=\"text-lg font-semibold\">{sectionLabel}</h2>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{sectionDescription && (\n\t\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground mt-1\">\n\t\t\t\t\t\t\t\t{sectionDescription}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{itemsContent}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Card wrapper\n\tif (wrapper === \"card\") {\n\t\treturn (\n\t\t\t<Card className={cn(\"col-span-full\", className)}>\n\t\t\t\t{(sectionLabel || sectionDescription) && (\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t{sectionLabel && <CardTitle>{sectionLabel}</CardTitle>}\n\t\t\t\t\t\t{sectionDescription && (\n\t\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t{sectionDescription}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</CardHeader>\n\t\t\t\t)}\n\t\t\t\t<CardContent>{itemsContent}</CardContent>\n\t\t\t</Card>\n\t\t);\n\t}\n\n\t// Collapsible wrapper\n\tif (wrapper === \"collapsible\") {\n\t\treturn (\n\t\t\t<Accordion\n\t\t\t\tdefaultValue={defaultCollapsed ? [] : [0]}\n\t\t\t\tclassName={cn(\"col-span-full\", className)}\n\t\t\t>\n\t\t\t\t<AccordionItem className=\"border-none\">\n\t\t\t\t\t<AccordionTrigger className=\"hover:no-underline py-2\">\n\t\t\t\t\t\t<div className=\"text-left\">\n\t\t\t\t\t\t\t{sectionLabel && (\n\t\t\t\t\t\t\t\t<span className=\"text-lg font-semibold\">{sectionLabel}</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{sectionDescription && (\n\t\t\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground font-normal\">\n\t\t\t\t\t\t\t\t\t{sectionDescription}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</AccordionTrigger>\n\t\t\t\t\t<AccordionContent className=\"pt-4\">{itemsContent}</AccordionContent>\n\t\t\t\t</AccordionItem>\n\t\t\t</Accordion>\n\t\t);\n\t}\n\n\treturn itemsContent;\n}\n\n// ============================================================================\n// Tabs Renderer\n// ============================================================================\n\ninterface TabsRendererProps {\n\ttabs: DashboardTabs;\n\tbasePath: string;\n\tnavigate?: (path: string) => void;\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n\tresolveText: (text: any) => string;\n\tdashboardRealtime?: boolean;\n}\n\nfunction TabsRenderer({\n\ttabs,\n\tbasePath,\n\tnavigate,\n\twidgetRegistry,\n\tresolveText,\n\tdashboardRealtime,\n}: TabsRendererProps) {\n\tconst { tabs: tabConfigs, defaultTab, variant = \"default\" } = tabs;\n\n\tconst defaultValue = defaultTab || tabConfigs[0]?.id;\n\n\treturn (\n\t\t<Tabs defaultValue={defaultValue} className=\"col-span-full\">\n\t\t\t<TabsList\n\t\t\t\tvariant={variant === \"line\" ? \"line\" : \"default\"}\n\t\t\t\tclassName=\"mb-4\"\n\t\t\t>\n\t\t\t\t{tabConfigs.map((tab) => (\n\t\t\t\t\t<TabsTrigger key={tab.id} value={tab.id}>\n\t\t\t\t\t\t{resolveIconElement(tab.icon, {\n\t\t\t\t\t\t\tclassName: \"h-4 w-4 mr-2\",\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{resolveText(tab.label)}\n\t\t\t\t\t\t{tab.badge !== undefined && (\n\t\t\t\t\t\t\t<span className=\"ml-2 rounded-full bg-muted px-2 py-0.5 text-xs\">\n\t\t\t\t\t\t\t\t{tab.badge}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</TabsTrigger>\n\t\t\t\t))}\n\t\t\t</TabsList>\n\n\t\t\t{tabConfigs.map((tab) => (\n\t\t\t\t<TabsContent key={tab.id} value={tab.id}>\n\t\t\t\t\t<TabContentRenderer\n\t\t\t\t\t\ttab={tab}\n\t\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\t\t\tresolveText={resolveText}\n\t\t\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t\t\t/>\n\t\t\t\t</TabsContent>\n\t\t\t))}\n\t\t</Tabs>\n\t);\n}\n\ninterface TabContentRendererProps {\n\ttab: DashboardTabConfig;\n\tbasePath: string;\n\tnavigate?: (path: string) => void;\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n\tresolveText: (text: any) => string;\n\tdashboardRealtime?: boolean;\n}\n\nfunction TabContentRenderer({\n\ttab,\n\tbasePath,\n\tnavigate,\n\twidgetRegistry,\n\tresolveText,\n\tdashboardRealtime,\n}: TabContentRendererProps) {\n\t// Default to 4 columns for tab content\n\tconst columns = 4;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"@container grid gap-4 items-stretch\",\n\t\t\t\tgetGridClass(columns),\n\t\t\t)}\n\t\t>\n\t\t\t{tab.items.map((item, index) => (\n\t\t\t\t<LayoutItemRenderer\n\t\t\t\t\tkey={getLayoutItemKey(item, index)}\n\t\t\t\t\titem={item}\n\t\t\t\t\tindex={index}\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\t\tresolveText={resolveText}\n\t\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * DashboardGrid - Renders a configurable grid of dashboard widgets\n *\n * @example\n * ```tsx\n * const dashboardConfig: DashboardConfig = {\n * title: \"Dashboard\",\n * description: \"Welcome to your admin dashboard\",\n * columns: 4,\n * items: [\n * { type: \"stats\", collection: \"posts\", label: \"Total Posts\", span: 1 },\n * { type: \"stats\", collection: \"users\", label: \"Total Users\", span: 1 },\n * {\n * type: \"section\",\n * label: \"Analytics\",\n * wrapper: \"card\",\n * items: [\n * { type: \"chart\", collection: \"posts\", field: \"createdAt\", span: 2 },\n * ]\n * },\n * {\n * type: \"tabs\",\n * tabs: [\n * { id: \"recent\", label: \"Recent\", items: [...] },\n * { id: \"popular\", label: \"Popular\", items: [...] },\n * ]\n * }\n * ],\n * };\n *\n * <DashboardGrid config={dashboardConfig} basePath=\"/admin\" navigate={navigate} />\n * ```\n */\nexport function DashboardGrid({\n\tconfig,\n\tbasePath = \"/admin\",\n\tnavigate,\n\twidgetRegistry,\n\tclassName,\n}: DashboardGridProps): React.ReactElement {\n\tconst resolveText = useResolveText();\n\tconst {\n\t\ttitle,\n\t\tdescription,\n\t\tcolumns = 4,\n\t\trealtime: dashboardRealtime,\n\t} = config;\n\n\t// Support both new `items` and legacy `widgets` array\n\tconst layoutItems = config.items || config.widgets || [];\n\n\tconst resolvedTitle = title ? resolveText(title) : undefined;\n\tconst resolvedDescription = description\n\t\t? resolveText(description)\n\t\t: undefined;\n\n\t// If no items, show empty state\n\tif (layoutItems.length === 0) {\n\t\treturn (\n\t\t\t<div className={cn(\"@container\", className)}>\n\t\t\t\t<DashboardHeader\n\t\t\t\t\ttitle={resolvedTitle}\n\t\t\t\t\tdescription={resolvedDescription}\n\t\t\t\t\tactions={config.actions}\n\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\tresolveText={resolveText}\n\t\t\t\t/>\n\t\t\t\t<div className=\"flex h-64 items-center justify-center border border-dashed border-border bg-card/50 rounded-lg\">\n\t\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t\t<p className=\"text-muted-foreground font-medium\">\n\t\t\t\t\t\t\tNo widgets configured\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"mt-1 text-sm text-muted-foreground\">\n\t\t\t\t\t\t\tAdd widgets to your dashboard configuration to display data here.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={cn(\"@container\", className)}>\n\t\t\t<DashboardHeader\n\t\t\t\ttitle={resolvedTitle}\n\t\t\t\tdescription={resolvedDescription}\n\t\t\t\tactions={config.actions}\n\t\t\t\tnavigate={navigate}\n\t\t\t\tresolveText={resolveText}\n\t\t\t/>\n\n\t\t\t<div className={cn(\"grid gap-4 items-stretch\", getGridClass(columns))}>\n\t\t\t\t{layoutItems.map((item, index) => (\n\t\t\t\t\t<LayoutItemRenderer\n\t\t\t\t\t\tkey={getLayoutItemKey(item, index)}\n\t\t\t\t\t\titem={item}\n\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\t\twidgetRegistry={widgetRegistry}\n\t\t\t\t\t\tresolveText={resolveText}\n\t\t\t\t\t\tdashboardRealtime={dashboardRealtime}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default DashboardGrid;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-widget.mjs","names":["React"],"sources":["../../../../src/client/views/dashboard/dashboard-widget.tsx"],"sourcesContent":["/**\n * DashboardWidget Component\n *\n * Renders individual dashboard widgets based on their type configuration.\n * Resolves widgets from the registry (built-in + custom).\n */\n\nimport * as React from \"react\";\nimport type { AnyWidgetConfig, WidgetComponentProps } from \"../../builder\";\nimport { WidgetErrorBoundary } from \"../../components/error-boundary\";\nimport { selectAdmin, useAdminStore } from \"../../runtime\";\nimport { WidgetCard } from \"./widget-card\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardWidgetProps {\n\t/**\n\t * Widget configuration\n\t */\n\tconfig: AnyWidgetConfig;\n\n\t/**\n\t * Base path for navigation links\n\t */\n\tbasePath?: string;\n\n\t/**\n\t * Navigate function for item clicks\n\t */\n\tnavigate?: (path: string) => void;\n\n\t/**\n\t * Custom widget registry for overrides\n\t */\n\twidgetRegistry?: Record<string, React.ComponentType<WidgetComponentProps>>;\n}\n\n// ============================================================================\n// Loading & Error States\n// ============================================================================\n\nfunction UnknownWidget({ type }: { type: string }) {\n\treturn (\n\t\t<WidgetCard\n\t\t\ttitle=\"Unknown Widget\"\n\t\t\tclassName=\"border-warning/20 bg-warning/5\"\n\t\t>\n\t\t\t<p className=\"text-xs text-muted-foreground\">\n\t\t\t\tWidget type \"{type}\" is not recognized.\n\t\t\t</p>\n\t\t</WidgetCard>\n\t);\n}\n\n// ============================================================================\n// Widget Renderer (handles lazy loading from registry)\n// ============================================================================\n\ninterface RegistryWidgetRendererProps {\n\tloader: any;\n\twidgetConfig: AnyWidgetConfig;\n\tbasePath: string;\n\tnavigate?: (path: string) => void;\n}\n\nfunction RegistryWidgetRenderer({\n\tloader,\n\twidgetConfig,\n\tbasePath,\n\tnavigate,\n}: RegistryWidgetRendererProps) {\n\tconst [state, setState] = React.useState<{\n\t\tComponent: React.ComponentType<any> | null;\n\t\tloading: boolean;\n\t\terror: Error | null;\n\t}>({\n\t\tComponent: null,\n\t\tloading: true,\n\t\terror: null,\n\t});\n\n\tReact.useEffect(() => {\n\t\tif (!loader) {\n\t\t\tsetState({ Component: null, loading: false, error: null });\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if it's already a component (not a lazy loader function)\n\t\tconst isLazyLoader =\n\t\t\ttypeof loader === \"function\" &&\n\t\t\t!loader.prototype?.render &&\n\t\t\t!loader.prototype?.isReactComponent &&\n\t\t\tloader.length === 0;\n\n\t\tif (!isLazyLoader) {\n\t\t\tsetState({ Component: loader, loading: false, error: null });\n\t\t\treturn;\n\t\t}\n\n\t\t// Load lazy component\n\t\tlet mounted = true;\n\n\t\t(async () => {\n\t\t\ttry {\n\t\t\t\tconst result = await loader();\n\t\t\t\tif (mounted) {\n\t\t\t\t\tconst Component = result.default || result;\n\t\t\t\t\tsetState({ Component, loading: false, error: null });\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tif (mounted) {\n\t\t\t\t\tsetState({\n\t\t\t\t\t\tComponent: null,\n\t\t\t\t\t\tloading: false,\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\terr instanceof Error\n\t\t\t\t\t\t\t\t? err\n\t\t\t\t\t\t\t\t: new Error(\"Failed to load component\"),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\n\t\treturn () => {\n\t\t\tmounted = false;\n\t\t};\n\t}, [loader]);\n\n\tif (state.loading) {\n\t\treturn <WidgetCard isLoading />;\n\t}\n\n\tif (state.error) {\n\t\treturn <WidgetCard error={state.error} />;\n\t}\n\n\tif (!state.Component) {\n\t\treturn <WidgetCard error={new Error(\"Component not found\")} />;\n\t}\n\n\tconst Component = state.Component;\n\treturn (\n\t\t<Component\n\t\t\tconfig={widgetConfig}\n\t\t\tbasePath={basePath}\n\t\t\tnavigate={navigate}\n\t\t\tspan={widgetConfig.span}\n\t\t/>\n\t);\n}\n\n// ============================================================================\n// Custom Widget Renderer (for type=\"custom\" with inline component)\n// ============================================================================\n\ninterface CustomWidgetRendererProps {\n\tloader: any;\n\twidgetConfig: Record<string, any>;\n\tspan?: number;\n}\n\nfunction CustomWidgetRenderer({\n\tloader,\n\twidgetConfig,\n\tspan,\n}: CustomWidgetRendererProps) {\n\tconst [state, setState] = React.useState<{\n\t\tComponent: React.ComponentType<WidgetComponentProps> | null;\n\t\tloading: boolean;\n\t\terror: Error | null;\n\t}>({\n\t\tComponent: null,\n\t\tloading: true,\n\t\terror: null,\n\t});\n\n\tReact.useEffect(() => {\n\t\tif (!loader) {\n\t\t\tsetState({ Component: null, loading: false, error: null });\n\t\t\treturn;\n\t\t}\n\n\t\tconst isLazyLoader =\n\t\t\ttypeof loader === \"function\" &&\n\t\t\t!loader.prototype?.render &&\n\t\t\t!loader.prototype?.isReactComponent &&\n\t\t\tloader.length === 0;\n\n\t\tif (!isLazyLoader) {\n\t\t\tsetState({ Component: loader, loading: false, error: null });\n\t\t\treturn;\n\t\t}\n\n\t\tlet mounted = true;\n\n\t\t(async () => {\n\t\t\ttry {\n\t\t\t\tconst result = await loader();\n\t\t\t\tif (mounted) {\n\t\t\t\t\tconst Component = result.default || result;\n\t\t\t\t\tsetState({ Component, loading: false, error: null });\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tif (mounted) {\n\t\t\t\t\tsetState({\n\t\t\t\t\t\tComponent: null,\n\t\t\t\t\t\tloading: false,\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\terr instanceof Error\n\t\t\t\t\t\t\t\t? err\n\t\t\t\t\t\t\t\t: new Error(\"Failed to load component\"),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\n\t\treturn () => {\n\t\t\tmounted = false;\n\t\t};\n\t}, [loader]);\n\n\tif (state.loading) {\n\t\treturn <WidgetCard isLoading />;\n\t}\n\n\tif (state.error) {\n\t\treturn <WidgetCard error={state.error} />;\n\t}\n\n\tif (!state.Component) {\n\t\treturn <WidgetCard error={new Error(\"Component not found\")} />;\n\t}\n\n\tconst Component = state.Component;\n\treturn <Component config={widgetConfig} span={span} />;\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * DashboardWidget - Renders a single widget based on its configuration.\n *\n * Resolves widgets from the admin store's widget registry (populated by\n * coreAdminModule and user extensions). Falls back to widgetRegistry prop\n * for overrides.\n */\nexport function DashboardWidget({\n\tconfig,\n\tbasePath = \"/admin\",\n\tnavigate,\n\twidgetRegistry,\n}: DashboardWidgetProps): React.ReactElement {\n\tconst admin = useAdminStore(selectAdmin);\n\tconst registeredWidgets = admin.getWidgets() as Record<string, any>;\n\n\tconst renderWidget = (): React.ReactElement => {\n\t\t// Handle custom widget type (inline component, not from registry)\n\t\tif (config.type === \"custom\") {\n\t\t\treturn (\n\t\t\t\t<CustomWidgetRenderer\n\t\t\t\t\tloader={config.component}\n\t\t\t\t\twidgetConfig={config.config || {}}\n\t\t\t\t\tspan={config.span}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\t// Check prop-based registry for overrides first\n\t\tif (widgetRegistry?.[config.type]) {\n\t\t\tconst CustomWidget = widgetRegistry[config.type];\n\t\t\treturn <CustomWidget config={config as any} span={config.span} />;\n\t\t}\n\n\t\t// Look up widget in the admin store registry (built-in + user-registered)\n\t\tconst widgetDef = registeredWidgets[config.type];\n\t\tif (widgetDef) {\n\t\t\tconst component = widgetDef.component ?? widgetDef.state?.component;\n\t\t\tif (component) {\n\t\t\t\treturn (\n\t\t\t\t\t<RegistryWidgetRenderer\n\t\t\t\t\t\tloader={component}\n\t\t\t\t\t\twidgetConfig={config}\n\t\t\t\t\t\tbasePath={basePath}\n\t\t\t\t\t\tnavigate={navigate}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn <UnknownWidget type={config.type} />;\n\t};\n\n\treturn (\n\t\t<WidgetErrorBoundary widgetType={config.type}>\n\t\t\t{renderWidget()}\n\t\t</WidgetErrorBoundary>\n\t);\n}\n\nexport default DashboardWidget;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-card.mjs","names":["variantStyles: Record<WidgetCardVariant, string>","variantContentStyles: Record<WidgetCardVariant, string>"],"sources":["../../../../src/client/views/dashboard/widget-card.tsx"],"sourcesContent":["/**\n * WidgetCard Component\n *\n * Standardized card wrapper for dashboard widgets with multiple variants.\n * Provides consistent styling, header actions, and loading/error states.\n */\n\nimport { Icon } from \"@iconify/react\";\nimport type * as React from \"react\";\nimport type { WidgetAction, WidgetCardVariant } from \"../../builder\";\nimport { resolveIconElement } from \"../../components/component-renderer\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n\tCard,\n\tCardAction,\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"../../components/ui/card\";\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n} from \"../../components/ui/dropdown-menu\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { cn } from \"../../lib/utils\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetCardProps {\n\t/** Widget title */\n\ttitle?: string;\n\t/** Widget description */\n\tdescription?: string;\n\t/** Widget icon */\n\ticon?: WidgetAction[\"icon\"];\n\t/** Card visual variant */\n\tvariant?: WidgetCardVariant;\n\t/** Loading state (initial load) */\n\tisLoading?: boolean;\n\t/** Refreshing state (background refetch) */\n\tisRefreshing?: boolean;\n\t/** Error state */\n\terror?: Error | null;\n\t/** Refresh handler */\n\tonRefresh?: () => void;\n\t/** Expand handler (for full screen view) */\n\tonExpand?: () => void;\n\t/** Header actions */\n\tactions?: WidgetAction[];\n\t/** Custom CSS class */\n\tclassName?: string;\n\t/** Custom loading skeleton */\n\tloadingSkeleton?: React.ReactNode;\n\t/** Children content (optional when loading/error) */\n\tchildren?: React.ReactNode;\n}\n\n// ============================================================================\n// Variant Styles\n// ============================================================================\n\nconst variantStyles: Record<WidgetCardVariant, string> = {\n\tdefault: \"\",\n\tcompact: \"py-3 gap-3\",\n\tfeatured:\n\t\t\"border-primary/30 bg-gradient-to-br from-primary/5 to-transparent shadow-sm\",\n};\n\nconst variantContentStyles: Record<WidgetCardVariant, string> = {\n\tdefault: \"\",\n\tcompact: \"pt-0\",\n\tfeatured: \"\",\n};\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\nfunction WidgetCardLoading({\n\tvariant = \"default\",\n}: {\n\tvariant?: WidgetCardVariant;\n}) {\n\treturn (\n\t\t<Card className={cn(\"h-full flex flex-col\", variantStyles[variant])}>\n\t\t\t<CardHeader>\n\t\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t</CardHeader>\n\t\t\t<CardContent className={cn(\"flex-1\", variantContentStyles[variant])}>\n\t\t\t\t<Skeleton className=\"h-20 w-full\" />\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n\nfunction WidgetCardError({\n\terror,\n\tvariant = \"default\",\n\tonRetry,\n}: {\n\terror: Error;\n\tvariant?: WidgetCardVariant;\n\tonRetry?: () => void;\n}) {\n\treturn (\n\t\t<Card\n\t\t\tclassName={cn(\n\t\t\t\t\"h-full flex flex-col border-destructive/20 bg-destructive/5\",\n\t\t\t\tvariantStyles[variant],\n\t\t\t)}\n\t\t>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle className=\"text-sm font-medium text-destructive\">\n\t\t\t\t\tError\n\t\t\t\t</CardTitle>\n\t\t\t\t{onRetry && (\n\t\t\t\t\t<CardAction>\n\t\t\t\t\t\t<Button variant=\"ghost\" size=\"icon-xs\" onClick={onRetry}>\n\t\t\t\t\t\t\t<Icon icon=\"ph:arrow-clockwise\" className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</CardAction>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t<CardContent className={cn(\"flex-1\", variantContentStyles[variant])}>\n\t\t\t\t<p className=\"text-xs text-muted-foreground\">{error.message}</p>\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * WidgetCard - Standardized card wrapper for dashboard widgets\n *\n * @example\n * ```tsx\n * <WidgetCard\n * title=\"Revenue\"\n * description=\"Monthly sales total\"\n * variant=\"featured\"\n * onRefresh={() => refetch()}\n * >\n * <div className=\"text-2xl font-bold\">$12,345</div>\n * </WidgetCard>\n * ```\n */\nexport function WidgetCard({\n\ttitle,\n\tdescription,\n\ticon,\n\tvariant = \"default\",\n\tisLoading,\n\tisRefreshing,\n\terror,\n\tonRefresh,\n\tonExpand,\n\tactions,\n\tclassName,\n\tloadingSkeleton,\n\tchildren,\n}: WidgetCardProps): React.ReactElement {\n\t// Loading state\n\tif (isLoading) {\n\t\tif (loadingSkeleton) {\n\t\t\treturn (\n\t\t\t\t<Card\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"h-full flex flex-col\",\n\t\t\t\t\t\tvariantStyles[variant],\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-24\" />\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent className={cn(\"flex-1\", variantContentStyles[variant])}>\n\t\t\t\t\t\t{loadingSkeleton}\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\t\t\t);\n\t\t}\n\t\treturn <WidgetCardLoading variant={variant} />;\n\t}\n\n\t// Error state\n\tif (error) {\n\t\treturn (\n\t\t\t<WidgetCardError error={error} variant={variant} onRetry={onRefresh} />\n\t\t);\n\t}\n\n\tconst hasHeader =\n\t\ttitle || description || icon || onRefresh || onExpand || actions?.length;\n\n\treturn (\n\t\t<Card\n\t\t\tclassName={cn(\"h-full flex flex-col\", variantStyles[variant], className)}\n\t\t>\n\t\t\t{hasHeader && (\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t{resolveIconElement(icon, {\n\t\t\t\t\t\t\tclassName: \"h-4 w-4 text-muted-foreground\",\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t<div className=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t{title && (\n\t\t\t\t\t\t\t\t<CardTitle className=\"text-sm font-medium truncate\">\n\t\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t\t</CardTitle>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{description && (\n\t\t\t\t\t\t\t\t<CardDescription className=\"truncate\">\n\t\t\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t\t\t</CardDescription>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{(onRefresh || onExpand || actions?.length) && (\n\t\t\t\t\t\t<CardAction>\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t\t{/* Show first action directly, rest in dropdown on small widgets */}\n\t\t\t\t\t\t\t\t{actions && actions.length > 0 && (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t{/* First action always visible */}\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tkey={actions[0].id}\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={actions[0].onClick}\n\t\t\t\t\t\t\t\t\t\t\ttitle={actions[0].label}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{resolveIconElement(actions[0].icon, {\n\t\t\t\t\t\t\t\t\t\t\t\tclassName: \"h-3.5 w-3.5\",\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t{/* Additional actions in dropdown */}\n\t\t\t\t\t\t\t\t\t\t{actions.length > 1 && (\n\t\t\t\t\t\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t\t\t\t\t\t<DropdownMenuTrigger\n\t\t\t\t\t\t\t\t\t\t\t\t\trender={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Button variant=\"ghost\" size=\"icon-xs\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ticon=\"ph:dots-three-vertical\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"h-3.5 w-3.5\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{actions.slice(1).map((action) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={action.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={action.onClick}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{resolveIconElement(action.icon, {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName: \"h-3.5 w-3.5 mr-2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{onRefresh && (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\t\t\tonClick={onRefresh}\n\t\t\t\t\t\t\t\t\t\ttitle=\"Refresh\"\n\t\t\t\t\t\t\t\t\t\tdisabled={isRefreshing}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\t\ticon=\"ph:arrow-clockwise\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\"h-3.5 w-3.5\",\n\t\t\t\t\t\t\t\t\t\t\t\tisRefreshing && \"animate-spin\",\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{onExpand && (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\t\t\tonClick={onExpand}\n\t\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:arrows-out-simple\" className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</CardAction>\n\t\t\t\t\t)}\n\t\t\t\t</CardHeader>\n\t\t\t)}\n\t\t\t<CardContent\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex-1\",\n\t\t\t\t\tvariantContentStyles[variant],\n\t\t\t\t\t!hasHeader && \"pt-0\",\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n\nexport default WidgetCard;\n"],"mappings":"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"}
@@ -1,74 +0,0 @@
1
- import { ComponentRegistry, FormViewConfig } from "../../builder/types/field-types.mjs";
2
- import { GlobalBuilderState } from "../../builder/types/global-types.mjs";
3
- import * as React$1 from "react";
4
- import * as react_jsx_runtime34 from "react/jsx-runtime";
5
-
6
- //#region src/client/views/globals/global-form-view.d.ts
7
-
8
- /**
9
- * Props for GlobalFormView component
10
- */
11
- interface GlobalFormViewProps {
12
- /**
13
- * Global name
14
- */
15
- global: string;
16
- /**
17
- * Global configuration from admin builder
18
- * Accepts GlobalBuilderState or any compatible config object
19
- */
20
- config?: Partial<GlobalBuilderState> | Record<string, any>;
21
- /**
22
- * View-specific configuration from registry/schema
23
- */
24
- viewConfig?: FormViewConfig;
25
- /**
26
- * Navigate function for routing
27
- */
28
- navigate: (path: string) => void;
29
- /**
30
- * Base path for admin routes (e.g., "/admin")
31
- */
32
- basePath?: string;
33
- /**
34
- * Component registry for custom field types
35
- */
36
- registry?: ComponentRegistry;
37
- /**
38
- * All globals config (for potential cross-references)
39
- */
40
- allGlobalsConfig?: Record<string, Partial<GlobalBuilderState> | Record<string, any>>;
41
- /**
42
- * Show metadata (updated dates)
43
- * @default true
44
- */
45
- showMeta?: boolean;
46
- /**
47
- * Custom header actions (in addition to default Save button)
48
- */
49
- headerActions?: React$1.ReactNode;
50
- /**
51
- * Callback on successful save
52
- */
53
- onSuccess?: (data: any) => void;
54
- /**
55
- * Callback on error
56
- */
57
- onError?: (error: Error) => void;
58
- }
59
- /**
60
- * GlobalFormView - Default form-based edit view for globals
61
- */
62
- declare function GlobalFormView({
63
- global: globalName,
64
- config,
65
- viewConfig,
66
- registry,
67
- showMeta,
68
- headerActions,
69
- onSuccess,
70
- onError
71
- }: GlobalFormViewProps): react_jsx_runtime34.JSX.Element;
72
- //#endregion
73
- export { GlobalFormView };
74
- //# sourceMappingURL=global-form-view.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"global-form-view.d.mts","names":[],"sources":["../../../../src/client/views/globals/global-form-view.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;AA6FU,UArCO,mBAAA,CAqCP;EAAR;;;EAYe,MAAM,EAAA,MAAA;EAUJ;;AAClB;;EAWA,MAAA,CAAA,EA7DS,OA6DT,CA7DiB,kBA6DjB,CAAA,GA7DuC,MA6DvC,CAAA,MAAA,EAAA,GAAA,CAAA;EACA;;;EAGA,UAAA,CAAA,EA5Da,cA4Db;EACA;;;EAEqB,QAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA;;;;;;;aAhDV;;;;qBAKQ,eAElB,QAAQ,sBAAsB;;;;;;;;;kBAYf,OAAA,CAAM;;;;;;;;oBAUJ;;;;;iBAUK,cAAA;UACf;;;;;;;;GAQN,sBAAmB,mBAAA,CAAA,GAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"global-form-view.mjs","names":["configs: Record<string, any>","React"],"sources":["../../../../src/client/views/globals/global-form-view.tsx"],"sourcesContent":["/**\n * Global Form View - Default edit view component for globals\n *\n * Mirrors FormView for collections but adapted for singleton globals.\n * Renders global settings form with sections, tabs, sidebar, validation.\n */\n\nimport { Icon } from \"@iconify/react\";\nimport { QuestpieClientError } from \"questpie/client\";\nimport * as React from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\nimport type {\n\tComponentRegistry,\n\tFormViewConfig,\n} from \"../../builder/types/field-types\";\nimport type { GlobalBuilderState } from \"../../builder/types/global-types\";\nimport { LocaleSwitcher } from \"../../components/locale-switcher\";\nimport { Button } from \"../../components/ui/button\";\nimport { useGlobal, useGlobalUpdate } from \"../../hooks\";\nimport { useGlobalFields } from \"../../hooks/use-global-fields\";\nimport { useReactiveFields } from \"../../hooks/use-reactive-fields\";\nimport { useGlobalServerValidation } from \"../../hooks/use-server-validation\";\nimport { useResolveText, useTranslation } from \"../../i18n/hooks\";\nimport { useSafeContentLocales, useScopedLocale } from \"../../runtime\";\nimport { AutoFormFields } from \"../collection/auto-form-fields\";\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extract reactive configs from global schema fields.\n * Used to determine which fields have server-side reactive behaviors.\n */\nfunction extractReactiveConfigs(schema: any): Record<string, any> {\n\tif (!schema?.fields) return {};\n\n\tconst configs: Record<string, any> = {};\n\n\tfor (const [fieldName, fieldDef] of Object.entries(schema.fields)) {\n\t\tif ((fieldDef as any).reactive) {\n\t\t\tconfigs[fieldName] = (fieldDef as any).reactive;\n\t\t}\n\t}\n\n\treturn configs;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Props for GlobalFormView component\n */\nexport interface GlobalFormViewProps {\n\t/**\n\t * Global name\n\t */\n\tglobal: string;\n\n\t/**\n\t * Global configuration from admin builder\n\t * Accepts GlobalBuilderState or any compatible config object\n\t */\n\tconfig?: Partial<GlobalBuilderState> | Record<string, any>;\n\n\t/**\n\t * View-specific configuration from registry/schema\n\t */\n\tviewConfig?: FormViewConfig;\n\n\t/**\n\t * Navigate function for routing\n\t */\n\tnavigate: (path: string) => void;\n\n\t/**\n\t * Base path for admin routes (e.g., \"/admin\")\n\t */\n\tbasePath?: string;\n\n\t/**\n\t * Component registry for custom field types\n\t */\n\tregistry?: ComponentRegistry;\n\n\t/**\n\t * All globals config (for potential cross-references)\n\t */\n\tallGlobalsConfig?: Record<\n\t\tstring,\n\t\tPartial<GlobalBuilderState> | Record<string, any>\n\t>;\n\n\t/**\n\t * Show metadata (updated dates)\n\t * @default true\n\t */\n\tshowMeta?: boolean;\n\n\t/**\n\t * Custom header actions (in addition to default Save button)\n\t */\n\theaderActions?: React.ReactNode;\n\n\t/**\n\t * Callback on successful save\n\t */\n\tonSuccess?: (data: any) => void;\n\n\t/**\n\t * Callback on error\n\t */\n\tonError?: (error: Error) => void;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * GlobalFormView - Default form-based edit view for globals\n */\nexport default function GlobalFormView({\n\tglobal: globalName,\n\tconfig,\n\tviewConfig,\n\tregistry,\n\tshowMeta = true,\n\theaderActions,\n\tonSuccess,\n\tonError,\n}: GlobalFormViewProps) {\n\tconst { t } = useTranslation();\n\tconst resolveText = useResolveText();\n\n\tconst { data: globalData, isLoading: dataLoading } = useGlobal(globalName);\n\tconst { fields: schemaFields } = useGlobalFields(globalName);\n\n\tconst { locale: contentLocale, setLocale: setContentLocale } =\n\t\tuseScopedLocale();\n\tconst contentLocales = useSafeContentLocales();\n\tconst localeOptions = contentLocales?.locales ?? [];\n\n\tconst updateMutation = useGlobalUpdate(globalName, {\n\t\tonSuccess: (data) => {\n\t\t\ttoast.success(t(\"toast.saveSuccess\"));\n\t\t\tonSuccess?.(data);\n\t\t},\n\t\tonError: (error) => {\n\t\t\tonError?.(error);\n\t\t},\n\t});\n\n\t// Get validation resolver - uses server JSON Schema for validation\n\tconst { resolver } = useGlobalServerValidation(globalName);\n\n\tconst form = useForm({\n\t\tdefaultValues: (globalData ?? {}) as any,\n\t\tresolver,\n\t});\n\n\t// Reset form when data loads\n\tReact.useEffect(() => {\n\t\tif (globalData) {\n\t\t\tform.reset(globalData as any);\n\t\t}\n\t}, [form, globalData]);\n\n\t// Extract reactive configs from schema for server-side reactive handlers\n\tconst reactiveConfigs = React.useMemo(\n\t\t() => extractReactiveConfigs(schemaFields),\n\t\t[schemaFields],\n\t);\n\n\t// Use reactive fields hook for server-side compute/hidden/readOnly/disabled\n\tuseReactiveFields({\n\t\tcollection: globalName,\n\t\tmode: \"global\",\n\t\treactiveConfigs,\n\t\tenabled: !dataLoading && Object.keys(reactiveConfigs).length > 0,\n\t\tdebounce: 300,\n\t});\n\n\tconst resolvedConfig = React.useMemo(() => {\n\t\tif (!viewConfig) return config;\n\n\t\treturn {\n\t\t\t...(config ?? {}),\n\t\t\tform: viewConfig,\n\t\t};\n\t}, [config, viewConfig]);\n\n\tconst onSubmit = React.useCallback(\n\t\tasync (data: any) => {\n\t\t\ttry {\n\t\t\t\tconst result = await updateMutation.mutateAsync({\n\t\t\t\t\tdata,\n\t\t\t\t});\n\t\t\t\tif (result) {\n\t\t\t\t\tform.reset(result as any);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\t// Handle field-level validation errors from the API\n\t\t\t\tif (\n\t\t\t\t\terror instanceof QuestpieClientError &&\n\t\t\t\t\terror.fieldErrors &&\n\t\t\t\t\terror.fieldErrors.length > 0\n\t\t\t\t) {\n\t\t\t\t\tfor (const fieldError of error.fieldErrors) {\n\t\t\t\t\t\tform.setError(fieldError.path as any, {\n\t\t\t\t\t\t\ttype: \"server\",\n\t\t\t\t\t\t\tmessage: fieldError.message,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\ttoast.error(t(\"toast.validationFailed\"), {\n\t\t\t\t\t\tdescription: t(\"toast.validationDescription\"),\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Handle generic errors\n\t\t\t\tconst message =\n\t\t\t\t\terror instanceof Error ? error.message : t(\"error.unknown\");\n\t\t\t\ttoast.error(\n\t\t\t\t\tt(\"toast.settingsSaveFailed\") || \"Failed to save settings\",\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: message,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[updateMutation, form, t],\n\t);\n\n\t// Keyboard shortcut: Cmd+S to save\n\tReact.useEffect(() => {\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif ((e.metaKey || e.ctrlKey) && e.key === \"s\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tform.handleSubmit(onSubmit)();\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown);\n\t\treturn () => document.removeEventListener(\"keydown\", handleKeyDown);\n\t}, [form, onSubmit]);\n\n\tconst isSubmitting = updateMutation.isPending || form.formState.isSubmitting;\n\n\t// Format date helper\n\tconst formatDate = (date: string | Date) => {\n\t\treturn new Date(date).toLocaleDateString(undefined, {\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"short\",\n\t\t\tday: \"numeric\",\n\t\t\thour: \"2-digit\",\n\t\t\tminute: \"2-digit\",\n\t\t});\n\t};\n\n\tif (dataLoading) {\n\t\treturn (\n\t\t\t<div className=\"flex h-64 items-center justify-center text-muted-foreground\">\n\t\t\t\t<Icon icon=\"ph:spinner-gap\" className=\"size-6 animate-spin\" />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst globalLabel = resolveText(\n\t\t(resolvedConfig as any)?.label ?? schemaFields?._globalLabel,\n\t\tglobalName,\n\t);\n\n\treturn (\n\t\t<FormProvider {...form}>\n\t\t\t<form onSubmit={form.handleSubmit(onSubmit)} className=\"w-full space-y-4\">\n\t\t\t\t{/* Header - Title & Actions */}\n\t\t\t\t<div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t\t\t\t<h1 className=\"text-2xl md:text-3xl font-extrabold tracking-tight\">\n\t\t\t\t\t\t\t\t{globalLabel}\n\t\t\t\t\t\t\t</h1>\n\t\t\t\t\t\t\t{localeOptions.length > 0 && (\n\t\t\t\t\t\t\t\t<LocaleSwitcher\n\t\t\t\t\t\t\t\t\tlocales={localeOptions}\n\t\t\t\t\t\t\t\t\tvalue={contentLocale}\n\t\t\t\t\t\t\t\t\tonChange={setContentLocale}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{showMeta && globalData?.updatedAt && (\n\t\t\t\t\t\t\t<p className=\"mt-1 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t{t(\"form.lastUpdated\")}: {formatDate(globalData.updatedAt)}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"flex items-center gap-2 shrink-0\">\n\t\t\t\t\t\t{headerActions}\n\t\t\t\t\t\t<Button type=\"submit\" disabled={isSubmitting} className=\"gap-2\">\n\t\t\t\t\t\t\t{isSubmitting ? (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:spinner-gap\" className=\"size-4 animate-spin\" />\n\t\t\t\t\t\t\t\t\t{t(\"common.loading\")}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:check\" width={16} height={16} />\n\t\t\t\t\t\t\t\t\t{t(\"common.save\")}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Main Content - Form Fields */}\n\t\t\t\t<AutoFormFields\n\t\t\t\t\tcollection={globalName}\n\t\t\t\t\tmode=\"global\"\n\t\t\t\t\tconfig={resolvedConfig}\n\t\t\t\t\tregistry={registry}\n\t\t\t\t/>\n\t\t\t</form>\n\t\t</FormProvider>\n\t);\n}\n"],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- import { AuthLayout, AuthLayoutProps } from "./auth/auth-layout.mjs";
2
- import { LoginForm, LoginFormProps, LoginFormValues } from "./auth/login-form.mjs";
3
- import { ForgotPasswordForm, ForgotPasswordFormProps, ForgotPasswordFormValues } from "./auth/forgot-password-form.mjs";
4
- import { ResetPasswordForm, ResetPasswordFormProps, ResetPasswordFormValues } from "./auth/reset-password-form.mjs";
5
- import { AcceptInviteForm, AcceptInviteFormProps, AcceptInviteFormValues } from "./auth/accept-invite-form.mjs";
6
- import { SetupForm, SetupFormProps, SetupFormValues } from "./auth/setup-form.mjs";
7
- import "./auth/index.mjs";
8
- import { ArrayCell, JsonCell, ObjectCell } from "./collection/cells/complex-cells.mjs";
9
- import { BooleanCell, DateCell, DateTimeCell, EmailCell, NumberCell, RichTextCell, SelectCell, TextCell, TimeCell } from "./collection/cells/primitive-cells.mjs";
10
- import { RelationCell } from "./collection/cells/relation-cells.mjs";
11
- import { UploadCell } from "./collection/cells/upload-cells.mjs";
12
- import { FormView, FormViewProps, FormViewRegistryConfig } from "./collection/form-view.mjs";
13
- import { TableView, TableViewConfig, TableViewProps } from "./collection/table-view.mjs";
14
- import "./collection/index.mjs";
15
- import "./common/index.mjs";
16
- import { AdminSidebarProps, LinkComponentProps } from "./layout/admin-sidebar.mjs";
17
- import { AdminLayout, AdminLayoutProps } from "./layout/admin-layout.mjs";
18
- import { AdminLayoutProvider, AdminLayoutProviderProps } from "./layout/admin-layout-provider.mjs";
19
- import { AdminRouter, AdminRouterProps } from "./layout/admin-router.mjs";
20
- import "./layout/index.mjs";
21
- import { DashboardPage, DashboardPageProps } from "./pages/dashboard-page.mjs";
22
- import { LoginPage, LoginPageProps } from "./pages/login-page.mjs";
23
- import { ForgotPasswordPage, ForgotPasswordPageProps } from "./pages/forgot-password-page.mjs";
24
- import { ResetPasswordPage, ResetPasswordPageProps } from "./pages/reset-password-page.mjs";
25
- import { InvitePage, InvitePageProps } from "./pages/invite-page.mjs";
26
- import { AcceptInvitePage, AcceptInvitePageProps } from "./pages/accept-invite-page.mjs";
27
- import { SetupPage, SetupPageProps } from "./pages/setup-page.mjs";
28
- import "./pages/index.mjs";
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-layout-provider.d.mts","names":[],"sources":["../../../../src/client/views/layout/admin-layout-provider.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;UAsEiB,sCACF,gBAAgB,uBACrB;;;;;;;;;;;;;;SAcD;;;;UAKC,eAAe;;;;;;;;gBAUT;;;;;;;;;;;;;;;;;;;;;wBA6BQ,OAAA,CAAM;;;;6BAKD,OAAA,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAsCV,OAAA,CAAM;;;;;;;;;;;YAanB,OAAA,CAAM;;;;;;;;iBAwEF,iCAAiC;SACxC;;;;;;;;;;;;;;;;;;;;;;;;GA4BN,yBAAyB,QAAQ,OAAA,CAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-layout-provider.mjs","names":["cachedQueryClient: QueryClient | undefined","QueryClientClass","innerContent: React.ReactNode"],"sources":["../../../../src/client/views/layout/admin-layout-provider.tsx"],"sourcesContent":["/**\n * AdminLayoutProvider Component\n *\n * Universal layout wrapper that works with any router.\n * Provides AdminProvider + AdminLayout and renders children.\n *\n * @example Next.js (App Router)\n * ```tsx\n * // app/admin/layout.tsx\n * export default function AdminLayout({ children }) {\n * return (\n * <AdminLayoutProvider\n * admin={myAdmin}\n * client={cmsClient}\n * authClient={authClient}\n * LinkComponent={Link}\n * >\n * {children}\n * </AdminLayoutProvider>\n * );\n * }\n * ```\n *\n * @example TanStack Router\n * ```tsx\n * // routes/admin.tsx\n * function AdminLayout() {\n * return (\n * <AdminLayoutProvider\n * admin={myAdmin}\n * client={cmsClient}\n * authClient={authClient}\n * LinkComponent={Link}\n * >\n * <Outlet />\n * </AdminLayoutProvider>\n * );\n * }\n * ```\n *\n * @example With Auth Protection\n * ```tsx\n * <AdminLayoutProvider\n * admin={myAdmin}\n * client={cmsClient}\n * authClient={authClient}\n * enableAuthGuard={true}\n * publicPaths={[\"/admin/login\", \"/admin/forgot-password\"]}\n * requiredRole=\"admin\"\n * >\n * {children}\n * </AdminLayoutProvider>\n * ```\n */\n\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport type { Questpie } from \"questpie\";\nimport type { QuestpieClient } from \"questpie/client\";\nimport type * as React from \"react\";\nimport { Admin, type AdminInput } from \"../../builder/admin\";\nimport type { AdminBuilder } from \"../../builder/admin-builder\";\nimport { AuthGuard } from \"../../components/auth\";\nimport { AdminProvider } from \"../../runtime/provider\";\nimport { AdminLayout, type AdminLayoutSharedProps } from \"./admin-layout\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AdminLayoutProviderProps<\n TApp extends Questpie<any> = Questpie<any>,\n> extends AdminLayoutSharedProps {\n /**\n * Admin configuration - pass your AdminBuilder directly.\n * Can also accept an Admin instance for backward compatibility.\n *\n * @example\n * ```tsx\n * // Recommended: pass builder directly\n * <AdminLayoutProvider admin={admin} ... />\n *\n * // Also works (backward compatible)\n * <AdminLayoutProvider admin={Admin.from(admin)} ... />\n * ```\n */\n admin: AdminInput<any>;\n\n /**\n * API client for data fetching\n */\n client: QuestpieClient<TApp>;\n\n /**\n * Auth client for authentication (created via createAdminAuthClient)\n */\n authClient?: any;\n\n /**\n * Optional QueryClient instance (will create one if not provided)\n */\n queryClient?: QueryClient;\n\n // =========================================================================\n // Auth Guard Options\n // =========================================================================\n\n /**\n * Enable authentication guard for protected routes.\n * When true, checks if user is authenticated before rendering content.\n * @default true if authClient is provided\n */\n enableAuthGuard?: boolean;\n\n /**\n * Paths that don't require authentication.\n * Use relative paths from basePath (e.g., \"/login\" for \"/admin/login\").\n * @default [\"/login\", \"/forgot-password\", \"/reset-password\", \"/accept-invite\"]\n */\n publicPaths?: string[];\n\n /**\n * Required role for accessing protected routes.\n * @default \"admin\"\n */\n requiredRole?: string;\n\n /**\n * Custom loading component while checking authentication.\n */\n authLoadingFallback?: React.ReactNode;\n\n /**\n * Custom unauthorized component (instead of redirecting to login).\n */\n authUnauthorizedFallback?: React.ReactNode;\n\n // =========================================================================\n // i18n Options\n // =========================================================================\n\n /**\n * Use server-side translations (fetched via getAdminTranslations RPC).\n * When true, translations are fetched from the server configured via\n * .adminLocale() and .messages() on QuestpieBuilder.\n *\n * @default false (for backwards compatibility)\n *\n * @example\n * ```tsx\n * // Server configures locales and messages\n * const cms = q()\n * .use(adminModule)\n * .adminLocale({ locales: [\"en\", \"sk\"], defaultLocale: \"en\" })\n * .messages({ sk: { \"common.save\": \"Ulozit\" } })\n * .build();\n *\n * // Client fetches from server\n * <AdminLayoutProvider\n * admin={admin}\n * client={client}\n * useServerTranslations\n * >\n * {children}\n * </AdminLayoutProvider>\n * ```\n */\n useServerTranslations?: boolean;\n\n /**\n * Fallback element to show while loading server translations.\n * Only used when useServerTranslations is true.\n */\n translationsFallback?: React.ReactNode;\n\n /**\n * Initial UI locale (admin interface language)\n * If not provided, reads from cookie or uses default from admin config\n */\n initialUiLocale?: string;\n\n /**\n * Children to render inside the layout\n * - Next.js: {children} from layout props\n * - TanStack Router: <Outlet />\n */\n children: React.ReactNode;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nimport { QueryClient as QueryClientClass } from \"@tanstack/react-query\";\n\nlet cachedQueryClient: QueryClient | undefined;\n\nfunction getDefaultQueryClient(): QueryClient {\n if (!cachedQueryClient) {\n cachedQueryClient = new QueryClientClass({\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000, // 1 minute\n },\n },\n });\n }\n return cachedQueryClient;\n}\n\n/**\n * Default public paths that don't require authentication\n * These paths also render WITHOUT the admin layout (no sidebar/header)\n */\nconst DEFAULT_PUBLIC_PATHS = [\n \"/login\",\n \"/forgot-password\",\n \"/reset-password\",\n \"/accept-invite\",\n \"/setup\",\n];\n\n/**\n * Check if current path matches any public path\n */\nfunction isPublicPath(\n currentPath: string | undefined,\n basePath: string,\n publicPaths: string[],\n): boolean {\n if (!currentPath) return false;\n\n // Normalize paths\n const normalizedCurrent = currentPath.replace(/\\/+$/, \"\");\n const normalizedBase = basePath.replace(/\\/+$/, \"\");\n\n for (const publicPath of publicPaths) {\n // Build full public path\n const fullPublicPath = `${normalizedBase}${publicPath}`.replace(/\\/+$/, \"\");\n\n // Check exact match or starts with (for nested routes)\n if (\n normalizedCurrent === fullPublicPath ||\n normalizedCurrent.startsWith(`${fullPublicPath}/`)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * AdminLayoutProvider Component\n *\n * Universal wrapper for admin layout that works with any router.\n * Handles all the provider setup and renders children inside the layout.\n */\nexport function AdminLayoutProvider<TApp extends Questpie<any>>({\n admin: adminInput,\n client,\n authClient,\n queryClient,\n // Shared layout props\n LinkComponent,\n activeRoute,\n basePath = \"/admin\",\n header,\n footer,\n sidebarProps,\n theme,\n setTheme,\n showThemeToggle,\n toasterProps,\n className,\n // Auth guard props\n enableAuthGuard,\n publicPaths = DEFAULT_PUBLIC_PATHS,\n requiredRole = \"admin\",\n authLoadingFallback,\n authUnauthorizedFallback,\n // i18n props\n useServerTranslations,\n translationsFallback,\n initialUiLocale,\n // Children\n children,\n}: AdminLayoutProviderProps<TApp>): React.ReactElement {\n const qc = queryClient ?? getDefaultQueryClient();\n\n // Normalize admin input - accepts both AdminBuilder and Admin instance\n const admin = Admin.normalize(adminInput);\n\n // Determine if auth guard should be enabled\n // Default: enabled if authClient is provided\n const shouldUseAuthGuard = enableAuthGuard ?? authClient != null;\n\n // Check if current route is public\n const currentPath =\n activeRoute ??\n (typeof window !== \"undefined\" ? window.location.pathname : undefined);\n const isCurrentPathPublic = isPublicPath(currentPath, basePath, publicPaths);\n\n // Determine content based on path type:\n // - Public paths (login, setup, etc.): render children directly (no AdminLayout)\n // - Protected paths: render with AdminLayout + optional AuthGuard\n let innerContent: React.ReactNode;\n\n if (isCurrentPathPublic) {\n // Public paths render children directly without admin layout (sidebar/header)\n // Auth pages (login, setup) use their own AuthLayout component\n innerContent = children;\n } else {\n // Protected paths get the full admin layout\n const layoutContent = (\n <AdminLayout\n LinkComponent={LinkComponent}\n activeRoute={activeRoute}\n basePath={basePath}\n header={header}\n footer={footer}\n sidebarProps={sidebarProps}\n theme={theme}\n setTheme={setTheme}\n showThemeToggle={showThemeToggle}\n toasterProps={toasterProps}\n className={className}\n >\n {children}\n </AdminLayout>\n );\n\n // Optionally wrap with auth guard\n innerContent = shouldUseAuthGuard ? (\n <AuthGuard\n loginPath={`${basePath}/login`}\n requiredRole={requiredRole}\n loadingFallback={authLoadingFallback}\n unauthorizedFallback={authUnauthorizedFallback}\n >\n {layoutContent}\n </AuthGuard>\n ) : (\n layoutContent\n );\n }\n\n const content = (\n <AdminProvider\n admin={admin}\n client={client}\n authClient={authClient}\n useServerTranslations={useServerTranslations}\n translationsFallback={translationsFallback}\n initialUiLocale={initialUiLocale}\n >\n {innerContent}\n </AdminProvider>\n );\n\n // Always wrap with QueryClientProvider\n return <QueryClientProvider client={qc}>{content}</QueryClientProvider>;\n}\n\nexport default AdminLayoutProvider;\n"],"mappings":";;;;;;;;AAmMA,IAAIA;AAEJ,SAAS,wBAAqC;AAC5C,KAAI,CAAC,kBACH,qBAAoB,IAAIC,YAAiB,EACvC,gBAAgB,EACd,SAAS,EACP,WAAW,KAAK,KACjB,EACF,EACF,CAAC;AAEJ,QAAO;;;;;;AAOT,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;CACD;;;;AAKD,SAAS,aACP,aACA,UACA,aACS;AACT,KAAI,CAAC,YAAa,QAAO;CAGzB,MAAM,oBAAoB,YAAY,QAAQ,QAAQ,GAAG;CACzD,MAAM,iBAAiB,SAAS,QAAQ,QAAQ,GAAG;AAEnD,MAAK,MAAM,cAAc,aAAa;EAEpC,MAAM,iBAAiB,GAAG,iBAAiB,aAAa,QAAQ,QAAQ,GAAG;AAG3E,MACE,sBAAsB,kBACtB,kBAAkB,WAAW,GAAG,eAAe,GAAG,CAElD,QAAO;;AAIX,QAAO;;;;;;;;AAST,SAAgB,oBAAgD,EAC9D,OAAO,YACP,QACA,YACA,aAEA,eACA,aACA,WAAW,UACX,QACA,QACA,cACA,OACA,UACA,iBACA,cACA,WAEA,iBACA,cAAc,sBACd,eAAe,SACf,qBACA,0BAEA,uBACA,sBACA,iBAEA,YACqD;CACrD,MAAM,KAAK,eAAe,uBAAuB;CAGjD,MAAM,QAAQ,MAAM,UAAU,WAAW;CAIzC,MAAM,qBAAqB,mBAAmB,cAAc;CAM5D,MAAM,sBAAsB,aAF1B,gBACC,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW,SACR,UAAU,YAAY;CAK5E,IAAIC;AAEJ,KAAI,oBAGF,gBAAe;MACV;EAEL,MAAM,gBACJ,oBAAC;GACgB;GACF;GACH;GACF;GACA;GACM;GACP;GACG;GACO;GACH;GACH;GAEV;IACW;AAIhB,iBAAe,qBACb,oBAAC;GACC,WAAW,GAAG,SAAS;GACT;GACd,iBAAiB;GACjB,sBAAsB;aAErB;IACS,GAEZ;;AAkBJ,QAAO,oBAAC;EAAoB,QAAQ;YAblC,oBAAC;GACQ;GACC;GACI;GACW;GACD;GACL;aAEhB;IACa;GAIqD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-layout.d.mts","names":[],"sources":["../../../../src/client/views/layout/admin-layout.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;AAuGsB,KAvEV,UAAA,GAuEU,OAAA,GAAA,MAAA,GAAA,QAAA;;;;AActB;;;;AAAgE,KA5EpD,UAAA,GA4EoD,SAAA,GAAA,MAAA,GAAA,MAAA,GAAA,WAAA;AAkGhE;;;;AAIE,UA5Ke,sBAAA,CA4Kf;EACW;;;EAGX,aAAA,EA5Ke,iBA4Kf,CAAA,eAAA,CAAA;EACA;;;EAGU,WAAA,CAAA,EAAA,MAAA;EACV;;;;EAIA,QAAA,CAAA,EAAA,MAAA;EACC;;;WAtKQ,OAAA,CAAM;;;;WAKN,OAAA,CAAM;;;;iBAKA,QACb,KAAK;;;;;;UAQC;;;;;qBAMW;;;;;;;;;iBAWJ,KAAK;;;;;;;;;eAWP;;UAGE,gBAAA,SAAyB;;;;;eAK3B;;;;;;;;;;;;;YAgBH,OAAA,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6EF,WAAA;cACF;;;;aAID;oBACO;;;;;;YAMR;;;;;;GAMT,mBAAmB,OAAA,CAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-layout.mjs","names":["React"],"sources":["../../../../src/client/views/layout/admin-layout.tsx"],"sourcesContent":["/**\n * AdminLayout Component\n *\n * Complete admin layout with:\n * - Sidebar navigation (using shadcn sidebar primitives)\n * - Main content area\n * - Optional header/footer\n *\n * Automatically reads from AdminProvider context when props are not provided.\n */\n\nimport * as React from \"react\";\nimport { SidebarInset, SidebarProvider } from \"../../components/ui/sidebar\";\nimport { type AdminToasterProps, Toaster } from \"../../components/ui/sonner\";\nimport {\n BreadcrumbProvider,\n useCurrentBreadcrumbs,\n} from \"../../contexts/breadcrumb-context\";\nimport { cn } from \"../../lib/utils\";\nimport { useAdminStore } from \"../../runtime/provider\";\nimport type { NavigationGroup } from \"../../runtime/routes\";\nimport { GlobalSearch } from \"../common\";\nimport { AdminSidebar, type AdminSidebarProps } from \"./admin-sidebar\";\nimport { AdminTopbar } from \"./admin-topbar\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Theme mode for the admin interface\n */\nexport type AdminTheme = \"light\" | \"dark\" | \"system\";\n\n/**\n * Layout mode for content area width\n * - default: max-w-6xl (forms, settings)\n * - wide: max-w-7xl (tables, cards)\n * - full: 100% with padding (kanban, calendar)\n * - immersive: 100% no padding (puck editor)\n */\nexport type LayoutMode = \"default\" | \"wide\" | \"full\" | \"immersive\";\n\n/**\n * Shared layout props that can be passed through AdminLayoutProvider\n * or directly to AdminLayout.\n */\nexport interface AdminLayoutSharedProps {\n /**\n * Link component (router-specific)\n */\n LinkComponent: AdminSidebarProps[\"LinkComponent\"];\n\n /**\n * Current active route\n */\n activeRoute?: string;\n\n /**\n * Base path for admin routes\n * @default \"/admin\"\n */\n basePath?: string;\n\n /**\n * Header content\n */\n header?: React.ReactNode;\n\n /**\n * Footer content\n */\n footer?: React.ReactNode;\n\n /**\n * Additional sidebar props\n */\n sidebarProps?: Partial<\n Omit<AdminSidebarProps, \"navigation\" | \"LinkComponent\">\n >;\n\n /**\n * Current theme.\n * Pass from your app's theme context.\n * @default \"system\"\n */\n theme?: AdminTheme;\n\n /**\n * Callback to change theme.\n * Connect to your app's theme context setTheme function.\n */\n setTheme?: (theme: AdminTheme) => void;\n\n /**\n * Show theme toggle button in the topbar\n * @default true (when setTheme is provided)\n */\n showThemeToggle?: boolean;\n\n /**\n * Additional toaster props\n */\n toasterProps?: Omit<AdminToasterProps, \"theme\">;\n\n /**\n * Custom layout className\n */\n className?: string;\n\n /**\n * Layout mode for content area width\n * @default \"default\"\n */\n layoutMode?: LayoutMode;\n}\n\nexport interface AdminLayoutProps extends AdminLayoutSharedProps {\n /**\n * Navigation groups for sidebar.\n * If not provided, reads from AdminProvider context.\n */\n navigation?: NavigationGroup[];\n\n /**\n * Brand name for sidebar.\n * If not provided, reads from AdminProvider context.\n */\n brandName?: string;\n\n /**\n * Whether sidebar is collapsed\n */\n sidebarCollapsed?: boolean;\n\n /**\n * Main content to render\n */\n children: React.ReactNode;\n\n /**\n * Navigation function (for search/quick actions)\n */\n navigate?: (path: string) => void;\n}\n\n// ============================================================================\n// Internal Hook - Resolve props from store\n// ============================================================================\n\nfunction useLayoutProps(props: {\n navigation?: NavigationGroup[];\n brandName?: string;\n navigate?: (path: string) => void;\n}): {\n navigation: NavigationGroup[];\n brandName: string;\n navigate: (path: string) => void;\n} {\n // Subscribe to store values reactively (for HMR support)\n const storeNavigation = useAdminStore((s) => s.navigation);\n const storeBrandName = useAdminStore((s) => s.brandName);\n const storeNavigate = useAdminStore((s) => s.navigate);\n\n return {\n navigation: props.navigation ?? storeNavigation,\n brandName: props.brandName ?? storeBrandName,\n navigate: props.navigate ?? storeNavigate,\n };\n}\n\n// ============================================================================\n// Internal Components\n// ============================================================================\n\n/**\n * Topbar wrapper that reads breadcrumbs from context\n */\nfunction AdminTopbarWithBreadcrumbs(\n props: Omit<React.ComponentProps<typeof AdminTopbar>, \"breadcrumbs\">,\n) {\n const breadcrumbs = useCurrentBreadcrumbs();\n return <AdminTopbar {...props} breadcrumbs={breadcrumbs} />;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * AdminLayout Component\n *\n * When used inside AdminProvider, navigation and brandName are automatically\n * read from context if not provided as props.\n *\n * @example\n * ```tsx\n * // With AdminProvider (automatic)\n * <AdminProvider admin={admin} client={client}>\n * <AdminLayout LinkComponent={Link} activeRoute=\"/admin/posts\">\n * <Outlet />\n * </AdminLayout>\n * </AdminProvider>\n *\n * // Without AdminProvider (manual)\n * <AdminLayout\n * navigation={buildNavigation(admin)}\n * LinkComponent={Link}\n * activeRoute=\"/admin/posts\"\n * brandName=\"My CMS\"\n * >\n * <Outlet />\n * </AdminLayout>\n * ```\n */\nexport function AdminLayout({\n navigation: navigationProp,\n LinkComponent,\n activeRoute,\n basePath = \"/admin\",\n brandName: brandNameProp,\n sidebarCollapsed: sidebarCollapsedProp = false,\n children,\n className,\n sidebarProps,\n header,\n footer,\n navigate: navigateProp,\n theme = \"system\",\n setTheme,\n showThemeToggle,\n toasterProps,\n layoutMode = \"default\",\n}: AdminLayoutProps): React.ReactElement {\n // Infer show flags from content\n const shouldShowHeader = !!header;\n const shouldShowFooter = !!footer;\n // Resolve navigation and brandName from props or store\n const { navigation, brandName, navigate } = useLayoutProps({\n navigation: navigationProp,\n brandName: brandNameProp,\n navigate: navigateProp,\n });\n\n const [isSearchOpen, setIsSearchOpen] = React.useState(false);\n\n // Keyboard shortcuts for search\n React.useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n setIsSearchOpen(true);\n }\n };\n document.addEventListener(\"keydown\", down);\n return () => document.removeEventListener(\"keydown\", down);\n }, []);\n\n return (\n <BreadcrumbProvider>\n <div\n className={cn(\"min-h-screen bg-background bg-grid-quest\", className)}\n >\n {/* <div className=\"fixed inset-0 bg-grid-quest pointer-events-none z-10\" /> */}\n <GlobalSearch\n isOpen={isSearchOpen}\n onClose={() => setIsSearchOpen(false)}\n navigate={navigate}\n basePath={basePath}\n />\n\n {/* Max-width container for ultrawide monitors - centered with subtle side borders */}\n <SidebarProvider\n defaultOpen={!sidebarCollapsedProp}\n className=\"mx-auto max-w-[1920px] border-x border-border/40 h-svh overflow-hidden\"\n >\n {/* Sidebar */}\n <AdminSidebar\n navigation={navigationProp}\n LinkComponent={LinkComponent}\n activeRoute={activeRoute}\n basePath={basePath}\n brandName={brandNameProp}\n {...sidebarProps}\n />\n\n {/* Content Area */}\n <SidebarInset className=\"flex h-svh flex-col\">\n <AdminTopbarWithBreadcrumbs\n onSearchOpen={() => setIsSearchOpen(true)}\n theme={theme}\n setTheme={setTheme}\n showThemeToggle={showThemeToggle}\n />\n\n {/* Header (optional) */}\n {shouldShowHeader && header && (\n <header className=\"border-b\">{header}</header>\n )}\n\n <main className=\"flex-1 overflow-y-auto\">\n <div\n className={cn(\n \"mx-auto\",\n layoutMode === \"default\" && \"max-w-6xl p-5 md:p-8 lg:p-10\",\n layoutMode === \"wide\" && \"max-w-7xl p-5 md:p-8 lg:p-10\",\n layoutMode === \"full\" && \"max-w-full p-4 md:p-6\",\n layoutMode === \"immersive\" && \"max-w-full p-0\",\n )}\n >\n {children}\n </div>\n </main>\n\n {/* Footer (optional) */}\n {shouldShowFooter && footer && (\n <footer className=\"border-t\">{footer}</footer>\n )}\n </SidebarInset>\n </SidebarProvider>\n\n {/* Toast notifications */}\n <Toaster theme={theme} {...toasterProps} />\n </div>\n </BreadcrumbProvider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsJA,SAAS,eAAe,OAQtB;CAEA,MAAM,kBAAkB,eAAe,MAAM,EAAE,WAAW;CAC1D,MAAM,iBAAiB,eAAe,MAAM,EAAE,UAAU;CACxD,MAAM,gBAAgB,eAAe,MAAM,EAAE,SAAS;AAEtD,QAAO;EACL,YAAY,MAAM,cAAc;EAChC,WAAW,MAAM,aAAa;EAC9B,UAAU,MAAM,YAAY;EAC7B;;;;;AAUH,SAAS,2BACP,OACA;CACA,MAAM,cAAc,uBAAuB;AAC3C,QAAO,oBAAC;EAAY,GAAI;EAAoB;GAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiC7D,SAAgB,YAAY,EAC1B,YAAY,gBACZ,eACA,aACA,WAAW,UACX,WAAW,eACX,kBAAkB,uBAAuB,OACzC,UACA,WACA,cACA,QACA,QACA,UAAU,cACV,QAAQ,UACR,UACA,iBACA,cACA,aAAa,aAC0B;CAEvC,MAAM,mBAAmB,CAAC,CAAC;CAC3B,MAAM,mBAAmB,CAAC,CAAC;CAE3B,MAAM,EAAE,YAAY,WAAW,aAAa,eAAe;EACzD,YAAY;EACZ,WAAW;EACX,UAAU;EACX,CAAC;CAEF,MAAM,CAAC,cAAc,mBAAmBA,QAAM,SAAS,MAAM;AAG7D,SAAM,gBAAgB;EACpB,MAAM,QAAQ,MAAqB;AACjC,OAAI,EAAE,QAAQ,QAAQ,EAAE,WAAW,EAAE,UAAU;AAC7C,MAAE,gBAAgB;AAClB,oBAAgB,KAAK;;;AAGzB,WAAS,iBAAiB,WAAW,KAAK;AAC1C,eAAa,SAAS,oBAAoB,WAAW,KAAK;IACzD,EAAE,CAAC;AAEN,QACE,oBAAC,gCACC,qBAAC;EACC,WAAW,GAAG,4CAA4C,UAAU;;GAGpE,oBAAC;IACC,QAAQ;IACR,eAAe,gBAAgB,MAAM;IAC3B;IACA;KACV;GAGF,qBAAC;IACC,aAAa,CAAC;IACd,WAAU;eAGV,oBAAC;KACC,YAAY;KACG;KACF;KACH;KACV,WAAW;KACX,GAAI;MACJ,EAGF,qBAAC;KAAa,WAAU;;MACtB,oBAAC;OACC,oBAAoB,gBAAgB,KAAK;OAClC;OACG;OACO;QACjB;MAGD,oBAAoB,UACnB,oBAAC;OAAO,WAAU;iBAAY;QAAgB;MAGhD,oBAAC;OAAK,WAAU;iBACd,oBAAC;QACC,WAAW,GACT,WACA,eAAe,aAAa,gCAC5B,eAAe,UAAU,gCACzB,eAAe,UAAU,yBACzB,eAAe,eAAe,iBAC/B;QAEA;SACG;QACD;MAGN,oBAAoB,UACnB,oBAAC;OAAO,WAAU;iBAAY;QAAgB;;MAEnC;KACC;GAGlB,oBAAC;IAAe;IAAO,GAAI;KAAgB;;GACvC,GACa"}