@pilotiq/pilotiq 0.7.2 → 0.8.1

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 (371) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +208 -0
  3. package/CLAUDE.md +59 -3
  4. package/dist/Pilotiq.d.ts +83 -0
  5. package/dist/Pilotiq.d.ts.map +1 -1
  6. package/dist/Pilotiq.js +39 -0
  7. package/dist/Pilotiq.js.map +1 -1
  8. package/dist/actions/Action.d.ts +27 -99
  9. package/dist/actions/Action.d.ts.map +1 -1
  10. package/dist/actions/Action.js +52 -754
  11. package/dist/actions/Action.js.map +1 -1
  12. package/dist/actions/bulkFactories.d.ts +46 -0
  13. package/dist/actions/bulkFactories.d.ts.map +1 -0
  14. package/dist/actions/bulkFactories.js +144 -0
  15. package/dist/actions/bulkFactories.js.map +1 -0
  16. package/dist/actions/crudFactories.d.ts +94 -0
  17. package/dist/actions/crudFactories.d.ts.map +1 -0
  18. package/dist/actions/crudFactories.js +209 -0
  19. package/dist/actions/crudFactories.js.map +1 -0
  20. package/dist/actions/factoryHelpers.d.ts +108 -0
  21. package/dist/actions/factoryHelpers.d.ts.map +1 -0
  22. package/dist/actions/factoryHelpers.js +138 -0
  23. package/dist/actions/factoryHelpers.js.map +1 -0
  24. package/dist/actions/m2mFactories.d.ts +47 -0
  25. package/dist/actions/m2mFactories.d.ts.map +1 -0
  26. package/dist/actions/m2mFactories.js +173 -0
  27. package/dist/actions/m2mFactories.js.map +1 -0
  28. package/dist/actions/relationFactories.d.ts +93 -0
  29. package/dist/actions/relationFactories.d.ts.map +1 -0
  30. package/dist/actions/relationFactories.js +321 -0
  31. package/dist/actions/relationFactories.js.map +1 -0
  32. package/dist/elements/dispatchForm.js +1 -1
  33. package/dist/elements/dispatchForm.js.map +1 -1
  34. package/dist/elements/dispatchTable.js +1 -1
  35. package/dist/elements/dispatchTable.js.map +1 -1
  36. package/dist/fields/Field.d.ts +31 -0
  37. package/dist/fields/Field.d.ts.map +1 -1
  38. package/dist/fields/Field.js +25 -0
  39. package/dist/fields/Field.js.map +1 -1
  40. package/dist/pageData/breadcrumbs.d.ts +42 -0
  41. package/dist/pageData/breadcrumbs.d.ts.map +1 -0
  42. package/dist/pageData/breadcrumbs.js +172 -0
  43. package/dist/pageData/breadcrumbs.js.map +1 -0
  44. package/dist/pageData/forms.d.ts +137 -0
  45. package/dist/pageData/forms.d.ts.map +1 -0
  46. package/dist/pageData/forms.js +427 -0
  47. package/dist/pageData/forms.js.map +1 -0
  48. package/dist/pageData/helpers.d.ts +239 -0
  49. package/dist/pageData/helpers.d.ts.map +1 -0
  50. package/dist/pageData/helpers.js +703 -0
  51. package/dist/pageData/helpers.js.map +1 -0
  52. package/dist/pageData/misc.d.ts +76 -0
  53. package/dist/pageData/misc.d.ts.map +1 -0
  54. package/dist/pageData/misc.js +263 -0
  55. package/dist/pageData/misc.js.map +1 -0
  56. package/dist/pageData/navigation.d.ts +292 -0
  57. package/dist/pageData/navigation.d.ts.map +1 -0
  58. package/dist/pageData/navigation.js +591 -0
  59. package/dist/pageData/navigation.js.map +1 -0
  60. package/dist/pageData/relationPages.d.ts +172 -0
  61. package/dist/pageData/relationPages.d.ts.map +1 -0
  62. package/dist/pageData/relationPages.js +867 -0
  63. package/dist/pageData/relationPages.js.map +1 -0
  64. package/dist/pageData/relationTabs.d.ts +65 -0
  65. package/dist/pageData/relationTabs.d.ts.map +1 -0
  66. package/dist/pageData/relationTabs.js +258 -0
  67. package/dist/pageData/relationTabs.js.map +1 -0
  68. package/dist/pageData/resourcePages.d.ts +48 -0
  69. package/dist/pageData/resourcePages.d.ts.map +1 -0
  70. package/dist/pageData/resourcePages.js +504 -0
  71. package/dist/pageData/resourcePages.js.map +1 -0
  72. package/dist/pageData.d.ts +12 -792
  73. package/dist/pageData.d.ts.map +1 -1
  74. package/dist/pageData.js +24 -3797
  75. package/dist/pageData.js.map +1 -1
  76. package/dist/react/AppShell.d.ts +8 -0
  77. package/dist/react/AppShell.d.ts.map +1 -1
  78. package/dist/react/AppShell.js +11 -1
  79. package/dist/react/AppShell.js.map +1 -1
  80. package/dist/react/CollabExtensionFactoryRegistry.d.ts +47 -0
  81. package/dist/react/CollabExtensionFactoryRegistry.d.ts.map +1 -0
  82. package/dist/react/CollabExtensionFactoryRegistry.js +14 -0
  83. package/dist/react/CollabExtensionFactoryRegistry.js.map +1 -0
  84. package/dist/react/CollabRoomContext.d.ts +37 -0
  85. package/dist/react/CollabRoomContext.d.ts.map +1 -0
  86. package/dist/react/CollabRoomContext.js +12 -0
  87. package/dist/react/CollabRoomContext.js.map +1 -0
  88. package/dist/react/FormCollabBindingRegistry.d.ts +62 -0
  89. package/dist/react/FormCollabBindingRegistry.d.ts.map +1 -0
  90. package/dist/react/FormCollabBindingRegistry.js +14 -0
  91. package/dist/react/FormCollabBindingRegistry.js.map +1 -0
  92. package/dist/react/FormStateContext.d.ts.map +1 -1
  93. package/dist/react/FormStateContext.js +87 -0
  94. package/dist/react/FormStateContext.js.map +1 -1
  95. package/dist/react/RecordWrapperGate.d.ts +25 -0
  96. package/dist/react/RecordWrapperGate.d.ts.map +1 -0
  97. package/dist/react/RecordWrapperGate.js +30 -0
  98. package/dist/react/RecordWrapperGate.js.map +1 -0
  99. package/dist/react/RecordWrapperRegistry.d.ts +31 -0
  100. package/dist/react/RecordWrapperRegistry.d.ts.map +1 -0
  101. package/dist/react/RecordWrapperRegistry.js +15 -0
  102. package/dist/react/RecordWrapperRegistry.js.map +1 -0
  103. package/dist/react/SchemaRenderer.d.ts +17 -23
  104. package/dist/react/SchemaRenderer.d.ts.map +1 -1
  105. package/dist/react/SchemaRenderer.js +71 -3647
  106. package/dist/react/SchemaRenderer.js.map +1 -1
  107. package/dist/react/component-slots.d.ts +103 -0
  108. package/dist/react/component-slots.d.ts.map +1 -0
  109. package/dist/react/component-slots.js +18 -0
  110. package/dist/react/component-slots.js.map +1 -0
  111. package/dist/react/fields/BuilderInput.d.ts.map +1 -1
  112. package/dist/react/fields/BuilderInput.js +21 -117
  113. package/dist/react/fields/BuilderInput.js.map +1 -1
  114. package/dist/react/fields/MarkdownInput.d.ts.map +1 -1
  115. package/dist/react/fields/MarkdownInput.js +1 -3
  116. package/dist/react/fields/MarkdownInput.js.map +1 -1
  117. package/dist/react/fields/RepeaterInput.d.ts.map +1 -1
  118. package/dist/react/fields/RepeaterInput.js +22 -127
  119. package/dist/react/fields/RepeaterInput.js.map +1 -1
  120. package/dist/react/fields/rowState.d.ts +40 -0
  121. package/dist/react/fields/rowState.d.ts.map +1 -0
  122. package/dist/react/fields/rowState.js +60 -0
  123. package/dist/react/fields/rowState.js.map +1 -0
  124. package/dist/react/fields/useRowReorderDnd.d.ts +28 -0
  125. package/dist/react/fields/useRowReorderDnd.d.ts.map +1 -0
  126. package/dist/react/fields/useRowReorderDnd.js +51 -0
  127. package/dist/react/fields/useRowReorderDnd.js.map +1 -0
  128. package/dist/react/index.d.ts +9 -0
  129. package/dist/react/index.d.ts.map +1 -1
  130. package/dist/react/index.js +8 -0
  131. package/dist/react/index.js.map +1 -1
  132. package/dist/react/layouts/SidebarLayout.d.ts +1 -1
  133. package/dist/react/layouts/SidebarLayout.d.ts.map +1 -1
  134. package/dist/react/layouts/SidebarLayout.js +10 -2
  135. package/dist/react/layouts/SidebarLayout.js.map +1 -1
  136. package/dist/react/layouts/TopbarLayout.d.ts +1 -1
  137. package/dist/react/layouts/TopbarLayout.d.ts.map +1 -1
  138. package/dist/react/layouts/TopbarLayout.js +19 -11
  139. package/dist/react/layouts/TopbarLayout.js.map +1 -1
  140. package/dist/react/parseRecordEditUrl.d.ts +29 -0
  141. package/dist/react/parseRecordEditUrl.d.ts.map +1 -0
  142. package/dist/react/parseRecordEditUrl.js +25 -0
  143. package/dist/react/parseRecordEditUrl.js.map +1 -0
  144. package/dist/react/persistedState.d.ts +19 -0
  145. package/dist/react/persistedState.d.ts.map +1 -0
  146. package/dist/react/persistedState.js +51 -0
  147. package/dist/react/persistedState.js.map +1 -0
  148. package/dist/react/schemaRenderer/AlertRenderer.d.ts +12 -0
  149. package/dist/react/schemaRenderer/AlertRenderer.d.ts.map +1 -0
  150. package/dist/react/schemaRenderer/AlertRenderer.js +61 -0
  151. package/dist/react/schemaRenderer/AlertRenderer.js.map +1 -0
  152. package/dist/react/schemaRenderer/EntryRenderer.d.ts +13 -0
  153. package/dist/react/schemaRenderer/EntryRenderer.d.ts.map +1 -0
  154. package/dist/react/schemaRenderer/EntryRenderer.js +277 -0
  155. package/dist/react/schemaRenderer/EntryRenderer.js.map +1 -0
  156. package/dist/react/schemaRenderer/SectionRenderer.d.ts +16 -0
  157. package/dist/react/schemaRenderer/SectionRenderer.d.ts.map +1 -0
  158. package/dist/react/schemaRenderer/SectionRenderer.js +62 -0
  159. package/dist/react/schemaRenderer/SectionRenderer.js.map +1 -0
  160. package/dist/react/schemaRenderer/SimpleElements.d.ts +25 -0
  161. package/dist/react/schemaRenderer/SimpleElements.d.ts.map +1 -0
  162. package/dist/react/schemaRenderer/SimpleElements.js +147 -0
  163. package/dist/react/schemaRenderer/SimpleElements.js.map +1 -0
  164. package/dist/react/schemaRenderer/TabsRenderer.d.ts +17 -0
  165. package/dist/react/schemaRenderer/TabsRenderer.d.ts.map +1 -0
  166. package/dist/react/schemaRenderer/TabsRenderer.js +31 -0
  167. package/dist/react/schemaRenderer/TabsRenderer.js.map +1 -0
  168. package/dist/react/schemaRenderer/WizardRenderer.d.ts +34 -0
  169. package/dist/react/schemaRenderer/WizardRenderer.d.ts.map +1 -0
  170. package/dist/react/schemaRenderer/WizardRenderer.js +208 -0
  171. package/dist/react/schemaRenderer/WizardRenderer.js.map +1 -0
  172. package/dist/react/schemaRenderer/action/ActionGroupTrigger.d.ts +21 -0
  173. package/dist/react/schemaRenderer/action/ActionGroupTrigger.d.ts.map +1 -0
  174. package/dist/react/schemaRenderer/action/ActionGroupTrigger.js +82 -0
  175. package/dist/react/schemaRenderer/action/ActionGroupTrigger.js.map +1 -0
  176. package/dist/react/schemaRenderer/action/ActionModalDialog.d.ts +30 -0
  177. package/dist/react/schemaRenderer/action/ActionModalDialog.d.ts.map +1 -0
  178. package/dist/react/schemaRenderer/action/ActionModalDialog.js +182 -0
  179. package/dist/react/schemaRenderer/action/ActionModalDialog.js.map +1 -0
  180. package/dist/react/schemaRenderer/action/ConfirmActionDialog.d.ts +17 -0
  181. package/dist/react/schemaRenderer/action/ConfirmActionDialog.d.ts.map +1 -0
  182. package/dist/react/schemaRenderer/action/ConfirmActionDialog.js +19 -0
  183. package/dist/react/schemaRenderer/action/ConfirmActionDialog.js.map +1 -0
  184. package/dist/react/schemaRenderer/action/HandlerActionButton.d.ts +16 -0
  185. package/dist/react/schemaRenderer/action/HandlerActionButton.d.ts.map +1 -0
  186. package/dist/react/schemaRenderer/action/HandlerActionButton.js +16 -0
  187. package/dist/react/schemaRenderer/action/HandlerActionButton.js.map +1 -0
  188. package/dist/react/schemaRenderer/action/MethodActionButton.d.ts +22 -0
  189. package/dist/react/schemaRenderer/action/MethodActionButton.d.ts.map +1 -0
  190. package/dist/react/schemaRenderer/action/MethodActionButton.js +26 -0
  191. package/dist/react/schemaRenderer/action/MethodActionButton.js.map +1 -0
  192. package/dist/react/schemaRenderer/action/buttons.d.ts +18 -0
  193. package/dist/react/schemaRenderer/action/buttons.d.ts.map +1 -0
  194. package/dist/react/schemaRenderer/action/buttons.js +74 -0
  195. package/dist/react/schemaRenderer/action/buttons.js.map +1 -0
  196. package/dist/react/schemaRenderer/action/helpers.d.ts +26 -0
  197. package/dist/react/schemaRenderer/action/helpers.d.ts.map +1 -0
  198. package/dist/react/schemaRenderer/action/helpers.js +126 -0
  199. package/dist/react/schemaRenderer/action/helpers.js.map +1 -0
  200. package/dist/react/schemaRenderer/action/renderAction.d.ts +21 -0
  201. package/dist/react/schemaRenderer/action/renderAction.d.ts.map +1 -0
  202. package/dist/react/schemaRenderer/action/renderAction.js +102 -0
  203. package/dist/react/schemaRenderer/action/renderAction.js.map +1 -0
  204. package/dist/react/schemaRenderer/columnFormat.d.ts +10 -0
  205. package/dist/react/schemaRenderer/columnFormat.d.ts.map +1 -0
  206. package/dist/react/schemaRenderer/columnFormat.js +76 -0
  207. package/dist/react/schemaRenderer/columnFormat.js.map +1 -0
  208. package/dist/react/schemaRenderer/constants.d.ts +8 -0
  209. package/dist/react/schemaRenderer/constants.d.ts.map +1 -0
  210. package/dist/react/schemaRenderer/constants.js +45 -0
  211. package/dist/react/schemaRenderer/constants.js.map +1 -0
  212. package/dist/react/schemaRenderer/form/FormRenderer.d.ts +29 -0
  213. package/dist/react/schemaRenderer/form/FormRenderer.d.ts.map +1 -0
  214. package/dist/react/schemaRenderer/form/FormRenderer.js +163 -0
  215. package/dist/react/schemaRenderer/form/FormRenderer.js.map +1 -0
  216. package/dist/react/schemaRenderer/form/renderField.d.ts +6 -0
  217. package/dist/react/schemaRenderer/form/renderField.d.ts.map +1 -0
  218. package/dist/react/schemaRenderer/form/renderField.js +239 -0
  219. package/dist/react/schemaRenderer/form/renderField.js.map +1 -0
  220. package/dist/react/schemaRenderer/helpers.d.ts +32 -0
  221. package/dist/react/schemaRenderer/helpers.d.ts.map +1 -0
  222. package/dist/react/schemaRenderer/helpers.js +52 -0
  223. package/dist/react/schemaRenderer/helpers.js.map +1 -0
  224. package/dist/react/schemaRenderer/table/CardsLayoutBody.d.ts +60 -0
  225. package/dist/react/schemaRenderer/table/CardsLayoutBody.d.ts.map +1 -0
  226. package/dist/react/schemaRenderer/table/CardsLayoutBody.js +189 -0
  227. package/dist/react/schemaRenderer/table/CardsLayoutBody.js.map +1 -0
  228. package/dist/react/schemaRenderer/table/TableRenderer.d.ts +29 -0
  229. package/dist/react/schemaRenderer/table/TableRenderer.d.ts.map +1 -0
  230. package/dist/react/schemaRenderer/table/TableRenderer.js +85 -0
  231. package/dist/react/schemaRenderer/table/TableRenderer.js.map +1 -0
  232. package/dist/react/schemaRenderer/table/TableRendererBody.d.ts +18 -0
  233. package/dist/react/schemaRenderer/table/TableRendererBody.d.ts.map +1 -0
  234. package/dist/react/schemaRenderer/table/TableRendererBody.js +555 -0
  235. package/dist/react/schemaRenderer/table/TableRendererBody.js.map +1 -0
  236. package/dist/react/schemaRenderer/table/filters.d.ts +263 -0
  237. package/dist/react/schemaRenderer/table/filters.d.ts.map +1 -0
  238. package/dist/react/schemaRenderer/table/filters.js +497 -0
  239. package/dist/react/schemaRenderer/table/filters.js.map +1 -0
  240. package/dist/react/schemaRenderer/table/formatCell.d.ts +11 -0
  241. package/dist/react/schemaRenderer/table/formatCell.d.ts.map +1 -0
  242. package/dist/react/schemaRenderer/table/formatCell.js +172 -0
  243. package/dist/react/schemaRenderer/table/formatCell.js.map +1 -0
  244. package/dist/react/schemaRenderer/table/links.d.ts +42 -0
  245. package/dist/react/schemaRenderer/table/links.d.ts.map +1 -0
  246. package/dist/react/schemaRenderer/table/links.js +55 -0
  247. package/dist/react/schemaRenderer/table/links.js.map +1 -0
  248. package/dist/react/schemaRenderer/table/renderRowActions.d.ts +13 -0
  249. package/dist/react/schemaRenderer/table/renderRowActions.d.ts.map +1 -0
  250. package/dist/react/schemaRenderer/table/renderRowActions.js +25 -0
  251. package/dist/react/schemaRenderer/table/renderRowActions.js.map +1 -0
  252. package/dist/react/schemaRenderer/table/url.d.ts +41 -0
  253. package/dist/react/schemaRenderer/table/url.d.ts.map +1 -0
  254. package/dist/react/schemaRenderer/table/url.js +114 -0
  255. package/dist/react/schemaRenderer/table/url.js.map +1 -0
  256. package/dist/routes/globals.d.ts +13 -0
  257. package/dist/routes/globals.d.ts.map +1 -0
  258. package/dist/routes/globals.js +131 -0
  259. package/dist/routes/globals.js.map +1 -0
  260. package/dist/routes/helpers.d.ts +217 -0
  261. package/dist/routes/helpers.d.ts.map +1 -0
  262. package/dist/routes/helpers.js +498 -0
  263. package/dist/routes/helpers.js.map +1 -0
  264. package/dist/routes/pages.d.ts +15 -0
  265. package/dist/routes/pages.d.ts.map +1 -0
  266. package/dist/routes/pages.js +145 -0
  267. package/dist/routes/pages.js.map +1 -0
  268. package/dist/routes/panel.d.ts +19 -0
  269. package/dist/routes/panel.d.ts.map +1 -0
  270. package/dist/routes/panel.js +191 -0
  271. package/dist/routes/panel.js.map +1 -0
  272. package/dist/routes/relations.d.ts +21 -0
  273. package/dist/routes/relations.d.ts.map +1 -0
  274. package/dist/routes/relations.js +1239 -0
  275. package/dist/routes/relations.js.map +1 -0
  276. package/dist/routes/resources.d.ts +28 -0
  277. package/dist/routes/resources.d.ts.map +1 -0
  278. package/dist/routes/resources.js +741 -0
  279. package/dist/routes/resources.js.map +1 -0
  280. package/dist/routes/theme.d.ts +12 -0
  281. package/dist/routes/theme.d.ts.map +1 -0
  282. package/dist/routes/theme.js +82 -0
  283. package/dist/routes/theme.js.map +1 -0
  284. package/dist/routes.d.ts.map +1 -1
  285. package/dist/routes.js +64 -3078
  286. package/dist/routes.js.map +1 -1
  287. package/dist/vite.d.ts +1 -0
  288. package/dist/vite.d.ts.map +1 -1
  289. package/dist/vite.js +26 -5
  290. package/dist/vite.js.map +1 -1
  291. package/package.json +2 -1
  292. package/src/Pilotiq.ts +95 -0
  293. package/src/actions/Action.ts +79 -723
  294. package/src/actions/bulkFactories.ts +168 -0
  295. package/src/actions/crudFactories.ts +220 -0
  296. package/src/actions/factoryHelpers.ts +177 -0
  297. package/src/actions/m2mFactories.ts +193 -0
  298. package/src/actions/relationFactories.ts +372 -0
  299. package/src/elements/dispatchForm.ts +1 -1
  300. package/src/elements/dispatchTable.ts +1 -1
  301. package/src/fields/Field.ts +39 -0
  302. package/src/pageData/breadcrumbs.ts +288 -0
  303. package/src/pageData/forms.ts +578 -0
  304. package/src/pageData/helpers.ts +764 -0
  305. package/src/pageData/misc.ts +347 -0
  306. package/src/pageData/navigation.ts +779 -0
  307. package/src/pageData/relationPages.ts +1246 -0
  308. package/src/pageData/relationTabs.ts +286 -0
  309. package/src/pageData/resourcePages.ts +593 -0
  310. package/src/pageData.ts +122 -4731
  311. package/src/react/AppShell.tsx +27 -1
  312. package/src/react/CollabExtensionFactoryRegistry.ts +55 -0
  313. package/src/react/CollabRoomContext.ts +42 -0
  314. package/src/react/FormCollabBindingRegistry.ts +72 -0
  315. package/src/react/FormStateContext.tsx +91 -0
  316. package/src/react/RecordWrapperGate.tsx +40 -0
  317. package/src/react/RecordWrapperRegistry.ts +39 -0
  318. package/src/react/SchemaRenderer.tsx +230 -6479
  319. package/src/react/component-slots.test.ts +103 -0
  320. package/src/react/component-slots.ts +116 -0
  321. package/src/react/fields/BuilderInput.tsx +29 -117
  322. package/src/react/fields/MarkdownInput.tsx +0 -1
  323. package/src/react/fields/RepeaterInput.tsx +29 -130
  324. package/src/react/fields/rowState.ts +106 -0
  325. package/src/react/fields/useRowReorderDnd.ts +78 -0
  326. package/src/react/index.ts +38 -0
  327. package/src/react/layouts/SidebarLayout.tsx +39 -28
  328. package/src/react/layouts/TopbarLayout.tsx +70 -57
  329. package/src/react/parseRecordEditUrl.test.ts +75 -0
  330. package/src/react/parseRecordEditUrl.ts +55 -0
  331. package/src/react/persistedState.ts +40 -0
  332. package/src/react/schemaRenderer/AlertRenderer.tsx +112 -0
  333. package/src/react/schemaRenderer/EntryRenderer.tsx +501 -0
  334. package/src/react/schemaRenderer/SectionRenderer.tsx +120 -0
  335. package/src/react/schemaRenderer/SimpleElements.tsx +306 -0
  336. package/src/react/schemaRenderer/TabsRenderer.tsx +62 -0
  337. package/src/react/schemaRenderer/WizardRenderer.tsx +338 -0
  338. package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +177 -0
  339. package/src/react/schemaRenderer/action/ActionModalDialog.tsx +273 -0
  340. package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +61 -0
  341. package/src/react/schemaRenderer/action/HandlerActionButton.tsx +43 -0
  342. package/src/react/schemaRenderer/action/MethodActionButton.tsx +64 -0
  343. package/src/react/schemaRenderer/action/buttons.tsx +99 -0
  344. package/src/react/schemaRenderer/action/helpers.ts +140 -0
  345. package/src/react/schemaRenderer/action/renderAction.tsx +245 -0
  346. package/src/react/schemaRenderer/columnFormat.ts +65 -0
  347. package/src/react/schemaRenderer/constants.ts +50 -0
  348. package/src/react/schemaRenderer/form/FormRenderer.tsx +245 -0
  349. package/src/react/schemaRenderer/form/renderField.tsx +511 -0
  350. package/src/react/schemaRenderer/helpers.tsx +81 -0
  351. package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +308 -0
  352. package/src/react/schemaRenderer/table/TableRenderer.tsx +123 -0
  353. package/src/react/schemaRenderer/table/TableRendererBody.tsx +974 -0
  354. package/src/react/schemaRenderer/table/filters.tsx +1233 -0
  355. package/src/react/schemaRenderer/table/formatCell.tsx +264 -0
  356. package/src/react/schemaRenderer/table/links.tsx +112 -0
  357. package/src/react/schemaRenderer/table/renderRowActions.tsx +52 -0
  358. package/src/react/schemaRenderer/table/url.tsx +143 -0
  359. package/src/routes/globals.ts +154 -0
  360. package/src/routes/helpers.ts +668 -0
  361. package/src/routes/pages.ts +173 -0
  362. package/src/routes/panel.ts +204 -0
  363. package/src/routes/relations.ts +1219 -0
  364. package/src/routes/resources.ts +786 -0
  365. package/src/routes/theme.ts +109 -0
  366. package/src/routes.test.ts +1 -1
  367. package/src/routes.ts +64 -3176
  368. package/src/schema/TableWidget.test.ts +2 -2
  369. package/src/theme/migrate.test.ts +178 -0
  370. package/src/vite.test.ts +184 -0
  371. package/src/vite.ts +26 -4
@@ -0,0 +1,286 @@
1
+ import type { ElementMeta } from '../schema/Element.js'
2
+ import type { Page } from '../Page.js'
3
+ import type { ResourceClass } from '../Resource.js'
4
+ import {
5
+ RelationManager,
6
+ safeManagerPolicy as safeManagerPolicyImpl,
7
+ type ManagerCanMethod as ManagerCanMethodType,
8
+ } from '../RelationManager.js'
9
+ import { RelationTabs, relationTab, type RelationTabMeta } from '../schema/RelationTabs.js'
10
+ import { resourceBasePath } from '../clusterPaths.js'
11
+ import type { IconValue } from '../icons/types.js'
12
+ import { getPrimaryKey } from '../orm/modelDefaults.js'
13
+ import type { RelationChainStep } from './breadcrumbs.js'
14
+ import { safeBool } from './helpers.js'
15
+
16
+ // ─── RelationTabs strip helpers ─────────────────────────────
17
+ //
18
+ // `buildRelationTabs` (depth 1) and `buildNestedRelationTabs` (depth 2)
19
+ // are called by both the resource view/edit page builders (parent
20
+ // tabs strip) AND the relation manager page builders (nested-tabs
21
+ // strip + record-sub-pages strip). Living in a shared module avoids
22
+ // pageData/resourcePages.ts ↔ pageData/relationPages.ts cycle.
23
+
24
+
25
+ /**
26
+ * Phase B — build a `RelationTabs` strip scoped to a parent's nested
27
+ * children (e.g. tabs for `replies / reactions` listed under a single
28
+ * comment). The strip's "back" tab points to the depth-2 view page for
29
+ * the leaf parent itself, then one tab per sibling nested manager.
30
+ *
31
+ * Only emitted when the depth-1 manager declares `M.relations()` —
32
+ * absent that, callers skip the prepend so single-manager surfaces stay
33
+ * clean. `activeKey` accepts the literal `'__view'` for the leaf
34
+ * parent's view tab, or any sibling manager's relationship key.
35
+ *
36
+ * Per-tab `canX` gating (2026-05-11) — sibling nested-manager tabs run
37
+ * `N.canViewAny(user, child1Record)` (with fall-through to the related
38
+ * Resource via `safeManagerPolicy`) so the strip hides tabs the user
39
+ * couldn't reach anyway. The back-link `__view` stays unconditional
40
+ * since the user is already on a page scoped under `M.canViewAny` —
41
+ * they reached this strip, they can navigate back to it.
42
+ */
43
+ export async function buildNestedRelationTabs(
44
+ R: ResourceClass,
45
+ M: typeof RelationManager,
46
+ basePath: string,
47
+ step0: RelationChainStep,
48
+ child1Id: string,
49
+ activeKey: string,
50
+ user: unknown,
51
+ child1Record: unknown,
52
+ ): Promise<RelationTabs | undefined> {
53
+ const siblings = M.relations()
54
+ if (siblings.length === 0) return undefined
55
+
56
+ const resourceBase = resourceBasePath(basePath, R)
57
+ const parentBase = `${resourceBase}/${step0.recordId}/${step0.relationship}`
58
+
59
+ // Sibling gating runs in parallel — each predicate may hit auth /
60
+ // db, so don't serialize them.
61
+ const siblingGates = siblings.map(N => {
62
+ const Related = (N as unknown as { relatedResource?: ResourceClass }).relatedResource
63
+ return safeManagerPolicyImpl(N, 'canViewAny', Related, user, child1Record)
64
+ })
65
+ const siblingVisible = await Promise.all(siblingGates)
66
+
67
+ const tabs: RelationTabMeta[] = []
68
+
69
+ // Back-link: depth-2 view page for the leaf parent record. Acts as
70
+ // the "View" tab in the same way `__view` does on depth-1 strips.
71
+ tabs.push(relationTab({
72
+ key: '__view',
73
+ label: M.getLabelSingular(),
74
+ url: `${parentBase}/${child1Id}`,
75
+ active: activeKey === '__view',
76
+ icon: M.getIcon(),
77
+ iconOwner: M.name,
78
+ }))
79
+
80
+ siblings.forEach((N, i) => {
81
+ if (!siblingVisible[i]) return
82
+ let nestedRel: string
83
+ try { nestedRel = N.getRelationship() } catch { return }
84
+ const icon = N.getIcon()
85
+ tabs.push(relationTab({
86
+ key: nestedRel,
87
+ label: N.getLabel(),
88
+ url: `${parentBase}/${child1Id}/${nestedRel}`,
89
+ active: activeKey === nestedRel,
90
+ ...(icon !== undefined ? { icon, iconOwner: N.name } : {}),
91
+ }))
92
+ })
93
+
94
+ // After gating, only the back-link may remain — one tab isn't a
95
+ // useful sub-nav. Drop the strip in that case (consistent with
96
+ // depth-1's empty-tabs branch).
97
+ if (tabs.length <= 1) return undefined
98
+
99
+ return RelationTabs.make(tabs)
100
+ }
101
+
102
+ /**
103
+ * Plan #11 — build the `RelationTabs` strip for a parent record. The
104
+ * strip surfaces the per-record sub-navigation: View, Edit, plus one
105
+ * tab per `R.relations()` manager. `activeKey` selects which tab the
106
+ * renderer highlights — `'__view'` / `'__edit'` for the parent tabs,
107
+ * the manager's relationship key for a manager tab.
108
+ *
109
+ * Sub-nav follow-up (2026-05-03 cont'd) — emit BOTH `__view` and
110
+ * `__edit` as sibling tabs (record sub-navigation) instead of one
111
+ * parent tab whose label depends on mode. Tabs are dropped when the
112
+ * corresponding page role isn't registered (a Resource overriding
113
+ * `pages()` to omit `view` or `edit` shouldn't surface a tab that
114
+ * 404s).
115
+ *
116
+ * Per-tab `canX` gating (2026-05-11) — the strip now also evaluates
117
+ * the matching predicate for each tab and drops the entry when the
118
+ * user can't reach it. Routes still enforce; this is presentation
119
+ * polish so the chrome doesn't promise a link that 403s on click.
120
+ *
121
+ * - `__view` → `R.canView(user, parentRecord)` (skip gating when
122
+ * `parentRecord` is undefined — record load failed,
123
+ * so the route's own load+gate will surface a 404/403
124
+ * rather than the strip hiding silently).
125
+ * - `__edit` → `R.canEdit(user, parentRecord)` (same posture).
126
+ * - manager → `safeManagerPolicy(M, 'canViewAny', Related, user,
127
+ * parentRecord)` (falls through to Related's
128
+ * `canViewAny` when the manager hasn't overridden).
129
+ *
130
+ * Returns `undefined` when the resource has no relation managers — the
131
+ * caller can then skip the prepend entirely so resources without
132
+ * relations stay shape-compatible with their existing schemaData.
133
+ * (View+Edit sub-nav alone isn't worth a tab strip; users navigate
134
+ * those via headerActions or the back link.)
135
+ */
136
+ export async function buildRelationTabs(
137
+ R: ResourceClass,
138
+ recordId: string,
139
+ basePath: string,
140
+ activeKey: string,
141
+ user: unknown,
142
+ parentRecord: unknown,
143
+ ): Promise<RelationTabs | undefined> {
144
+ const managers = R.relations()
145
+ const recordPageMap = R.getRecordPages()
146
+ const recordPageSlugs = Object.keys(recordPageMap)
147
+ // No managers AND no record sub-pages → no strip. View+Edit alone
148
+ // isn't worth a tab strip; users navigate those via headerActions or
149
+ // the back link. (When either is non-empty, the strip is worth
150
+ // mounting even if all the dynamic tabs end up gated away — the
151
+ // post-gate emptiness check below catches that.)
152
+ if (managers.length === 0 && recordPageSlugs.length === 0) return undefined
153
+
154
+ const resourceBase = resourceBasePath(basePath, R)
155
+ const pages = R.resolvePages()
156
+
157
+ // Evaluate every per-tab predicate in parallel. The arrays line up
158
+ // 1:1 with `pages.view` / `pages.edit` / `recordPageSlugs` /
159
+ // `managers` below — we resolve all gates first so the tab-build
160
+ // loop stays straight-line.
161
+ // Record-aware predicates short-circuit to `true` when no parent
162
+ // record was loaded (presentation should never hide more aggressively
163
+ // than the route can enforce; a missing record means the route will
164
+ // 404/403 on click and the strip stays consistent with that).
165
+ const canViewPromise = pages.view && parentRecord !== undefined && parentRecord !== null
166
+ ? safeBool(() => R.canView(user, parentRecord))
167
+ : Promise.resolve(true)
168
+ const canEditPromise = pages.edit && parentRecord !== undefined && parentRecord !== null
169
+ ? safeBool(() => R.canEdit(user, parentRecord))
170
+ : Promise.resolve(true)
171
+ const recordPageGates = recordPageSlugs.map(subSlug => {
172
+ // Record sub-page gates run against the parent record verbatim —
173
+ // missing record still calls the predicate so a sub-page that
174
+ // gates on global user state (no record needed) still evaluates.
175
+ // safeBool fails closed for throwing predicates.
176
+ return safeBool(() => recordPageMap[subSlug]!.canAccess(user, parentRecord))
177
+ })
178
+ const managerGates = managers.map(M => {
179
+ const Related = (M as unknown as { relatedResource?: ResourceClass }).relatedResource
180
+ return safeManagerPolicyImpl(M, 'canViewAny', Related, user, parentRecord)
181
+ })
182
+ const gateResults = await Promise.all([
183
+ canViewPromise, canEditPromise,
184
+ ...recordPageGates,
185
+ ...managerGates,
186
+ ])
187
+ const canView = gateResults[0] as boolean
188
+ const canEdit = gateResults[1] as boolean
189
+ const recordPageVisible = gateResults.slice(2, 2 + recordPageSlugs.length) as boolean[]
190
+ const managerVisible = gateResults.slice(2 + recordPageSlugs.length) as boolean[]
191
+
192
+ const tabs: RelationTabMeta[] = []
193
+
194
+ if (pages.view && canView) {
195
+ tabs.push(relationTab({
196
+ key: '__view',
197
+ label: 'View',
198
+ url: `${resourceBase}/${recordId}`,
199
+ active: activeKey === '__view',
200
+ icon: R.icon as IconValue | undefined,
201
+ iconOwner: R.name,
202
+ }))
203
+ }
204
+
205
+ if (pages.edit && canEdit) {
206
+ tabs.push(relationTab({
207
+ key: '__edit',
208
+ label: 'Edit',
209
+ url: `${resourceBase}/${recordId}/edit`,
210
+ active: activeKey === '__edit',
211
+ // Re-use the resource icon so when ViewPage is pruned, Edit
212
+ // still carries the visual identity. When both are present, the
213
+ // icon repeats — acceptable; the labels disambiguate.
214
+ icon: R.icon as IconValue | undefined,
215
+ iconOwner: R.name,
216
+ }))
217
+ }
218
+
219
+ // Record sub-page tabs — between Edit and the managers, in declaration
220
+ // order. Tab label inherits from the sub-page's class (`getLabel()`);
221
+ // icon picks up the sub-page's static `icon` when set. Slug doubles as
222
+ // the URL segment AND the `activeKey` discriminator the data builder
223
+ // passes when rendering the sub-page.
224
+ recordPageSlugs.forEach((subSlug, i) => {
225
+ if (!recordPageVisible[i]) return
226
+ const SubPage = recordPageMap[subSlug]!
227
+ tabs.push(relationTab({
228
+ key: subSlug,
229
+ label: SubPage.getLabel(),
230
+ url: `${resourceBase}/${recordId}/${subSlug}`,
231
+ active: activeKey === subSlug,
232
+ ...(SubPage.icon !== undefined
233
+ ? { icon: SubPage.icon, iconOwner: SubPage.name }
234
+ : {}),
235
+ }))
236
+ })
237
+
238
+ managers.forEach((M, i) => {
239
+ if (!managerVisible[i]) return
240
+ let rel: string
241
+ try { rel = M.getRelationship() } catch { return }
242
+ const icon = M.getIcon()
243
+ tabs.push(relationTab({
244
+ key: rel,
245
+ label: M.getLabel(),
246
+ url: `${resourceBase}/${recordId}/${rel}`,
247
+ active: activeKey === rel,
248
+ ...(icon !== undefined ? { icon, iconOwner: M.name } : {}),
249
+ }))
250
+ })
251
+
252
+ // After gating, the strip may collapse to zero entries. Mirror the
253
+ // "no managers + no sub-pages" branch above — no strip is friendlier
254
+ // than a one-tab strip with just the active page.
255
+ if (tabs.length === 0) return undefined
256
+
257
+ return RelationTabs.make(tabs)
258
+ }
259
+
260
+ export { safeBool }
261
+
262
+ /** Pull a human-readable title off a parent record for breadcrumb /
263
+ * page-title use. Falls back through `recordTitleAttribute` →
264
+ * `name` → `title` → primary key value → 'Record'. */
265
+ export function deriveParentTitle(
266
+ R: ResourceClass,
267
+ record: unknown,
268
+ manager?: typeof RelationManager,
269
+ ): string {
270
+ const r = record as Record<string, unknown>
271
+ // Manager-scoped child rows prefer the manager's `recordTitleAttribute`
272
+ // when set — the manager owns its presentation surface, and the related
273
+ // Resource may not opt into the same column (e.g. nested-only Resources
274
+ // that exist purely to back a manager).
275
+ const managerAttr = manager?.recordTitleAttribute
276
+ if (managerAttr && r[managerAttr] != null) return String(r[managerAttr])
277
+ const attr = R.recordTitleAttribute
278
+ if (attr && r[attr] != null) return String(r[attr])
279
+ if (r['name'] != null) return String(r['name'])
280
+ if (r['title'] != null) return String(r['title'])
281
+ if (R.model) {
282
+ const pk = getPrimaryKey(R.model)
283
+ if (r[pk] != null) return String(r[pk])
284
+ }
285
+ return 'Record'
286
+ }