@pilotiq/pilotiq 0.24.1 → 0.24.3

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 (518) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/boost/guidelines.md +571 -0
  3. package/boost/skills/pilotiq-actions/SKILL.md +49 -0
  4. package/boost/skills/pilotiq-actions/rules/dispatch-modes.md +177 -0
  5. package/boost/skills/pilotiq-actions/rules/factories.md +130 -0
  6. package/boost/skills/pilotiq-actions/rules/visibility-and-authorization.md +125 -0
  7. package/boost/skills/pilotiq-fields/SKILL.md +47 -0
  8. package/boost/skills/pilotiq-fields/rules/field-catalog.md +288 -0
  9. package/boost/skills/pilotiq-fields/rules/reactive-fields.md +199 -0
  10. package/boost/skills/pilotiq-fields/rules/validation.md +198 -0
  11. package/boost/skills/pilotiq-relations/SKILL.md +47 -0
  12. package/boost/skills/pilotiq-relations/rules/relation-managers.md +256 -0
  13. package/boost/skills/pilotiq-relations/rules/repeater-relationship.md +177 -0
  14. package/boost/skills/pilotiq-resource/SKILL.md +61 -0
  15. package/boost/skills/pilotiq-resource/rules/authorization.md +242 -0
  16. package/boost/skills/pilotiq-resource/rules/defining-resources.md +228 -0
  17. package/boost/skills/pilotiq-resource/rules/page-overrides.md +296 -0
  18. package/dist/Pilotiq.d.ts +31 -0
  19. package/dist/Pilotiq.d.ts.map +1 -1
  20. package/dist/Pilotiq.js +3 -1
  21. package/dist/Pilotiq.js.map +1 -1
  22. package/dist/PilotiqRegistry.d.ts +13 -0
  23. package/dist/PilotiqRegistry.d.ts.map +1 -1
  24. package/dist/PilotiqRegistry.js +15 -0
  25. package/dist/PilotiqRegistry.js.map +1 -1
  26. package/dist/pageData/misc.d.ts.map +1 -1
  27. package/dist/pageData/misc.js +6 -0
  28. package/dist/pageData/misc.js.map +1 -1
  29. package/dist/pageData/navigation.d.ts +1 -0
  30. package/dist/pageData/navigation.d.ts.map +1 -1
  31. package/dist/pageData/navigation.js +3 -0
  32. package/dist/pageData/navigation.js.map +1 -1
  33. package/dist/pageData/relationPages.d.ts.map +1 -1
  34. package/dist/pageData/relationPages.js +3 -0
  35. package/dist/pageData/relationPages.js.map +1 -1
  36. package/dist/pageData/resourcePages.d.ts.map +1 -1
  37. package/dist/pageData/resourcePages.js +8 -0
  38. package/dist/pageData/resourcePages.js.map +1 -1
  39. package/dist/react/AppShell.d.ts +8 -0
  40. package/dist/react/AppShell.d.ts.map +1 -1
  41. package/dist/react/AppShell.js.map +1 -1
  42. package/dist/react/layouts/SidebarLayout.d.ts.map +1 -1
  43. package/dist/react/layouts/SidebarLayout.js +10 -2
  44. package/dist/react/layouts/SidebarLayout.js.map +1 -1
  45. package/dist/react/widgets/StatsOverviewRenderer.d.ts.map +1 -1
  46. package/dist/react/widgets/StatsOverviewRenderer.js +32 -18
  47. package/dist/react/widgets/StatsOverviewRenderer.js.map +1 -1
  48. package/dist/routes/relations.d.ts.map +1 -1
  49. package/dist/routes/relations.js +25 -18
  50. package/dist/routes/relations.js.map +1 -1
  51. package/dist/routes/resources.js.map +1 -1
  52. package/package.json +10 -5
  53. package/.turbo/turbo-build.log +0 -8
  54. package/CLAUDE.md +0 -265
  55. package/src/Cluster.test.ts +0 -283
  56. package/src/Cluster.ts +0 -83
  57. package/src/Column.test.ts +0 -199
  58. package/src/Column.ts +0 -710
  59. package/src/Global.test.ts +0 -367
  60. package/src/Global.ts +0 -169
  61. package/src/Page.test.ts +0 -114
  62. package/src/Page.ts +0 -208
  63. package/src/Pilotiq.perf.test.ts +0 -252
  64. package/src/Pilotiq.test.ts +0 -129
  65. package/src/Pilotiq.ts +0 -1158
  66. package/src/PilotiqRegistry.ts +0 -36
  67. package/src/PilotiqServiceProvider.ts +0 -121
  68. package/src/RelationManager.test.ts +0 -400
  69. package/src/RelationManager.ts +0 -527
  70. package/src/RenderHook.test.ts +0 -252
  71. package/src/RenderHook.ts +0 -242
  72. package/src/Resource.test.ts +0 -284
  73. package/src/Resource.ts +0 -526
  74. package/src/RightPanel.test.ts +0 -202
  75. package/src/RightPanel.ts +0 -132
  76. package/src/Tab.test.ts +0 -91
  77. package/src/Tab.ts +0 -156
  78. package/src/UserMenuItem.ts +0 -145
  79. package/src/actions/Action.test.ts +0 -2526
  80. package/src/actions/Action.ts +0 -1515
  81. package/src/actions/ActionGroup.test.ts +0 -112
  82. package/src/actions/ActionGroup.ts +0 -173
  83. package/src/actions/attachFactory.ts +0 -172
  84. package/src/actions/bulkFactories.ts +0 -168
  85. package/src/actions/crudFactories.ts +0 -220
  86. package/src/actions/exportFactory.ts +0 -225
  87. package/src/actions/factoryHelpers.ts +0 -177
  88. package/src/actions/importFactory.ts +0 -243
  89. package/src/actions/index.ts +0 -17
  90. package/src/actions/m2mFactories.ts +0 -193
  91. package/src/actions/relationFactories.ts +0 -372
  92. package/src/applyPageHooks.test.ts +0 -463
  93. package/src/applyPageHooks.ts +0 -330
  94. package/src/authorization.test.ts +0 -483
  95. package/src/breadcrumbs.test.ts +0 -238
  96. package/src/cells/coerce.test.ts +0 -85
  97. package/src/cells/coerce.ts +0 -84
  98. package/src/clusterPaths.ts +0 -35
  99. package/src/columns/BadgeColumn.test.ts +0 -54
  100. package/src/columns/BadgeColumn.ts +0 -32
  101. package/src/columns/BooleanColumn.test.ts +0 -41
  102. package/src/columns/BooleanColumn.ts +0 -18
  103. package/src/columns/ColorColumn.test.ts +0 -37
  104. package/src/columns/ColorColumn.ts +0 -38
  105. package/src/columns/IconColumn.test.ts +0 -54
  106. package/src/columns/IconColumn.ts +0 -37
  107. package/src/columns/ImageColumn.test.ts +0 -41
  108. package/src/columns/ImageColumn.ts +0 -28
  109. package/src/columns/SelectColumn.ts +0 -98
  110. package/src/columns/TextColumn.test.ts +0 -190
  111. package/src/columns/TextColumn.ts +0 -20
  112. package/src/columns/TextInputColumn.ts +0 -68
  113. package/src/columns/ToggleColumn.ts +0 -46
  114. package/src/columns/editableColumns.test.ts +0 -238
  115. package/src/columns/index.ts +0 -9
  116. package/src/defaultGlobalPages.ts +0 -95
  117. package/src/defaultPages.test.ts +0 -634
  118. package/src/defaultPages.ts +0 -617
  119. package/src/defaultViewPage.test.ts +0 -147
  120. package/src/elements/Form.test.ts +0 -223
  121. package/src/elements/Form.ts +0 -416
  122. package/src/elements/ListTabs.ts +0 -28
  123. package/src/elements/Table.test.ts +0 -422
  124. package/src/elements/Table.ts +0 -850
  125. package/src/elements/TableGroup.test.ts +0 -260
  126. package/src/elements/TableGroup.ts +0 -334
  127. package/src/elements/dispatchAction.test.ts +0 -463
  128. package/src/elements/dispatchAction.ts +0 -355
  129. package/src/elements/dispatchForm.test.ts +0 -477
  130. package/src/elements/dispatchForm.ts +0 -1993
  131. package/src/elements/dispatchTable.test.ts +0 -1514
  132. package/src/elements/dispatchTable.ts +0 -745
  133. package/src/elements/index.ts +0 -21
  134. package/src/entries/BadgeEntry.ts +0 -39
  135. package/src/entries/CodeEntry.test.ts +0 -40
  136. package/src/entries/CodeEntry.ts +0 -52
  137. package/src/entries/ColorEntry.ts +0 -63
  138. package/src/entries/ComponentEntry.test.ts +0 -173
  139. package/src/entries/ComponentEntry.ts +0 -95
  140. package/src/entries/Entry.ts +0 -304
  141. package/src/entries/IconEntry.ts +0 -49
  142. package/src/entries/ImageEntry.ts +0 -61
  143. package/src/entries/KeyValueEntry.ts +0 -47
  144. package/src/entries/RepeatableEntry.test.ts +0 -239
  145. package/src/entries/RepeatableEntry.ts +0 -173
  146. package/src/entries/TextEntry.test.ts +0 -394
  147. package/src/entries/TextEntry.ts +0 -60
  148. package/src/entries/index.ts +0 -12
  149. package/src/entries/leaves.test.ts +0 -306
  150. package/src/entries/registry.ts +0 -54
  151. package/src/fields/BuilderField.test.ts +0 -1188
  152. package/src/fields/BuilderField.ts +0 -605
  153. package/src/fields/BuilderRelationship.test.ts +0 -811
  154. package/src/fields/CheckboxField.test.ts +0 -44
  155. package/src/fields/CheckboxField.ts +0 -27
  156. package/src/fields/CheckboxListField.test.ts +0 -99
  157. package/src/fields/CheckboxListField.ts +0 -66
  158. package/src/fields/ColorPickerField.test.ts +0 -33
  159. package/src/fields/ColorPickerField.ts +0 -25
  160. package/src/fields/DateField.ts +0 -54
  161. package/src/fields/DateTimeField.test.ts +0 -55
  162. package/src/fields/EmailField.ts +0 -16
  163. package/src/fields/Field.test.ts +0 -654
  164. package/src/fields/Field.ts +0 -817
  165. package/src/fields/FileUploadField.test.ts +0 -143
  166. package/src/fields/FileUploadField.ts +0 -159
  167. package/src/fields/HiddenField.test.ts +0 -27
  168. package/src/fields/HiddenField.ts +0 -28
  169. package/src/fields/KeyValueField.test.ts +0 -105
  170. package/src/fields/KeyValueField.ts +0 -55
  171. package/src/fields/MarkdownField.test.ts +0 -167
  172. package/src/fields/MarkdownField.ts +0 -162
  173. package/src/fields/NumberField.ts +0 -33
  174. package/src/fields/RadioField.test.ts +0 -94
  175. package/src/fields/RadioField.ts +0 -67
  176. package/src/fields/RepeaterField.test.ts +0 -1806
  177. package/src/fields/RepeaterField.ts +0 -939
  178. package/src/fields/RepeaterRelationship.test.ts +0 -1923
  179. package/src/fields/RepeaterSimple.test.ts +0 -248
  180. package/src/fields/RowButton.test.ts +0 -219
  181. package/src/fields/RowButton.ts +0 -135
  182. package/src/fields/SelectField.test.ts +0 -192
  183. package/src/fields/SelectField.ts +0 -235
  184. package/src/fields/SliderField.test.ts +0 -50
  185. package/src/fields/SliderField.ts +0 -53
  186. package/src/fields/SlugField.ts +0 -24
  187. package/src/fields/TagsInputField.test.ts +0 -154
  188. package/src/fields/TagsInputField.ts +0 -133
  189. package/src/fields/TextField.test.ts +0 -213
  190. package/src/fields/TextField.ts +0 -177
  191. package/src/fields/TextareaField.test.ts +0 -58
  192. package/src/fields/TextareaField.ts +0 -59
  193. package/src/fields/ToggleButtonsField.test.ts +0 -106
  194. package/src/fields/ToggleButtonsField.ts +0 -59
  195. package/src/fields/ToggleField.ts +0 -16
  196. package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +0 -319
  197. package/src/fields/optionsResolver.ts +0 -95
  198. package/src/fields/resolveField.ts +0 -28
  199. package/src/filters/BooleanFilter.ts +0 -35
  200. package/src/filters/DateRangeFilter.test.ts +0 -194
  201. package/src/filters/DateRangeFilter.ts +0 -148
  202. package/src/filters/Filter.test.ts +0 -268
  203. package/src/filters/Filter.ts +0 -184
  204. package/src/filters/FormFilter.test.ts +0 -238
  205. package/src/filters/FormFilter.ts +0 -215
  206. package/src/filters/MultiSelectFilter.test.ts +0 -119
  207. package/src/filters/MultiSelectFilter.ts +0 -78
  208. package/src/filters/QueryBuilderFilter.test.ts +0 -662
  209. package/src/filters/QueryBuilderFilter.ts +0 -398
  210. package/src/filters/SelectFilter.ts +0 -46
  211. package/src/filters/TernaryFilter.test.ts +0 -160
  212. package/src/filters/TernaryFilter.ts +0 -72
  213. package/src/filters/TrashedFilter.test.ts +0 -149
  214. package/src/filters/TrashedFilter.ts +0 -55
  215. package/src/filters/queryBuilder/BooleanConstraint.ts +0 -31
  216. package/src/filters/queryBuilder/Constraint.ts +0 -115
  217. package/src/filters/queryBuilder/DateConstraint.ts +0 -69
  218. package/src/filters/queryBuilder/NumberConstraint.ts +0 -66
  219. package/src/filters/queryBuilder/SelectConstraint.ts +0 -72
  220. package/src/filters/queryBuilder/TextConstraint.ts +0 -64
  221. package/src/filters/queryBuilder/index.ts +0 -12
  222. package/src/icons/index.ts +0 -2
  223. package/src/icons/lucide.ts +0 -204
  224. package/src/icons/registry.test.ts +0 -56
  225. package/src/icons/registry.ts +0 -41
  226. package/src/icons/types.ts +0 -47
  227. package/src/index.ts +0 -525
  228. package/src/io/csv.test.ts +0 -142
  229. package/src/io/csv.ts +0 -170
  230. package/src/nestedRelationManagerData.test.ts +0 -547
  231. package/src/notifications/Notification.test.ts +0 -210
  232. package/src/notifications/Notification.ts +0 -354
  233. package/src/notifications/broadcast.test.ts +0 -110
  234. package/src/notifications/broadcast.ts +0 -95
  235. package/src/notifications/database.test.ts +0 -383
  236. package/src/notifications/database.ts +0 -398
  237. package/src/notifications/databaseNotifications.test.ts +0 -187
  238. package/src/notifications/dispatchNotificationAction.test.ts +0 -341
  239. package/src/notifications/dispatchNotificationAction.ts +0 -142
  240. package/src/notifications/flash.test.ts +0 -89
  241. package/src/notifications/flash.ts +0 -71
  242. package/src/notifications/index.ts +0 -45
  243. package/src/notifications/registerBroadcastAuth.test.ts +0 -134
  244. package/src/notifications/registerBroadcastAuth.ts +0 -100
  245. package/src/notifications/resolveSavedNotification.test.ts +0 -82
  246. package/src/notifications/resolveSavedNotification.ts +0 -59
  247. package/src/notifications/types.ts +0 -93
  248. package/src/orm/m2mAccessor.ts +0 -66
  249. package/src/orm/modelDefaults.test.ts +0 -633
  250. package/src/orm/modelDefaults.ts +0 -666
  251. package/src/pageData/breadcrumbs.ts +0 -288
  252. package/src/pageData/forms.ts +0 -578
  253. package/src/pageData/helpers.ts +0 -857
  254. package/src/pageData/misc.ts +0 -347
  255. package/src/pageData/navigation.ts +0 -842
  256. package/src/pageData/relationPages.ts +0 -1248
  257. package/src/pageData/relationTabs.ts +0 -286
  258. package/src/pageData/resourcePages.ts +0 -609
  259. package/src/pageData.test.ts +0 -1545
  260. package/src/pageData.ts +0 -341
  261. package/src/plugins/index.ts +0 -8
  262. package/src/plugins/themeEditor.test.ts +0 -36
  263. package/src/plugins/themeEditor.ts +0 -45
  264. package/src/react/AppShell.tsx +0 -251
  265. package/src/react/CollabExtensionFactoryRegistry.ts +0 -55
  266. package/src/react/CollabRoomContext.ts +0 -98
  267. package/src/react/CollabTextRendererRegistry.ts +0 -102
  268. package/src/react/CommandPalette.tsx +0 -375
  269. package/src/react/CurrentUserContext.tsx +0 -50
  270. package/src/react/CustomPageWrapperGate.tsx +0 -69
  271. package/src/react/CustomPageWrapperRegistry.ts +0 -45
  272. package/src/react/FieldFocusReporterRegistry.ts +0 -37
  273. package/src/react/FieldLabelSlotRegistry.ts +0 -30
  274. package/src/react/FieldPresenceRegistry.ts +0 -46
  275. package/src/react/FormCollabBindingRegistry.ts +0 -242
  276. package/src/react/FormStateContext.tsx +0 -591
  277. package/src/react/HeadHooks.tsx +0 -126
  278. package/src/react/MarkdownEditorRegistry.test.ts +0 -38
  279. package/src/react/MarkdownEditorRegistry.ts +0 -107
  280. package/src/react/NotificationActionStrip.tsx +0 -263
  281. package/src/react/NotificationBell.tsx +0 -426
  282. package/src/react/PendingSuggestionApplierRegistry.test.ts +0 -97
  283. package/src/react/PendingSuggestionApplierRegistry.ts +0 -98
  284. package/src/react/PendingSuggestionOverlayRegistry.ts +0 -54
  285. package/src/react/PendingSuggestionsContext.tsx +0 -172
  286. package/src/react/RecordWrapperGate.tsx +0 -58
  287. package/src/react/RecordWrapperRegistry.ts +0 -39
  288. package/src/react/RenderHookSlot.tsx +0 -32
  289. package/src/react/RightSidebar.tsx +0 -257
  290. package/src/react/RightSidebarContext.tsx +0 -234
  291. package/src/react/RightSidebarTrigger.tsx +0 -53
  292. package/src/react/RowCoordsContext.tsx +0 -23
  293. package/src/react/SchemaRenderer.tsx +0 -549
  294. package/src/react/SearchTrigger.tsx +0 -46
  295. package/src/react/ThemeProvider.tsx +0 -93
  296. package/src/react/ThemeSettingsPage.tsx +0 -579
  297. package/src/react/ThemeToggle.tsx +0 -20
  298. package/src/react/Toaster.tsx +0 -158
  299. package/src/react/UserMenu.tsx +0 -196
  300. package/src/react/WidgetDataContext.tsx +0 -157
  301. package/src/react/cells/EditableCell.tsx +0 -389
  302. package/src/react/component-slots.test.ts +0 -103
  303. package/src/react/component-slots.ts +0 -116
  304. package/src/react/fieldJsHandler.test.ts +0 -166
  305. package/src/react/fieldJsHandler.ts +0 -79
  306. package/src/react/fields/BuilderInput.tsx +0 -1078
  307. package/src/react/fields/CheckboxInput.tsx +0 -39
  308. package/src/react/fields/CheckboxListInput.tsx +0 -102
  309. package/src/react/fields/ColorInput.tsx +0 -71
  310. package/src/react/fields/DateFieldInput.tsx +0 -70
  311. package/src/react/fields/DateTimeInput.tsx +0 -62
  312. package/src/react/fields/FieldShell.tsx +0 -348
  313. package/src/react/fields/FileUploadInput.tsx +0 -639
  314. package/src/react/fields/HiddenInput.tsx +0 -17
  315. package/src/react/fields/KeyValueInput.tsx +0 -230
  316. package/src/react/fields/MarkdownInput.tsx +0 -560
  317. package/src/react/fields/RadioInput.tsx +0 -81
  318. package/src/react/fields/RepeaterInput.test.ts +0 -116
  319. package/src/react/fields/RepeaterInput.tsx +0 -1420
  320. package/src/react/fields/SelectFieldInput.tsx +0 -280
  321. package/src/react/fields/SliderInput.tsx +0 -81
  322. package/src/react/fields/TagsInput.tsx +0 -283
  323. package/src/react/fields/TextLikeInput.tsx +0 -256
  324. package/src/react/fields/ToggleButtonsInput.tsx +0 -60
  325. package/src/react/fields/ToggleFieldInput.tsx +0 -56
  326. package/src/react/fields/relationshipRenameDispatch.test.ts +0 -106
  327. package/src/react/fields/relationshipRenameDispatch.ts +0 -97
  328. package/src/react/fields/repeaterReconcile.test.ts +0 -114
  329. package/src/react/fields/repeaterReconcile.ts +0 -104
  330. package/src/react/fields/rowChromeButton.tsx +0 -336
  331. package/src/react/fields/rowState.ts +0 -106
  332. package/src/react/fields/syncRowGates.test.ts +0 -202
  333. package/src/react/fields/syncRowGates.ts +0 -66
  334. package/src/react/fields/textInputControls.tsx +0 -238
  335. package/src/react/fields/useRowReorderDnd.ts +0 -78
  336. package/src/react/formStateHelpers.test.ts +0 -508
  337. package/src/react/formStateHelpers.ts +0 -381
  338. package/src/react/hooks/use-mobile.ts +0 -19
  339. package/src/react/icon-context.tsx +0 -60
  340. package/src/react/index.ts +0 -194
  341. package/src/react/layouts/SidebarLayout.tsx +0 -250
  342. package/src/react/layouts/TopbarLayout.tsx +0 -258
  343. package/src/react/navigate.tsx +0 -37
  344. package/src/react/onProviderSynced.test.ts +0 -90
  345. package/src/react/parseRecordEditUrl.test.ts +0 -122
  346. package/src/react/parseRecordEditUrl.ts +0 -94
  347. package/src/react/persistedState.ts +0 -40
  348. package/src/react/registry.ts +0 -48
  349. package/src/react/right-panel-registry.tsx +0 -47
  350. package/src/react/schemaRenderer/AlertRenderer.tsx +0 -112
  351. package/src/react/schemaRenderer/EntryRenderer.tsx +0 -501
  352. package/src/react/schemaRenderer/SectionRenderer.tsx +0 -120
  353. package/src/react/schemaRenderer/SimpleElements.tsx +0 -306
  354. package/src/react/schemaRenderer/TabsRenderer.tsx +0 -62
  355. package/src/react/schemaRenderer/WizardRenderer.tsx +0 -338
  356. package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +0 -177
  357. package/src/react/schemaRenderer/action/ActionModalDialog.tsx +0 -273
  358. package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +0 -61
  359. package/src/react/schemaRenderer/action/HandlerActionButton.tsx +0 -43
  360. package/src/react/schemaRenderer/action/MethodActionButton.tsx +0 -64
  361. package/src/react/schemaRenderer/action/buttons.tsx +0 -99
  362. package/src/react/schemaRenderer/action/helpers.ts +0 -140
  363. package/src/react/schemaRenderer/action/renderAction.tsx +0 -245
  364. package/src/react/schemaRenderer/columnFormat.ts +0 -65
  365. package/src/react/schemaRenderer/constants.ts +0 -50
  366. package/src/react/schemaRenderer/form/FormRenderer.tsx +0 -274
  367. package/src/react/schemaRenderer/form/renderField.tsx +0 -511
  368. package/src/react/schemaRenderer/helpers.tsx +0 -81
  369. package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +0 -308
  370. package/src/react/schemaRenderer/table/TableRenderer.tsx +0 -123
  371. package/src/react/schemaRenderer/table/TableRendererBody.tsx +0 -974
  372. package/src/react/schemaRenderer/table/filters.tsx +0 -1233
  373. package/src/react/schemaRenderer/table/formatCell.tsx +0 -264
  374. package/src/react/schemaRenderer/table/links.tsx +0 -112
  375. package/src/react/schemaRenderer/table/renderRowActions.tsx +0 -52
  376. package/src/react/schemaRenderer/table/url.tsx +0 -143
  377. package/src/react/theme-preview/apply.ts +0 -99
  378. package/src/react/theme-preview/build-html.ts +0 -436
  379. package/src/react/ui/button.tsx +0 -51
  380. package/src/react/ui/calendar.tsx +0 -67
  381. package/src/react/ui/checkbox.tsx +0 -29
  382. package/src/react/ui/dialog.tsx +0 -108
  383. package/src/react/ui/dropdown-menu.tsx +0 -97
  384. package/src/react/ui/input.tsx +0 -20
  385. package/src/react/ui/label.tsx +0 -21
  386. package/src/react/ui/popover.tsx +0 -50
  387. package/src/react/ui/select.tsx +0 -169
  388. package/src/react/ui/separator.tsx +0 -25
  389. package/src/react/ui/sheet.tsx +0 -136
  390. package/src/react/ui/sidebar.tsx +0 -723
  391. package/src/react/ui/skeleton.tsx +0 -13
  392. package/src/react/ui/slider.tsx +0 -34
  393. package/src/react/ui/switch.tsx +0 -28
  394. package/src/react/ui/table.tsx +0 -105
  395. package/src/react/ui/tabs.tsx +0 -63
  396. package/src/react/ui/textarea.tsx +0 -18
  397. package/src/react/ui/tooltip.tsx +0 -64
  398. package/src/react/useResizableWidth.ts +0 -139
  399. package/src/react/utils.ts +0 -6
  400. package/src/react/widgetRegistry.test.ts +0 -43
  401. package/src/react/widgetRegistry.ts +0 -50
  402. package/src/react/widgets/StatsOverviewRenderer.tsx +0 -232
  403. package/src/react/widgets/TableWidgetRenderer.tsx +0 -231
  404. package/src/react/widgets/ViewRenderer.tsx +0 -71
  405. package/src/relationManagerData.test.ts +0 -1595
  406. package/src/richtext/index.ts +0 -8
  407. package/src/richtext/registry.ts +0 -89
  408. package/src/routes/globals.ts +0 -148
  409. package/src/routes/guard.test.ts +0 -325
  410. package/src/routes/helpers.ts +0 -704
  411. package/src/routes/pages.ts +0 -175
  412. package/src/routes/panel.ts +0 -204
  413. package/src/routes/relations.ts +0 -1243
  414. package/src/routes/resources.ts +0 -781
  415. package/src/routes/theme.ts +0 -91
  416. package/src/routes-nested-relations.test.ts +0 -676
  417. package/src/routes-relations.test.ts +0 -972
  418. package/src/routes.test.ts +0 -2027
  419. package/src/routes.ts +0 -303
  420. package/src/schema/Alert.test.ts +0 -109
  421. package/src/schema/Alert.ts +0 -131
  422. package/src/schema/Block.ts +0 -169
  423. package/src/schema/Breadcrumbs.ts +0 -40
  424. package/src/schema/Card.ts +0 -35
  425. package/src/schema/Divider.ts +0 -20
  426. package/src/schema/Element.ts +0 -219
  427. package/src/schema/EmptyState.test.ts +0 -37
  428. package/src/schema/EmptyState.ts +0 -63
  429. package/src/schema/Fieldset.ts +0 -43
  430. package/src/schema/Grid.ts +0 -43
  431. package/src/schema/Group.ts +0 -30
  432. package/src/schema/Heading.ts +0 -39
  433. package/src/schema/Html.ts +0 -67
  434. package/src/schema/Icon.ts +0 -54
  435. package/src/schema/Image.ts +0 -57
  436. package/src/schema/LinkTag.ts +0 -41
  437. package/src/schema/Markdown.ts +0 -85
  438. package/src/schema/MetaTag.ts +0 -41
  439. package/src/schema/RelationTabs.ts +0 -71
  440. package/src/schema/ScriptTag.ts +0 -55
  441. package/src/schema/Section.ts +0 -160
  442. package/src/schema/ServerDataElement.test.ts +0 -140
  443. package/src/schema/ServerDataElement.ts +0 -156
  444. package/src/schema/SlotComponent.test.ts +0 -77
  445. package/src/schema/SlotComponent.ts +0 -71
  446. package/src/schema/Split.ts +0 -50
  447. package/src/schema/Stat.test.ts +0 -118
  448. package/src/schema/Stat.ts +0 -154
  449. package/src/schema/StatsOverview.test.ts +0 -141
  450. package/src/schema/StatsOverview.ts +0 -119
  451. package/src/schema/StyleTag.ts +0 -35
  452. package/src/schema/TableWidget.test.ts +0 -297
  453. package/src/schema/TableWidget.ts +0 -289
  454. package/src/schema/Tabs.ts +0 -79
  455. package/src/schema/Text.ts +0 -58
  456. package/src/schema/UnorderedList.ts +0 -49
  457. package/src/schema/View.test.ts +0 -111
  458. package/src/schema/View.ts +0 -127
  459. package/src/schema/Wizard.ts +0 -220
  460. package/src/schema/containers.test.ts +0 -564
  461. package/src/schema/headTags.test.ts +0 -134
  462. package/src/schema/index.ts +0 -40
  463. package/src/schema/primes.test.ts +0 -269
  464. package/src/schema/resolveSchema.test.ts +0 -379
  465. package/src/schema/resolveSchema.ts +0 -917
  466. package/src/schema/sanitize.ts +0 -58
  467. package/src/search.test.ts +0 -446
  468. package/src/search.ts +0 -178
  469. package/src/sessionFilters.test.ts +0 -375
  470. package/src/sessionFilters.ts +0 -143
  471. package/src/slot-components/index.ts +0 -10
  472. package/src/slot-components/registry.ts +0 -56
  473. package/src/styles/file-upload.css +0 -13
  474. package/src/summarizers/Summarizer.test.ts +0 -84
  475. package/src/summarizers/Summarizer.ts +0 -123
  476. package/src/summarizers/index.ts +0 -11
  477. package/src/theme/base-colors.ts +0 -68
  478. package/src/theme/chart-colors.ts +0 -50
  479. package/src/theme/colors.ts +0 -447
  480. package/src/theme/generate-css.test.ts +0 -139
  481. package/src/theme/generate-css.ts +0 -44
  482. package/src/theme/generate-scale.test.ts +0 -106
  483. package/src/theme/generate-scale.ts +0 -97
  484. package/src/theme/icon-map.ts +0 -42
  485. package/src/theme/index.ts +0 -34
  486. package/src/theme/migrate.test.ts +0 -178
  487. package/src/theme/migrate.ts +0 -81
  488. package/src/theme/presets.ts +0 -135
  489. package/src/theme/radius.ts +0 -18
  490. package/src/theme/resolve.test.ts +0 -238
  491. package/src/theme/resolve.ts +0 -96
  492. package/src/theme/spacing.ts +0 -18
  493. package/src/theme/storage.test.ts +0 -126
  494. package/src/theme/storage.ts +0 -106
  495. package/src/theme/theme-colors.ts +0 -88
  496. package/src/theme/types.ts +0 -125
  497. package/src/uploads/UploadAdapter.ts +0 -35
  498. package/src/uploads/index.ts +0 -2
  499. package/src/uploads/localUpload.test.ts +0 -70
  500. package/src/uploads/localUpload.ts +0 -84
  501. package/src/validation/Validator.ts +0 -49
  502. package/src/validation/index.ts +0 -28
  503. package/src/validation/rules.ts +0 -78
  504. package/src/validation/runValidators.ts +0 -435
  505. package/src/validation/uniqueValidator.test.ts +0 -196
  506. package/src/validation/uniqueValidator.ts +0 -133
  507. package/src/validation/validators.test.ts +0 -268
  508. package/src/vite.test.ts +0 -184
  509. package/src/vite.ts +0 -787
  510. package/src/widgets/index.ts +0 -10
  511. package/src/widgets/registry.ts +0 -45
  512. package/src/widgets.test.ts +0 -592
  513. package/tsconfig.build.json +0 -11
  514. package/tsconfig.json +0 -4
  515. package/tsconfig.test.json +0 -10
  516. package/views/react/Dashboard.tsx +0 -27
  517. package/views/react/Resources/Form.tsx +0 -102
  518. package/views/react/Resources/Index.tsx +0 -49
package/src/Column.ts DELETED
@@ -1,710 +0,0 @@
1
- import { Element, type ElementMeta } from './schema/Element.js'
2
- import { Summarizer, type SummarizerMeta } from './summarizers/Summarizer.js'
3
- import type { SanitizeConfig } from './schema/sanitize.js'
4
- import type {
5
- Validator,
6
- ValidatorContext,
7
- SerializedRule,
8
- } from './validation/Validator.js'
9
-
10
- /** Cell content alignment. Maps to text-{start|center|end} on the cell. */
11
- export type ColumnAlignment = 'start' | 'center' | 'end'
12
-
13
- /** Visual variant. The default `text` covers most cases — formatters
14
- * (dateTime / money / since / numeric / limit) layer on top.
15
- * `badge` / `icon` / `boolean` / `image` are subclasses that change
16
- * how the cell is *rendered* rather than just *formatted*.
17
- * `textInput` / `toggle` / `select` are inline-edit subclasses — the
18
- * renderer mounts an interactive control that PATCHes a single column
19
- * via `POST {base}/{slug}/:id/_cell/:column`. */
20
- export type ColumnType =
21
- | 'text' | 'badge' | 'icon' | 'boolean' | 'image' | 'color'
22
- | 'textInput' | 'toggle' | 'select'
23
-
24
- /** Per-row predicate for `Column.disabled(fn)` — evaluated server-side
25
- * inside `loadTableRecords` so the renderer just reads the result. */
26
- export type ColumnDisabledFn = (record: Record<string, unknown>) => boolean
27
-
28
- /** Context handed to `Column.beforeStateUpdated / afterStateUpdated`
29
- * hooks on editable cell columns. `record` is the row as loaded
30
- * *before* the update; `user` is the resolved panel user. */
31
- export interface CellStateHookContext {
32
- record: Record<string, unknown>
33
- user?: unknown
34
- }
35
-
36
- /** Hook signature for `Column.beforeStateUpdated / afterStateUpdated`.
37
- * Return value is ignored — these are side-effect hooks. Throw an
38
- * Error to halt the PATCH; the thrown message lands under `errors._cell`
39
- * in the 422 response so the renderer can surface it next to the cell. */
40
- export type CellStateHook = (
41
- value: unknown,
42
- ctx: CellStateHookContext,
43
- ) => void | Promise<void>
44
-
45
- /** SelectColumn option shape — mirrors `SelectField`'s static option form. */
46
- export interface ColumnSelectOption {
47
- value: string
48
- label: string
49
- }
50
-
51
- /** Font weight preset — maps to a Tailwind `font-*` class. */
52
- export type ColumnWeight = 'normal' | 'medium' | 'semibold' | 'bold'
53
-
54
- /** Color preset for the cell text. `muted` greys the value. */
55
- export type ColumnColor = 'default' | 'muted' | 'primary' | 'destructive' | 'success' | 'warning' | 'info'
56
-
57
- /** Built-in formatters serialized to the client. `kind` drives the
58
- * client-side switch; the rest of the fields carry per-kind options. */
59
- export type ColumnFormat =
60
- | { kind: 'dateTime'; pattern?: string }
61
- | { kind: 'since' }
62
- | { kind: 'money'; currency: string; locale?: string }
63
- | { kind: 'numeric'; decimals?: number; locale?: string }
64
- | { kind: 'limit'; chars: number }
65
- | { kind: 'words'; words: number }
66
-
67
- /** Rich-text column kind — server-rendered HTML stamped per row.
68
- * Markdown values run through `marked` first; HTML values pass straight
69
- * to `sanitize-html`. Both honor `_sanitize` (default `true`). */
70
- export type ColumnRichTextKind = 'markdown' | 'html'
71
-
72
- /** Per-row formatter callback. Returns the rendered cell content as a
73
- * string. Runs server-side inside `loadTableRecords` (the function
74
- * isn't serializable to the client). */
75
- export type FormatStateHandler = (value: unknown, record: Record<string, unknown>) => string
76
-
77
- /** Per-row record-URL callback. Returns the destination URL for clicks
78
- * on this column's cell, or `undefined` to skip linking that row. Runs
79
- * server-side inside `loadTableRecords`. */
80
- export type ColumnRecordUrlHandler = (record: Record<string, unknown>) => string | undefined
81
-
82
- /** Configuration for `Column.toggleable(...)`. The user can show / hide the
83
- * column from a per-table dropdown; preference persists to localStorage so
84
- * it survives reloads + SPA navs. `initiallyHidden` flips the default state
85
- * so the column starts off-screen and the user opts in. */
86
- export interface ColumnToggleableConfig {
87
- initiallyHidden?: boolean
88
- }
89
-
90
- export interface ColumnMeta extends ElementMeta {
91
- type: 'column'
92
- name: string
93
- label: string
94
- sortable: boolean
95
- searchable: boolean
96
- columnType?: ColumnType
97
- alignment?: ColumnAlignment
98
- width?: string
99
- default?: string
100
- tooltip?: string
101
- wrap?: boolean
102
- lineClamp?: number
103
- weight?: ColumnWeight
104
- color?: ColumnColor
105
- format?: ColumnFormat
106
- /** True when a `formatStateUsing` callback is set. The renderer reads
107
- * formatted values out of `row._formatted[columnName]` instead of
108
- * re-applying the column's format spec. */
109
- hasFormatter?: boolean
110
- /** Per-column footer summarizers — kind + optional label. The actual
111
- * computed values for each summarizer land on the table meta under
112
- * `summaries[columnName]` (`SummaryResult[]`), not on the column. */
113
- summaries?: SummarizerMeta[]
114
- /** True when the user can show / hide this column from the toolbar's
115
- * "Columns" dropdown. `initiallyHidden` flips the default state so
116
- * the column starts off until the user opts in. */
117
- toggleable?: { initiallyHidden?: true }
118
- /** Render array values one-per-line (each item separated by `<br>`).
119
- * Composes with `bulleted()` — when both are set, `bulleted()` wins
120
- * and the renderer mounts a `<ul>` with bullet markers instead. */
121
- listWithLineBreaks?: true
122
- /** Render array values as a `<ul>` bullet list. Wins over
123
- * `listWithLineBreaks()` when both are set. */
124
- bulleted?: true
125
- /** Mounts a copy-to-clipboard trigger after the cell value. The string
126
- * is the toast message shown after a successful copy (default
127
- * `"Copied!"` when bare `.copyable()` is used). */
128
- copyMessage?: string
129
- /** Server-rendered rich-text discriminator. When set, the renderer
130
- * reads the rendered HTML from `row._formatted[col.name]` and
131
- * dangerouslySetsInnerHTML it (matches the existing Tiptap richtext
132
- * cell path). The kind drives server-side rendering — `markdown` runs
133
- * through `marked` first; `html` is passthrough. Sanitization applies
134
- * to both unless the column opts out. */
135
- richText?: ColumnRichTextKind
136
- /**
137
- * Per-column record-URL behavior. The default (absent) means the cell
138
- * inherits the table's `recordUrl` for click navigation. `false` opts
139
- * the column out — clicks on this column's cell don't navigate anywhere.
140
- * `true` means the column has its own URL handler; the resolved URL
141
- * is stamped onto each row under `row._columnRecordUrls[columnName]`.
142
- */
143
- recordUrl?: boolean
144
- // ─── Editable cell columns (TextInput / Toggle / Select) ───
145
- /** Confirmation message — when set, the renderer gates the PATCH
146
- * behind a Dialog confirm before firing. */
147
- confirm?: string
148
- /** Static disable. Per-row disable (`disabled(fn)`) lands on the row
149
- * under `row._cellDisabled[columnName]` — not on the column meta. */
150
- disabled?: true
151
- /** Mirrored validator descriptors — same shape as `FieldMeta.rules`,
152
- * for client-side hint rendering. The actual rules run server-side
153
- * inside the `_cell` route. */
154
- rules?: SerializedRule[]
155
- /** Default debounce (ms) for committed-after-typing PATCHes on
156
- * `TextInputColumn`. Stamped on the meta only when explicitly set;
157
- * the renderer falls back to its own default. */
158
- debounceMs?: number
159
- // Subclass-specific extras land in `_extra` to keep the meta typed.
160
- // BadgeColumn — value-to-color map.
161
- badgeColors?: Record<string, string>
162
- // IconColumn — value-to-{icon,color} map.
163
- iconOptions?: Record<string, { icon: string; color?: string }>
164
- // ImageColumn — sizing.
165
- imageSize?: number
166
- imageShape?: 'square' | 'circle'
167
- // ColorColumn — swatch shape + value-text suppression.
168
- colorShape?: 'rounded' | 'square' | 'circle'
169
- colorHideValue?: true
170
- // TextInputColumn.
171
- inputType?: 'text' | 'number' | 'email' | 'url' | 'tel'
172
- inputPlaceholder?: string
173
- inputStep?: number
174
- inputMin?: number
175
- inputMax?: number
176
- // ToggleColumn.
177
- toggleOnColor?: ColumnColor
178
- toggleOffColor?: ColumnColor
179
- toggleOnIcon?: string
180
- toggleOffIcon?: string
181
- // SelectColumn.
182
- selectOptions?: ColumnSelectOption[]
183
- selectNullable?: true
184
- /** Hide the placeholder option once a value is set. Default: keep
185
- * showing it so users can clear the value (matches Filament). */
186
- selectablePlaceholder?: false
187
- }
188
-
189
- /**
190
- * Base column primitive — used directly for text cells (the most common
191
- * case) or extended into `BadgeColumn` / `IconColumn` / `BooleanColumn` /
192
- * `ImageColumn` for visual variants. Joins the schema tree as an
193
- * Element so it serializes through the same resolver pipeline as
194
- * Fields and display elements. Lives as a child of `Table`.
195
- */
196
- export class Column extends Element {
197
- readonly name: string
198
- protected _label?: string
199
- protected _sortable = false
200
- protected _searchable = false
201
-
202
- // Visual / layout
203
- protected _columnType: ColumnType = 'text'
204
- protected _alignment?: ColumnAlignment
205
- protected _width?: string
206
- protected _default?: string
207
- protected _tooltip?: string
208
- protected _wrap = false
209
- protected _lineClamp?: number
210
- protected _weight?: ColumnWeight
211
- protected _color?: ColumnColor
212
-
213
- // Formatters
214
- protected _format?: ColumnFormat
215
- protected _formatState?: FormatStateHandler
216
-
217
- // Per-column record-URL override / opt-out. `false` disables linking
218
- // for this column; a function overrides the table's URL with a
219
- // column-specific one. Unset = inherit the table's recordUrl.
220
- protected _recordUrl?: false | ColumnRecordUrlHandler
221
-
222
- // Footer summarizers (Sum / Average / Count / Range). Computed by
223
- // `loadTableRecords` over the rendered rows; values land on the
224
- // table-level summaries map keyed by column name.
225
- protected _summarizers: Summarizer[] = []
226
-
227
- // Rich-display chrome (Filament-parity Tier-2). All optional, all
228
- // emit-only-when-set — the wire shape stays tidy on the bare-text path.
229
- protected _listWithLineBreaks = false
230
- protected _bulleted = false
231
- protected _copyMessage?: string
232
- // Rich-text rendering — either `'markdown'` or `'html'`. The dispatcher
233
- // server-renders the cell + stamps `_formatted[name] / _richtextCells[name]`.
234
- protected _richText?: ColumnRichTextKind
235
- protected _sanitize: boolean | SanitizeConfig = true
236
-
237
- // User-toggleable column visibility — `Table.toggleColumns()` opt-in
238
- // chrome reads this and stamps the toolbar dropdown. State persists
239
- // per-table to localStorage so the user's choice sticks across loads.
240
- protected _toggleable: false | ColumnToggleableConfig = false
241
-
242
- // ─── Editable cell columns (TextInput / Toggle / Select) ───
243
- // Per-cell PATCH validators — same shape as Field validators. Only
244
- // consulted when the column is editable (the route handler reads
245
- // them server-side). Inert on read-only columns.
246
- protected _required = false
247
- protected _validators: Validator[] = []
248
- protected _confirm?: string
249
- protected _staticDisabled = false
250
- protected _disabledFn?: ColumnDisabledFn
251
- protected _beforeStateUpdated?: CellStateHook
252
- protected _afterStateUpdated?: CellStateHook
253
-
254
- protected constructor(name: string) {
255
- super()
256
- this.name = name
257
- }
258
-
259
- static make(name: string): Column {
260
- return new Column(name)
261
- }
262
-
263
- // ─── Identity ─────────────────────────────────────────
264
-
265
- label(l: string): this { this._label = l; return this }
266
- sortable(v = true): this { this._sortable = v; return this }
267
- searchable(v = true): this { this._searchable = v; return this }
268
-
269
- /**
270
- * Let the user show / hide this column from the table toolbar's
271
- * "Columns" dropdown. Preference persists per-table to localStorage
272
- * under `pilotiq.table.<currentPath>.columns.<col>` so the choice
273
- * sticks across reloads + SPA navigations.
274
- *
275
- * Pass `{ initiallyHidden: true }` to start the column off-screen —
276
- * useful for technical / debug columns the user opts into.
277
- *
278
- * Column.make('email').toggleable()
279
- * Column.make('internalId').toggleable({ initiallyHidden: true })
280
- * Column.make('name').toggleable(false) // explicit opt-out
281
- *
282
- * Any non-toggleable column always renders. Hidden state is purely
283
- * presentational — the column's data still loads from the server (so
284
- * sorts / filters that reference it keep working, and a re-toggle
285
- * shows fresh values without a roundtrip).
286
- */
287
- toggleable(opts: boolean | ColumnToggleableConfig = true): this {
288
- if (opts === false) {
289
- this._toggleable = false
290
- } else if (opts === true) {
291
- this._toggleable = {}
292
- } else {
293
- this._toggleable = { ...opts }
294
- }
295
- return this
296
- }
297
-
298
- isToggleable(): boolean { return this._toggleable !== false }
299
- getToggleableConfig(): ColumnToggleableConfig | undefined {
300
- return this._toggleable === false ? undefined : this._toggleable
301
- }
302
-
303
- // ─── Layout ───────────────────────────────────────────
304
-
305
- alignment(a: ColumnAlignment): this { this._alignment = a; return this }
306
- width(w: string): this { this._width = w; return this }
307
-
308
- /** Fallback string when the cell value is null / undefined / empty. */
309
- default(s: string): this { this._default = s; return this }
310
- /** Alias for `default()` to match the Filament spelling. */
311
- placeholder(s: string): this { return this.default(s) }
312
-
313
- tooltip(t: string): this { this._tooltip = t; return this }
314
-
315
- /** Render the cell with `whitespace-normal`; long content wraps onto
316
- * multiple lines instead of getting truncated. */
317
- wrap(v = true): this { this._wrap = v; return this }
318
-
319
- /** CSS line-clamp for multi-line truncation (replaces `wrap`). */
320
- lineClamp(n: number): this { this._lineClamp = n; return this }
321
-
322
- weight(w: ColumnWeight): this { this._weight = w; return this }
323
- color(c: ColumnColor): this { this._color = c; return this }
324
-
325
- // ─── Built-in formatters ──────────────────────────────
326
-
327
- /** Format a date / datetime value via `Intl.DateTimeFormat`. The
328
- * default pattern produces "Jan 1, 2026, 9:00 AM"-style output. */
329
- dateTime(pattern?: string): this {
330
- this._format = pattern ? { kind: 'dateTime', pattern } : { kind: 'dateTime' }
331
- return this
332
- }
333
-
334
- /** Render the value as relative time ("5 minutes ago"). */
335
- since(): this {
336
- this._format = { kind: 'since' }
337
- return this
338
- }
339
-
340
- /** Format the value as currency. `currency` is the ISO 4217 code
341
- * (e.g. 'USD', 'EUR'). */
342
- money(currency: string, locale?: string): this {
343
- this._format = locale ? { kind: 'money', currency, locale } : { kind: 'money', currency }
344
- return this
345
- }
346
-
347
- /** Format the value as a decimal number. */
348
- numeric(opts: { decimals?: number; locale?: string } = {}): this {
349
- this._format = {
350
- kind: 'numeric',
351
- ...(opts.decimals !== undefined ? { decimals: opts.decimals } : {}),
352
- ...(opts.locale !== undefined ? { locale: opts.locale } : {}),
353
- }
354
- return this
355
- }
356
-
357
- /** Truncate the cell to `chars` characters with an ellipsis. */
358
- limit(chars: number): this {
359
- this._format = { kind: 'limit', chars }
360
- return this
361
- }
362
-
363
- /**
364
- * Truncate the cell to `n` words with an ellipsis. Splits on whitespace
365
- * runs (`/\s+/`) — empty lead/trail tokens collapse so a value like
366
- * `" hello world "` truncates the same as `"hello world"`. Composes
367
- * mutually-exclusively with `limit()` and `characters()` (each
368
- * formatter overwrites the previous one — last call wins).
369
- */
370
- words(n: number): this {
371
- this._format = { kind: 'words', words: n }
372
- return this
373
- }
374
-
375
- /**
376
- * Filament-parity alias for `limit(n)`. Same wire shape — both call
377
- * sites read better depending on whether you're capping by character
378
- * count or word count.
379
- */
380
- characters(n: number): this { return this.limit(n) }
381
-
382
- /**
383
- * Render array values one-per-line. Non-array values pass through
384
- * unchanged. Composes with `bulleted()` — when both are set,
385
- * `bulleted()` wins (bullet list is the strictly richer presentation;
386
- * line breaks become implicit).
387
- */
388
- listWithLineBreaks(v = true): this { this._listWithLineBreaks = v; return this }
389
-
390
- /**
391
- * Render array values as a `<ul>` bullet list. Non-array values pass
392
- * through unchanged. Wins over `listWithLineBreaks()` when both are
393
- * set.
394
- */
395
- bulleted(v = true): this { this._bulleted = v; return this }
396
-
397
- /**
398
- * Mount a copy-to-clipboard trigger next to the cell value. The
399
- * `message` (default `"Copied!"`) is the toast shown after a
400
- * successful copy. The button copies the rendered cell text — for
401
- * rich-text cells (`markdown() / html()`) the underlying source is
402
- * copied instead of the rendered HTML so users get the version they
403
- * can re-edit. Bare `copyMessage()` opts in with the default copy.
404
- */
405
- copyMessage(message?: string): this {
406
- this._copyMessage = message ?? 'Copied!'
407
- return this
408
- }
409
-
410
- /**
411
- * Render the cell's value as Markdown — server-runs through `marked`
412
- * (already a dep of pilotiq from `Markdown` prime) and the result
413
- * lands as sanitized HTML in `row._formatted[name]` with
414
- * `_richtextCells[name] = true`. The renderer recognizes the flag and
415
- * mounts the cell via `dangerouslySetInnerHTML` against the same
416
- * `prose-sm` container the Tiptap richtext path uses.
417
- *
418
- * Mutually exclusive with `html()` — the last call wins. Pair with
419
- * `.allowRaw()` / `.sanitize({ allowedTags: [...] })` to relax the
420
- * default-secure allowlist for admin-trusted content.
421
- */
422
- markdown(v = true): this {
423
- if (v) this._richText = 'markdown'
424
- else delete this._richText
425
- return this
426
- }
427
-
428
- /**
429
- * Render the cell's value as raw HTML — passes straight through
430
- * `sanitize-html` against the default-secure allowlist (no Markdown
431
- * conversion). Mutually exclusive with `markdown()`.
432
- */
433
- html(v = true): this {
434
- if (v) this._richText = 'html'
435
- else delete this._richText
436
- return this
437
- }
438
-
439
- /**
440
- * Sanitization control for `markdown()` / `html()` cells. Default
441
- * `true` — runs the rendered HTML through `DEFAULT_SANITIZE_CONFIG`
442
- * before the wire shape ships. Pass `false` (or call `.allowRaw()`)
443
- * to disable; pass a `sanitize-html` config to widen the allowlist
444
- * (e.g. legacy CMS content with embedded media). Mirrors the
445
- * `Markdown` / `Html` prime APIs so authors can carry the same
446
- * intuition into a column context.
447
- */
448
- sanitize(v: boolean | SanitizeConfig = true): this {
449
- this._sanitize = v
450
- return this
451
- }
452
-
453
- /** Sugar — opt out of the default-secure sanitizer. */
454
- allowRaw(): this { this._sanitize = false; return this }
455
-
456
- /** Custom per-row formatter — runs server-side inside `loadTableRecords`
457
- * and stashes the resulting string on `row._formatted[name]`. Wins
458
- * over the built-in `format` spec when both are set. */
459
- formatStateUsing(fn: FormatStateHandler): this {
460
- this._formatState = fn
461
- return this
462
- }
463
-
464
- /**
465
- * Per-column record-URL behavior. Pass `false` to opt this column out
466
- * of the table's row-level `recordUrl` — clicks on this column's cell
467
- * won't navigate. Pass a function to override with a column-specific
468
- * URL. Without calling this, the column inherits the table's
469
- * `recordUrl`.
470
- *
471
- * Filament parity: matches `Tables\Columns\Column::url(...)` and
472
- * `->recordUrl(false)` semantics.
473
- */
474
- recordUrl(target: false | ColumnRecordUrlHandler): this {
475
- this._recordUrl = target
476
- return this
477
- }
478
-
479
- /**
480
- * Attach summarizers (Sum / Average / Count / Range) to this column.
481
- * They render in a `<tfoot>` row under the column. Values are computed
482
- * server-side over the rows currently on screen — per-page only in
483
- * v1; cross-page aggregation is deferred.
484
- */
485
- summarize(summarizers: Summarizer[]): this {
486
- this._summarizers = summarizers
487
- return this
488
- }
489
-
490
- // ─── Editable cell columns ────────────────────────────
491
- // These are no-ops on read-only column types but live on the base so
492
- // subclass authors don't need to redeclare. `isEditable()` derives
493
- // from `_columnType` — TextInputColumn / ToggleColumn / SelectColumn
494
- // call `setColumnType()` in their `make()` factory.
495
-
496
- /** Mark the value as required for inline edits. Auto-contributes a
497
- * required check unless `validate(required())` is already present
498
- * (matches `Field.required()` semantics — see `hasRequiredValidator`). */
499
- required(v = true): this { this._required = v; return this }
500
-
501
- /**
502
- * Attach one or more server-side validators. Reuses the same `Validator`
503
- * type used by `Field.validate()` so existing rules (`required`, `email`,
504
- * `minLength`, `unique`, …) work unchanged. Validators run inside the
505
- * `POST {…}/_cell/:column` route before `R.model.update`; on failure
506
- * the response is `422 { ok:false, errors: { value: string[] } }`.
507
- */
508
- validate(v: Validator | Validator[]): this {
509
- if (Array.isArray(v)) this._validators.push(...v)
510
- else this._validators.push(v)
511
- return this
512
- }
513
-
514
- /**
515
- * Gate the PATCH behind a confirm dialog. Renderer opens a Dialog with
516
- * `message` before firing the network call; cancel rolls back the
517
- * optimistic local state.
518
- */
519
- confirm(message: string): this { this._confirm = message; return this }
520
-
521
- /**
522
- * Run a hook on the server BEFORE the editable cell's value is written
523
- * to the database. Receives the coerced + validated value plus the
524
- * current row as `{ record, user }`. Use for cross-cell invariants,
525
- * audit-log writes that must precede the update, or async availability
526
- * checks that the schema-level validators don't cover. Throw an Error
527
- * to halt — the thrown message lands under the reserved `_cell` error
528
- * key in the 422 response.
529
- */
530
- beforeStateUpdated(fn: CellStateHook): this { this._beforeStateUpdated = fn; return this }
531
-
532
- /**
533
- * Run a hook on the server AFTER the editable cell's value is written
534
- * to the database. Same context shape as `beforeStateUpdated`. Use for
535
- * notifications, broadcast events, or follow-up writes that should
536
- * fire only on a confirmed save. Throwing here returns 422 with the
537
- * message under `_cell` — the row is already updated, so prefer
538
- * surfacing the error and letting the user retry rather than rolling
539
- * back manually.
540
- */
541
- afterStateUpdated(fn: CellStateHook): this { this._afterStateUpdated = fn; return this }
542
-
543
- getBeforeStateUpdated(): CellStateHook | undefined { return this._beforeStateUpdated }
544
- getAfterStateUpdated(): CellStateHook | undefined { return this._afterStateUpdated }
545
-
546
- /**
547
- * Render the inline-edit control disabled. Pass `true` (or call with no
548
- * args) for static disable; pass a `(record) => boolean` predicate for
549
- * per-row disable — evaluated server-side inside `loadTableRecords`,
550
- * stashed under `row._cellDisabled[columnName]`.
551
- *
552
- * Independent from `R.canEdit(user, record)` — the auth check fires
553
- * regardless and a forbidden record never sees an editable affordance.
554
- */
555
- disabled(value: boolean | ColumnDisabledFn = true): this {
556
- if (typeof value === 'function') {
557
- this._disabledFn = value
558
- this._staticDisabled = false
559
- } else {
560
- this._staticDisabled = value
561
- delete this._disabledFn
562
- }
563
- return this
564
- }
565
-
566
- // ─── Column-type setter (subclass internal) ───────────
567
-
568
- protected setColumnType(t: ColumnType): this {
569
- this._columnType = t
570
- return this
571
- }
572
-
573
- // ─── Getters ──────────────────────────────────────────
574
-
575
- getLabel(): string {
576
- return this._label ?? this.name.charAt(0).toUpperCase() + this.name.slice(1)
577
- }
578
- isSortable(): boolean { return this._sortable }
579
- isSearchable(): boolean { return this._searchable }
580
- getColumnType(): ColumnType { return this._columnType }
581
- getFormatStateHandler(): FormatStateHandler | undefined { return this._formatState }
582
- hasFormatter(): boolean { return this._formatState !== undefined }
583
- /** True when a built-in `format` spec (`dateTime / since / money /
584
- * numeric / limit`) is configured. Used by walkers that want to skip
585
- * columns the user has already chosen formatting for. */
586
- hasFormat(): boolean { return this._format !== undefined }
587
- getRecordUrlHandler(): ColumnRecordUrlHandler | undefined {
588
- return typeof this._recordUrl === 'function' ? this._recordUrl : undefined
589
- }
590
- hasRecordUrlHandler(): boolean { return typeof this._recordUrl === 'function' }
591
- isRecordUrlDisabled(): boolean { return this._recordUrl === false }
592
- getSummarizers(): ReadonlyArray<Summarizer> { return this._summarizers }
593
- hasSummarizers(): boolean { return this._summarizers.length > 0 }
594
-
595
- /** Rich-text discriminator. Used by `dispatchTable` to decide whether
596
- * to server-render the cell value through `marked` + `sanitize-html`. */
597
- getRichTextKind(): ColumnRichTextKind | undefined { return this._richText }
598
- isRichText(): boolean { return this._richText !== undefined }
599
- getSanitize(): boolean | SanitizeConfig { return this._sanitize }
600
-
601
- // ─── Editable getters ─────────────────────────────────
602
-
603
- /** True for `TextInputColumn / ToggleColumn / SelectColumn`. The route
604
- * handler + `dispatchTable` per-row stamping consult this. */
605
- isEditable(): boolean {
606
- return this._columnType === 'textInput'
607
- || this._columnType === 'toggle'
608
- || this._columnType === 'select'
609
- }
610
-
611
- /** Resolve per-row disable for an editable cell. Returns `true` when
612
- * the static flag is set or the optional predicate returns truthy.
613
- * Errors in the predicate fail closed (disabled) — silently swallowing
614
- * a save attempt is the worse outcome here. */
615
- isDisabledFor(record: Record<string, unknown>): boolean {
616
- if (this._staticDisabled) return true
617
- if (this._disabledFn) {
618
- try { return Boolean(this._disabledFn(record)) }
619
- catch { return true }
620
- }
621
- return false
622
- }
623
-
624
- isRequired(): boolean { return this._required }
625
- getValidators(): ReadonlyArray<Validator> { return this._validators }
626
-
627
- /** Run the column's validators against a candidate value. Mirrors
628
- * `Field.runValidators` — including the implicit required check when
629
- * `_required` is set without an explicit `required()` validator. */
630
- async runValidators(value: unknown, ctx?: ValidatorContext): Promise<string[]> {
631
- const errors: string[] = []
632
- if (this._required && !this.hasRequiredValidator()) {
633
- if (value === undefined || value === null || value === '') {
634
- errors.push('This field is required')
635
- }
636
- }
637
- for (const v of this._validators) {
638
- const result = await v(value, ctx)
639
- if (result) errors.push(result)
640
- }
641
- return errors
642
- }
643
-
644
- private hasRequiredValidator(): boolean {
645
- return this._validators.some(v => v.serialized?.rule === 'required')
646
- }
647
-
648
- /** Serialized rule descriptors mirrored to the client. */
649
- protected getSerializedRules(): SerializedRule[] {
650
- const rules: SerializedRule[] = []
651
- if (this._required && !this.hasRequiredValidator()) {
652
- rules.push({ rule: 'required', message: 'This field is required' })
653
- }
654
- for (const v of this._validators) {
655
- if (v.serialized) rules.push(v.serialized)
656
- }
657
- return rules
658
- }
659
-
660
- // ─── Serialization ────────────────────────────────────
661
-
662
- override getType(): string { return 'column' }
663
-
664
- override toMeta(): ColumnMeta {
665
- const meta: ColumnMeta = {
666
- type: 'column',
667
- name: this.name,
668
- label: this.getLabel(),
669
- sortable: this._sortable,
670
- searchable: this._searchable,
671
- }
672
- // Only emit columnType when non-default to keep meta tidy.
673
- if (this._columnType !== 'text') meta.columnType = this._columnType
674
- if (this._alignment !== undefined) meta.alignment = this._alignment
675
- if (this._width !== undefined) meta.width = this._width
676
- if (this._default !== undefined) meta.default = this._default
677
- if (this._tooltip !== undefined) meta.tooltip = this._tooltip
678
- if (this._wrap) meta.wrap = true
679
- if (this._lineClamp !== undefined) meta.lineClamp = this._lineClamp
680
- if (this._weight !== undefined) meta.weight = this._weight
681
- if (this._color !== undefined) meta.color = this._color
682
- if (this._format !== undefined) meta.format = this._format
683
- if (this._formatState !== undefined) meta.hasFormatter = true
684
- if (this._summarizers.length > 0) meta.summaries = this._summarizers.map(s => s.toMeta())
685
- if (this._toggleable !== false) {
686
- meta.toggleable = this._toggleable.initiallyHidden ? { initiallyHidden: true } : {}
687
- }
688
- if (this._listWithLineBreaks) meta.listWithLineBreaks = true
689
- if (this._bulleted) meta.bulleted = true
690
- if (this._copyMessage !== undefined) meta.copyMessage = this._copyMessage
691
- if (this._richText !== undefined) meta.richText = this._richText
692
- if (this._recordUrl === false) meta.recordUrl = false
693
- else if (typeof this._recordUrl === 'function') meta.recordUrl = true
694
- // Editable cell columns — chrome that the renderer needs to mount
695
- // the right inline control. Per-row `_cellEditable / _cellEditUrls /
696
- // _cellDisabled` are stamped onto each row by `loadTableRecords` +
697
- // `tagCellEditUrls` and aren't part of the column's static meta.
698
- if (this.isEditable()) {
699
- if (this._confirm !== undefined) meta.confirm = this._confirm
700
- if (this._staticDisabled) meta.disabled = true
701
- const rules = this.getSerializedRules()
702
- if (rules.length > 0) meta.rules = rules
703
- }
704
- this.serializeExtras(meta)
705
- return meta
706
- }
707
-
708
- /** Hook for subclasses to add columnType-specific fields to the meta. */
709
- protected serializeExtras(_meta: ColumnMeta): void {}
710
- }