@jini-ai/admin 0.4.2 → 0.4.4

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 (361) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -0
  3. package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +1 -1
  4. package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +1 -1
  5. package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +1 -1
  6. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +1 -1
  7. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +1 -1
  8. package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +1 -1
  9. package/dist/agent-plugins/react/index.js +1 -1
  10. package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +1 -1
  11. package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +1 -1
  12. package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +1 -1
  13. package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +1 -1
  14. package/dist/comments/adapters/http.d.ts +29 -0
  15. package/dist/comments/adapters/http.js +50 -0
  16. package/dist/comments/adapters/memory.d.ts +17 -0
  17. package/dist/comments/adapters/memory.js +61 -0
  18. package/dist/comments/comments.module.d.ts +73 -0
  19. package/dist/comments/comments.module.js +16 -0
  20. package/dist/comments/conformance/comments-api.conformance.d.ts +9 -0
  21. package/dist/comments/conformance/comments-api.conformance.js +63 -0
  22. package/dist/comments/controllers/comment-queue.controller.d.ts +48 -0
  23. package/dist/comments/controllers/comment-queue.controller.js +164 -0
  24. package/dist/comments/controllers/comment-settings.controller.d.ts +32 -0
  25. package/dist/comments/controllers/comment-settings.controller.js +77 -0
  26. package/dist/comments/controllers/comments.controller.d.ts +16 -0
  27. package/dist/comments/controllers/comments.controller.js +16 -0
  28. package/dist/comments/index.d.ts +13 -0
  29. package/dist/comments/index.js +8 -0
  30. package/dist/comments/messages.en.d.ts +54 -0
  31. package/dist/comments/messages.en.js +56 -0
  32. package/dist/comments/models.d.ts +22 -0
  33. package/dist/comments/models.js +2 -0
  34. package/dist/comments/ports.d.ts +14 -0
  35. package/dist/comments/ports.js +5 -0
  36. package/dist/comments/react/components/QueueSection.d.ts +30 -0
  37. package/dist/comments/react/components/QueueSection.js +57 -0
  38. package/dist/comments/react/components/SettingsSection.d.ts +14 -0
  39. package/dist/comments/react/components/SettingsSection.js +23 -0
  40. package/dist/comments/react/hooks/CommentsPage.hooks.d.ts +9 -0
  41. package/dist/comments/react/hooks/CommentsPage.hooks.js +10 -0
  42. package/dist/comments/react/hooks/CommentsPorts.hooks.d.ts +13 -0
  43. package/dist/comments/react/hooks/CommentsPorts.hooks.js +15 -0
  44. package/dist/comments/react/hooks/QueueSection.hooks.d.ts +62 -0
  45. package/dist/comments/react/hooks/QueueSection.hooks.js +57 -0
  46. package/dist/comments/react/hooks/SettingsSection.hooks.d.ts +12 -0
  47. package/dist/comments/react/hooks/SettingsSection.hooks.js +21 -0
  48. package/dist/comments/react/hooks/use-comment-queue.hooks.d.ts +34 -0
  49. package/dist/comments/react/hooks/use-comment-queue.hooks.js +47 -0
  50. package/dist/comments/react/hooks/use-comment-settings.hooks.d.ts +22 -0
  51. package/dist/comments/react/hooks/use-comment-settings.hooks.js +30 -0
  52. package/dist/comments/react/hooks/use-comments.hooks.d.ts +15 -0
  53. package/dist/comments/react/hooks/use-comments.hooks.js +20 -0
  54. package/dist/comments/react/index.d.ts +316 -0
  55. package/dist/comments/react/index.js +35 -0
  56. package/dist/comments/react/pages/CommentsPage.d.ts +12 -0
  57. package/dist/comments/react/pages/CommentsPage.js +15 -0
  58. package/dist/comments/rules.d.ts +140 -0
  59. package/dist/comments/rules.js +199 -0
  60. package/dist/core/index.d.ts +3 -1
  61. package/dist/core/index.js +1 -0
  62. package/dist/core/ledger-slice.d.ts +90 -0
  63. package/dist/core/ledger-slice.js +81 -0
  64. package/dist/core/ports/comments.d.ts +2 -0
  65. package/dist/core/ports/forms.d.ts +19 -7
  66. package/dist/core/ports/forms.js +4 -4
  67. package/dist/core/ports/index.d.ts +1 -1
  68. package/dist/core/ports/seo.d.ts +33 -6
  69. package/dist/core/react/bind-react.d.ts +46 -0
  70. package/dist/core/react/bind-react.js +28 -0
  71. package/dist/core/react/index.d.ts +3 -0
  72. package/dist/core/react/index.js +3 -0
  73. package/dist/core/react/use-controller.d.ts +16 -0
  74. package/dist/core/react/use-controller.js +18 -0
  75. package/dist/forms/adapters/http.d.ts +26 -0
  76. package/dist/forms/adapters/http.js +43 -0
  77. package/dist/forms/adapters/memory.d.ts +14 -0
  78. package/dist/forms/adapters/memory.js +77 -0
  79. package/dist/forms/conformance/forms-api.conformance.d.ts +17 -0
  80. package/dist/forms/conformance/forms-api.conformance.js +71 -0
  81. package/dist/forms/controllers/draft-store.d.ts +18 -0
  82. package/dist/forms/controllers/draft-store.js +17 -0
  83. package/dist/forms/controllers/field-attributes-dialog.controller.d.ts +37 -0
  84. package/dist/forms/controllers/field-attributes-dialog.controller.js +27 -0
  85. package/dist/forms/controllers/form-editor.controller.d.ts +36 -0
  86. package/dist/forms/controllers/form-editor.controller.js +22 -0
  87. package/dist/forms/controllers/form-fields-editor.controller.d.ts +20 -0
  88. package/dist/forms/controllers/form-fields-editor.controller.js +10 -0
  89. package/dist/forms/controllers/form-submission-detail.controller.d.ts +20 -0
  90. package/dist/forms/controllers/form-submission-detail.controller.js +10 -0
  91. package/dist/forms/controllers/form-submissions.controller.d.ts +25 -0
  92. package/dist/forms/controllers/form-submissions.controller.js +10 -0
  93. package/dist/forms/controllers/forms-list.controller.d.ts +22 -0
  94. package/dist/forms/controllers/forms-list.controller.js +10 -0
  95. package/dist/forms/forms.module.d.ts +138 -0
  96. package/dist/forms/forms.module.js +17 -0
  97. package/dist/forms/html-rules.d.ts +34 -0
  98. package/dist/forms/html-rules.js +34 -0
  99. package/dist/forms/index.d.ts +14 -0
  100. package/dist/forms/index.js +12 -0
  101. package/dist/forms/messages.en.d.ts +101 -0
  102. package/dist/forms/messages.en.js +105 -0
  103. package/dist/forms/models.d.ts +29 -0
  104. package/dist/forms/models.js +8 -0
  105. package/dist/forms/ports.d.ts +26 -0
  106. package/dist/forms/ports.js +6 -0
  107. package/dist/forms/react/components/FieldAttributesDialog.d.ts +14 -0
  108. package/dist/forms/react/components/FieldAttributesDialog.js +47 -0
  109. package/dist/forms/react/components/FormEditorFieldsBody.d.ts +28 -0
  110. package/dist/forms/react/components/FormEditorFieldsBody.js +24 -0
  111. package/dist/forms/react/components/FormEditorHeaderText.d.ts +7 -0
  112. package/dist/forms/react/components/FormEditorHeaderText.js +8 -0
  113. package/dist/forms/react/components/FormEditorMainPanel.d.ts +12 -0
  114. package/dist/forms/react/components/FormEditorMainPanel.js +13 -0
  115. package/dist/forms/react/components/FormEditorTabStrip.d.ts +13 -0
  116. package/dist/forms/react/components/FormEditorTabStrip.js +14 -0
  117. package/dist/forms/react/components/FormFieldsEditor.d.ts +13 -0
  118. package/dist/forms/react/components/FormFieldsEditor.js +39 -0
  119. package/dist/forms/react/components/FormSubmissionDate.d.ts +8 -0
  120. package/dist/forms/react/components/FormSubmissionDate.js +5 -0
  121. package/dist/forms/react/components/FormSubmissionDetail.d.ts +15 -0
  122. package/dist/forms/react/components/FormSubmissionDetail.js +30 -0
  123. package/dist/forms/react/components/FormSubmissions.d.ts +12 -0
  124. package/dist/forms/react/components/FormSubmissions.js +46 -0
  125. package/dist/forms/react/hooks/FormsPorts.hooks.d.ts +41 -0
  126. package/dist/forms/react/hooks/FormsPorts.hooks.js +16 -0
  127. package/dist/forms/react/hooks/forms-view.hooks.d.ts +117 -0
  128. package/dist/forms/react/hooks/forms-view.hooks.js +78 -0
  129. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.d.ts +31 -0
  130. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.js +22 -0
  131. package/dist/forms/react/hooks/use-form-editor.hooks.d.ts +118 -0
  132. package/dist/forms/react/hooks/use-form-editor.hooks.js +208 -0
  133. package/dist/forms/react/hooks/use-form-fields-editor.hooks.d.ts +34 -0
  134. package/dist/forms/react/hooks/use-form-fields-editor.hooks.js +36 -0
  135. package/dist/forms/react/hooks/use-form-submission-date.hooks.d.ts +12 -0
  136. package/dist/forms/react/hooks/use-form-submission-date.hooks.js +9 -0
  137. package/dist/forms/react/hooks/use-form-submission-detail.hooks.d.ts +68 -0
  138. package/dist/forms/react/hooks/use-form-submission-detail.hooks.js +81 -0
  139. package/dist/forms/react/hooks/use-form-submissions.hooks.d.ts +67 -0
  140. package/dist/forms/react/hooks/use-form-submissions.hooks.js +110 -0
  141. package/dist/forms/react/hooks/use-forms-list.hooks.d.ts +78 -0
  142. package/dist/forms/react/hooks/use-forms-list.hooks.js +103 -0
  143. package/dist/forms/react/index.d.ts +452 -0
  144. package/dist/forms/react/index.js +35 -0
  145. package/dist/forms/react/pages/FormEditor.d.ts +19 -0
  146. package/dist/forms/react/pages/FormEditor.js +40 -0
  147. package/dist/forms/react/pages/FormsList.d.ts +39 -0
  148. package/dist/forms/react/pages/FormsList.js +50 -0
  149. package/dist/forms/rules.d.ts +291 -0
  150. package/dist/forms/rules.js +338 -0
  151. package/dist/media/react/hooks/EditMediaPanel.hooks.js +1 -1
  152. package/dist/media/react/hooks/LibraryTab.hooks.d.ts +1 -1
  153. package/dist/media/react/hooks/LibraryTab.hooks.js +1 -1
  154. package/dist/media/react/hooks/MediaCard.hooks.js +6 -20
  155. package/dist/media/react/hooks/MediaGrid.hooks.d.ts +2 -2
  156. package/dist/media/react/hooks/MediaPage.hooks.d.ts +1 -1
  157. package/dist/media/react/hooks/MediaPage.hooks.js +1 -1
  158. package/dist/media/react/hooks/MediaPicker.hooks.js +1 -1
  159. package/dist/media/react/index.js +1 -1
  160. package/dist/media/react/tabs/LibraryTab.d.ts +1 -1
  161. package/dist/media/react/tabs/ProvidersTab.d.ts +1 -1
  162. package/dist/playground/react/components/Canvas.d.ts +1 -1
  163. package/dist/playground/react/hooks/Canvas.hooks.d.ts +1 -1
  164. package/dist/playground/react/hooks/Canvas.hooks.js +1 -1
  165. package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +1 -1
  166. package/dist/playground/react/index.js +1 -1
  167. package/dist/playground/react/pages/PlaygroundPage.d.ts +1 -1
  168. package/dist/playground/react/tabs/CanvasTab.d.ts +1 -1
  169. package/dist/react/bind-react.d.ts +1 -45
  170. package/dist/react/bind-react.js +2 -27
  171. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +22 -5
  172. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -2
  173. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +17 -55
  174. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +33 -70
  175. package/dist/react/components/RowMenu/RowMenu.hooks.js +14 -3
  176. package/dist/react/use-controller.d.ts +1 -15
  177. package/dist/react/use-controller.js +2 -17
  178. package/dist/redirects/adapters/http.d.ts +20 -0
  179. package/dist/redirects/adapters/http.js +31 -0
  180. package/dist/redirects/adapters/memory.d.ts +13 -0
  181. package/dist/redirects/adapters/memory.js +83 -0
  182. package/dist/redirects/conformance/redirects-api.conformance.d.ts +12 -0
  183. package/dist/redirects/conformance/redirects-api.conformance.js +66 -0
  184. package/dist/redirects/controllers/hit-count.controller.d.ts +14 -0
  185. package/dist/redirects/controllers/hit-count.controller.js +10 -0
  186. package/dist/redirects/controllers/import-redirects.controller.d.ts +28 -0
  187. package/dist/redirects/controllers/import-redirects.controller.js +29 -0
  188. package/dist/redirects/controllers/redirects.controller.d.ts +37 -0
  189. package/dist/redirects/controllers/redirects.controller.js +38 -0
  190. package/dist/redirects/index.d.ts +11 -0
  191. package/dist/redirects/index.js +10 -0
  192. package/dist/redirects/messages.en.d.ts +58 -0
  193. package/dist/redirects/messages.en.js +60 -0
  194. package/dist/redirects/models.d.ts +14 -0
  195. package/dist/redirects/models.js +2 -0
  196. package/dist/redirects/ports.d.ts +9 -0
  197. package/dist/redirects/ports.js +4 -0
  198. package/dist/redirects/react/components/HitCountCell.d.ts +19 -0
  199. package/dist/redirects/react/components/HitCountCell.js +19 -0
  200. package/dist/redirects/react/components/ImportRedirectsForm.d.ts +17 -0
  201. package/dist/redirects/react/components/ImportRedirectsForm.js +12 -0
  202. package/dist/redirects/react/hooks/RedirectsOptions.hooks.d.ts +27 -0
  203. package/dist/redirects/react/hooks/RedirectsOptions.hooks.js +15 -0
  204. package/dist/redirects/react/hooks/RedirectsPage.hooks.d.ts +50 -0
  205. package/dist/redirects/react/hooks/RedirectsPage.hooks.js +30 -0
  206. package/dist/redirects/react/hooks/RedirectsPorts.hooks.d.ts +10 -0
  207. package/dist/redirects/react/hooks/RedirectsPorts.hooks.js +11 -0
  208. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.d.ts +19 -0
  209. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.js +15 -0
  210. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.d.ts +21 -0
  211. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.js +25 -0
  212. package/dist/redirects/react/hooks/use-redirects.hooks.d.ts +34 -0
  213. package/dist/redirects/react/hooks/use-redirects.hooks.js +63 -0
  214. package/dist/redirects/react/hooks/wired.hooks.d.ts +55 -0
  215. package/dist/redirects/react/hooks/wired.hooks.js +31 -0
  216. package/dist/redirects/react/index.d.ts +324 -0
  217. package/dist/redirects/react/index.js +28 -0
  218. package/dist/redirects/react/pages/RedirectsPage.d.ts +15 -0
  219. package/dist/redirects/react/pages/RedirectsPage.js +20 -0
  220. package/dist/redirects/redirects.module.d.ts +77 -0
  221. package/dist/redirects/redirects.module.js +13 -0
  222. package/dist/redirects/rules.d.ts +131 -0
  223. package/dist/redirects/rules.js +134 -0
  224. package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +1 -1
  225. package/dist/security/react/hooks/AccessTokensTab.hooks.js +1 -1
  226. package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +1 -1
  227. package/dist/security/react/hooks/RootKeyTab.hooks.js +1 -1
  228. package/dist/security/react/hooks/SecurityPage.hooks.d.ts +1 -1
  229. package/dist/security/react/index.js +1 -1
  230. package/dist/security/react/pages/SecurityPage.d.ts +1 -1
  231. package/dist/security/react/tabs/AccessTokensTab.d.ts +1 -1
  232. package/dist/security/react/tabs/RootKeyTab.d.ts +1 -1
  233. package/dist/seo/adapters/http.d.ts +31 -0
  234. package/dist/seo/adapters/http.js +37 -0
  235. package/dist/seo/adapters/memory.d.ts +28 -0
  236. package/dist/seo/adapters/memory.js +129 -0
  237. package/dist/seo/conformance/seo-api.conformance.d.ts +8 -0
  238. package/dist/seo/conformance/seo-api.conformance.js +44 -0
  239. package/dist/seo/controllers/entry-picker.controller.d.ts +21 -0
  240. package/dist/seo/controllers/entry-picker.controller.js +17 -0
  241. package/dist/seo/controllers/entry-section.controller.d.ts +20 -0
  242. package/dist/seo/controllers/entry-section.controller.js +7 -0
  243. package/dist/seo/controllers/media-ref.controller.d.ts +26 -0
  244. package/dist/seo/controllers/media-ref.controller.js +14 -0
  245. package/dist/seo/controllers/seo-entry.controller.d.ts +31 -0
  246. package/dist/seo/controllers/seo-entry.controller.js +52 -0
  247. package/dist/seo/controllers/seo.controller.d.ts +29 -0
  248. package/dist/seo/controllers/seo.controller.js +50 -0
  249. package/dist/seo/controllers/sitemap.controller.d.ts +25 -0
  250. package/dist/seo/controllers/sitemap.controller.js +27 -0
  251. package/dist/seo/index.d.ts +14 -0
  252. package/dist/seo/index.js +12 -0
  253. package/dist/seo/messages.en.d.ts +79 -0
  254. package/dist/seo/messages.en.js +79 -0
  255. package/dist/seo/models.d.ts +179 -0
  256. package/dist/seo/models.js +8 -0
  257. package/dist/seo/ports.d.ts +11 -0
  258. package/dist/seo/ports.js +4 -0
  259. package/dist/seo/react/components/MediaPickerBridge.d.ts +4 -0
  260. package/dist/seo/react/components/MediaPickerBridge.js +8 -0
  261. package/dist/seo/react/components/MediaRefField.d.ts +40 -0
  262. package/dist/seo/react/components/MediaRefField.js +12 -0
  263. package/dist/seo/react/components/SeoIcons.d.ts +13 -0
  264. package/dist/seo/react/components/SeoIcons.js +32 -0
  265. package/dist/seo/react/components/SitemapModal.d.ts +48 -0
  266. package/dist/seo/react/components/SitemapModal.js +72 -0
  267. package/dist/seo/react/hooks/MediaPickerBridge.hooks.d.ts +6 -0
  268. package/dist/seo/react/hooks/MediaPickerBridge.hooks.js +27 -0
  269. package/dist/seo/react/hooks/MediaRefField.hooks.d.ts +25 -0
  270. package/dist/seo/react/hooks/MediaRefField.hooks.js +30 -0
  271. package/dist/seo/react/hooks/SeoModuleTabs.d.ts +14 -0
  272. package/dist/seo/react/hooks/SeoModuleTabs.js +18 -0
  273. package/dist/seo/react/hooks/SeoPage.hooks.d.ts +69 -0
  274. package/dist/seo/react/hooks/SeoPage.hooks.js +37 -0
  275. package/dist/seo/react/hooks/SeoPorts.hooks.d.ts +19 -0
  276. package/dist/seo/react/hooks/SeoPorts.hooks.js +22 -0
  277. package/dist/seo/react/hooks/SitemapModal.hooks.d.ts +26 -0
  278. package/dist/seo/react/hooks/SitemapModal.hooks.js +20 -0
  279. package/dist/seo/react/hooks/use-entry-picker.hooks.d.ts +11 -0
  280. package/dist/seo/react/hooks/use-entry-picker.hooks.js +20 -0
  281. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.d.ts +14 -0
  282. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.js +26 -0
  283. package/dist/seo/react/hooks/use-seo-entry-section.hooks.d.ts +4 -0
  284. package/dist/seo/react/hooks/use-seo-entry-section.hooks.js +7 -0
  285. package/dist/seo/react/hooks/use-seo.hooks.d.ts +11 -0
  286. package/dist/seo/react/hooks/use-seo.hooks.js +29 -0
  287. package/dist/seo/react/hooks/use-sitemap-modal.hooks.d.ts +10 -0
  288. package/dist/seo/react/hooks/use-sitemap-modal.hooks.js +18 -0
  289. package/dist/seo/react/index.d.ts +369 -0
  290. package/dist/seo/react/index.js +30 -0
  291. package/dist/seo/react/options.d.ts +26 -0
  292. package/dist/seo/react/options.js +2 -0
  293. package/dist/seo/react/pages/SeoPage.d.ts +161 -0
  294. package/dist/seo/react/pages/SeoPage.js +215 -0
  295. package/dist/seo/rules.d.ts +142 -0
  296. package/dist/seo/rules.js +220 -0
  297. package/dist/seo/seo.module.d.ts +115 -0
  298. package/dist/seo/seo.module.js +14 -0
  299. package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +1 -1
  300. package/dist/source-control/react/hooks/ProvidersTab.hooks.js +1 -1
  301. package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +1 -1
  302. package/dist/source-control/react/index.js +1 -1
  303. package/dist/source-control/react/pages/SourceControlPage.d.ts +1 -1
  304. package/dist/source-control/react/tabs/ProvidersTab.d.ts +1 -1
  305. package/dist/widgets/adapters/http.d.ts +19 -0
  306. package/dist/widgets/adapters/http.js +33 -0
  307. package/dist/widgets/adapters/memory.d.ts +22 -0
  308. package/dist/widgets/adapters/memory.js +93 -0
  309. package/dist/widgets/conformance/widgets-api.conformance.d.ts +6 -0
  310. package/dist/widgets/conformance/widgets-api.conformance.js +55 -0
  311. package/dist/widgets/controllers/instance-editor.controller.d.ts +49 -0
  312. package/dist/widgets/controllers/instance-editor.controller.js +87 -0
  313. package/dist/widgets/controllers/library.controller.d.ts +33 -0
  314. package/dist/widgets/controllers/library.controller.js +53 -0
  315. package/dist/widgets/controllers/region-editor.controller.d.ts +42 -0
  316. package/dist/widgets/controllers/region-editor.controller.js +69 -0
  317. package/dist/widgets/controllers/regions.controller.d.ts +27 -0
  318. package/dist/widgets/controllers/regions.controller.js +44 -0
  319. package/dist/widgets/index.d.ts +11 -0
  320. package/dist/widgets/index.js +9 -0
  321. package/dist/widgets/messages.en.d.ts +78 -0
  322. package/dist/widgets/messages.en.js +83 -0
  323. package/dist/widgets/models.d.ts +62 -0
  324. package/dist/widgets/models.js +2 -0
  325. package/dist/widgets/ports.d.ts +79 -0
  326. package/dist/widgets/ports.js +5 -0
  327. package/dist/widgets/react/components/WidgetInstanceNotices.d.ts +14 -0
  328. package/dist/widgets/react/components/WidgetInstanceNotices.js +25 -0
  329. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.d.ts +22 -0
  330. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.js +18 -0
  331. package/dist/widgets/react/components/WidgetsLibraryNotices.d.ts +13 -0
  332. package/dist/widgets/react/components/WidgetsLibraryNotices.js +10 -0
  333. package/dist/widgets/react/hooks/WidgetsPorts.hooks.d.ts +270 -0
  334. package/dist/widgets/react/hooks/WidgetsPorts.hooks.js +17 -0
  335. package/dist/widgets/react/hooks/navigation.hooks.d.ts +9 -0
  336. package/dist/widgets/react/hooks/navigation.hooks.js +6 -0
  337. package/dist/widgets/react/hooks/page-views.hooks.d.ts +87 -0
  338. package/dist/widgets/react/hooks/page-views.hooks.js +30 -0
  339. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.d.ts +56 -0
  340. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.js +38 -0
  341. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.d.ts +32 -0
  342. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.js +22 -0
  343. package/dist/widgets/react/hooks/use-widget-regions.hooks.d.ts +23 -0
  344. package/dist/widgets/react/hooks/use-widget-regions.hooks.js +22 -0
  345. package/dist/widgets/react/hooks/use-widgets-library.hooks.d.ts +37 -0
  346. package/dist/widgets/react/hooks/use-widgets-library.hooks.js +23 -0
  347. package/dist/widgets/react/index.d.ts +391 -0
  348. package/dist/widgets/react/index.js +31 -0
  349. package/dist/widgets/react/pages/WidgetInstanceEditor.d.ts +23 -0
  350. package/dist/widgets/react/pages/WidgetInstanceEditor.js +37 -0
  351. package/dist/widgets/react/pages/WidgetRegionEditor.d.ts +22 -0
  352. package/dist/widgets/react/pages/WidgetRegionEditor.js +25 -0
  353. package/dist/widgets/react/pages/WidgetRegions.d.ts +21 -0
  354. package/dist/widgets/react/pages/WidgetRegions.js +31 -0
  355. package/dist/widgets/react/pages/WidgetsLibrary.d.ts +24 -0
  356. package/dist/widgets/react/pages/WidgetsLibrary.js +61 -0
  357. package/dist/widgets/rules.d.ts +94 -0
  358. package/dist/widgets/rules.js +83 -0
  359. package/dist/widgets/widgets.module.d.ts +122 -0
  360. package/dist/widgets/widgets.module.js +21 -0
  361. package/package.json +206 -9
@@ -0,0 +1,338 @@
1
+ import { AdminApiError as ApiError, describeApiError as describeCoreApiError } from "../core/transport/errors.js";
2
+ const describeApiError = (e, fallback) => describeCoreApiError({ e, fallback });
3
+ /**
4
+ * @file Pure logic for the `forms` feature (`FormEditor.tsx` — see `FormsList.tsx`'s own
5
+ * `rules.ts`/hook for the list screen's extraction) — everything that computes a value rather than
6
+ * rendering one. Follows the convention `features/posts/rules.ts` establishes: no React, no
7
+ * hooks, importable and directly testable.
8
+ *
9
+ * One deliberate exception to "pure", same as `collections/rules.ts`'s `nextRowId`:
10
+ * {@link nextAttrRowId} is a module-level counter `attrRowsFromField`/`addAttrRow` advance. Only
11
+ * `FieldAttributesDialog` (via `use-field-attributes-dialog.hooks.ts`) consumes it today, so it
12
+ * would be equally correct sitting in that hook file — kept here instead for the same reason
13
+ * `collections/rules.ts` keeps its row-id counter alongside its other draft-list transforms: one
14
+ * place for "how draft rows get local keys" per feature, not split by which hook happens to use it
15
+ * first.
16
+ *
17
+ * `KEYS` (fetch-query migration, 2026-08-12): forms and form-submissions are two independent
18
+ * resources (separate ports, no method overlap — see `core/ports/forms.ts`/`form-submissions-
19
+ * port.hooks.ts`'s own doc comments), so they get two entirely separate top-level key namespaces
20
+ * rather than sharing one grandparent. Within each, `list`/`detail(id)` (and `submissionsList(formId)`/
21
+ * `submissionDetail(formId, id)`) are SIBLINGS, not parent/child — `@jini-ai/ui/fetch-query`'s
22
+ * `QueryKey` doc warns that invalidation matches by prefix, and `collections/rules.ts`'s own `KEYS`
23
+ * doc records the regression that bit the predecessor when a detail key nested under its list: every
24
+ * save silently fired 3 extra background requests because invalidating the list also invalidated the
25
+ * editor's own currently-open read. Fixed second-array-element ("list" vs "detail") rather than
26
+ * nesting keeps `KEYS.list`'s invalidation from ever touching an open `KEYS.form(id)`/
27
+ * `KEYS.submissionDetail(...)` read, regardless of what `id` happens to be.
28
+ */
29
+ /**
30
+ * This screen's name on `lib/content-refresh-bus.ts` — see `taxonomy/rules.ts`'s `TAXONOMY_RESOURCE`
31
+ * for why this is a plain colocated constant rather than a shared registry. `forms_create_definition`/
32
+ * `forms_update_definition`/`forms_set_definition_status` (`apps/website/src/features/forms/agent-
33
+ * tools.ts`) are agent-callable, so `FormsList.tsx` needs the same "an assistant write shows up
34
+ * without a reload" fix `use-taxonomy.hooks.ts` shipped first.
35
+ */
36
+ export const FORMS_LIST_RESOURCE = "forms";
37
+ /** The list has no sort control: recently edited forms belong first. Copy before sorting so
38
+ * the query cache and injected repository keep their own order; ties retain response order. */
39
+ export function newestUpdatedForms({ forms }, _optional = {}) {
40
+ return [...forms].sort((a, b) => (Date.parse(b.updatedAt) || 0) - (Date.parse(a.updatedAt) || 0));
41
+ }
42
+ /** One form event's compact local date and full tooltip. Shared by definitions and submissions;
43
+ * malformed legacy values stay visible as a dash rather than throwing during table rendering. */
44
+ export function formDateDisplay({ iso, locale }, { timeZone } = {}) {
45
+ const date = new Date(iso);
46
+ if (Number.isNaN(date.getTime()))
47
+ return { text: "—", full: "—", dateTime: undefined };
48
+ return {
49
+ text: new Intl.DateTimeFormat(locale, { dateStyle: "short", timeStyle: "short", timeZone }).format(date),
50
+ full: new Intl.DateTimeFormat(locale, {
51
+ year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "2-digit", timeZone,
52
+ }).format(date),
53
+ dateTime: date.toISOString(),
54
+ };
55
+ }
56
+ /** Form-specific date copy. The shared admin timestamp helper intentionally slices ISO text
57
+ * and its relative helper is English-only; these two events need the operator's locale and
58
+ * browser time zone. Absolute dates remain accurate while the list stays open without a timer.
59
+ *
60
+ * Owner 2026-10-05: line 1 created, line 2 updated, each a compact short date + time with no event
61
+ * word; one line when updated shows the same date and minute as created. The comparison is on the
62
+ * displayed short text, so edits within the same minute collapse and the rule follows the locale's
63
+ * own precision. Intl picks the date order — never a hand-built "M/D/YY".
64
+ *
65
+ * @complexity O(1) time and space — two dates, fixed-size formatting.
66
+ */
67
+ export function formDatesLines({ form, locale, t }, options = {}) {
68
+ const created = formDateDisplay({ iso: form.createdAt, locale }, options);
69
+ const updated = formDateDisplay({ iso: form.updatedAt, locale }, options);
70
+ if (created.text === updated.text) {
71
+ const label = t("Created {created} · Updated {updated}")
72
+ .replace("{created}", created.full)
73
+ .replace("{updated}", updated.full);
74
+ return [{ kind: "both", text: created.text, dateTime: created.dateTime, label }];
75
+ }
76
+ return [
77
+ { kind: "created", text: created.text, dateTime: created.dateTime, label: t("Created {date}").replace("{date}", created.full) },
78
+ { kind: "updated", text: updated.text, dateTime: updated.dateTime, label: t("Updated {date}").replace("{date}", updated.full) },
79
+ ];
80
+ }
81
+ export const KEYS = {
82
+ list: ["forms", "list"],
83
+ form: (id) => ["forms", "detail", id],
84
+ submissionsList: (formId) => ["form-submissions", "list", formId],
85
+ submissionDetail: (formId, submissionId) => [
86
+ "form-submissions",
87
+ "detail",
88
+ formId,
89
+ submissionId,
90
+ ],
91
+ };
92
+ /**
93
+ * `useFormEditor`'s error banner, extracted out of that hook (`refactor/fetch-query` complexity
94
+ * pass, 2026-08-12 — same reason `collections/rules.ts`'s `visibleEntryEditorError` was extracted:
95
+ * the hook's own precedence chain over four sources pushed it past the complexity ceiling).
96
+ *
97
+ * Precedence: an active write's own failure (update/create/status, in that order — mirrors
98
+ * `redirects/rules.ts`'s `firstWriteError` array-order precedence, since `update`/`status` can both
99
+ * apply to the SAME loaded form) always wins. The list-load failure only surfaces before the form
100
+ * has ever loaded — once `hasForm` is true, a later BACKGROUND refresh failure must not blank an
101
+ * editor the operator is actively using (same "a later failure must not erase what already
102
+ * rendered" guard `FormEditor.tsx`'s own file header already documents at the render layer; this is
103
+ * its data-layer half).
104
+ *
105
+ * @complexity Time/space: O(1) — four fixed checks, no iteration.
106
+ */
107
+ export function visibleFormEditorError(params, _optional = {}) {
108
+ // Two distinct fallback strings, matching the pre-migration `handleSave`/`handleStatusToggle`
109
+ // catch blocks verbatim ("save failed" vs "status update failed") — not one shared string.
110
+ if (params.updateError)
111
+ return describeApiError(params.updateError, params.saveFallback);
112
+ if (params.createError)
113
+ return describeApiError(params.createError, params.saveFallback);
114
+ if (params.statusError)
115
+ return describeApiError(params.statusError, params.statusUpdateFallback);
116
+ if (params.hasForm)
117
+ return null;
118
+ return params.listError ? describeApiError(params.listError, params.loadFormFallback) : null;
119
+ }
120
+ /**
121
+ * `useFormsList`'s error banner: the row-toggle write's own failure outranks a background
122
+ * list-refresh failure, same precedence `redirects/rules.ts`'s `visibleRedirectsError` documents.
123
+ * Two sources only (not the three-plus that pushed `visibleFormEditorError`/`visibleTaxonomyError`
124
+ * out to `rules.ts`), kept here anyway rather than inlined so the hook body doesn't grow a nested
125
+ * ternary chain (`@jini-ai/ui/fetch-query`'s `resolveFetchQueryStatus` doc explains why a flat
126
+ * extraction beats a nested ternary of the same branch count for the complexity gate).
127
+ *
128
+ * @complexity Time/space: O(1) — two fixed checks, no iteration.
129
+ */
130
+ export function formsListError(params, _optional = {}) {
131
+ // The delete's own failure outranks both the toggle's and a background list-refresh failure —
132
+ // same precedence tier `use-posts.hooks.ts`'s `removePost` gives its own delete, and a 404
133
+ // "already gone" resolves to `message: null` here so it never reaches this banner at all (see
134
+ // `describeTrashError`'s own doc for why).
135
+ const deleteMessage = describeTrashError({ error: params.deleteError, fallback: params.deleteFallback, versionChangedMessage: params.versionChangedMessage }).message;
136
+ if (deleteMessage)
137
+ return deleteMessage;
138
+ if (params.toggleError)
139
+ return describeApiError(params.toggleError, params.statusUpdateFallback);
140
+ if (params.hasForms)
141
+ return null;
142
+ return params.listError ? describeApiError(params.listError, params.loadFormsFallback) : null;
143
+ }
144
+ /**
145
+ * Classifies a failed `api.trash` call — shared by `useFormsList`'s `removeForm` (forms) and
146
+ * `useFormSubmissionDetail`'s `confirmDelete` (submissions), since both routes now go through the
147
+ * same generic `POST /trash/items` (`routes/trash/items.ts`) and its 404/409 contract:
148
+ *
149
+ * - 404 (`NOT_FOUND`/`FORMS_SUBMISSION_NOT_FOUND`/…): the row is already gone — another tab,
150
+ * another operator, or a prior click that actually succeeded before a flaky response read as a
151
+ * failure. `alreadyGone: true`, `message: null` — the caller's job is a quiet list refresh, not
152
+ * an error banner blaming the operator for something that already happened.
153
+ * - 409 `TRASH_VERSION_CHANGED`: the row changed under the operator since this screen last read
154
+ * it. Specific reload-and-retry copy, not the generic fallback.
155
+ * - Anything else (network failure, an unrelated `ApiError`, …): falls through to
156
+ * `describeApiError`'s generic fallback message.
157
+ *
158
+ * @complexity O(1) — one `instanceof` check plus two fixed comparisons.
159
+ */
160
+ export function describeTrashError({ error: e, fallback, versionChangedMessage }, _optional = {}) {
161
+ if (!e)
162
+ return { alreadyGone: false, message: null };
163
+ if (e instanceof ApiError || ("status" in e && typeof e.status === "number")) {
164
+ // Existing host transports may retain their own ApiError constructor; status/code are wire fields.
165
+ if (e.status === 404)
166
+ return { alreadyGone: true, message: null };
167
+ if ("code" in e && e.code === "TRASH_VERSION_CHANGED") {
168
+ return { alreadyGone: false, message: versionChangedMessage };
169
+ }
170
+ }
171
+ return { alreadyGone: false, message: describeApiError(e, fallback) };
172
+ }
173
+ /**
174
+ * The row-action menu for one form. `RowMenu` has no per-item `disabled` — the in-flight guard lives
175
+ * in `use-forms-list.hooks.ts`'s own `toggleStatus` (a no-op while `rowSavingId` is already set), the
176
+ * same shape `use-redirects.hooks.ts`'s `onToggleStatus` uses for its identical `if (saving) return;`
177
+ * guard. (CORRECTED 2026-09-05: this comment previously said the guard "stays in the caller's
178
+ * `onToggleStatus` closure (`FormsList.tsx`'s own `if (rowSavingId) return;`)" and claimed that was
179
+ * the same shape `Redirects.tsx` uses — false; `Redirects.tsx` never had such a guard inline, only its
180
+ * hook does. Flagged by the 2026-09-05 Gemini admin-tooling audit as a standing no-logic-in-`.tsx`
181
+ * violation; moving the guard into the hook also fixed the comment's own false precedent claim.)
182
+ *
183
+ * @complexity Time/space: O(1) — three fixed entries, no iteration.
184
+ */
185
+ export function formRowMenuItems({ form, handlers, t }, _optional = {}) {
186
+ return [
187
+ // Slug, not id — the admin URL reads `/admin/forms/<slug>` (ui-fixes-backlog.md #8); the GET
188
+ // route still resolves an id too, so this is not a behavior change for any existing bookmark.
189
+ { key: "edit", label: t("Edit"), onSelect: () => handlers.onEdit(form) },
190
+ {
191
+ key: "toggle-status",
192
+ label: form.status === "active" ? t("Disable") : t("Enable"),
193
+ tone: form.status === "active" ? "warning" : "default",
194
+ onSelect: () => handlers.onToggleStatus(form),
195
+ },
196
+ // Opens `FormsList.tsx`'s `ConfirmDialog` — no network call from this selection itself, same
197
+ // "a click alone can never delete" contract `use-form-submission-detail.hooks.ts`'s
198
+ // `requestDelete` already documents for the sibling submission-delete flow.
199
+ { key: "delete", label: t("Delete"), tone: "danger", onSelect: () => handlers.onDelete(form) },
200
+ ];
201
+ }
202
+ export const FIELD_TYPES = ["text", "email", "textarea", "checkbox"];
203
+ /** The two tab-panel views on an existing form's editor (`formId !== "new"`). */
204
+ export const FORM_TABS = [
205
+ { id: "fields", label: "Fields" },
206
+ { id: "submissions", label: "Submissions" },
207
+ ];
208
+ /**
209
+ * Roving-tabindex arrow-key step for the Fields/Submissions tablist — ArrowLeft/ArrowRight cycle
210
+ * between the two tabs, Home/End jump to the first/last.
211
+ *
212
+ * @complexity O(1) — `FORM_TABS` is a fixed 2-item array.
213
+ */
214
+ export function nextTabIndex({ key, currentIndex }, _optional = {}) {
215
+ if (key === "ArrowRight")
216
+ return (currentIndex + 1) % FORM_TABS.length;
217
+ if (key === "ArrowLeft")
218
+ return (currentIndex - 1 + FORM_TABS.length) % FORM_TABS.length;
219
+ if (key === "Home")
220
+ return 0;
221
+ if (key === "End")
222
+ return FORM_TABS.length - 1;
223
+ return null;
224
+ }
225
+ export function blankField(_required = {}, _optional = {}) {
226
+ return { id: "", label: "", type: "text", required: false };
227
+ }
228
+ /** Shared "what do we call this field in a title/label" fallback — a blank draft field has neither
229
+ * a label nor an id yet, so both the kebab's `aria-label` and the modal's own `<h2>` need the same
230
+ * `label -> id -> "Field N"` chain rather than risking the two drifting apart. */
231
+ export function fieldDisplayName({ field, index }, _optional = {}) {
232
+ return field.label || field.id || `Field ${index + 1}`;
233
+ }
234
+ /** @complexity O(n) in `fields.length`. */
235
+ export function updateFormField({ fields, index, patch }, _optional = {}) {
236
+ return fields.map((f, i) => (i === index ? { ...f, ...patch } : f));
237
+ }
238
+ /** @complexity O(n) in `fields.length`. */
239
+ export function addFormField({ fields }, _optional = {}) {
240
+ return [...fields, blankField()];
241
+ }
242
+ /** @complexity O(n) in `fields.length`. */
243
+ export function removeFormField({ fields, index }, _optional = {}) {
244
+ return fields.filter((_, i) => i !== index);
245
+ }
246
+ /** The already-persisted field ids on a form — `FormFieldsEditor` disables the id input and the
247
+ * Remove button for these (a saved field's id cannot be changed or removed once created). `null`
248
+ * (form not loaded yet, or the "new form" case) has no existing ids. */
249
+ export function existingFieldIdsOf({ form }, _optional = {}) {
250
+ return form ? form.fields.map((f) => f.id) : [];
251
+ }
252
+ // ---------------------------------------------------------------------------
253
+ // Field attributes modal (per-field CSS classes + HTML attributes)
254
+ // ---------------------------------------------------------------------------
255
+ /** Mirrors `forms.ts`'s `ATTRIBUTE_NAME_PATTERN` exactly — see `FormEditor.tsx`'s own header
256
+ * comment for why this is a fast-reject-only duplicate, not the authoritative check. Keep in sync
257
+ * by hand if the server allowlist changes. */
258
+ export const ATTRIBUTE_NAME_PATTERN = /^(aria-[a-z0-9-]+|data-[a-z0-9-]+|placeholder|autocomplete|inputmode|pattern|title|min|max|step|minlength|spellcheck|readonly)$/;
259
+ /** Same bounds as `forms.ts`'s `MAX_CLASS_NAME_LENGTH`/`MAX_ATTRIBUTES_PER_FIELD` — client-side
260
+ * early-reject only, not enforcement (see `ATTRIBUTE_NAME_PATTERN` above). */
261
+ export const MAX_CLASS_NAME_LENGTH = 300;
262
+ export const MAX_ATTRIBUTES_PER_FIELD = 12;
263
+ /** A handful of the allowlisted names as real, pickable suggestions (the modal's own "here's what
264
+ * you can do" surface — an operator has no other way to discover the allowlist) rather than every
265
+ * one: `aria-*`/`data-*` are open namespaces, so `aria-label`/`data-testid` stand in for the whole
266
+ * prefix family instead of listing every field-specific `aria-*` name that doesn't exist yet. */
267
+ export const ATTRIBUTE_NAME_SUGGESTIONS = [
268
+ "aria-label",
269
+ "aria-describedby",
270
+ "data-testid",
271
+ "placeholder",
272
+ "autocomplete",
273
+ "inputmode",
274
+ "pattern",
275
+ "title",
276
+ "min",
277
+ "max",
278
+ "step",
279
+ "minlength",
280
+ "spellcheck",
281
+ "readonly",
282
+ ];
283
+ /** Local-only row key for the modal's attribute list, so React can key a row before it has a
284
+ * stable identity — same `_rowId`/module-counter pattern `collections/rules.ts`'s
285
+ * `EditFieldsDialog` support uses for its own draft field rows. */
286
+ let nextAttrRowId = 0;
287
+ export function attrRowsFromField({ field }, _optional = {}) {
288
+ return Object.entries(field.attributes ?? {}).map(([name, value]) => ({ _rowId: nextAttrRowId++, name, value }));
289
+ }
290
+ /** @complexity O(n) in `rows.length`. */
291
+ export function updateAttrRow({ rows, rowId, patch }, _optional = {}) {
292
+ return rows.map((r) => (r._rowId === rowId ? { ...r, ...patch } : r));
293
+ }
294
+ /** @complexity O(n) in `rows.length`. */
295
+ export function removeAttrRow({ rows, rowId }, _optional = {}) {
296
+ return rows.filter((r) => r._rowId !== rowId);
297
+ }
298
+ /** @complexity O(n) in `rows.length`. */
299
+ export function addAttrRow({ rows }, _optional = {}) {
300
+ return [...rows, { _rowId: nextAttrRowId++, name: "", value: "" }];
301
+ }
302
+ /**
303
+ * Validates + shapes `FieldAttributesDialog`'s draft into the `Partial<AdminFormField>` patch
304
+ * `onSave` applies: a class-name length cap, then every named attribute row against the allowlist
305
+ * (blank names are silently skipped — an empty trailing row is not an error), then a total-count
306
+ * cap on the surviving attributes. The security-relevant check is server-side (`forms.ts`'s
307
+ * `validateFieldDescriptors`); this is the fast, pre-save rejection only — see this feature's own
308
+ * `ATTRIBUTE_NAME_PATTERN` doc.
309
+ *
310
+ * @complexity O(n) in `rows.length`, short-circuiting on the first disallowed name.
311
+ */
312
+ export function buildFieldAttributesPatch(draft, _optional = {}) {
313
+ const trimmedClassName = draft.className.trim();
314
+ if (trimmedClassName.length > MAX_CLASS_NAME_LENGTH) {
315
+ return { ok: false, error: `CSS classes must be at most ${MAX_CLASS_NAME_LENGTH} characters.` };
316
+ }
317
+ const attributes = {};
318
+ for (const row of draft.rows) {
319
+ const name = row.name.trim();
320
+ if (!name)
321
+ continue;
322
+ if (!ATTRIBUTE_NAME_PATTERN.test(name)) {
323
+ return { ok: false, error: `Attribute "${name}" isn't allowed. Use aria-*, data-*, or one of the suggested names.` };
324
+ }
325
+ attributes[name] = row.value;
326
+ }
327
+ if (Object.keys(attributes).length > MAX_ATTRIBUTES_PER_FIELD) {
328
+ return { ok: false, error: `At most ${MAX_ATTRIBUTES_PER_FIELD} attributes are allowed per field.` };
329
+ }
330
+ return {
331
+ ok: true,
332
+ patch: {
333
+ className: trimmedClassName || undefined,
334
+ attributes: Object.keys(attributes).length > 0 ? attributes : undefined,
335
+ },
336
+ };
337
+ }
338
+ //# sourceMappingURL=rules.js.map
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useLayoutEffect, useRef, useState } from 'react';
2
- import { useController } from '../../../react/use-controller.js';
2
+ import { useController } from '../../../core/react/use-controller.js';
3
3
  import { createEditMediaController } from '../../controllers/edit-media.controller.js';
4
4
  import { canReplaceMedia, mediaEmbedSnippet, parseOptionalPixelSize, safeMediaUrl } from '../../rules.js';
5
5
  import { parseMediaHtmlAttributes, describeMediaHtmlAttributeError } from '../../html-attributes.js';
@@ -1,4 +1,4 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  import { createLibraryController } from '../../controllers/library.controller.js';
3
3
  import type { MediaAsset } from '../../models.js';
4
4
  export declare function useLibraryTab({ params, permissions }: TabViewProps, _optional?: Record<string, never>): {
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useLayoutEffect, useRef, useState } from 'react';
2
- import { useController } from '../../../react/use-controller.js';
2
+ import { useController } from '../../../core/react/use-controller.js';
3
3
  import { createLibraryController } from '../../controllers/library.controller.js';
4
4
  import { useSharedMediaLibrary } from './MediaPage.hooks.js';
5
5
  import { useMediaPorts } from './MediaPorts.hooks.js';
@@ -1,24 +1,11 @@
1
1
  import { useState } from 'react';
2
2
  import { safeMediaUrl, formatByteSize, formatUploadDate, mediaRowHandles } from '../../rules.js';
3
3
  export function useMediaCard(props, _optional = {}) {
4
- /** Historical preview rationale, retained with the ported fallback chain:
5
- * The hard problem this rewrite had to solve: **the media list response carried no content type**
6
- * (neither `media` nor `asset_blobs` stored one — upload validated `contentType` then discarded
7
- * it), so nothing in `AdminMedia` told the client whether a given asset was an image, a video, or
8
- * something unpreviewable. `MediaPreview` below resolves this client-side with an optimistic
9
- * render-and-fall-back chain (`<img>` → onError → `<video>` → onError → placeholder) rather than a
10
- * HEAD probe per card. Chosen over the HEAD approach because: (1) the byte route's documented
11
- * contract covers GET — sniffing/Range were specified for that, not for HEAD, so building on HEAD
12
- * would be assuming a behavior nobody confirmed; (2) a HEAD-first design means every card blocks on
13
- * a round trip before any pixel paints, working against the fixed-aspect-box + lazy-loading this
14
- * grid needs anyway, whereas the optimistic path costs nothing extra for the common case (a real
15
- * image just loads) and only "wastes" a request for the video/unsupported minority — and even then,
16
- * a browser's image decoder typically fails off the header bytes rather than pulling the whole
17
- * file; (3) it composes for free with the server's security defusal: a sniffed HTML/SVG comes back
18
- * as `application/octet-stream` with `Content-Disposition: attachment`, which is not a valid image
19
- * OR video MIME, so it fails both probes and lands on the placeholder with zero special-casing —
20
- * this file never needs to detect "is this the defused case" itself.
21
- */
4
+ /** Preview optimistically: image -> video -> placeholder. The list supplies no reliable media
5
+ * kind, and the byte route guarantees GET rather than HEAD, so probing headers would assume an
6
+ * unsupported contract and delay every card's first paint. Images load directly; failed decoders
7
+ * usually stop at header bytes. Defused HTML/SVG served as octet-stream attachments fails both
8
+ * decoders and reaches the placeholder without content-specific handling. */
22
9
  const src = safeMediaUrl({ url: props.api.originalUrl({ id: props.item.id, version: props.item.version }) });
23
10
  const [probe, setProbe] = useState({ src, stage: 'image' });
24
11
  // New bytes can change media type under the same id. Retry the fallback from image
@@ -45,8 +32,7 @@ export function useMediaCard(props, _optional = {}) {
45
32
  menuItems: [
46
33
  ...(props.onEdit ? [{ id: 'edit', label: 'Edit metadata', onPress: props.onEdit, disabled: props.busy === true }] : []),
47
34
  ...(props.onTrash && props.item.status !== 'trashed' ? [{ id: 'trash', label: 'Trash', onPress: props.onTrash, disabled: props.busy === true }] : []),
48
- // Restore is owner-requested beyond legacy; it lives only in a trashed card's menu, so
49
- // the card itself keeps the legacy look and active cards' menus stay legacy-identical.
35
+ // Restore belongs only in a trashed card's menu; active cards have nothing to restore.
50
36
  ...(props.onRestore && props.item.status === 'trashed' ? [{ id: 'restore', label: 'Restore', onPress: props.onRestore, disabled: props.busy === true }] : []),
51
37
  ...(props.onPurge && props.item.status === 'trashed' ? [{ id: 'purge', label: 'Delete permanently', attrs: { 'data-jini-variant': 'danger' }, onPress: props.onPurge, disabled: props.busy === true }] : []),
52
38
  ],
@@ -11,13 +11,13 @@ export declare function useMediaGrid(props: MediaGridProps, _optional?: Record<s
11
11
  actions: {
12
12
  handleBase: string;
13
13
  busy?: boolean;
14
- item: import("../../models.js").MediaAsset;
14
+ onPurge?: () => void;
15
15
  locale?: string;
16
+ item: import("../../models.js").MediaAsset;
16
17
  onEdit?: () => void;
17
18
  onPreview?: () => void;
18
19
  onTrash?: () => void;
19
20
  onRestore?: () => void;
20
- onPurge?: () => void;
21
21
  onChoose?: () => void;
22
22
  }[];
23
23
  gridRef?: Ref<HTMLDivElement>;
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { ModulePageProps } from '../../../react/bind-react.js';
2
+ import type { ModulePageProps } from '../../../core/react/bind-react.js';
3
3
  import { createLibraryController } from '../../controllers/library.controller.js';
4
4
  import type { LibraryState } from '../../controllers/library.controller.js';
5
5
  export declare const MediaLibraryContext: import("react").Context<{
@@ -1,5 +1,5 @@
1
1
  import { createElement, createContext, useContext, useEffect, useState } from 'react';
2
- import { useController } from '../../../react/use-controller.js';
2
+ import { useController } from '../../../core/react/use-controller.js';
3
3
  import { createLibraryController } from '../../controllers/library.controller.js';
4
4
  import { useMediaPorts } from './MediaPorts.hooks.js';
5
5
  import { AllIcon, ImageIcon, VideoIcon, CloudIcon } from '../components/MediaIcons.js';
@@ -1,4 +1,4 @@
1
- import { useController } from '../../../react/use-controller.js';
1
+ import { useController } from '../../../core/react/use-controller.js';
2
2
  import { createLibraryController } from '../../controllers/library.controller.js';
3
3
  import { acceptsMedia } from '../../rules.js';
4
4
  export function useMediaPicker(props, _optional = {}) {
@@ -1,5 +1,5 @@
1
1
  import { createElement } from 'react';
2
- import { bindReact } from '../../react/bind-react.js';
2
+ import { bindReact } from '../../core/react/bind-react.js';
3
3
  import { mediaModule } from '../media.module.js';
4
4
  import { MediaPortsContext } from './hooks/MediaPorts.hooks.js';
5
5
  export { useMediaPorts } from './hooks/MediaPorts.hooks.js';
@@ -1,4 +1,4 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  export declare function LibraryTab(props: TabViewProps, _optional?: Record<string, never>): import("react").JSX.Element;
3
3
  export default LibraryTab;
4
4
  //# sourceMappingURL=LibraryTab.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  export declare function ProvidersTab(_props: TabViewProps, _optional?: Record<string, never>): import("react").JSX.Element;
3
3
  export default ProvidersTab;
4
4
  //# sourceMappingURL=ProvidersTab.d.ts.map
@@ -1,3 +1,3 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  export declare function Canvas(props: TabViewProps, _optional?: {}): import("react").JSX.Element;
3
3
  //# sourceMappingURL=Canvas.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  export declare function useCanvas({ permissions }: TabViewProps, _optional?: {}): {
3
3
  denied: boolean;
4
4
  registerCanvas: (node: HTMLDivElement | null) => void | undefined;
@@ -1,5 +1,5 @@
1
1
  import { useCallback } from 'react';
2
- import { useController } from '../../../react/use-controller.js';
2
+ import { useController } from '../../../core/react/use-controller.js';
3
3
  import { createPlaygroundController } from '../../controllers/playground.controller.js';
4
4
  import { canMountPlayground } from '../../rules.js';
5
5
  import { usePlaygroundPorts } from './PlaygroundPorts.hooks.js';
@@ -1,4 +1,4 @@
1
- import type { ModulePageProps } from '../../../react/bind-react.js';
1
+ import type { ModulePageProps } from '../../../core/react/bind-react.js';
2
2
  export declare function usePlaygroundPage(props: ModulePageProps, _optional?: {}): {
3
3
  denied: boolean;
4
4
  ActiveTab: import("react").LazyExoticComponent<import("react").ComponentType<import("../../../react/bind-react.js").TabViewProps>> | undefined;
@@ -1,4 +1,4 @@
1
- import { bindReact } from '../../react/bind-react.js';
1
+ import { bindReact } from '../../core/react/bind-react.js';
2
2
  import { playgroundModule } from '../playground.module.js';
3
3
  import { PlaygroundPortsContext } from './hooks/PlaygroundPorts.hooks.js';
4
4
  export { usePlaygroundPorts } from './hooks/PlaygroundPorts.hooks.js';
@@ -1,4 +1,4 @@
1
- import type { ModulePageProps } from '../../../react/bind-react.js';
1
+ import type { ModulePageProps } from '../../../core/react/bind-react.js';
2
2
  export declare function PlaygroundPage(props: ModulePageProps, _optional?: {}): import("react").JSX.Element;
3
3
  export default PlaygroundPage;
4
4
  //# sourceMappingURL=PlaygroundPage.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { TabViewProps } from '../../../react/bind-react.js';
1
+ import type { TabViewProps } from '../../../core/react/bind-react.js';
2
2
  export declare function CanvasTab(props: TabViewProps, _optional?: {}): import("react").JSX.Element;
3
3
  export default CanvasTab;
4
4
  //# sourceMappingURL=CanvasTab.d.ts.map
@@ -1,46 +1,2 @@
1
- import type { ComponentType, ReactNode, LazyExoticComponent, Context as ReactContext } from 'react';
2
- import type { AdminInstance, AdminModule, ScopedPorts } from '../core/module/types.js';
3
- export interface TabViewProps {
4
- readonly params: Readonly<Record<string, unknown>>;
5
- readonly permissions?: readonly string[];
6
- }
7
- export interface ModulePageProps {
8
- readonly tabs: Readonly<Record<string, LazyExoticComponent<ComponentType<TabViewProps>>>>;
9
- readonly description: ReturnType<AdminInstance['describe']>['pages'][number];
10
- readonly requestedTab?: string;
11
- readonly onTabChange?: (required: {
12
- tab: string;
13
- }, optional?: Record<string, never>) => void;
14
- }
15
- type Loader<P> = () => Promise<{
16
- default: ComponentType<P>;
17
- }>;
18
- export type ReactViews<M extends AdminModule> = {
19
- readonly [P in keyof M['pages']]: {
20
- readonly page: Loader<ModulePageProps>;
21
- readonly tabs: {
22
- readonly [T in keyof M['pages'][P]['tabs']]: Loader<TabViewProps>;
23
- };
24
- };
25
- };
26
- /** Every page and tab is lazy. The only port context is private to this binding;
27
- * a sibling module can never read another module's dependencies through a global locator. */
28
- export declare function bindReact<const M extends AdminModule>({ module, views }: {
29
- module: M;
30
- views: ReactViews<M>;
31
- }, { context }?: {
32
- context?: ReactContext<ScopedPorts<M> | null>;
33
- }): {
34
- module: M;
35
- pages: { [P in keyof M["pages"]]: {
36
- Page: LazyExoticComponent<ComponentType<ModulePageProps>>;
37
- tabs: { [T in keyof M["pages"][P]["tabs"]]: LazyExoticComponent<ComponentType<TabViewProps>>; };
38
- }; };
39
- Provider: ({ admin, children }: {
40
- admin: AdminInstance;
41
- children: ReactNode;
42
- }, _optional?: Record<string, never>) => import("react").FunctionComponentElement<import("react").ProviderProps<ScopedPorts<M> | null>>;
43
- usePorts: (_required?: Record<string, never>, _optional?: Record<string, never>) => ScopedPorts<M>;
44
- };
45
- export {};
1
+ export * from '../core/react/bind-react.js';
46
2
  //# sourceMappingURL=bind-react.d.ts.map
@@ -1,28 +1,3 @@
1
- import { createContext, createElement, lazy, useContext } from 'react';
2
- import { AdminConfigError } from '../core/module/create-admin.js';
3
- /** Every page and tab is lazy. The only port context is private to this binding;
4
- * a sibling module can never read another module's dependencies through a global locator. */
5
- export function bindReact({ module, views }, { context } = {}) {
6
- const Context = context ?? createContext(null);
7
- const pages = Object.fromEntries(Object.entries(views).map(([id, raw]) => {
8
- const view = raw;
9
- return [
10
- id,
11
- {
12
- Page: lazy(view.page),
13
- tabs: Object.fromEntries(Object.entries(view.tabs).map(([tab, load]) => [tab, lazy(load)])),
14
- },
15
- ];
16
- }));
17
- function usePorts(_required = {}, _optional = {}) {
18
- const ports = useContext(Context);
19
- if (!ports)
20
- throw new AdminConfigError({ issues: [`React scope unavailable: ${module.id}`] });
21
- return ports;
22
- }
23
- function Provider({ admin, children }, _optional = {}) {
24
- return createElement(Context.Provider, { value: admin.scope({ module }) }, children);
25
- }
26
- return { module, pages, Provider, usePorts };
27
- }
1
+ // Compatibility path; the shared implementation lives in core.
2
+ export * from '../core/react/bind-react.js';
28
3
  //# sourceMappingURL=bind-react.js.map