@pilotiq/pilotiq 0.23.1 → 0.24.2

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 (500) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/boost/guidelines.md +566 -0
  3. package/boost/skills/pilotiq-fields/SKILL.md +47 -0
  4. package/boost/skills/pilotiq-fields/rules/field-catalog.md +288 -0
  5. package/boost/skills/pilotiq-fields/rules/reactive-fields.md +199 -0
  6. package/boost/skills/pilotiq-fields/rules/validation.md +198 -0
  7. package/boost/skills/pilotiq-relations/SKILL.md +47 -0
  8. package/boost/skills/pilotiq-relations/rules/relation-managers.md +256 -0
  9. package/boost/skills/pilotiq-relations/rules/repeater-relationship.md +177 -0
  10. package/boost/skills/pilotiq-resource/SKILL.md +61 -0
  11. package/boost/skills/pilotiq-resource/rules/authorization.md +242 -0
  12. package/boost/skills/pilotiq-resource/rules/defining-resources.md +228 -0
  13. package/boost/skills/pilotiq-resource/rules/page-overrides.md +296 -0
  14. package/dist/actions/exportFactory.d.ts +10 -0
  15. package/dist/actions/exportFactory.d.ts.map +1 -1
  16. package/dist/actions/exportFactory.js +10 -0
  17. package/dist/actions/exportFactory.js.map +1 -1
  18. package/dist/react/CollabRoomContext.d.ts +5 -5
  19. package/dist/react/index.d.ts +0 -1
  20. package/dist/react/index.d.ts.map +1 -1
  21. package/dist/react/index.js +0 -1
  22. package/dist/react/index.js.map +1 -1
  23. package/dist/routes/helpers.d.ts.map +1 -1
  24. package/dist/routes/helpers.js +6 -2
  25. package/dist/routes/helpers.js.map +1 -1
  26. package/dist/routes/relations.d.ts.map +1 -1
  27. package/dist/routes/relations.js +12 -0
  28. package/dist/routes/relations.js.map +1 -1
  29. package/package.json +6 -1
  30. package/.turbo/turbo-build.log +0 -8
  31. package/CLAUDE.md +0 -265
  32. package/dist/react/useCollabSeed.d.ts +0 -23
  33. package/dist/react/useCollabSeed.d.ts.map +0 -1
  34. package/dist/react/useCollabSeed.js +0 -82
  35. package/dist/react/useCollabSeed.js.map +0 -1
  36. package/src/Cluster.test.ts +0 -283
  37. package/src/Cluster.ts +0 -83
  38. package/src/Column.test.ts +0 -199
  39. package/src/Column.ts +0 -710
  40. package/src/Global.test.ts +0 -367
  41. package/src/Global.ts +0 -169
  42. package/src/Page.test.ts +0 -114
  43. package/src/Page.ts +0 -208
  44. package/src/Pilotiq.perf.test.ts +0 -252
  45. package/src/Pilotiq.test.ts +0 -129
  46. package/src/Pilotiq.ts +0 -1158
  47. package/src/PilotiqRegistry.ts +0 -36
  48. package/src/PilotiqServiceProvider.ts +0 -121
  49. package/src/RelationManager.test.ts +0 -400
  50. package/src/RelationManager.ts +0 -527
  51. package/src/RenderHook.test.ts +0 -252
  52. package/src/RenderHook.ts +0 -242
  53. package/src/Resource.test.ts +0 -284
  54. package/src/Resource.ts +0 -526
  55. package/src/RightPanel.test.ts +0 -202
  56. package/src/RightPanel.ts +0 -132
  57. package/src/Tab.test.ts +0 -91
  58. package/src/Tab.ts +0 -156
  59. package/src/UserMenuItem.ts +0 -145
  60. package/src/actions/Action.test.ts +0 -2526
  61. package/src/actions/Action.ts +0 -1515
  62. package/src/actions/ActionGroup.test.ts +0 -112
  63. package/src/actions/ActionGroup.ts +0 -173
  64. package/src/actions/attachFactory.ts +0 -172
  65. package/src/actions/bulkFactories.ts +0 -168
  66. package/src/actions/crudFactories.ts +0 -220
  67. package/src/actions/exportFactory.ts +0 -215
  68. package/src/actions/factoryHelpers.ts +0 -177
  69. package/src/actions/importFactory.ts +0 -243
  70. package/src/actions/index.ts +0 -17
  71. package/src/actions/m2mFactories.ts +0 -193
  72. package/src/actions/relationFactories.ts +0 -372
  73. package/src/applyPageHooks.test.ts +0 -463
  74. package/src/applyPageHooks.ts +0 -330
  75. package/src/authorization.test.ts +0 -483
  76. package/src/breadcrumbs.test.ts +0 -238
  77. package/src/cells/coerce.test.ts +0 -85
  78. package/src/cells/coerce.ts +0 -84
  79. package/src/clusterPaths.ts +0 -35
  80. package/src/columns/BadgeColumn.test.ts +0 -54
  81. package/src/columns/BadgeColumn.ts +0 -32
  82. package/src/columns/BooleanColumn.test.ts +0 -41
  83. package/src/columns/BooleanColumn.ts +0 -18
  84. package/src/columns/ColorColumn.test.ts +0 -37
  85. package/src/columns/ColorColumn.ts +0 -38
  86. package/src/columns/IconColumn.test.ts +0 -54
  87. package/src/columns/IconColumn.ts +0 -37
  88. package/src/columns/ImageColumn.test.ts +0 -41
  89. package/src/columns/ImageColumn.ts +0 -28
  90. package/src/columns/SelectColumn.ts +0 -98
  91. package/src/columns/TextColumn.test.ts +0 -190
  92. package/src/columns/TextColumn.ts +0 -20
  93. package/src/columns/TextInputColumn.ts +0 -68
  94. package/src/columns/ToggleColumn.ts +0 -46
  95. package/src/columns/editableColumns.test.ts +0 -238
  96. package/src/columns/index.ts +0 -9
  97. package/src/defaultGlobalPages.ts +0 -95
  98. package/src/defaultPages.test.ts +0 -634
  99. package/src/defaultPages.ts +0 -617
  100. package/src/defaultViewPage.test.ts +0 -147
  101. package/src/elements/Form.test.ts +0 -223
  102. package/src/elements/Form.ts +0 -416
  103. package/src/elements/ListTabs.ts +0 -28
  104. package/src/elements/Table.test.ts +0 -422
  105. package/src/elements/Table.ts +0 -850
  106. package/src/elements/TableGroup.test.ts +0 -260
  107. package/src/elements/TableGroup.ts +0 -334
  108. package/src/elements/dispatchAction.test.ts +0 -463
  109. package/src/elements/dispatchAction.ts +0 -355
  110. package/src/elements/dispatchForm.test.ts +0 -477
  111. package/src/elements/dispatchForm.ts +0 -1993
  112. package/src/elements/dispatchTable.test.ts +0 -1514
  113. package/src/elements/dispatchTable.ts +0 -745
  114. package/src/elements/index.ts +0 -21
  115. package/src/entries/BadgeEntry.ts +0 -39
  116. package/src/entries/CodeEntry.test.ts +0 -40
  117. package/src/entries/CodeEntry.ts +0 -52
  118. package/src/entries/ColorEntry.ts +0 -63
  119. package/src/entries/ComponentEntry.test.ts +0 -173
  120. package/src/entries/ComponentEntry.ts +0 -95
  121. package/src/entries/Entry.ts +0 -304
  122. package/src/entries/IconEntry.ts +0 -49
  123. package/src/entries/ImageEntry.ts +0 -61
  124. package/src/entries/KeyValueEntry.ts +0 -47
  125. package/src/entries/RepeatableEntry.test.ts +0 -239
  126. package/src/entries/RepeatableEntry.ts +0 -173
  127. package/src/entries/TextEntry.test.ts +0 -394
  128. package/src/entries/TextEntry.ts +0 -60
  129. package/src/entries/index.ts +0 -12
  130. package/src/entries/leaves.test.ts +0 -306
  131. package/src/entries/registry.ts +0 -54
  132. package/src/fields/BuilderField.test.ts +0 -1188
  133. package/src/fields/BuilderField.ts +0 -605
  134. package/src/fields/BuilderRelationship.test.ts +0 -811
  135. package/src/fields/CheckboxField.test.ts +0 -44
  136. package/src/fields/CheckboxField.ts +0 -27
  137. package/src/fields/CheckboxListField.test.ts +0 -99
  138. package/src/fields/CheckboxListField.ts +0 -66
  139. package/src/fields/ColorPickerField.test.ts +0 -33
  140. package/src/fields/ColorPickerField.ts +0 -25
  141. package/src/fields/DateField.ts +0 -54
  142. package/src/fields/DateTimeField.test.ts +0 -55
  143. package/src/fields/EmailField.ts +0 -16
  144. package/src/fields/Field.test.ts +0 -654
  145. package/src/fields/Field.ts +0 -817
  146. package/src/fields/FileUploadField.test.ts +0 -143
  147. package/src/fields/FileUploadField.ts +0 -159
  148. package/src/fields/HiddenField.test.ts +0 -27
  149. package/src/fields/HiddenField.ts +0 -28
  150. package/src/fields/KeyValueField.test.ts +0 -105
  151. package/src/fields/KeyValueField.ts +0 -55
  152. package/src/fields/MarkdownField.test.ts +0 -167
  153. package/src/fields/MarkdownField.ts +0 -162
  154. package/src/fields/NumberField.ts +0 -33
  155. package/src/fields/RadioField.test.ts +0 -94
  156. package/src/fields/RadioField.ts +0 -67
  157. package/src/fields/RepeaterField.test.ts +0 -1806
  158. package/src/fields/RepeaterField.ts +0 -939
  159. package/src/fields/RepeaterRelationship.test.ts +0 -1923
  160. package/src/fields/RepeaterSimple.test.ts +0 -248
  161. package/src/fields/RowButton.test.ts +0 -219
  162. package/src/fields/RowButton.ts +0 -135
  163. package/src/fields/SelectField.test.ts +0 -192
  164. package/src/fields/SelectField.ts +0 -235
  165. package/src/fields/SliderField.test.ts +0 -50
  166. package/src/fields/SliderField.ts +0 -53
  167. package/src/fields/SlugField.ts +0 -24
  168. package/src/fields/TagsInputField.test.ts +0 -154
  169. package/src/fields/TagsInputField.ts +0 -133
  170. package/src/fields/TextField.test.ts +0 -213
  171. package/src/fields/TextField.ts +0 -177
  172. package/src/fields/TextareaField.test.ts +0 -58
  173. package/src/fields/TextareaField.ts +0 -59
  174. package/src/fields/ToggleButtonsField.test.ts +0 -106
  175. package/src/fields/ToggleButtonsField.ts +0 -59
  176. package/src/fields/ToggleField.ts +0 -16
  177. package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +0 -319
  178. package/src/fields/optionsResolver.ts +0 -95
  179. package/src/fields/resolveField.ts +0 -28
  180. package/src/filters/BooleanFilter.ts +0 -35
  181. package/src/filters/DateRangeFilter.test.ts +0 -194
  182. package/src/filters/DateRangeFilter.ts +0 -148
  183. package/src/filters/Filter.test.ts +0 -268
  184. package/src/filters/Filter.ts +0 -184
  185. package/src/filters/FormFilter.test.ts +0 -238
  186. package/src/filters/FormFilter.ts +0 -215
  187. package/src/filters/MultiSelectFilter.test.ts +0 -119
  188. package/src/filters/MultiSelectFilter.ts +0 -78
  189. package/src/filters/QueryBuilderFilter.test.ts +0 -662
  190. package/src/filters/QueryBuilderFilter.ts +0 -398
  191. package/src/filters/SelectFilter.ts +0 -46
  192. package/src/filters/TernaryFilter.test.ts +0 -160
  193. package/src/filters/TernaryFilter.ts +0 -72
  194. package/src/filters/TrashedFilter.test.ts +0 -149
  195. package/src/filters/TrashedFilter.ts +0 -55
  196. package/src/filters/queryBuilder/BooleanConstraint.ts +0 -31
  197. package/src/filters/queryBuilder/Constraint.ts +0 -115
  198. package/src/filters/queryBuilder/DateConstraint.ts +0 -69
  199. package/src/filters/queryBuilder/NumberConstraint.ts +0 -66
  200. package/src/filters/queryBuilder/SelectConstraint.ts +0 -72
  201. package/src/filters/queryBuilder/TextConstraint.ts +0 -64
  202. package/src/filters/queryBuilder/index.ts +0 -12
  203. package/src/icons/index.ts +0 -2
  204. package/src/icons/lucide.ts +0 -204
  205. package/src/icons/registry.test.ts +0 -56
  206. package/src/icons/registry.ts +0 -41
  207. package/src/icons/types.ts +0 -47
  208. package/src/index.ts +0 -525
  209. package/src/io/csv.test.ts +0 -142
  210. package/src/io/csv.ts +0 -170
  211. package/src/nestedRelationManagerData.test.ts +0 -547
  212. package/src/notifications/Notification.test.ts +0 -210
  213. package/src/notifications/Notification.ts +0 -354
  214. package/src/notifications/broadcast.test.ts +0 -110
  215. package/src/notifications/broadcast.ts +0 -95
  216. package/src/notifications/database.test.ts +0 -383
  217. package/src/notifications/database.ts +0 -398
  218. package/src/notifications/databaseNotifications.test.ts +0 -187
  219. package/src/notifications/dispatchNotificationAction.test.ts +0 -341
  220. package/src/notifications/dispatchNotificationAction.ts +0 -142
  221. package/src/notifications/flash.test.ts +0 -89
  222. package/src/notifications/flash.ts +0 -71
  223. package/src/notifications/index.ts +0 -45
  224. package/src/notifications/registerBroadcastAuth.test.ts +0 -134
  225. package/src/notifications/registerBroadcastAuth.ts +0 -100
  226. package/src/notifications/resolveSavedNotification.test.ts +0 -82
  227. package/src/notifications/resolveSavedNotification.ts +0 -59
  228. package/src/notifications/types.ts +0 -93
  229. package/src/orm/m2mAccessor.ts +0 -66
  230. package/src/orm/modelDefaults.test.ts +0 -633
  231. package/src/orm/modelDefaults.ts +0 -666
  232. package/src/pageData/breadcrumbs.ts +0 -288
  233. package/src/pageData/forms.ts +0 -578
  234. package/src/pageData/helpers.ts +0 -857
  235. package/src/pageData/misc.ts +0 -347
  236. package/src/pageData/navigation.ts +0 -842
  237. package/src/pageData/relationPages.ts +0 -1248
  238. package/src/pageData/relationTabs.ts +0 -286
  239. package/src/pageData/resourcePages.ts +0 -609
  240. package/src/pageData.test.ts +0 -1545
  241. package/src/pageData.ts +0 -341
  242. package/src/plugins/index.ts +0 -8
  243. package/src/plugins/themeEditor.test.ts +0 -36
  244. package/src/plugins/themeEditor.ts +0 -45
  245. package/src/react/AppShell.tsx +0 -251
  246. package/src/react/CollabExtensionFactoryRegistry.ts +0 -55
  247. package/src/react/CollabRoomContext.ts +0 -98
  248. package/src/react/CollabTextRendererRegistry.ts +0 -102
  249. package/src/react/CommandPalette.tsx +0 -375
  250. package/src/react/CurrentUserContext.tsx +0 -50
  251. package/src/react/CustomPageWrapperGate.tsx +0 -69
  252. package/src/react/CustomPageWrapperRegistry.ts +0 -45
  253. package/src/react/FieldFocusReporterRegistry.ts +0 -37
  254. package/src/react/FieldLabelSlotRegistry.ts +0 -30
  255. package/src/react/FieldPresenceRegistry.ts +0 -46
  256. package/src/react/FormCollabBindingRegistry.ts +0 -242
  257. package/src/react/FormStateContext.tsx +0 -591
  258. package/src/react/HeadHooks.tsx +0 -126
  259. package/src/react/MarkdownEditorRegistry.test.ts +0 -38
  260. package/src/react/MarkdownEditorRegistry.ts +0 -107
  261. package/src/react/NotificationActionStrip.tsx +0 -263
  262. package/src/react/NotificationBell.tsx +0 -426
  263. package/src/react/PendingSuggestionApplierRegistry.test.ts +0 -97
  264. package/src/react/PendingSuggestionApplierRegistry.ts +0 -98
  265. package/src/react/PendingSuggestionOverlayRegistry.ts +0 -54
  266. package/src/react/PendingSuggestionsContext.tsx +0 -172
  267. package/src/react/RecordWrapperGate.tsx +0 -58
  268. package/src/react/RecordWrapperRegistry.ts +0 -39
  269. package/src/react/RenderHookSlot.tsx +0 -32
  270. package/src/react/RightSidebar.tsx +0 -257
  271. package/src/react/RightSidebarContext.tsx +0 -234
  272. package/src/react/RightSidebarTrigger.tsx +0 -53
  273. package/src/react/RowCoordsContext.tsx +0 -23
  274. package/src/react/SchemaRenderer.tsx +0 -549
  275. package/src/react/SearchTrigger.tsx +0 -46
  276. package/src/react/ThemeProvider.tsx +0 -93
  277. package/src/react/ThemeSettingsPage.tsx +0 -579
  278. package/src/react/ThemeToggle.tsx +0 -20
  279. package/src/react/Toaster.tsx +0 -158
  280. package/src/react/UserMenu.tsx +0 -196
  281. package/src/react/WidgetDataContext.tsx +0 -157
  282. package/src/react/cells/EditableCell.tsx +0 -389
  283. package/src/react/component-slots.test.ts +0 -103
  284. package/src/react/component-slots.ts +0 -116
  285. package/src/react/fieldJsHandler.test.ts +0 -166
  286. package/src/react/fieldJsHandler.ts +0 -79
  287. package/src/react/fields/BuilderInput.tsx +0 -1078
  288. package/src/react/fields/CheckboxInput.tsx +0 -39
  289. package/src/react/fields/CheckboxListInput.tsx +0 -102
  290. package/src/react/fields/ColorInput.tsx +0 -71
  291. package/src/react/fields/DateFieldInput.tsx +0 -70
  292. package/src/react/fields/DateTimeInput.tsx +0 -62
  293. package/src/react/fields/FieldShell.tsx +0 -348
  294. package/src/react/fields/FileUploadInput.tsx +0 -639
  295. package/src/react/fields/HiddenInput.tsx +0 -17
  296. package/src/react/fields/KeyValueInput.tsx +0 -230
  297. package/src/react/fields/MarkdownInput.tsx +0 -560
  298. package/src/react/fields/RadioInput.tsx +0 -81
  299. package/src/react/fields/RepeaterInput.test.ts +0 -116
  300. package/src/react/fields/RepeaterInput.tsx +0 -1420
  301. package/src/react/fields/SelectFieldInput.tsx +0 -280
  302. package/src/react/fields/SliderInput.tsx +0 -81
  303. package/src/react/fields/TagsInput.tsx +0 -283
  304. package/src/react/fields/TextLikeInput.tsx +0 -256
  305. package/src/react/fields/ToggleButtonsInput.tsx +0 -60
  306. package/src/react/fields/ToggleFieldInput.tsx +0 -56
  307. package/src/react/fields/relationshipRenameDispatch.test.ts +0 -106
  308. package/src/react/fields/relationshipRenameDispatch.ts +0 -97
  309. package/src/react/fields/repeaterReconcile.test.ts +0 -114
  310. package/src/react/fields/repeaterReconcile.ts +0 -104
  311. package/src/react/fields/rowChromeButton.tsx +0 -336
  312. package/src/react/fields/rowState.ts +0 -106
  313. package/src/react/fields/syncRowGates.test.ts +0 -202
  314. package/src/react/fields/syncRowGates.ts +0 -66
  315. package/src/react/fields/textInputControls.tsx +0 -238
  316. package/src/react/fields/useRowReorderDnd.ts +0 -78
  317. package/src/react/formStateHelpers.test.ts +0 -508
  318. package/src/react/formStateHelpers.ts +0 -381
  319. package/src/react/hooks/use-mobile.ts +0 -19
  320. package/src/react/icon-context.tsx +0 -60
  321. package/src/react/index.ts +0 -195
  322. package/src/react/layouts/SidebarLayout.tsx +0 -250
  323. package/src/react/layouts/TopbarLayout.tsx +0 -258
  324. package/src/react/navigate.tsx +0 -37
  325. package/src/react/onProviderSynced.test.ts +0 -90
  326. package/src/react/parseRecordEditUrl.test.ts +0 -122
  327. package/src/react/parseRecordEditUrl.ts +0 -94
  328. package/src/react/persistedState.ts +0 -40
  329. package/src/react/registry.ts +0 -48
  330. package/src/react/right-panel-registry.tsx +0 -47
  331. package/src/react/schemaRenderer/AlertRenderer.tsx +0 -112
  332. package/src/react/schemaRenderer/EntryRenderer.tsx +0 -501
  333. package/src/react/schemaRenderer/SectionRenderer.tsx +0 -120
  334. package/src/react/schemaRenderer/SimpleElements.tsx +0 -306
  335. package/src/react/schemaRenderer/TabsRenderer.tsx +0 -62
  336. package/src/react/schemaRenderer/WizardRenderer.tsx +0 -338
  337. package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +0 -177
  338. package/src/react/schemaRenderer/action/ActionModalDialog.tsx +0 -273
  339. package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +0 -61
  340. package/src/react/schemaRenderer/action/HandlerActionButton.tsx +0 -43
  341. package/src/react/schemaRenderer/action/MethodActionButton.tsx +0 -64
  342. package/src/react/schemaRenderer/action/buttons.tsx +0 -99
  343. package/src/react/schemaRenderer/action/helpers.ts +0 -140
  344. package/src/react/schemaRenderer/action/renderAction.tsx +0 -245
  345. package/src/react/schemaRenderer/columnFormat.ts +0 -65
  346. package/src/react/schemaRenderer/constants.ts +0 -50
  347. package/src/react/schemaRenderer/form/FormRenderer.tsx +0 -274
  348. package/src/react/schemaRenderer/form/renderField.tsx +0 -511
  349. package/src/react/schemaRenderer/helpers.tsx +0 -81
  350. package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +0 -308
  351. package/src/react/schemaRenderer/table/TableRenderer.tsx +0 -123
  352. package/src/react/schemaRenderer/table/TableRendererBody.tsx +0 -974
  353. package/src/react/schemaRenderer/table/filters.tsx +0 -1233
  354. package/src/react/schemaRenderer/table/formatCell.tsx +0 -264
  355. package/src/react/schemaRenderer/table/links.tsx +0 -112
  356. package/src/react/schemaRenderer/table/renderRowActions.tsx +0 -52
  357. package/src/react/schemaRenderer/table/url.tsx +0 -143
  358. package/src/react/theme-preview/apply.ts +0 -99
  359. package/src/react/theme-preview/build-html.ts +0 -436
  360. package/src/react/ui/button.tsx +0 -51
  361. package/src/react/ui/calendar.tsx +0 -67
  362. package/src/react/ui/checkbox.tsx +0 -29
  363. package/src/react/ui/dialog.tsx +0 -108
  364. package/src/react/ui/dropdown-menu.tsx +0 -97
  365. package/src/react/ui/input.tsx +0 -20
  366. package/src/react/ui/label.tsx +0 -21
  367. package/src/react/ui/popover.tsx +0 -50
  368. package/src/react/ui/select.tsx +0 -169
  369. package/src/react/ui/separator.tsx +0 -25
  370. package/src/react/ui/sheet.tsx +0 -136
  371. package/src/react/ui/sidebar.tsx +0 -723
  372. package/src/react/ui/skeleton.tsx +0 -13
  373. package/src/react/ui/slider.tsx +0 -34
  374. package/src/react/ui/switch.tsx +0 -28
  375. package/src/react/ui/table.tsx +0 -105
  376. package/src/react/ui/tabs.tsx +0 -63
  377. package/src/react/ui/textarea.tsx +0 -18
  378. package/src/react/ui/tooltip.tsx +0 -64
  379. package/src/react/useCollabSeed.ts +0 -86
  380. package/src/react/useResizableWidth.ts +0 -139
  381. package/src/react/utils.ts +0 -6
  382. package/src/react/widgetRegistry.test.ts +0 -43
  383. package/src/react/widgetRegistry.ts +0 -50
  384. package/src/react/widgets/StatsOverviewRenderer.tsx +0 -232
  385. package/src/react/widgets/TableWidgetRenderer.tsx +0 -231
  386. package/src/react/widgets/ViewRenderer.tsx +0 -71
  387. package/src/relationManagerData.test.ts +0 -1595
  388. package/src/richtext/index.ts +0 -8
  389. package/src/richtext/registry.ts +0 -89
  390. package/src/routes/globals.ts +0 -148
  391. package/src/routes/guard.test.ts +0 -325
  392. package/src/routes/helpers.ts +0 -700
  393. package/src/routes/pages.ts +0 -175
  394. package/src/routes/panel.ts +0 -204
  395. package/src/routes/relations.ts +0 -1227
  396. package/src/routes/resources.ts +0 -781
  397. package/src/routes/theme.ts +0 -91
  398. package/src/routes-nested-relations.test.ts +0 -676
  399. package/src/routes-relations.test.ts +0 -972
  400. package/src/routes.test.ts +0 -2027
  401. package/src/routes.ts +0 -303
  402. package/src/schema/Alert.test.ts +0 -109
  403. package/src/schema/Alert.ts +0 -131
  404. package/src/schema/Block.ts +0 -169
  405. package/src/schema/Breadcrumbs.ts +0 -40
  406. package/src/schema/Card.ts +0 -35
  407. package/src/schema/Divider.ts +0 -20
  408. package/src/schema/Element.ts +0 -219
  409. package/src/schema/EmptyState.test.ts +0 -37
  410. package/src/schema/EmptyState.ts +0 -63
  411. package/src/schema/Fieldset.ts +0 -43
  412. package/src/schema/Grid.ts +0 -43
  413. package/src/schema/Group.ts +0 -30
  414. package/src/schema/Heading.ts +0 -39
  415. package/src/schema/Html.ts +0 -67
  416. package/src/schema/Icon.ts +0 -54
  417. package/src/schema/Image.ts +0 -57
  418. package/src/schema/LinkTag.ts +0 -41
  419. package/src/schema/Markdown.ts +0 -85
  420. package/src/schema/MetaTag.ts +0 -41
  421. package/src/schema/RelationTabs.ts +0 -71
  422. package/src/schema/ScriptTag.ts +0 -55
  423. package/src/schema/Section.ts +0 -160
  424. package/src/schema/ServerDataElement.test.ts +0 -140
  425. package/src/schema/ServerDataElement.ts +0 -156
  426. package/src/schema/SlotComponent.test.ts +0 -77
  427. package/src/schema/SlotComponent.ts +0 -71
  428. package/src/schema/Split.ts +0 -50
  429. package/src/schema/Stat.test.ts +0 -118
  430. package/src/schema/Stat.ts +0 -154
  431. package/src/schema/StatsOverview.test.ts +0 -141
  432. package/src/schema/StatsOverview.ts +0 -119
  433. package/src/schema/StyleTag.ts +0 -35
  434. package/src/schema/TableWidget.test.ts +0 -297
  435. package/src/schema/TableWidget.ts +0 -289
  436. package/src/schema/Tabs.ts +0 -79
  437. package/src/schema/Text.ts +0 -58
  438. package/src/schema/UnorderedList.ts +0 -49
  439. package/src/schema/View.test.ts +0 -111
  440. package/src/schema/View.ts +0 -127
  441. package/src/schema/Wizard.ts +0 -220
  442. package/src/schema/containers.test.ts +0 -564
  443. package/src/schema/headTags.test.ts +0 -134
  444. package/src/schema/index.ts +0 -40
  445. package/src/schema/primes.test.ts +0 -269
  446. package/src/schema/resolveSchema.test.ts +0 -379
  447. package/src/schema/resolveSchema.ts +0 -917
  448. package/src/schema/sanitize.ts +0 -58
  449. package/src/search.test.ts +0 -446
  450. package/src/search.ts +0 -178
  451. package/src/sessionFilters.test.ts +0 -375
  452. package/src/sessionFilters.ts +0 -143
  453. package/src/slot-components/index.ts +0 -10
  454. package/src/slot-components/registry.ts +0 -56
  455. package/src/styles/file-upload.css +0 -13
  456. package/src/summarizers/Summarizer.test.ts +0 -84
  457. package/src/summarizers/Summarizer.ts +0 -123
  458. package/src/summarizers/index.ts +0 -11
  459. package/src/theme/base-colors.ts +0 -68
  460. package/src/theme/chart-colors.ts +0 -50
  461. package/src/theme/colors.ts +0 -447
  462. package/src/theme/generate-css.test.ts +0 -139
  463. package/src/theme/generate-css.ts +0 -44
  464. package/src/theme/generate-scale.test.ts +0 -106
  465. package/src/theme/generate-scale.ts +0 -97
  466. package/src/theme/icon-map.ts +0 -42
  467. package/src/theme/index.ts +0 -34
  468. package/src/theme/migrate.test.ts +0 -178
  469. package/src/theme/migrate.ts +0 -81
  470. package/src/theme/presets.ts +0 -135
  471. package/src/theme/radius.ts +0 -18
  472. package/src/theme/resolve.test.ts +0 -238
  473. package/src/theme/resolve.ts +0 -96
  474. package/src/theme/spacing.ts +0 -18
  475. package/src/theme/storage.test.ts +0 -126
  476. package/src/theme/storage.ts +0 -106
  477. package/src/theme/theme-colors.ts +0 -88
  478. package/src/theme/types.ts +0 -125
  479. package/src/uploads/UploadAdapter.ts +0 -35
  480. package/src/uploads/index.ts +0 -2
  481. package/src/uploads/localUpload.test.ts +0 -70
  482. package/src/uploads/localUpload.ts +0 -84
  483. package/src/validation/Validator.ts +0 -49
  484. package/src/validation/index.ts +0 -28
  485. package/src/validation/rules.ts +0 -78
  486. package/src/validation/runValidators.ts +0 -435
  487. package/src/validation/uniqueValidator.test.ts +0 -196
  488. package/src/validation/uniqueValidator.ts +0 -133
  489. package/src/validation/validators.test.ts +0 -268
  490. package/src/vite.test.ts +0 -184
  491. package/src/vite.ts +0 -787
  492. package/src/widgets/index.ts +0 -10
  493. package/src/widgets/registry.ts +0 -45
  494. package/src/widgets.test.ts +0 -592
  495. package/tsconfig.build.json +0 -11
  496. package/tsconfig.json +0 -4
  497. package/tsconfig.test.json +0 -10
  498. package/views/react/Dashboard.tsx +0 -27
  499. package/views/react/Resources/Form.tsx +0 -102
  500. package/views/react/Resources/Index.tsx +0 -49
package/src/pageData.ts DELETED
@@ -1,341 +0,0 @@
1
- /**
2
- * Per-page-role data builders. The framework's GET route handlers and
3
- * Vike's auto-generated `+data.ts` hooks both call these to produce the
4
- * exact props the page renderer needs.
5
- *
6
- * Why this exists: SSR runs through the rudder router (which calls
7
- * `view(...)` and populates `pageContext.viewProps`). SPA navigation only
8
- * triggers Vike's `+data` hook — the rudder handler doesn't run, so the
9
- * data needs to come from the same builder. Routing both paths through a
10
- * single builder keeps them in sync.
11
- */
12
- import { PilotiqRegistry } from './PilotiqRegistry.js'
13
-
14
- // Re-export `RelationChainStep` so external callsites importing it via
15
- // `./pageData.js` keep working.
16
- export type { RelationChainStep } from './pageData/breadcrumbs.js'
17
-
18
- // Re-export `ServerDataMap` so external imports via `./pageData.js` keep
19
- // working — the type is also surfaced from `packages/pilotiq/src/index.ts`.
20
- export type { ServerDataMap } from './pageData/helpers.js'
21
-
22
- // Re-export the URL-tag helpers + fill pipeline + server-data resolver
23
- // for consumers that import them through `./pageData.js`.
24
- export {
25
- applyEditPageHydrators,
26
- applyFillPipeline,
27
- applyRelationshipBuilderFill,
28
- applyRelationshipRepeaterFill,
29
- callPageSchema,
30
- normalizeArrayFieldStrings,
31
- resolveServerDataElements,
32
- tagActionDispatch,
33
- tagCellEditUrls,
34
- tagFieldAiUrls,
35
- tagFormActions,
36
- tagFormStateUrls,
37
- tagFormWizardUrls,
38
- tagRichTextMentionUrls,
39
- tagSelectCreateOptionUrls,
40
- tagTableDeferred,
41
- tagTableReorderUrls,
42
- tagWidgetUrls,
43
- } from './pageData/helpers.js'
44
-
45
- // Re-export navigation chrome surface so external callsites importing
46
- // it via `./pageData.js` keep working (e.g. routes/test harnesses).
47
- export type {
48
- DatabaseNotificationsMeta,
49
- NavItem,
50
- PanelInfoRoute,
51
- RightPanelMeta,
52
- RightSidebarMeta,
53
- UserMenuMeta,
54
- } from './pageData/navigation.js'
55
- export {
56
- applyRoleHooks,
57
- panelInfo,
58
- resolvePageHooks,
59
- } from './pageData/navigation.js'
60
-
61
- import {
62
- dashboardData,
63
- resourceCreateData,
64
- resourceEditData,
65
- resourceIndexData,
66
- resourceRecordPageData,
67
- resourceViewData,
68
- } from './pageData/resourcePages.js'
69
-
70
- // Re-export resource page builders so external callsites importing
71
- // through `./pageData.js` keep working (e.g. routes.ts handlers, tests).
72
- export {
73
- dashboardData,
74
- resolveActiveTab,
75
- resourceCreateData,
76
- resourceEditData,
77
- resourceIndexData,
78
- resourceRecordPageData,
79
- resourceTableData,
80
- resourceViewData,
81
- } from './pageData/resourcePages.js'
82
-
83
- import { relationManagerData } from './pageData/relationPages.js'
84
-
85
- // Re-export relation manager builder surface for external consumers
86
- // (routes.ts dispatches every relation-* role through these).
87
- export type {
88
- RelationManagerResult,
89
- RelationManagerScope,
90
- ResolvedChain,
91
- } from './pageData/relationPages.js'
92
- export {
93
- findRelatedResource,
94
- relationManagerData,
95
- resolveRelationChain,
96
- safeManagerPolicy,
97
- } from './pageData/relationPages.js'
98
-
99
- // Re-export form-related builders + types for external callsites.
100
- export type {
101
- FormCreateOptionFailure,
102
- FormCreateOptionRequest,
103
- FormCreateOptionSuccess,
104
- FormStateError,
105
- FormStateRequest,
106
- FormStateResult,
107
- FormStateScope,
108
- FormWizardFailure,
109
- FormWizardRequest,
110
- FormWizardSuccess,
111
- } from './pageData/forms.js'
112
- export {
113
- formCreateOptionData,
114
- formStateData,
115
- formWizardData,
116
- mentionResolveData,
117
- } from './pageData/forms.js'
118
-
119
- import {
120
- customPageData,
121
- globalEditData,
122
- globalViewData,
123
- } from './pageData/misc.js'
124
-
125
- // Re-export the misc page builders for external callsites (routes.ts
126
- // dispatches into globals / custom-page / widget / search routes).
127
- export {
128
- customPageData,
129
- globalEditData,
130
- globalViewData,
131
- searchData,
132
- widgetData,
133
- } from './pageData/misc.js'
134
- export type {
135
- WidgetFailure,
136
- WidgetRequest,
137
- WidgetScope,
138
- WidgetSuccess,
139
- } from './pageData/misc.js'
140
-
141
-
142
- // ─── Vike +data dispatcher ───────────────────────────────────
143
-
144
- export interface PageContextLike {
145
- urlPathname?: string
146
- urlOriginal?: string
147
- urlParsed?: { search?: Record<string, string>; searchOriginal?: string }
148
- routeParams?: Record<string, string | undefined>
149
- pageId?: string
150
- }
151
-
152
- /**
153
- * Single entry point Vike's `+data` hook calls. Inspects the page id and
154
- * route params, finds the panel via `PilotiqRegistry`, and dispatches to
155
- * the matching builder. Returns the same shape SSR's `viewProps` carries.
156
- */
157
- export async function dispatchPageData(pageContext: PageContextLike): Promise<unknown | null> {
158
- const { pageId, routeParams = {} } = pageContext
159
- const search = pageContext.urlParsed?.search ?? {}
160
- const basePathParam = routeParams['basePath']
161
- const basePath = basePathParam ? `/${basePathParam}` : ''
162
- const panel = basePath ? PilotiqRegistry.findByPath(basePath) : null
163
-
164
- if (!panel) return null
165
-
166
- switch (pageId) {
167
- case '/pages/(pilotiq)/dashboard':
168
- return dashboardData(panel)
169
-
170
- case '/pages/(pilotiq)/slug': {
171
- // 2-segment URL: could be a resource list, a global edit, or a custom page.
172
- const slug = routeParams['slug']
173
- if (!slug) return null
174
- const cfg = panel.getConfig()
175
- if (cfg.resources.some(R => R.getSlug() === slug)) {
176
- return resourceIndexData(panel, slug, search)
177
- }
178
- if (cfg.globals.some(G => G.getSlug() === slug)) {
179
- return globalEditData(panel, slug)
180
- }
181
- return customPageData(panel, slug)
182
- }
183
-
184
- case '/pages/(pilotiq)/resource-create': {
185
- const slug = routeParams['slug']
186
- if (!slug) return null
187
- return resourceCreateData(panel, slug)
188
- }
189
-
190
- case '/pages/(pilotiq)/resource-edit': {
191
- const slug = routeParams['slug']
192
- const id = routeParams['id']
193
- if (!slug || !id) return null
194
- return resourceEditData(panel, slug, id)
195
- }
196
-
197
- case '/pages/(pilotiq)/resource-view': {
198
- const slug = routeParams['slug']
199
- const id = routeParams['id']
200
- if (!slug) return null
201
- // Globals also use this route under `/{slug}/view` — id will be 'view'.
202
- if (id === 'view') return globalViewData(panel, slug)
203
- if (!id) return null
204
- return resourceViewData(panel, slug, id)
205
- }
206
-
207
- case '/pages/(pilotiq)/relation-list': {
208
- const slug = routeParams['slug']
209
- const id = routeParams['id']
210
- const relationship = routeParams['relationship']
211
- if (!slug || !id || !relationship) return null
212
- const out = await relationManagerData(panel, {
213
- kind: 'relation-list', slug, recordId: id, relationship,
214
- query: search as Record<string, string>,
215
- })
216
- // Tagged failure shapes (`{ ok: false, status: 403 }`) leak straight
217
- // through to the +Page renderer, which can branch on the shape.
218
- // null = no manager named `relationship` on R; fall through to the
219
- // record sub-page lookup so URLs like `/admin/users/u1/activity`
220
- // (where `activity` is registered under `pages().record`) route
221
- // through `resourceRecordPageData` rather than 404ing.
222
- if (out !== null) return out as Record<string, unknown>
223
- const recordOut = await resourceRecordPageData(panel, slug, id, relationship)
224
- return recordOut === null ? null : (recordOut as Record<string, unknown>)
225
- }
226
-
227
- case '/pages/(pilotiq)/relation-create': {
228
- const slug = routeParams['slug']
229
- const id = routeParams['id']
230
- const relationship = routeParams['relationship']
231
- if (!slug || !id || !relationship) return null
232
- const out = await relationManagerData(panel, {
233
- kind: 'relation-create', slug, recordId: id, relationship,
234
- })
235
- return out === null ? null : (out as Record<string, unknown>)
236
- }
237
-
238
- case '/pages/(pilotiq)/relation-view': {
239
- const slug = routeParams['slug']
240
- const id = routeParams['id']
241
- const relationship = routeParams['relationship']
242
- const childId = routeParams['childId']
243
- if (!slug || !id || !relationship || !childId) return null
244
- const out = await relationManagerData(panel, {
245
- kind: 'relation-view', slug, recordId: id, relationship, childId,
246
- })
247
- return out === null ? null : (out as Record<string, unknown>)
248
- }
249
-
250
- case '/pages/(pilotiq)/relation-edit': {
251
- const slug = routeParams['slug']
252
- const id = routeParams['id']
253
- const relationship = routeParams['relationship']
254
- const childId = routeParams['childId']
255
- if (!slug || !id || !relationship || !childId) return null
256
- const out = await relationManagerData(panel, {
257
- kind: 'relation-edit', slug, recordId: id, relationship, childId,
258
- })
259
- return out === null ? null : (out as Record<string, unknown>)
260
- }
261
-
262
- // Phase B nested-relation routes. Param names match those declared
263
- // by the auto-gen Vike stubs in `src/vite.ts`:
264
- // id, relationship, childId1, relationship2, childId2.
265
- case '/pages/(pilotiq)/nested-relation-list': {
266
- const slug = routeParams['slug']
267
- const id = routeParams['id']
268
- const relationship = routeParams['relationship']
269
- const childId1 = routeParams['childId1']
270
- const relationship2 = routeParams['relationship2']
271
- if (!slug || !id || !relationship || !childId1 || !relationship2) return null
272
- const out = await relationManagerData(panel, {
273
- kind: 'nested-relation-list', slug,
274
- chain: [
275
- { recordId: id, relationship },
276
- { recordId: childId1, relationship: relationship2 },
277
- ],
278
- query: search as Record<string, string>,
279
- })
280
- return out === null ? null : (out as Record<string, unknown>)
281
- }
282
-
283
- case '/pages/(pilotiq)/nested-relation-create': {
284
- const slug = routeParams['slug']
285
- const id = routeParams['id']
286
- const relationship = routeParams['relationship']
287
- const childId1 = routeParams['childId1']
288
- const relationship2 = routeParams['relationship2']
289
- if (!slug || !id || !relationship || !childId1 || !relationship2) return null
290
- const out = await relationManagerData(panel, {
291
- kind: 'nested-relation-create', slug,
292
- chain: [
293
- { recordId: id, relationship },
294
- { recordId: childId1, relationship: relationship2 },
295
- ],
296
- })
297
- return out === null ? null : (out as Record<string, unknown>)
298
- }
299
-
300
- case '/pages/(pilotiq)/nested-relation-view': {
301
- const slug = routeParams['slug']
302
- const id = routeParams['id']
303
- const relationship = routeParams['relationship']
304
- const childId1 = routeParams['childId1']
305
- const relationship2 = routeParams['relationship2']
306
- const childId2 = routeParams['childId2']
307
- if (!slug || !id || !relationship || !childId1 || !relationship2 || !childId2) return null
308
- const out = await relationManagerData(panel, {
309
- kind: 'nested-relation-view', slug,
310
- chain: [
311
- { recordId: id, relationship },
312
- { recordId: childId1, relationship: relationship2 },
313
- ],
314
- childId: childId2,
315
- })
316
- return out === null ? null : (out as Record<string, unknown>)
317
- }
318
-
319
- case '/pages/(pilotiq)/nested-relation-edit': {
320
- const slug = routeParams['slug']
321
- const id = routeParams['id']
322
- const relationship = routeParams['relationship']
323
- const childId1 = routeParams['childId1']
324
- const relationship2 = routeParams['relationship2']
325
- const childId2 = routeParams['childId2']
326
- if (!slug || !id || !relationship || !childId1 || !relationship2 || !childId2) return null
327
- const out = await relationManagerData(panel, {
328
- kind: 'nested-relation-edit', slug,
329
- chain: [
330
- { recordId: id, relationship },
331
- { recordId: childId1, relationship: relationship2 },
332
- ],
333
- childId: childId2,
334
- })
335
- return out === null ? null : (out as Record<string, unknown>)
336
- }
337
-
338
- default:
339
- return null
340
- }
341
- }
@@ -1,8 +0,0 @@
1
- export { themeEditor } from './themeEditor.js'
2
- export type { ThemeEditorOptions } from './themeEditor.js'
3
- export { prismaThemeStorage } from '../theme/storage.js'
4
- export type {
5
- ThemeStorageAdapter,
6
- PanelGlobalDelegate,
7
- PrismaThemeStorageOptions,
8
- } from '../theme/storage.js'
@@ -1,36 +0,0 @@
1
- import { describe, it } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { Pilotiq } from '../Pilotiq.js'
4
- import { themeEditor } from './themeEditor.js'
5
- import type { ThemeStorageAdapter } from '../theme/storage.js'
6
-
7
- function makeStubAdapter(): ThemeStorageAdapter {
8
- return {
9
- async load() { return null },
10
- async save() { /* noop */ },
11
- async clear() { /* noop */ },
12
- }
13
- }
14
-
15
- describe('themeEditor() plugin', () => {
16
- it('bare themeEditor() leaves the storage slot undefined (boot resolves it)', () => {
17
- const panel = Pilotiq.make('admin').use(themeEditor())
18
- assert.equal(panel.getConfig().themeEditor, true)
19
- assert.equal(panel.getThemeStorage(), undefined)
20
- })
21
-
22
- it('themeEditor({ storage }) stamps the adapter onto the panel', () => {
23
- const adapter = makeStubAdapter()
24
- const panel = Pilotiq.make('admin').use(themeEditor({ storage: adapter }))
25
- assert.equal(panel.getThemeStorage(), adapter)
26
- })
27
-
28
- it('themeEditor() can be called on multiple panels without leaking adapters', () => {
29
- const a = makeStubAdapter()
30
- const b = makeStubAdapter()
31
- const panelA = Pilotiq.make('admin').use(themeEditor({ storage: a }))
32
- const panelB = Pilotiq.make('billing').use(themeEditor({ storage: b }))
33
- assert.equal(panelA.getThemeStorage(), a)
34
- assert.equal(panelB.getThemeStorage(), b)
35
- })
36
- })
@@ -1,45 +0,0 @@
1
- import type { PilotiqPlugin } from '../Pilotiq.js'
2
- import type { ThemeStorageAdapter } from '../theme/storage.js'
3
-
4
- export interface ThemeEditorOptions {
5
- /**
6
- * Override persistence adapter. Defaults to the implicit Prisma
7
- * fallback (auto-resolved from `app.make('prisma')` against the
8
- * `panelGlobal` row) — that fallback is deprecated; pass an explicit
9
- * adapter to opt out and silence the deprecation warning.
10
- *
11
- * @example
12
- * ```ts
13
- * import { prismaThemeStorage, themeEditor } from '@pilotiq/pilotiq/plugins'
14
- *
15
- * .use(themeEditor({
16
- * storage: prismaThemeStorage(prisma, { slug: 'admin__theme' }),
17
- * }))
18
- * ```
19
- */
20
- storage?: ThemeStorageAdapter
21
- }
22
-
23
- /**
24
- * Theme editor plugin — adds an interactive theme customization page
25
- * with live preview, save/reset functionality, and DB persistence.
26
- *
27
- * @example
28
- * ```ts
29
- * import { Pilotiq } from '@pilotiq/pilotiq'
30
- * import { themeEditor } from '@pilotiq/pilotiq/plugins'
31
- *
32
- * Pilotiq.make('Admin')
33
- * .theme({ preset: 'vega', themeColor: 'blue' })
34
- * .use(themeEditor())
35
- * ```
36
- */
37
- export function themeEditor(opts: ThemeEditorOptions = {}): PilotiqPlugin {
38
- return {
39
- name: 'theme-editor',
40
- register(panel) {
41
- panel.enableThemeEditor()
42
- if (opts.storage) panel._setThemeStorage(opts.storage)
43
- },
44
- }
45
- }
@@ -1,251 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { SidebarLayout } from './layouts/SidebarLayout.js'
3
- import { TopbarLayout } from './layouts/TopbarLayout.js'
4
- import { ToasterProvider } from './Toaster.js'
5
- import { CommandPalette, CommandPaletteProvider } from './CommandPalette.js'
6
- import type { NotificationMeta } from '../notifications/Notification.js'
7
- import type { ComponentRegistry } from './icon-context.js'
8
- import { ComponentRegistryProvider } from './icon-context.js'
9
- import type { RightPanelRegistry } from './right-panel-registry.js'
10
- import { RightPanelRegistryProvider } from './right-panel-registry.js'
11
- import { RightSidebarProvider, useRightSidebarOptional } from './RightSidebarContext.js'
12
- import { RightSidebar } from './RightSidebar.js'
13
- import { RecordWrapperGate, type RecordCollabMap } from './RecordWrapperGate.js'
14
- import { CustomPageWrapperGate, type PageCollabMap } from './CustomPageWrapperGate.js'
15
- import { useIsMobile } from './hooks/use-mobile.js'
16
- import type { NavItem, UserMenuMeta, DatabaseNotificationsMeta, RightSidebarMeta } from '../pageData.js'
17
- import type { RenderHookMap } from '../RenderHook.js'
18
- import { RenderHookSlot } from './RenderHookSlot.js'
19
- import type { ComponentSlotRegistry } from './component-slots.js'
20
- import { CurrentUserProvider } from './CurrentUserContext.js'
21
-
22
- export interface AppShellProps {
23
- panel: {
24
- name: string
25
- branding: { title?: string; logo?: string }
26
- /** Pre-grouped navigation tree built by `panelInfo()` (Plan #9). */
27
- navigation?: NavItem[]
28
- /** Top-right dropdown shape — `null`/absent suppresses the menu
29
- * entirely (no resolver configured or no logged-in user). */
30
- userMenu?: UserMenuMeta | null
31
- /** Bell-icon dropdown config — absent suppresses the bell.
32
- * `panelInfo()` only ships this when the panel opted in via
33
- * `Pilotiq.databaseNotifications()` AND a user resolved. */
34
- databaseNotifications?: DatabaseNotificationsMeta
35
- /** Right-sidebar plugin meta — absent suppresses the surface.
36
- * `panelInfo()` only ships this when at least one contribution
37
- * was registered AND passed the auth gate AND is non-hidden. */
38
- rightSidebar?: RightSidebarMeta
39
- /** Per-resource collab opt-in map — read by `RecordWrapperGate` to
40
- * decide whether to mount the plugin-registered RecordWrapper on
41
- * a record edit/view URL. Absent when no resource opted in. */
42
- recordCollab?: RecordCollabMap
43
- /** Per-custom-page collab opt-in map — read by `CustomPageWrapperGate`
44
- * to decide whether to mount the plugin-registered CustomPageWrapper
45
- * on a custom-page URL. Absent when no page opted in. */
46
- pageCollab?: PageCollabMap
47
- /** Pre-resolved render-hook slots for the panel chrome (body /
48
- * topbar / sidebar / user-menu / footer / head). Sparse map —
49
- * slots with no registered entries are absent. Built by
50
- * `panelInfo()` server-side. */
51
- renderHooks?: RenderHookMap
52
- themeEditor?: boolean
53
- /** AI suggestion mode — absent means `'auto'` (the default). When
54
- * set to `'review'`, AI plugins read this and stage writes as
55
- * `PendingSuggestion`s for user approval instead of applying
56
- * immediately. Plan: `docs/plans/ai-review-mode.md`. */
57
- aiSuggestionsMode?: 'auto' | 'review'
58
- }
59
- basePath: string
60
- /** Pathname used to compute active-link state in the sidebar/topbar. */
61
- currentPath?: string
62
- layout?: 'sidebar' | 'topbar'
63
- /** Server-flashed notifications from `viewProps.notifications`. The
64
- * Toaster mounts them on first render. */
65
- notifications?: NotificationMeta[]
66
- /** Build-time class manifest emitted by the Pilotiq Vite plugin
67
- * (`pages/(pilotiq)/_components.ts`). Maps Resource/Global/Page class
68
- * names to the actual class refs so component-typed icons (e.g.,
69
- * `Resource.icon = Newspaper`) render. Optional — when missing, only
70
- * string-registry icons resolve. */
71
- componentRegistry?: ComponentRegistry
72
- /**
73
- * Build-time right-panel registry from the Vite plugin. Maps each
74
- * `RightPanelContribution.id` to the React component supplied as
75
- * `render`. Phase C's `RightSidebar` chrome reads this via
76
- * `useRightPanelComponent(id)`. Sparse `{}` is a valid value — the
77
- * chrome simply doesn't mount.
78
- */
79
- rightPanelRegistry?: RightPanelRegistry
80
- /**
81
- * Build-time layout-provider registry from the Vite plugin. Each entry
82
- * is a React component that wraps the panel's layout tree at the
83
- * root. Plugins register via `Pilotiq.layoutProvider(C)`; the Vite
84
- * plugin harvests refs into this array. Empty `[]` is the no-op
85
- * default — chrome renders without any extra wrapping.
86
- */
87
- layoutProviderRegistry?: ReadonlyArray<React.ComponentType<{ children: React.ReactNode; basePath?: string }>>
88
- /**
89
- * Build-time chrome-slot overrides from the Vite plugin. Populated
90
- * when the panel module calls `Pilotiq.components({ nav, … })`.
91
- * Sparse `{}` is the no-op default. Currently only `nav` is honored;
92
- * additional slots will land as concrete consumers ask.
93
- */
94
- componentSlotRegistry?: ComponentSlotRegistry
95
- children: React.ReactNode
96
- }
97
-
98
- export function AppShell({ layout = 'sidebar', notifications, componentRegistry, rightPanelRegistry, layoutProviderRegistry, ...props }: AppShellProps) {
99
- const Layout = layout === 'topbar' ? TopbarLayout : SidebarLayout
100
- // exactOptionalPropertyTypes: only spread `initialNotifications` when set.
101
- const toasterProps = notifications ? { initialNotifications: notifications } : {}
102
-
103
- // Stamp the panel-wide AI suggestion mode on a window global so the
104
- // AI plugin's `update_form_state` client-tool handler can read it
105
- // without context plumbing. Singleton flag — doesn't change between
106
- // pages within the same panel. Plan: `docs/plans/ai-review-mode.md`.
107
- const aiSuggestionsMode = props.panel.aiSuggestionsMode ?? 'auto'
108
- useEffect(() => {
109
- if (typeof window === 'undefined') return
110
- ;(window as unknown as { __pilotiqAiSuggestionsMode?: 'auto' | 'review' }).__pilotiqAiSuggestionsMode = aiSuggestionsMode
111
- }, [aiSuggestionsMode])
112
-
113
- // Plan #12 — palette open state lives at AppShell so the trigger pill
114
- // (rendered inside the layout's header) and the palette dialog both
115
- // observe the same flag via context.
116
- const [paletteOpen, setPaletteOpen] = useState(false)
117
- const paletteProps: {
118
- basePath: string
119
- navigation?: NavItem[]
120
- open: boolean
121
- onOpenChange: (open: boolean) => void
122
- } = {
123
- basePath: props.basePath,
124
- open: paletteOpen,
125
- onOpenChange: setPaletteOpen,
126
- }
127
- if (props.panel.navigation) paletteProps.navigation = props.panel.navigation
128
-
129
- const hooks = props.panel.renderHooks
130
- const rightSidebarMeta = props.panel.rightSidebar
131
-
132
- // Record-scoped wrapper (collab room, audit trail, …) — pass-through
133
- // when no plugin registered a wrapper or when the URL isn't a
134
- // record-edit page. Wrapping `children` before forwarding to `Layout`
135
- // mounts the wrapper around the page content area only, leaving the
136
- // sidebar / topbar chrome outside.
137
- const layoutProps = {
138
- ...props,
139
- children: (
140
- <RecordWrapperGate
141
- basePath={props.basePath}
142
- {...(props.currentPath !== undefined ? { currentPath: props.currentPath } : {})}
143
- {...(props.panel.recordCollab !== undefined ? { recordCollab: props.panel.recordCollab } : {})}
144
- >
145
- <CustomPageWrapperGate
146
- basePath={props.basePath}
147
- {...(props.currentPath !== undefined ? { currentPath: props.currentPath } : {})}
148
- {...(props.panel.pageCollab !== undefined ? { pageCollab: props.panel.pageCollab } : {})}
149
- >
150
- {props.children}
151
- </CustomPageWrapperGate>
152
- </RecordWrapperGate>
153
- ),
154
- }
155
-
156
- const inner = (
157
- <ToasterProvider {...toasterProps}>
158
- <CommandPaletteProvider setOpen={setPaletteOpen}>
159
- <RenderHookSlot name="panels::body.start" hooks={hooks} />
160
- <RightSidebarLayoutFrame>
161
- <Layout {...layoutProps} />
162
- </RightSidebarLayoutFrame>
163
- <RenderHookSlot name="panels::body.end" hooks={hooks} />
164
- <CommandPalette {...paletteProps} />
165
- {rightSidebarMeta && (
166
- <RightSidebar
167
- basePath={props.basePath}
168
- {...(props.currentPath !== undefined ? { currentPath: props.currentPath } : {})}
169
- />
170
- )}
171
- </CommandPaletteProvider>
172
- </ToasterProvider>
173
- )
174
-
175
- // Plugin-registered layout providers (e.g. AI chat queue, tenant
176
- // theme switcher). Wraps in registration order: the FIRST registered
177
- // provider sits OUTERMOST (closest to the layout root); LAST sits
178
- // INNERMOST (closest to the page tree). Empty / unset → no wrap.
179
- const wrapped = wrapInLayoutProviders(
180
- <ComponentRegistryProvider value={componentRegistry}>
181
- <RightPanelRegistryProvider value={rightPanelRegistry}>
182
- {rightSidebarMeta ? (
183
- <RightSidebarProvider meta={rightSidebarMeta} basePath={props.basePath}>
184
- {inner}
185
- </RightSidebarProvider>
186
- ) : (
187
- inner
188
- )}
189
- </RightPanelRegistryProvider>
190
- </ComponentRegistryProvider>,
191
- layoutProviderRegistry,
192
- props.basePath,
193
- )
194
-
195
- // `CurrentUserProvider` sits OUTSIDE the layout-provider chain so
196
- // plugin-registered providers (e.g. `@pilotiq-pro/collab`'s
197
- // CollabProvider, which threads the user into CollaborationCaret
198
- // presence labels) can read the active user via `useCurrentUser()`.
199
- // Value source mirrors what the top-right user dropdown renders.
200
- return (
201
- <CurrentUserProvider value={props.panel.userMenu?.user ?? null}>
202
- {wrapped}
203
- </CurrentUserProvider>
204
- )
205
- }
206
-
207
- /**
208
- * Fold registered layout providers around `tree` from last to first so
209
- * the first-registered provider ends up outermost in the React tree
210
- * (closest to the layout root) — matches the registration-order
211
- * intuition documented on `Pilotiq.layoutProvider`.
212
- */
213
- function wrapInLayoutProviders(
214
- tree: React.ReactElement,
215
- registry: ReadonlyArray<React.ComponentType<{ children: React.ReactNode; basePath?: string }>> | undefined,
216
- basePath: string,
217
- ): React.ReactElement {
218
- if (!registry || registry.length === 0) return tree
219
- let acc: React.ReactElement = tree
220
- for (let i = registry.length - 1; i >= 0; i--) {
221
- const Provider = registry[i]!
222
- acc = <Provider basePath={basePath}>{acc}</Provider>
223
- }
224
- return acc
225
- }
226
-
227
- /**
228
- * Padding shim that compresses host content when the right sidebar is
229
- * open on desktop. The fixed-position rail would otherwise overlap
230
- * content; this wrapper reads the optional `RightSidebarProvider`
231
- * context (it's a no-op when the surface isn't mounted) and applies
232
- * `padding-inline-end` matching the active panel width.
233
- *
234
- * The shim avoids touching SidebarLayout / TopbarLayout internals — the
235
- * layouts expand to fill the wrapper's content box, so trimming inside
236
- * the wrapper compresses both the sticky header and the main scroll
237
- * region together.
238
- */
239
- function RightSidebarLayoutFrame({ children }: { children: React.ReactNode }) {
240
- const sidebar = useRightSidebarOptional()
241
- const isMobile = useIsMobile()
242
- const apply = sidebar && sidebar.open && !isMobile
243
- // Always render the same wrapper element so toggling open/closed
244
- // doesn't remount the Layout subtree (which would drop the user's
245
- // scroll position and any uncontrolled-input state). Only the inline
246
- // style flips.
247
- const style: React.CSSProperties | undefined = apply
248
- ? { paddingInlineEnd: sidebar!.width, transition: 'padding-inline-end 150ms ease-out' }
249
- : { transition: 'padding-inline-end 150ms ease-out' }
250
- return <div style={style}>{children}</div>
251
- }