@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/CHANGELOG.md CHANGED
@@ -1,5 +1,62 @@
1
1
  # @pilotiq/pilotiq
2
2
 
3
+ ## 0.24.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 02d5793: fix(pilotiq): panel routes resolve the live panel at request time — dev edits reflect without a server restart
8
+
9
+ Panel route handlers closed over the `Pilotiq` instance captured when their routes were registered. In dev, editing the panel module (or a resource/page schema it imports) re-registers a fresh panel in `PilotiqRegistry`, but those already-registered handler closures kept pointing at the stale instance — so SSR-rendered chrome and schema lagged a reload behind (the panel only updated after editing some _other_ watched file, or a restart).
10
+
11
+ The render-data layer now re-resolves the panel from `PilotiqRegistry` by name at request time, via a new `livePanel()` helper, applied at the top of `panelInfo` (chrome) and every render-data builder (`resourcePages`, `misc`, `relationPages`). This mirrors what `dispatchPageData()` already did for the client-nav path; the SSR route path was the only outlier. `livePanel()` falls back to the passed instance when the registry has no entry (tests, teardown), so non-dev behavior is unchanged.
12
+
13
+ - 539c87a: feat(pilotiq): ship `pilotiq-actions` boost skill — Phase B residual #1
14
+
15
+ First of the four still-open Phase B skill candidates. `SKILL.md` declares `appliesTo: ['@pilotiq/pilotiq']` so `@rudderjs/boost`'s `boost:install` writes it under `.ai/skills/` only when the consumer has `@pilotiq/pilotiq` installed. Trigger scopes to specific action-authoring contexts — adding header/row/bulk buttons, wiring a modal-form action, customizing per-row visibility, reaching for a built-in factory.
16
+
17
+ Three rule files under `boost/skills/pilotiq-actions/rules/`:
18
+
19
+ - **`dispatch-modes.md`** — 4 mutually-exclusive modes (`href` / `method` / `handler` / `submit`), modal-form as a flavor of handler, return shape, `ctx` shape, 12 modal chrome setters, `.confirm()` + `.formField()` interactions.
20
+ - **`visibility-and-authorization.md`** — 4 conditional setters (`visible / hidden / disabled / authorize`), `ActionVisibilityContext`, fail-closed semantics (opposite of layout-visible), per-row gating cost model, composing with Resource policies.
21
+ - **`factories.md`** — 25 pre-built factories (`create / edit / view / delete / replicate / restore / forceDelete / markAsRead`, bulk variants, `import / export`, relation\* variants including M2M `attach / detach`), `ReplicateOptions` with `getCreatedNotificationTitle / getRedirectUrl` callbacks, when to skip factories for compound flows.
22
+
23
+ Mirrors the shape established by `pilotiq-resource` / `pilotiq-fields` / `pilotiq-relations` / `pilotiq-tiptap-blocks`.
24
+
25
+ Remaining Phase B residuals (lower priority — `guidelines.md` already covers most of what they'd add): `pilotiq-widgets`, `pilotiq-theme`, `pilotiq-vite-plugin`.
26
+
27
+ ## 0.24.2
28
+
29
+ ### Patch Changes
30
+
31
+ - 28fbd5f: feat(pilotiq): ship `boost/guidelines.md` for `@rudderjs/boost` discovery
32
+
33
+ Consumer Rudder apps with `@rudderjs/boost` installed now pick up `@pilotiq/pilotiq` AI coding guidelines automatically. Running `rudder boost:install` in the consumer writes the contents to `.ai/guidelines/pilotiq.md`, and the per-agent config files (`CLAUDE.md` / `.cursorrules` / `AGENTS.md` / etc.) include them in the concatenated guideline body.
34
+
35
+ The guidelines cover Resource definition (with `static model` auto-fill), folder-per-resource layout, the form-field catalog + common setters, layout primitives (Section / Tabs / Group / Wizard / Split / Fieldset), tables (columns + filters + groups + actions + reorder), Action with the four dispatch modes and modal-form variant, Page base classes (`ListPage` / `CreatePage` / `EditPage` / `ViewPage`) with override hooks, authorization via `Pilotiq.user()` + `can*` statics, Globals, Relations (`RelationManager` + `Repeater.relationship()`), reactive fields, theming, common pitfalls, and the key import surface.
36
+
37
+ Phase A of the boost-producer rollout — skills (`boost/skills/<name>/SKILL.md`) follow in subsequent releases. Adapter packages (`@pilotiq/tiptap` / `@pilotiq/codemirror` / `@pilotiq/recharts`) ship their own guidelines + `appliesTo`-gated skills separately.
38
+
39
+ - e36d65c: feat(pilotiq): ship boost skills — pilotiq-resource, pilotiq-fields, pilotiq-relations
40
+
41
+ Phase B of the boost-producer rollout. Adds three task-specific skill modules under `packages/pilotiq/boost/skills/`:
42
+
43
+ - **pilotiq-resource** — `SKILL.md` + 3 rules: defining-resources, page-overrides, authorization
44
+ - **pilotiq-fields** — `SKILL.md` + 3 rules: field-catalog (24 field types), validation (built-ins + `unique` + `distinct`), reactive-fields (`live` + `afterStateUpdated` + `$get`/`$set`)
45
+ - **pilotiq-relations** — `SKILL.md` + 2 rules: relation-managers (hasMany / morph / M2M), repeater-relationship (`Repeater.relationship` + `Builder.relationship`)
46
+
47
+ Each SKILL.md declares `appliesTo: ['@pilotiq/pilotiq']` so `@rudderjs/boost`'s `boost:install` only writes them to `.ai/skills/` when the consumer has `@pilotiq/pilotiq` installed. Triggers are scoped to specific work contexts — defining a Resource, adding a form field, wiring a relation — so AI agents load the deeper rule files on-demand rather than always-on.
48
+
49
+ Phase C (adapter packages — `@pilotiq/tiptap` / `@pilotiq/codemirror` / `@pilotiq/recharts`) and the remaining four skill candidates (pilotiq-actions, pilotiq-widgets, pilotiq-theme, pilotiq-vite-plugin) follow in subsequent releases.
50
+
51
+ - 6d2ac13: chore: slim published tarballs to `dist` + `boost` + `CHANGELOG.md`
52
+
53
+ All four packages now declare `"files": ["dist", "boost", "CHANGELOG.md"]` so npm pack only ships the compiled output, the `@rudderjs/boost` guidelines + skills tree, and the changelog. Previously `@pilotiq/pilotiq` shipped its full `src/`, `CLAUDE.md`, `.turbo/`, and test files; the three adapters shipped `src/` deliberately but no longer need to.
54
+
55
+ - **`@pilotiq/pilotiq`** — 2.1 MB → 1.3 MB (~38% smaller). Drops `src/**`, `CLAUDE.md`, `.turbo/` from the tarball.
56
+ - **`@pilotiq/tiptap` / `@pilotiq/codemirror` / `@pilotiq/recharts`** — drop `src/**` from the tarball.
57
+
58
+ No API impact. Consumer Tailwind `@source` rules that previously scanned `node_modules/@pilotiq/*/src` should re-point at `node_modules/@pilotiq/*/dist` (Tailwind scans `.js` just fine). Source maps in `dist/` still reference `../src/*.ts` paths that are no longer in the tarball — sourcemap navigation inside `node_modules` won't resolve to TS, but stack traces still line up.
59
+
3
60
  ## 0.24.1
4
61
 
5
62
  ### Patch Changes
@@ -0,0 +1,571 @@
1
+ # @pilotiq/pilotiq
2
+
3
+ ## Overview
4
+
5
+ View-based admin panel for RudderJS. A declarative class hierarchy (`Resource`, `Page`, `Action`, schema `Element`s) describes CRUD-managed entities; the framework auto-generates list / create / edit / view pages, table chrome, form validation + submit, and dropdown actions. The Vite plugin generates Vike page stubs at the panel's mount path; the runtime provider registers the routes. No code generation, no codegen step — declare the resource, register it on a panel, the pages exist.
6
+
7
+ Pilotiq sits on top of `@rudderjs/orm` (ergonomically — `Resource.model = ModelLike` auto-fills `Form.save` / `Form.loadRecord` / `Resource.deleteRecord` / `Table.records`) but doesn't hard-depend on it. Any `ModelLike` shape works (custom ORMs, testing doubles).
8
+
9
+ ## Setup
10
+
11
+ Two files, two lines each.
12
+
13
+ **`vite.config.ts`**
14
+
15
+ ```ts
16
+ import { pilotiq } from '@pilotiq/pilotiq/vite'
17
+
18
+ export default defineConfig({
19
+ plugins: [
20
+ pilotiq(), // before @rudderjs/vite + vike
21
+ rudderjs(),
22
+ vike(),
23
+ tailwindcss(),
24
+ react(),
25
+ ],
26
+ })
27
+ ```
28
+
29
+ **`bootstrap/providers.ts`**
30
+
31
+ ```ts
32
+ import { pilotiq } from '@pilotiq/pilotiq'
33
+ import { adminPanel } from '../app/Pilotiq/AdminPanel.js'
34
+
35
+ export default [
36
+ ...(await defaultProviders()),
37
+ pilotiq([adminPanel]),
38
+ ] satisfies (new (app: Application) => ServiceProvider)[]
39
+ ```
40
+
41
+ `@pilotiq/pilotiq` MUST be in `optimizeDeps.exclude` (it imports `node:fs` server-side and Vite must not pre-bundle for the browser).
42
+
43
+ ## Key Patterns
44
+
45
+ ### Defining a Resource
46
+
47
+ The shortest path: point `static model` at a `@rudderjs/orm` `Model` and the framework infers CRUD from the column metadata.
48
+
49
+ ```ts
50
+ import { Resource, Form, Table, Column, TextField } from '@pilotiq/pilotiq'
51
+ import { Article } from '../Models/Article.js'
52
+
53
+ export class ArticleResource extends Resource {
54
+ static override label = 'Articles'
55
+ static override labelSingular = 'Article'
56
+ static override icon = 'file-text'
57
+ static override model = Article
58
+
59
+ static override form(form: Form): Form {
60
+ return form.schema([
61
+ TextField.make('title').required().placeholder('Article title…'),
62
+ TextField.make('slug').required(),
63
+ ])
64
+ }
65
+
66
+ static override table(table: Table): Table {
67
+ return table
68
+ .columns([
69
+ Column.make('title').sortable().searchable(),
70
+ Column.make('slug').searchable(),
71
+ Column.make('createdAt').sortable().label('Created'),
72
+ ])
73
+ .defaultSort('createdAt', 'desc')
74
+ .paginate(10)
75
+ }
76
+ }
77
+ ```
78
+
79
+ What you get for free with `static model`:
80
+
81
+ - **List**: `Table.records()` paginates `Article.query()`. `Column.searchable()` joins via `LIKE`/`orWhere`; `Column.sortable()` maps to `orderBy`.
82
+ - **Create**: `Form.save()` calls `Article.create(data)`.
83
+ - **Edit**: `Form.loadRecord(id)` calls `Article.find(id)`; `Form.save()` discriminates create vs update by the record's PK.
84
+ - **Delete**: `Resource.deleteRecord(id)` calls `Article.delete(id)`. Soft-deletes work out of the box if the Model declares `static softDeletes = true` AND the Resource declares `static softDeletes = true`.
85
+ - **Observers / mass-assignment / casts**: anything you set on the Model carries through.
86
+
87
+ Register on the panel:
88
+
89
+ ```ts
90
+ Pilotiq.make('Admin').path('/admin').resources([ArticleResource])
91
+ ```
92
+
93
+ This gives working list / create / edit / view pages at `/admin/articles*`. Every method on `Resource` is **static** — Resources register as classes, not instances.
94
+
95
+ ### Folder-per-resource layout (for non-trivial resources)
96
+
97
+ ```
98
+ app/Pilotiq/Articles/
99
+ ├── ArticleResource.ts # binds form / table / detail / pages
100
+ ├── Pages/
101
+ │ ├── ListArticles.ts # extends ListPage
102
+ │ ├── CreateArticle.ts # extends CreatePage
103
+ │ ├── EditArticle.ts # extends EditPage
104
+ │ └── ViewArticle.ts # extends ViewPage
105
+ ├── Schemas/
106
+ │ ├── form.ts # exported form() function
107
+ │ └── table.ts # exported table() function
108
+ └── RelationManagers/
109
+ └── CommentsRelationManager.ts
110
+ ```
111
+
112
+ ### Form Fields
113
+
114
+ | Field | Renders |
115
+ |---|---|
116
+ | `TextField` | `<input type="text">` — adds `password()`, `revealable()`, `copyable()`, `mask()`, `prefixAction()`, `suffixAction()` |
117
+ | `EmailField` | `<input type="email">` (auto `email()` validator) |
118
+ | `NumberField` | `<input type="number">` + `min() / max() / step()` |
119
+ | `Slider` | range track |
120
+ | `Textarea` | `<textarea>` + `autosize()` / `rows()` |
121
+ | `MarkdownField` | textarea + preview tabs |
122
+ | `RichTextField` | Tiptap editor (`@pilotiq/tiptap`) |
123
+ | `CodeEditorField` | CodeMirror 6 (`@pilotiq/codemirror`) |
124
+ | `SelectField` | searchable Select; `options(arr \| fn)`, `createOptionForm()` for inline-create |
125
+ | `RadioField` | radio stack |
126
+ | `ToggleButtons` | chip-style segmented (sugar over Radio) |
127
+ | `CheckboxField` | single checkbox (bool) |
128
+ | `CheckboxList` | checkbox stack (`string[]`) |
129
+ | `ToggleField` | switch (bool) |
130
+ | `TagsInput` | chip multi-tag (`string[]`) |
131
+ | `KeyValueField` | key/value rows (`Record<string, string>`) |
132
+ | `DateField` / `DateTimePicker` | calendar popovers |
133
+ | `ColorPicker` | hex input + swatch |
134
+ | `FileUpload` | drop zone (needs `Pilotiq.uploads({ adapter })`) |
135
+ | `Repeater` | array-of-subschema with reorderable rows |
136
+ | `Builder` | heterogeneous Repeater — each row is one of N block types |
137
+ | `HiddenField` | submitted but not rendered |
138
+
139
+ Every field inherits these setters from `Field`:
140
+
141
+ ```ts
142
+ Field.make('name')
143
+ .label('Display label')
144
+ .helperText('Shown below the input')
145
+ .placeholder('e.g. Hello world')
146
+ .default('initial value')
147
+ .prefix('$') // or .prefix({ icon: 'dollar' })
148
+ .suffix('USD')
149
+ .required()
150
+ .validate([Field.email(), Field.unique({ model: User })])
151
+ .visible(({ user }) => user.role === 'admin')
152
+ .hidden(rule)
153
+ .disabled(rule)
154
+ .columnSpan(2) // inside a Grid / Section.columns(n)
155
+ .live() // re-resolve schema on change
156
+ .afterStateUpdated((value, ctx) => ctx.$set('slug', slugify(value)))
157
+ .dehydrated(false) // don't submit
158
+ .autofocus()
159
+ .hiddenLabel()
160
+ .disabledOn(['edit']) // page-mode sugar
161
+ .hiddenOn(['view'])
162
+ .visibleOn(['create', 'edit'])
163
+ ```
164
+
165
+ ### Form Layouts
166
+
167
+ ```ts
168
+ Section.make('Customer details')
169
+ .description('Name and contact info')
170
+ .icon('user')
171
+ .columns(2)
172
+ .schema([
173
+ TextField.make('first'),
174
+ TextField.make('last'),
175
+ TextField.make('email').columnSpan(2),
176
+ ])
177
+ ```
178
+
179
+ Section setters: `.description(text)`, `.icon(name)`, `.badge(text)`, `.aside()` (right rail under `Split`), `.compact()`, `.dense()`, `.secondary()` (muted), `.collapsible()`, `.collapsed()`, `.persistCollapsed('key')`, `.afterHeader([Action…])`.
180
+
181
+ Other layout primitives:
182
+
183
+ | Element | Use case |
184
+ |---|---|
185
+ | `Grid` | Named CSS grid; children declare `columnSpan(n)` / `columnStart(n)` |
186
+ | `Group` | Chrome-less wrapper — useful for visibility gating without a border |
187
+ | `Fieldset` | `<fieldset><legend>` semantics, lighter than Section |
188
+ | `Split` | Two-column layout; second child auto-routes to right-rail (or use `Section.aside()`) |
189
+ | `Tabs` | Tab strip; each `Tab.make(name).schema([…])` is one panel |
190
+ | `Wizard` | Multi-step form. Each `Step.make().schema(...)` validates before advancing |
191
+
192
+ ```ts
193
+ Wizard.make()
194
+ .steps([
195
+ Step.make('Account') .icon('user') .schema([...]),
196
+ Step.make('Billing') .icon('credit-card').schema([...]),
197
+ Step.make('Confirm') .icon('check') .schema([...]),
198
+ ])
199
+ .skippable() // allow forward without saving
200
+ .startOnStep(0)
201
+ .persist(false) // disable URL ?step= persistence
202
+ ```
203
+
204
+ ### Tables
205
+
206
+ ```ts
207
+ table
208
+ .columns([
209
+ Column.make('title').sortable().searchable(),
210
+ Column.make('status').badge().colors({ draft: 'gray', live: 'success' }),
211
+ Column.make('createdAt').sortable().since().label('Created'),
212
+ ])
213
+ .defaultSort('createdAt', 'desc')
214
+ .paginate(10)
215
+ .filters([
216
+ SelectFilter.make('status').options({ draft: 'Draft', live: 'Live' }),
217
+ TernaryFilter.make('isPublished').label('Published?'),
218
+ TrashedFilter.make(), // when softDeletes = true
219
+ ])
220
+ .actions([Action.edit, Action.delete])
221
+ .bulkActions([Action.bulkDelete])
222
+ .reorderable('position') // drag-handle reorder + persistence
223
+ .persistFiltersInSession() // 302-restore stored URL slice
224
+ .groups([
225
+ TableGroup.make('status').collapsible(),
226
+ ])
227
+ ```
228
+
229
+ Column types: `Column` (text, default), `ImageColumn`, `IconColumn`, `BadgeColumn` / `Column.badge()`, `ColorColumn`, `TextColumn` (rich-display: words/chars/bulleted/markdown/html), `IconColumn`. Common setters: `.sortable()`, `.searchable()`, `.label()`, `.copyable()`, `.tooltip()`, `.formatStateUsing(v => …)`, `.url(rec => '/path')`.
230
+
231
+ Filters: `Filter` (generic), `SelectFilter`, `TernaryFilter` (yes/no/all), `TrashedFilter`, `QueryBuilderFilter` (runtime constraint builder).
232
+
233
+ ### Actions
234
+
235
+ `Action` is the unified primitive for buttons — header / row / bulk / form-submit / dropdown items. Same builder, four placement modes (`inline | row | header | bulk`), four mutually-exclusive dispatch modes (`href / method / handler / submit`).
236
+
237
+ ```ts
238
+ Action.make('publish')
239
+ .label('Publish')
240
+ .color('success')
241
+ .icon('send')
242
+ .visible(({ record }) => record.status === 'draft')
243
+ .handler(async (ctx) => {
244
+ await ctx.record.publish()
245
+ return { notify: Notification.success('Published') }
246
+ })
247
+ ```
248
+
249
+ Built-in factories: `Action.create(...)`, `Action.edit(R, base, id)`, `Action.delete()`, `Action.replicate(R, base, id)`, `Action.restore(...)`, `Action.forceDelete(...)`, `Action.export(...)`, `Action.import(...)`, `Action.bulkDelete()`, `Action.relation*(...)` (attach / detach / bulkDetach).
250
+
251
+ Add `.schema([…])` to make the action open a form-modal:
252
+
253
+ ```ts
254
+ Action.make('reschedule')
255
+ .icon('calendar')
256
+ .schema([DateTimePicker.make('at').required()])
257
+ .handler(async (ctx) => {
258
+ await ctx.record.reschedule(ctx.values.at)
259
+ })
260
+ ```
261
+
262
+ Modal chrome setters: `.modalHeading(...)`, `.modalDescription(...)`, `.modalIcon(...)`, `.modalWidth('sm'|'md'|'lg'|'xl')`, `.slideOver()`, `.stickyModalHeader()`, `.closeModalByEscaping(false)`, `.modalContentFooter([Alert, …])`.
263
+
264
+ Group actions in a dropdown:
265
+
266
+ ```ts
267
+ ActionGroup.make('more').label('More').icon('more-horizontal').actions([
268
+ Action.make('export').handler(…),
269
+ Action.make('clone').handler(…),
270
+ ])
271
+ ```
272
+
273
+ ### Pages
274
+
275
+ A Page is "anything with a `schema()`" — the unit of routing, content, and lifecycle. The base `Page` class covers custom pages registered via `panel.pages([AnalyticsPage])`; resource-bound pages can additionally extend `ListPage`, `CreatePage`, `EditPage`, or `ViewPage` to expose override hooks (`getHeader`, `getFormActions`, `beforeCreate`, `afterUpdate`, etc.).
276
+
277
+ ```ts
278
+ import { Page, Heading, Card, Text } from '@pilotiq/pilotiq'
279
+
280
+ class AnalyticsPage extends Page {
281
+ static override slug = 'analytics' // optional — derived from class name
282
+ static override label = 'Analytics'
283
+ static override icon = 'bar-chart-3'
284
+
285
+ static override schema(ctx) {
286
+ return [
287
+ Heading.make('Site analytics').level(1),
288
+ Card.make().schema([
289
+ Text.make('Stats coming soon.'),
290
+ ]),
291
+ ]
292
+ }
293
+ }
294
+ ```
295
+
296
+ Resource page overrides — `static pages()` returns the four (or fewer) bases:
297
+
298
+ ```ts
299
+ class ArticleResource extends Resource {
300
+ static override pages() {
301
+ return {
302
+ list: ListArticles,
303
+ create: CreateArticle,
304
+ edit: EditArticle,
305
+ view: ViewArticle,
306
+ }
307
+ }
308
+ }
309
+
310
+ class CreateArticle extends CreatePage {
311
+ static override beforeCreate(data, ctx) {
312
+ data.authorId = ctx.user.id
313
+ return data
314
+ }
315
+ }
316
+
317
+ class EditArticle extends EditPage {
318
+ static override getFormActions(actions: Action[]): Action[] {
319
+ return [
320
+ ...actions,
321
+ Action.make('preview').href(`/preview/${'${ctx.record.id}'}`).color('ghost'),
322
+ ]
323
+ }
324
+ }
325
+ ```
326
+
327
+ Wizard create-page:
328
+
329
+ ```ts
330
+ class CreateArticle extends CreatePage {
331
+ static override getSteps() {
332
+ return [
333
+ Step.make('Content') .schema([TextField.make('title'), MarkdownField.make('body')]),
334
+ Step.make('Publish') .schema([DateField.make('publishAt'), ToggleField.make('isPublic')]),
335
+ ]
336
+ }
337
+ }
338
+ ```
339
+
340
+ ### Authorization
341
+
342
+ Resources declare `can*` statics; the framework calls them with the resolved user from `Pilotiq.user(req => …)`. Routes fail closed (403 if any predicate returns false).
343
+
344
+ ```ts
345
+ Pilotiq.make('Admin')
346
+ .path('/admin')
347
+ .user(async (req) => req.session?.user ?? null)
348
+ .resources([ArticleResource])
349
+
350
+ class ArticleResource extends Resource {
351
+ static override canAccess(user) { return Boolean(user) }
352
+ static override canView(user, record) { return user.id === record.authorId || user.role === 'admin' }
353
+ static override canCreate(user) { return user.role !== 'reader' }
354
+ static override canEdit(user, record) { return user.id === record.authorId }
355
+ static override canDelete(user, record) { return user.role === 'admin' }
356
+ }
357
+ ```
358
+
359
+ Per-record gates on collection pages stamp `_visibleActions` / `_disabledActions` on each row before rendering, so server-side eval results are consistent with what the client renders.
360
+
361
+ ### Globals (singleton resources)
362
+
363
+ `Global` is a singleton-shaped Resource. Same builder, minus list/create/delete; routes are `GET/POST {base}/{slug}` for edit, `GET {base}/{slug}/view` for view.
364
+
365
+ ```ts
366
+ class SiteSettings extends Global {
367
+ static override label = 'Site Settings'
368
+ static override icon = 'settings'
369
+ static override model = Settings
370
+ static override navigationGroup = 'Settings' // default
371
+
372
+ static override form(form) {
373
+ return form.schema([
374
+ TextField.make('siteName').required(),
375
+ Textarea.make('description'),
376
+ ColorPicker.make('brandColor'),
377
+ ])
378
+ }
379
+
380
+ static override canAccess(user) { return user.role === 'admin' }
381
+ static override canEdit(user) { return user.role === 'admin' }
382
+ }
383
+ ```
384
+
385
+ ### Relations
386
+
387
+ `Resource.relations()` returns `RelationManager[]`. Each manager renders as a tab on the parent resource's view/edit page.
388
+
389
+ ```ts
390
+ class ArticleResource extends Resource {
391
+ static override relations(): RelationManagerClass[] {
392
+ return [CommentsRelationManager, TagsRelationManager]
393
+ }
394
+ }
395
+
396
+ class CommentsRelationManager extends RelationManager {
397
+ static override relationName = 'comments' // Article.comments() relation
398
+ static override label = 'Comments'
399
+ static override icon = 'message-square'
400
+
401
+ static override table(table) {
402
+ return table.columns([
403
+ Column.make('body').searchable(),
404
+ Column.make('author.name').label('Author'),
405
+ Column.make('createdAt').since(),
406
+ ])
407
+ }
408
+
409
+ static override form(form) {
410
+ return form.schema([Textarea.make('body').required()])
411
+ }
412
+ }
413
+ ```
414
+
415
+ Supports `hasMany`, `belongsToMany` (with pivot extras via `.pivotColumns([…])`), `morphMany`, `morphTo`, `morphToMany`, `morphedByMany`. Use `Action.relationAttach()`, `Action.relationDetach()`, `Action.relationBulkDetach()` for M2M attach/detach UI.
416
+
417
+ Repeater fields can also be relation-backed via `.relationship('comments')` — same `hasMany`/`morph*`/`M2M` set.
418
+
419
+ ### Reactive fields
420
+
421
+ `.live()` re-resolves the schema on change; `afterStateUpdated()` fires server-side imperative updates against `$state`:
422
+
423
+ ```ts
424
+ TextField.make('title')
425
+ .live()
426
+ .afterStateUpdated((title, ctx) => ctx.$set('slug', slugify(title)))
427
+
428
+ SelectField.make('country').options(countries).live()
429
+ SelectField.make('region').options(({ $get }) => {
430
+ const country = $get('country')
431
+ return country ? regionsFor(country) : {}
432
+ })
433
+ ```
434
+
435
+ Multi-form pages (record-page with multiple panels) must pin `formId` explicitly: `Form.make().formId('details')`. The auto-fallback covers single-form pages.
436
+
437
+ Client-only reactivity (no server round-trip): `afterStateUpdatedJs(`$set('slug', $state.title.toLowerCase().replace(/\s+/g, '-'))`)`.
438
+
439
+ ### Theming / Branding
440
+
441
+ ```ts
442
+ Pilotiq.make('Admin')
443
+ .branding({ name: 'Acme', logo: '/logo.svg', primaryColor: '#3b82f6' })
444
+ .theme('nova') // built-in preset
445
+ .layout('sidebar', { variant: 'inset', collapsible: 'icon', side: 'left' }) // see below
446
+ .use(themeEditor()) // exposes /admin/theme runtime editor
447
+ ```
448
+
449
+ Presets: `default`, `nova`, `maia`, `lyra`. Custom themes pass a `Theme` object to `.theme()`.
450
+
451
+ **`.layout(mode, opts?)`** — `mode` is `'sidebar' | 'topbar'`. The optional second arg configures the sidebar's chrome and is **bound to the `'sidebar'` mode**: `.layout('topbar', {...})` is a compile error (so sidebar-only config can't silently no-op under topbar). Sidebar keys (all optional):
452
+ - `variant`: `'inset'` (default — content floats in a rounded card) · `'floating'` (sidebar itself floats) · `'sidebar'` (classic full-height flush rail)
453
+ - `collapsible`: `'icon'` (default — collapses to an icon rail) · `'offcanvas'` (slides fully off-screen) · `'none'` (always expanded)
454
+ - `side`: `'left'` (default, RTL-aware) · `'right'`
455
+
456
+ Plugin-shaped extensions: `.plugins([tiptap(), codeEditor(), recharts()])` — register adapter packages in one call.
457
+
458
+ ## Common Pitfalls
459
+
460
+ - **`@pilotiq/pilotiq` must be in `optimizeDeps.exclude`.** Pre-bundling pulls `node:fs` into the browser bundle and crashes the dev server with a `node:fs` client error.
461
+ - **`static`, not instance.** Every Resource / Page / RelationManager method (`form`, `table`, `relations`, `canAccess`, …) is static. The framework invokes `R.form(…)` directly — instance methods don't run.
462
+ - **Folder-per-resource for non-trivial resources.** Inlining everything in `index.ts` becomes unwieldy past two columns of code. Split `Pages/`, `Schemas/`, `RelationManagers/` early.
463
+ - **Soft-deletes are two-sided.** `Model.softDeletes = true` (in `@rudderjs/orm`) AND `Resource.softDeletes = true` are both required. Setting only one silently drops the restore/force-delete UI without an error.
464
+ - **Multi-form record pages must pin `formId`.** `Form.make().formId('details')` is required when more than one form lives on a single page; otherwise live-resolves cross-talk between forms.
465
+ - **Use real per-cell `<a href>` over row `onClick`.** `Column.url(rec => …)` preserves cmd-click, new-tab, middle-click, and screen-reader semantics. Row-level click handlers break all of those.
466
+ - **Manual provider composition is fine — auto-discovery is optional.** `bootstrap/providers.ts` can return an explicit array `[pilotiq([panel]), ...]` without invoking `rudder providers:discover`. The doctor warn for "providers manifest missing" doesn't apply.
467
+ - **Auto-generated `pages/(pilotiq)/` stubs are gitignored.** Never commit them — the Vite plugin regenerates them on every dev start.
468
+
469
+ ## Key Imports
470
+
471
+ ```ts
472
+ import {
473
+ // Builder + provider
474
+ Pilotiq,
475
+ pilotiq, // service-provider factory
476
+
477
+ // Core classes
478
+ Resource,
479
+ Global,
480
+ Page,
481
+ ListPage,
482
+ CreatePage,
483
+ EditPage,
484
+ ViewPage,
485
+ RelationManager,
486
+ Cluster, // group resources under a URL prefix
487
+ Notification,
488
+ AdminPanel,
489
+
490
+ // Schema base + layouts
491
+ Form,
492
+ Table,
493
+ Section,
494
+ Tabs,
495
+ Tab,
496
+ Group,
497
+ Fieldset,
498
+ Split,
499
+ Grid,
500
+ Wizard,
501
+ Step,
502
+ Repeater,
503
+ Builder,
504
+ Heading,
505
+ Text,
506
+ Alert,
507
+ Card,
508
+ Divider,
509
+ UnorderedList,
510
+
511
+ // Fields
512
+ Field,
513
+ TextField,
514
+ EmailField,
515
+ NumberField,
516
+ Slider,
517
+ Textarea,
518
+ MarkdownField,
519
+ SelectField,
520
+ RadioField,
521
+ ToggleButtons,
522
+ CheckboxField,
523
+ CheckboxList,
524
+ ToggleField,
525
+ TagsInput,
526
+ KeyValueField,
527
+ DateField,
528
+ DateTimePicker,
529
+ ColorPicker,
530
+ FileUpload,
531
+ HiddenField,
532
+
533
+ // Tables
534
+ Column,
535
+ ImageColumn,
536
+ IconColumn,
537
+ BadgeColumn,
538
+ ColorColumn,
539
+ TextColumn,
540
+ TableGroup,
541
+
542
+ // Filters
543
+ Filter,
544
+ SelectFilter,
545
+ TernaryFilter,
546
+ TrashedFilter,
547
+ QueryBuilderFilter,
548
+
549
+ // Actions
550
+ Action,
551
+ ActionGroup,
552
+
553
+ // Infolist entries (read-only display)
554
+ Entry,
555
+ TextEntry,
556
+ BadgeEntry,
557
+ IconEntry,
558
+ ImageEntry,
559
+ KeyValueEntry,
560
+ ColorEntry,
561
+ RepeatableEntry,
562
+ } from '@pilotiq/pilotiq'
563
+
564
+ // Subpaths
565
+ import { pilotiq } from '@pilotiq/pilotiq/vite' // vite plugin
566
+ import { useNavigate } from '@pilotiq/pilotiq/react' // SPA navigate
567
+ import { localUpload, s3Upload } from '@pilotiq/pilotiq/uploads' // upload adapters
568
+ import { themeEditor } from '@pilotiq/pilotiq/plugins' // built-in plugins
569
+ ```
570
+
571
+ Adapter packages (separate npm packages — install only what you use): `@pilotiq/tiptap` (RichTextField + custom blocks), `@pilotiq/codemirror` (CodeEditorField), `@pilotiq/recharts` (Chart widget).
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: pilotiq-actions
3
+ description: Buttons, modal-form actions, and built-in CRUD/import/export/relation factories in pilotiq — the 4 dispatch modes, visibility/authorize layers, and per-row gating
4
+ license: MIT
5
+ appliesTo:
6
+ - '@pilotiq/pilotiq'
7
+ trigger: adding header / row / bulk action buttons to a `Resource.table()` / page, wiring a modal-form action, customizing per-row visibility via `visible()` / `authorize()`, or using one of the `Action.*` factories (`create` / `edit` / `delete` / `replicate` / `import` / `export` / `relation*` / `bulk*`)
8
+ skip: customizing the form schema itself (use `pilotiq-fields`) or wiring a relation tab as a whole (use `pilotiq-relations`)
9
+ metadata:
10
+ author: pilotiq
11
+ ---
12
+
13
+ # Pilotiq Actions
14
+
15
+ ## When to use this skill
16
+
17
+ Load when you're:
18
+
19
+ - Adding action buttons to a page — header actions, row actions, bulk actions, inline actions
20
+ - Wiring a modal-form action (`Action.make('foo').schema([Field…]).handler(ctx => …)`)
21
+ - Customizing chrome (colors, sizes, icons, tooltips, outlined / icon-only / destructive)
22
+ - Setting visibility / disabled / authorize rules — including per-row gating that re-evaluates on every list row
23
+ - Reaching for a built-in factory: `Action.create / edit / view / delete / replicate / import / export / restore / forceDelete / markAsRead / bulkDelete / bulkRestore / bulkForceDelete / bulkReplicate / bulkExport / relation*`
24
+
25
+ For the form schema *inside* an action's modal, that's `pilotiq-fields`. For the resource-side `Resource.table().recordActions([…])` wiring, this skill covers the action surface itself; `pilotiq-resource` covers when to subclass `ListPage` to override `getHeaderActions()` etc.
26
+
27
+ ## Quick Reference
28
+
29
+ | Task | Open |
30
+ |---|---|
31
+ | 4 dispatch modes — `href` / `method` / `handler` / `submit`; modal-form via `.schema([…]).handler()`; `formField` for submit-button pairs | `rules/dispatch-modes.md` |
32
+ | Visibility, disabled, authorize — `ActionVisibilityContext`, per-row gating, fail-closed semantics, async predicates | `rules/visibility-and-authorization.md` |
33
+ | Built-in factories — `Action.create / .edit / .delete / .replicate / .import / .export / .relation*` plus bulk variants; chrome + visibility defaults | `rules/factories.md` |
34
+
35
+ ## Key concepts (load once)
36
+
37
+ - **Every action is `Action.make(name).<setters>`.** No subclassing. The `name` is the discriminator for visibility lookups + the dispatch URL slug.
38
+ - **Four dispatch modes are mutually exclusive.** `.href(url)` = link. `.method('POST').action(url)` = form-post. `.handler(ctx => …)` = JSON dispatch via the framework's `_action/:name` route. `.submit()` = trigger the enclosing form's submit.
39
+ - **Modal-form is a flavor of handler.** Calling `.schema([Field, …])` flips an action into modal-form mode: clicking the trigger opens a Dialog with the schema as a real pilotiq form; submit fetches the action's dispatch URL with the form body.
40
+ - **Placement determines where the button mounts.** `inline` (default, in-page) / `bulk` (toolbar when rows selected) / `row` (per-row) / `header` (page header). Placement is implicit from how you pass the action — `Resource.table().recordActions([…])` are row, `.bulkActions([…])` are bulk, etc.
41
+ - **Visibility is fail-closed.** `.visible(rule)` / `.hidden(rule)` / `.disabled(rule)` / `.authorize(rule)` accept `boolean | (ctx) => boolean | Promise<boolean>`. Throwing → visibility false. `ActionVisibilityContext` carries `{ record?, records?, user? }` depending on placement.
42
+ - **Row-placement actions evaluate per row.** The framework calls each row's predicates in `loadTableRecords` and stamps `row._visibleActions: name[]` / `row._disabledActions: name[]`. The renderer filters its action strip against that stamp.
43
+ - **All non-modal handler dispatches SPA-update.** Fetch with `Accept: application/json`, drain notifications via `useToast()`, then `useNavigate(redirect)`. No page reload. Only form-post `method` actions (e.g. `Action.delete`) still use the 303-redirect path for back-compat.
44
+
45
+ ## Examples
46
+
47
+ - `playground/app/Pilotiq/Articles/ArticleResource.ts` — header/row actions with built-in factories.
48
+ - `playground/app/Pilotiq/Posts/PostResource.ts` — modal-form action (`Action.make('publish').schema([…]).handler(…)`).
49
+ - `playground/app/Pilotiq/Users/UserResource.ts` — `Action.replicate` with `beforeReplicaSaved` mutator.