@antelopejs/interface-dms 0.10.4 → 0.13.0

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 (384) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +21 -10
  3. package/dist/attachments.d.ts +15 -2
  4. package/dist/attachments.js +14 -1
  5. package/dist/attachments.js.map +1 -1
  6. package/dist/auth/db/models/sessions.model.d.ts +7 -5
  7. package/dist/auth/db/models/sessions.model.js +2 -9
  8. package/dist/auth/db/models/sessions.model.js.map +1 -1
  9. package/dist/auth/db/models/userExternalIdentities.model.d.ts +7 -5
  10. package/dist/auth/db/models/users.model.d.ts +7 -5
  11. package/dist/auth/db/tables/users.table.d.ts +2 -2
  12. package/dist/auth/db/tables/users.table.js.map +1 -1
  13. package/dist/auth/index.d.ts +4 -4
  14. package/dist/auth/internal/jwt-auth-decorator.d.ts +1 -1
  15. package/dist/auth/internal/jwt-auth-decorator.js +6 -3
  16. package/dist/auth/internal/jwt-auth-decorator.js.map +1 -1
  17. package/dist/auth/internal/request-authenticators.d.ts +12 -0
  18. package/dist/auth/internal/request-authenticators.js +53 -10
  19. package/dist/auth/internal/request-authenticators.js.map +1 -1
  20. package/dist/base/activity-feed.d.ts +34 -32
  21. package/dist/base/activity-feed.js +2 -0
  22. package/dist/base/activity-feed.js.map +1 -1
  23. package/dist/base/banner.d.ts +12 -10
  24. package/dist/base/banner.js +2 -0
  25. package/dist/base/banner.js.map +1 -1
  26. package/dist/base/block-registry/internal/describe.js +4 -12
  27. package/dist/base/block-registry/internal/describe.js.map +1 -1
  28. package/dist/base/block-registry/internal/ui.js +1 -1
  29. package/dist/base/block-registry/internal/ui.js.map +1 -1
  30. package/dist/base/card.d.ts +11 -9
  31. package/dist/base/card.js +2 -0
  32. package/dist/base/card.js.map +1 -1
  33. package/dist/base/chart-card.d.ts +4 -2
  34. package/dist/base/chart-card.js +2 -0
  35. package/dist/base/chart-card.js.map +1 -1
  36. package/dist/base/chart-schemas.d.ts +148 -148
  37. package/dist/base/chart.d.ts +65 -0
  38. package/dist/base/chart.js +65 -0
  39. package/dist/base/chart.js.map +1 -1
  40. package/dist/base/code-block.d.ts +5 -3
  41. package/dist/base/code-block.js +2 -0
  42. package/dist/base/code-block.js.map +1 -1
  43. package/dist/base/custom.d.ts +5 -0
  44. package/dist/base/custom.js +5 -0
  45. package/dist/base/custom.js.map +1 -1
  46. package/dist/base/data-types/default/address.d.ts +5 -0
  47. package/dist/base/data-types/default/address.js +5 -0
  48. package/dist/base/data-types/default/address.js.map +1 -1
  49. package/dist/base/data-types/default/choices.d.ts +20 -0
  50. package/dist/base/data-types/default/choices.js +20 -0
  51. package/dist/base/data-types/default/choices.js.map +1 -1
  52. package/dist/base/data-types/default/files.d.ts +22 -5
  53. package/dist/base/data-types/default/files.js +20 -0
  54. package/dist/base/data-types/default/files.js.map +1 -1
  55. package/dist/base/data-types/default/numbers.d.ts +15 -0
  56. package/dist/base/data-types/default/numbers.js +25 -9
  57. package/dist/base/data-types/default/numbers.js.map +1 -1
  58. package/dist/base/data-types/default/relations.d.ts +10 -2
  59. package/dist/base/data-types/default/relations.js +9 -6
  60. package/dist/base/data-types/default/relations.js.map +1 -1
  61. package/dist/base/data-types/default/strings.d.ts +25 -0
  62. package/dist/base/data-types/default/strings.js +25 -0
  63. package/dist/base/data-types/default/strings.js.map +1 -1
  64. package/dist/base/data-types/default-types.d.ts +1 -1
  65. package/dist/base/data-types/field-types.d.ts +10 -0
  66. package/dist/base/data-types/field-types.js +10 -0
  67. package/dist/base/data-types/field-types.js.map +1 -1
  68. package/dist/base/data-types/internal/relation-endpoints.js +1 -0
  69. package/dist/base/data-types/internal/relation-endpoints.js.map +1 -1
  70. package/dist/base/data-types/status-type.d.ts +5 -0
  71. package/dist/base/data-types/status-type.js +5 -0
  72. package/dist/base/data-types/status-type.js.map +1 -1
  73. package/dist/base/display.d.ts +6 -6
  74. package/dist/base/empty-state.d.ts +15 -13
  75. package/dist/base/empty-state.js +2 -0
  76. package/dist/base/empty-state.js.map +1 -1
  77. package/dist/base/form-block-schema.d.ts +50 -50
  78. package/dist/base/form-schema.d.ts +2 -0
  79. package/dist/base/form-schema.js +2 -0
  80. package/dist/base/form-schema.js.map +1 -1
  81. package/dist/base/grid.d.ts +4 -0
  82. package/dist/base/grid.js +4 -0
  83. package/dist/base/grid.js.map +1 -1
  84. package/dist/base/guard.d.ts +30 -28
  85. package/dist/base/guard.js +2 -0
  86. package/dist/base/guard.js.map +1 -1
  87. package/dist/base/helpers/archive-mode-helpers.d.ts +1 -1
  88. package/dist/base/helpers/file-refs.js +15 -15
  89. package/dist/base/helpers/file-refs.js.map +1 -1
  90. package/dist/base/internal/form-schema-validation.js +7 -1
  91. package/dist/base/internal/form-schema-validation.js.map +1 -1
  92. package/dist/base/internal/realtime-topics.js.map +1 -1
  93. package/dist/base/internal/searchable.d.ts +2 -1
  94. package/dist/base/internal/searchable.js +1 -3
  95. package/dist/base/internal/searchable.js.map +1 -1
  96. package/dist/base/key-value-list.d.ts +21 -19
  97. package/dist/base/key-value-list.js +2 -0
  98. package/dist/base/key-value-list.js.map +1 -1
  99. package/dist/base/kpi-card.d.ts +4 -2
  100. package/dist/base/kpi-card.js +2 -0
  101. package/dist/base/kpi-card.js.map +1 -1
  102. package/dist/base/live-toggle.d.ts +2 -0
  103. package/dist/base/live-toggle.js +2 -0
  104. package/dist/base/live-toggle.js.map +1 -1
  105. package/dist/base/meter.d.ts +23 -21
  106. package/dist/base/meter.js +2 -0
  107. package/dist/base/meter.js.map +1 -1
  108. package/dist/base/nav-card-grid.d.ts +24 -19
  109. package/dist/base/nav-card-grid.js +5 -0
  110. package/dist/base/nav-card-grid.js.map +1 -1
  111. package/dist/base/page-toolbar.d.ts +2 -0
  112. package/dist/base/page-toolbar.js +2 -0
  113. package/dist/base/page-toolbar.js.map +1 -1
  114. package/dist/base/period-selector.d.ts +3 -1
  115. package/dist/base/period-selector.js +2 -0
  116. package/dist/base/period-selector.js.map +1 -1
  117. package/dist/base/placeholder.d.ts +2 -0
  118. package/dist/base/placeholder.js +2 -0
  119. package/dist/base/placeholder.js.map +1 -1
  120. package/dist/base/resource-form-schema.d.ts +2 -2
  121. package/dist/base/searchable.d.ts +3 -2
  122. package/dist/base/searchable.js +2 -2
  123. package/dist/base/searchable.js.map +1 -1
  124. package/dist/base/section.d.ts +6 -2
  125. package/dist/base/section.js +4 -0
  126. package/dist/base/section.js.map +1 -1
  127. package/dist/base/stack.d.ts +6 -0
  128. package/dist/base/stack.js +6 -0
  129. package/dist/base/stack.js.map +1 -1
  130. package/dist/base/stat-group.d.ts +16 -14
  131. package/dist/base/stat-group.js +2 -0
  132. package/dist/base/stat-group.js.map +1 -1
  133. package/dist/base/tab.d.ts +10 -8
  134. package/dist/base/tab.js +2 -0
  135. package/dist/base/tab.js.map +1 -1
  136. package/dist/base/table-view/column-display.d.ts +1 -1
  137. package/dist/base/table-view/column-display.js.map +1 -1
  138. package/dist/base/table-view/data-functions.d.ts +10 -4
  139. package/dist/base/table-view/data-functions.js.map +1 -1
  140. package/dist/base/table-view/factory.d.ts +5 -0
  141. package/dist/base/table-view/factory.js +8 -4
  142. package/dist/base/table-view/factory.js.map +1 -1
  143. package/dist/base/table-view/internal/auth.d.ts +17 -3
  144. package/dist/base/table-view/internal/auth.js +26 -5
  145. package/dist/base/table-view/internal/auth.js.map +1 -1
  146. package/dist/base/table-view/internal/column-conditions.d.ts +8 -1
  147. package/dist/base/table-view/internal/column-conditions.js +25 -13
  148. package/dist/base/table-view/internal/column-conditions.js.map +1 -1
  149. package/dist/base/table-view/internal/column-display.d.ts +1 -2
  150. package/dist/base/table-view/internal/column-display.js +3 -9
  151. package/dist/base/table-view/internal/column-display.js.map +1 -1
  152. package/dist/base/table-view/internal/factory-helpers.d.ts +1 -1
  153. package/dist/base/table-view/internal/factory-helpers.js +17 -14
  154. package/dist/base/table-view/internal/factory-helpers.js.map +1 -1
  155. package/dist/base/table-view/internal/factory-lifecycle-created.d.ts +2 -3
  156. package/dist/base/table-view/internal/factory-lifecycle-created.js +5 -5
  157. package/dist/base/table-view/internal/factory-lifecycle-created.js.map +1 -1
  158. package/dist/base/table-view/internal/factory-lifecycle-filter.d.ts +2 -2
  159. package/dist/base/table-view/internal/factory-private-actions.d.ts +2 -2
  160. package/dist/base/table-view/internal/files.d.ts +2 -1
  161. package/dist/base/table-view/internal/files.js +14 -5
  162. package/dist/base/table-view/internal/files.js.map +1 -1
  163. package/dist/base/table-view/internal/footer.d.ts +3 -3
  164. package/dist/base/table-view/internal/footer.js +16 -15
  165. package/dist/base/table-view/internal/footer.js.map +1 -1
  166. package/dist/base/table-view/internal/guards.d.ts +27 -5
  167. package/dist/base/table-view/internal/guards.js +133 -49
  168. package/dist/base/table-view/internal/guards.js.map +1 -1
  169. package/dist/base/table-view/internal/meta-helpers.d.ts +1 -1
  170. package/dist/base/table-view/internal/meta-helpers.js +3 -4
  171. package/dist/base/table-view/internal/meta-helpers.js.map +1 -1
  172. package/dist/base/table-view/internal/meta.js +2 -3
  173. package/dist/base/table-view/internal/meta.js.map +1 -1
  174. package/dist/base/table-view/internal/option-contract.d.ts +9 -1
  175. package/dist/base/table-view/internal/option-footer.d.ts +2 -2
  176. package/dist/base/table-view/internal/option-row-actions.d.ts +1 -1
  177. package/dist/base/table-view/internal/realtime.d.ts +52 -11
  178. package/dist/base/table-view/internal/realtime.js +23 -16
  179. package/dist/base/table-view/internal/realtime.js.map +1 -1
  180. package/dist/base/table-view/internal/resource-form.d.ts +1 -1
  181. package/dist/base/table-view/internal/resource-form.js +1 -1
  182. package/dist/base/table-view/internal/resource-form.js.map +1 -1
  183. package/dist/base/table-view/internal/row-actions-schema.d.ts +12 -12
  184. package/dist/base/table-view/internal/row-rule-shape.d.ts +11 -5
  185. package/dist/base/table-view/internal/row-rule-shape.js +60 -30
  186. package/dist/base/table-view/internal/row-rule-shape.js.map +1 -1
  187. package/dist/base/table-view/internal/row-rules.d.ts +28 -1
  188. package/dist/base/table-view/internal/row-rules.js +8 -19
  189. package/dist/base/table-view/internal/row-rules.js.map +1 -1
  190. package/dist/base/table-view/internal/tabs.d.ts +1 -1
  191. package/dist/base/table-view/internal/tabs.js +1 -4
  192. package/dist/base/table-view/internal/tabs.js.map +1 -1
  193. package/dist/base/table-view/internal/validation.d.ts +2 -2
  194. package/dist/base/table-view/internal/validation.js +7 -7
  195. package/dist/base/table-view/internal/validation.js.map +1 -1
  196. package/dist/base/table-view/meta.d.ts +7 -6
  197. package/dist/base/table-view/meta.js +12 -7
  198. package/dist/base/table-view/meta.js.map +1 -1
  199. package/dist/base/table-view/resource-form.d.ts +3 -1
  200. package/dist/base/table-view/resource-form.js +2 -0
  201. package/dist/base/table-view/resource-form.js.map +1 -1
  202. package/dist/base/table-view/routes.d.ts +73 -21
  203. package/dist/base/table-view/routes.js +13 -10
  204. package/dist/base/table-view/routes.js.map +1 -1
  205. package/dist/base/table-view/schema.d.ts +157 -152
  206. package/dist/base/table-view/schema.js +2 -1
  207. package/dist/base/table-view/schema.js.map +1 -1
  208. package/dist/base/table-view/source.js +4 -1
  209. package/dist/base/table-view/source.js.map +1 -1
  210. package/dist/base/table-view.d.ts +1 -1
  211. package/dist/base/table-view.js.map +1 -1
  212. package/dist/base/top-list-card.d.ts +35 -33
  213. package/dist/base/top-list-card.js +2 -0
  214. package/dist/base/top-list-card.js.map +1 -1
  215. package/dist/base/types/error.js +5 -2
  216. package/dist/base/types/error.js.map +1 -1
  217. package/dist/base/types/guards.d.ts +4 -4
  218. package/dist/base/types/json.d.ts +1 -10
  219. package/dist/base/types/row-action.d.ts +7 -7
  220. package/dist/component-options/confirm-dialog.d.ts +2 -0
  221. package/dist/component-options/confirm-dialog.js.map +1 -1
  222. package/dist/component-options/data-type.d.ts +2 -2
  223. package/dist/component-options/data-type.js +7 -7
  224. package/dist/component-options/data-type.js.map +1 -1
  225. package/dist/component-options/page-layout.d.ts +3 -2
  226. package/dist/component-options/page-layout.js.map +1 -1
  227. package/dist/component-options/row-action.d.ts +14 -9
  228. package/dist/component-slots.d.ts +11 -2
  229. package/dist/component-slots.js +1 -0
  230. package/dist/component-slots.js.map +1 -1
  231. package/dist/component.d.ts +7 -8
  232. package/dist/component.js +17 -25
  233. package/dist/component.js.map +1 -1
  234. package/dist/data-controllers/members.d.ts +11 -7
  235. package/dist/data-controllers/members.js +1 -1
  236. package/dist/data-controllers/members.js.map +1 -1
  237. package/dist/data-controllers/roles.d.ts +32 -10
  238. package/dist/db/internal/exportJobs.model.d.ts +7 -5
  239. package/dist/db/internal/inviteResolutions.model.d.ts +7 -5
  240. package/dist/db/internal/tenantLifecycle.model.d.ts +15 -7
  241. package/dist/db/internal/tenantLifecycle.model.js +16 -7
  242. package/dist/db/internal/tenantLifecycle.model.js.map +1 -1
  243. package/dist/db/models/roles.model.d.ts +7 -5
  244. package/dist/db/models/tenantMembers.model.d.ts +7 -5
  245. package/dist/db/models/tenants.model.d.ts +7 -5
  246. package/dist/db/models/user_invites.model.d.ts +7 -5
  247. package/dist/guards.d.ts +1 -1
  248. package/dist/hooks.d.ts +1 -2
  249. package/dist/hooks.js +33 -26
  250. package/dist/hooks.js.map +1 -1
  251. package/dist/internal/attachments.d.ts +2 -2
  252. package/dist/internal/component-builder.js +2 -1
  253. package/dist/internal/component-builder.js.map +1 -1
  254. package/dist/internal/component-serialization.d.ts +2 -4
  255. package/dist/internal/component-serialization.js +4 -3
  256. package/dist/internal/component-serialization.js.map +1 -1
  257. package/dist/internal/component-slots.d.ts +19 -2
  258. package/dist/internal/component-slots.js +35 -12
  259. package/dist/internal/component-slots.js.map +1 -1
  260. package/dist/internal/component-watch-filter.d.ts +11 -0
  261. package/dist/internal/component-watch-filter.js +22 -0
  262. package/dist/internal/component-watch-filter.js.map +1 -0
  263. package/dist/internal/component-watches.js +0 -1
  264. package/dist/internal/component-watches.js.map +1 -1
  265. package/dist/internal/own-entry.d.ts +7 -0
  266. package/dist/internal/own-entry.js +13 -0
  267. package/dist/internal/own-entry.js.map +1 -0
  268. package/dist/internal/uploads.d.ts +30 -0
  269. package/dist/internal/uploads.js +19 -0
  270. package/dist/internal/uploads.js.map +1 -1
  271. package/dist/invite-extension-payloads.d.ts +14 -2
  272. package/dist/invite-extensions/internal/delivery.js +1 -2
  273. package/dist/invite-extensions/internal/delivery.js.map +1 -1
  274. package/dist/invite-extensions/internal/edit.d.ts +2 -1
  275. package/dist/invite-extensions/internal/edit.js +8 -9
  276. package/dist/invite-extensions/internal/edit.js.map +1 -1
  277. package/dist/invite-extensions/internal/form-slot.js +8 -15
  278. package/dist/invite-extensions/internal/form-slot.js.map +1 -1
  279. package/dist/invite-extensions/internal/payload-slices.d.ts +33 -3
  280. package/dist/invite-extensions/internal/payload-slices.js +84 -19
  281. package/dist/invite-extensions/internal/payload-slices.js.map +1 -1
  282. package/dist/invite-extensions/internal/types.d.ts +10 -1
  283. package/dist/invite-resolution.js +6 -4
  284. package/dist/invite-resolution.js.map +1 -1
  285. package/dist/json.d.ts +10 -0
  286. package/dist/json.js +3 -0
  287. package/dist/json.js.map +1 -0
  288. package/dist/layout-banners.d.ts +5 -2
  289. package/dist/layout-banners.js.map +1 -1
  290. package/dist/page/controllers.d.ts +2 -2
  291. package/dist/page/internal/extension-validation.js +3 -2
  292. package/dist/page/internal/extension-validation.js.map +1 -1
  293. package/dist/page/internal/metadata-layout.js +1 -1
  294. package/dist/page/internal/metadata-layout.js.map +1 -1
  295. package/dist/page/internal/metadata-publish.js +3 -2
  296. package/dist/page/internal/metadata-publish.js.map +1 -1
  297. package/dist/page/internal/metadata-registration.js +5 -4
  298. package/dist/page/internal/metadata-registration.js.map +1 -1
  299. package/dist/page/internal/metadata-upload-registration.d.ts +4 -2
  300. package/dist/page/internal/metadata-upload-registration.js +13 -4
  301. package/dist/page/internal/metadata-upload-registration.js.map +1 -1
  302. package/dist/page/internal/metadata-uploads.d.ts +5 -5
  303. package/dist/page/internal/metadata-uploads.js +4 -8
  304. package/dist/page/internal/metadata-uploads.js.map +1 -1
  305. package/dist/page/internal/page-record.d.ts +2 -3
  306. package/dist/page/internal/page-record.js +23 -16
  307. package/dist/page/internal/page-record.js.map +1 -1
  308. package/dist/page/layout-filter.js +17 -6
  309. package/dist/page/layout-filter.js.map +1 -1
  310. package/dist/page/metadata.js +5 -7
  311. package/dist/page/metadata.js.map +1 -1
  312. package/dist/request-tenant.d.ts +10 -4
  313. package/dist/request-tenant.js +16 -34
  314. package/dist/request-tenant.js.map +1 -1
  315. package/dist/tenant-export.d.ts +2 -1
  316. package/dist/tenant-lifecycle.d.ts +43 -4
  317. package/dist/tenant-lifecycle.js +97 -18
  318. package/dist/tenant-lifecycle.js.map +1 -1
  319. package/dist/types.d.ts +20 -0
  320. package/dist/uploads.d.ts +1 -1
  321. package/dist/uploads.js +39 -60
  322. package/dist/uploads.js.map +1 -1
  323. package/dist/utils/fire-and-forget.js.map +1 -1
  324. package/dist/utils/internal/decorated-class.d.ts +14 -0
  325. package/dist/utils/internal/decorated-class.js +37 -0
  326. package/dist/utils/internal/decorated-class.js.map +1 -0
  327. package/dist/utils/internal/type-check.d.ts +9 -0
  328. package/dist/utils/internal/type-check.js +13 -5
  329. package/dist/utils/internal/type-check.js.map +1 -1
  330. package/dist/utils/internal/value-parser.d.ts +1 -1
  331. package/dist/utils/internal/value-parser.js +22 -9
  332. package/dist/utils/internal/value-parser.js.map +1 -1
  333. package/dist/watch-actions.d.ts +1 -1
  334. package/docs/1.core/1.introduction.md +82 -77
  335. package/docs/1.core/10.layout-banners.md +57 -45
  336. package/docs/1.core/11.modules-and-dynamic-menus.md +178 -0
  337. package/docs/1.core/12.frontend-modules-and-request-helpers.md +155 -0
  338. package/docs/1.core/13.tenant-data-export.md +120 -0
  339. package/docs/1.core/2.pages-and-modules.md +140 -367
  340. package/docs/1.core/3.components.md +21 -22
  341. package/docs/1.core/4.permissions.md +92 -71
  342. package/docs/1.core/5.tenancy.md +150 -86
  343. package/docs/1.core/6.invites.md +90 -65
  344. package/docs/1.core/7.hooks.md +96 -166
  345. package/docs/1.core/8.realtime.md +44 -45
  346. package/docs/1.core/9.quick-actions.md +37 -30
  347. package/docs/2.auth/1.introduction.md +33 -35
  348. package/docs/2.auth/2.authentication.md +60 -38
  349. package/docs/2.auth/3.tokens-and-sessions.md +56 -55
  350. package/docs/2.auth/4.users.md +79 -51
  351. package/docs/2.auth/5.external-identities.md +25 -26
  352. package/docs/3.base/1.introduction.md +64 -60
  353. package/docs/3.base/10.display-blocks.md +15 -16
  354. package/docs/3.base/11.page-layouts.md +270 -0
  355. package/docs/3.base/12.table-row-actions.md +122 -0
  356. package/docs/3.base/13.table-filters-and-forms.md +104 -0
  357. package/docs/3.base/14.table-events-and-helpers.md +114 -0
  358. package/docs/3.base/15.table-sources-and-gates.md +24 -0
  359. package/docs/3.base/2.types.md +44 -41
  360. package/docs/3.base/3.forms.md +27 -28
  361. package/docs/3.base/4.tables.md +35 -368
  362. package/docs/3.base/5.charts-and-widgets.md +28 -29
  363. package/docs/3.base/6.layout.md +21 -270
  364. package/docs/3.base/8.data-types.md +39 -40
  365. package/docs/3.base/9.helpers.md +36 -38
  366. package/docs/4.notifications/1.introduction.md +22 -26
  367. package/docs/4.notifications/2.categories-and-subjects.md +58 -55
  368. package/docs/4.notifications/3.sending.md +72 -68
  369. package/docs/5.html-render/1.introduction.md +119 -81
  370. package/docs/5.html-render/2.built-in-emails.md +71 -51
  371. package/docs/index.md +18 -29
  372. package/docs/tsconfig.json +4 -0
  373. package/package.json +11 -11
  374. package/docs/images/emails-admin-invite.png +0 -0
  375. package/docs/images/emails-change-notice.png +0 -0
  376. package/docs/images/emails-change-verification.png +0 -0
  377. package/docs/images/emails-digest-logo-dark.png +0 -0
  378. package/docs/images/emails-digest-logo-light.png +0 -0
  379. package/docs/images/emails-digest.png +0 -0
  380. package/docs/images/emails-export-partial.png +0 -0
  381. package/docs/images/emails-export-ready.png +0 -0
  382. package/docs/images/emails-reset-password.png +0 -0
  383. package/docs/images/emails-two-factor.png +0 -0
  384. package/docs/images/emails-user-validation.png +0 -0
@@ -13,7 +13,7 @@ export interface WatchAction {
13
13
  component: string;
14
14
  event: string;
15
15
  functionId: string;
16
- params?: Record<string, unknown>;
16
+ params?: object;
17
17
  onParam?: WatchActionCondition | WatchActionCondition[];
18
18
  requirePermission?: string;
19
19
  }
@@ -1,55 +1,68 @@
1
1
  ---
2
2
  title: "Introduction"
3
3
  description: "The core contract of the DMS: pages and modules, components, permissions, tenancy, invites, hooks, realtime, quick actions and layout banners."
4
+ mode: explanation
4
5
  ---
5
6
 
6
- # Introduction
7
-
8
7
  ## Overview
9
8
 
10
- The root export of `@antelopejs/interface-dms` and the subpaths listed below are the core contract of the AntelopeJS DMS. It encodes one inversion: the backend declares the screen, as serializable data. A page is a controller class, its components are static fields holding builders, and the page's layout route returns the description a shared frontend renders. Adding an admin screen is a backend change.
9
+ The root export of `@antelopejs/interface-dms` and the subpaths listed below are the core contract of the AntelopeJS DMS. The contract rests on one inversion. The backend declares the screen as serializable data. A page is a controller class, its components are static fields that hold builders, and the page's layout route returns the description that a shared frontend renders. To add an admin screen, you change the backend.
11
10
 
12
- Around that core the interface carries what an admin backend needs to be more than a renderer: hierarchical permissions derived from the page tree, multi-tenant data access scoped by the model handle, lifecycle hooks, realtime topics, and command-palette entries.
11
+ Around that core, the interface carries what an admin backend needs beyond rendering. It derives hierarchical permissions from the page tree and scopes multi-tenant data access through the model handle. It also dispatches lifecycle hooks, carries realtime topics, and adds entries to the command palette.
13
12
 
14
- Everything here is imported from a subpath of `@antelopejs/interface-dms`. Two other domains of the same package complete the picture and are referenced throughout these pages: [Auth](/docs/interfaces/auth/introduction) (`/auth`) for authentication and the `User` table, and [Base](/docs/interfaces/base/introduction) (`/base`) for the concrete component vocabulary (`Form`, `TableView`, `Grid`, the chart family) built on the component types documented here.
13
+ You import everything here from a subpath of `@antelopejs/interface-dms`. Two other domains of the same package complete the picture, and these pages refer to them throughout. [Auth](/docs/interfaces/auth/introduction) (`/auth`) covers authentication and the `User` table. [Base](/docs/interfaces/base/introduction) (`/base`) holds the concrete component vocabulary (`Form`, `TableView`, `Grid`, the chart family), built on the component types documented here.
15
14
 
16
- ## Key Features
15
+ ## What the core provides
17
16
 
18
- - **Pages as controllers** — `PageController` builds a controller class bound to a URL; `@RegisterPage()` records it, registers its permissions, and serves its layout.
19
- - **Components that serialize** — a `ComponentBuilder` produces data, not a live component, so one frontend renders every module's screens.
20
- - **Categories and modules** — a sidebar tree of nested categories, plus modules that own a whole branch under `/modules`.
21
- - **Dynamic navigation** — providers that resolve extra menu entries per request, so one page can back an entry per project or workspace.
22
- - **Page extensions** — inject components into a page owned by another module, permissioned in that page's own tree.
23
- - **Hierarchical permissions** — ids derived from page, component and action, with a base set from roles and an effective set shaped by registered resolvers.
24
- - **Route guards** — permission, tenant-member and tenant-owner decorators usable as parameter or property decorators.
25
- - **Tenancy in the handle** — per-tenant schemas and model handles bound to one tenant, rather than a tenant column filtered on every query.
26
- - **Tenant access gates** — one binary check that denies a tenant at every authorization surface at once.
27
- - **Invites** — one call that either grants membership to an existing user or issues a token-bearing invite.
28
- - **Lifecycle hooks** — typed events for tenants, members, invites and registrations, dispatched either to notify or to collect contributions.
29
- - **Realtime topics** — bind a topic to a page, publish to whoever is on it, and subscribe from the backend to what others publish.
30
- - **Quick actions** — contribute grouped, permission-gated entries to the command palette.
17
+ - **Pages as controllers.** `PageController` builds a controller class bound to a URL. `@RegisterPage()` records it, registers its permissions, and serves its layout.
18
+ - **Components that serialize.** A `ComponentBuilder` produces data, not a live component, so one frontend renders the screens of every module.
19
+ - **Categories and modules.** Nested categories form a sidebar tree, and a module owns a whole branch under `/modules`.
20
+ - **Dynamic navigation.** Providers resolve extra menu entries for each request, so one page can back an entry per project or workspace.
21
+ - **Page extensions.** A module injects components into a page that another module owns. The injected components get their permissions in that page's own tree.
22
+ - **Hierarchical permissions.** Permission ids derive from the page, the component and the action. Roles grant a base set, and registered resolvers shape it into the effective set.
23
+ - **Route guards.** The permission, tenant-member and tenant-owner decorators work as parameter decorators or as property decorators.
24
+ - **Tenancy in the handle.** Each tenant has its own schemas, and a model handle is bound to one tenant. No query filters a tenant column.
25
+ - **Tenant access gates.** One binary check denies a tenant at every authorization surface at once.
26
+ - **Invites.** One call either grants membership to an existing user or issues an invite that carries a token.
27
+ - **Lifecycle hooks.** Typed events for tenants, members, invites and registrations. The DMS dispatches each one either to notify handlers or to collect their contributions.
28
+ - **Realtime topics.** You bind a topic to a page, publish to the sessions on that page, and subscribe from the backend to what others publish.
29
+ - **Quick actions.** You contribute grouped entries to the command palette, each gated by a permission.
31
30
 
32
31
  ## Dependencies
33
32
 
34
33
  This interface relies on the following AntelopeJS packages:
35
34
 
36
- - [@antelopejs/interface-api](https://github.com/AntelopeJS/interface-api) - Controllers, route registration and request context.
37
- - [@antelopejs/interface-auth](https://github.com/AntelopeJS/interface-auth) - The authentication decorator machinery the guards build on.
38
- - [@antelopejs/interface-core](https://github.com/AntelopeJS/interface-core) - Interface functions, registering proxies and decorator helpers.
39
- - [@antelopejs/interface-database-decorators](https://github.com/AntelopeJS/interface-database-decorators) - Table definitions, data models and model injection.
40
- - [@antelopejs/interface-data-api](https://github.com/AntelopeJS/interface-data-api) - Used by the `/data-controllers` subpath for the built-in members and roles controllers.
35
+ - [`@antelopejs/interface-api`](https://github.com/AntelopeJS/interface-api): Controllers, route registration and the request context.
36
+ - [`@antelopejs/interface-api-util`](https://github.com/AntelopeJS/interface-api-util): The `assert` helper that rejects a request with an HTTP status, used by invite resolution, tenant lifecycle admission and the table view routes.
37
+ - [`@antelopejs/interface-core`](https://github.com/AntelopeJS/interface-core): Interface functions, registering proxies and decorator helpers.
38
+ - [`@antelopejs/interface-database`](https://github.com/AntelopeJS/interface-database): Query value proxies and the `Schema` handle, used by the tenancy models and tenant provisioning.
39
+ - [`@antelopejs/interface-database-decorators`](https://github.com/AntelopeJS/interface-database-decorators): Table definitions, data models and model injection.
40
+ - [`@antelopejs/interface-data-api`](https://github.com/AntelopeJS/interface-data-api): The data controllers behind the table views of `/base` and the built-in members and roles controllers of `/data-controllers`.
41
+ - [`@antelopejs/interface-file-storage`](https://github.com/AntelopeJS/interface-file-storage): File metadata and upload constraints, used by `/attachments` and the file data types.
42
+
43
+ The route guards build on the [Auth](/docs/interfaces/auth/introduction) domain of this same package, not on a separate package.
41
44
 
42
- ## Quick Start
45
+ ## Quick start
43
46
 
44
- Declare the application's table and model first. `BookModel` is not a DMS export; this example defines it with the stock flag used by the KPI query.
47
+ The following file declares the application's table and model, a category, a page with a component, and the route that the component fetches from. `Book` and `BookModel` are not DMS exports. The example defines them with the stock flag that the KPI query reads.
45
48
 
46
- ```typescript [db.ts]
49
+ ```typescript [books-page.ts]
50
+ import { Get } from "@antelopejs/interface-api";
47
51
  import {
48
52
  BasicDataModel,
49
53
  Field,
54
+ GetModel,
50
55
  RegisterTable,
51
56
  Table,
52
57
  } from "@antelopejs/interface-database-decorators";
58
+ import {
59
+ Category,
60
+ PageController,
61
+ RegisterPage,
62
+ pageRoutePath,
63
+ pagesCategory,
64
+ } from "@antelopejs/interface-dms/page";
65
+ import { KpiCard } from "@antelopejs/interface-dms/base";
53
66
 
54
67
  export const CATALOG_SCHEMA = "example_catalog";
55
68
 
@@ -61,21 +74,6 @@ export class Book extends Table {
61
74
  }
62
75
 
63
76
  export class BookModel extends BasicDataModel(Book, "books") {}
64
- ```
65
-
66
- Then declare a category, a page with a component, and the route that component fetches from:
67
-
68
- ```typescript [books-page.ts]
69
- import { Get } from "@antelopejs/interface-api";
70
- import { GetModel } from "@antelopejs/interface-database-decorators";
71
- import {
72
- Category,
73
- PageController,
74
- RegisterPage,
75
- pagesCategory,
76
- } from "@antelopejs/interface-dms/page";
77
- import { KpiCard } from "@antelopejs/interface-dms/base";
78
- import { BookModel } from "./db";
79
77
 
80
78
  export const catalog = Category("catalog", {
81
79
  displayName: "Catalog",
@@ -94,7 +92,7 @@ export class BooksPage extends PageController("books", {
94
92
  static inStockKpi = KpiCard({
95
93
  title: "In stock",
96
94
  icon: "i-ph-package",
97
- fetchUrl: "/catalog/books/stats/in-stock",
95
+ fetchUrl: pageRoutePath("/catalog/books", "/stats/in-stock"),
98
96
  valueFormat: "number",
99
97
  });
100
98
 
@@ -107,63 +105,70 @@ export class BooksPage extends PageController("books", {
107
105
  }
108
106
  ```
109
107
 
110
- Import the page and register the schema from your module's entry file, merging this into an existing `start()` if necessary:
108
+ Import the page and register the schema from the entry file of your module. If the module already has a `start()`, add these lines to it.
111
109
 
112
- ```typescript [index.ts]
110
+ ```typescript fragment [index.ts]
113
111
  import "./books-page";
114
112
  import { RegisterSchema } from "@antelopejs/interface-database-decorators";
115
- import { CATALOG_SCHEMA } from "./db";
113
+ import { CATALOG_SCHEMA } from "./books-page";
116
114
 
117
115
  export async function start(): Promise<void> {
118
116
  await RegisterSchema(CATALOG_SCHEMA);
119
117
  }
120
118
  ```
121
119
 
122
- The page resolves at `/catalog/books` and its layout at `/dms/pages/catalog/books/pagelayout`: a page controller's routes live under `/dms/pages` (`pageRoutePath`), a prefix the frontend server proxies to the backend, since the page's own path is the page. Its permission id is the chain of ids down from the root category — `pages.catalog.books` — with `pages.catalog.books.inStockKpi` registered underneath it.
120
+ The page resolves at `/catalog/books`. Its layout resolves at `/dms/pages/catalog/books/pagelayout`, and its `/stats/in-stock` route at `/dms/pages/catalog/books/stats/in-stock`. The routes of a page controller live under the `/dms/pages` prefix (`PAGE_ROUTE_PREFIX`), because the frontend server answers the page's own path with the page and proxies only `/api` and `/dms` to the backend. `pageRoutePath` builds the path under that prefix, so the component's `fetchUrl` reaches the route.
121
+
122
+ The page's permission id is the chain of ids down from the root category, `pages.catalog.books`. The DMS registers `pages.catalog.books.inStockKpi` underneath it.
123
123
 
124
- ## Subpath Map
124
+ ## Subpath map
125
125
 
126
126
  | Subpath | Contains | Documented in |
127
127
  | ------- | -------- | ------------- |
128
- | `/page` | Pages, categories, modules, layouts, page extensions, dynamic menus, frontend modules | [Pages and Modules](/docs/interfaces/core/pages-and-modules) |
128
+ | `/page` | Pages, categories, layouts, page extensions | [Pages and modules](/docs/interfaces/core/pages-and-modules) |
129
+ | `/page` | Modules, the modules catalog, dynamic menus | [Modules and dynamic menus](/docs/interfaces/core/modules-and-dynamic-menus) |
130
+ | `/page` | Frontend modules | [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers#ship-a-frontend-module) |
129
131
  | `/component` | `Component`, `ComponentBuilder`, actions, watches | [Components](/docs/interfaces/core/components) |
130
132
  | `/component-slots` | `RegisterComponentSlot`, `ComponentSlotResolver`, `SlotOptions` | [Components](/docs/interfaces/core/components#registercomponentslot) |
131
- | `/attachments` | `SaveComponentFiles` and its request, field and result types | [Pages and Modules](/docs/interfaces/core/pages-and-modules#savecomponentfiles) |
133
+ | `/attachments` | `SaveComponentFiles` and its request, field and result types | [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers#savecomponentfiles) |
132
134
  | `/permission-gate` | Shared `PermissionGate` fields | [Base types](/docs/interfaces/base/types#permissiongate) |
133
135
  | `/permissions` | The permission registry and the permission computation | [Permissions](/docs/interfaces/core/permissions) |
134
- | `/permissions-resolver` | Registering and running permission resolvers | [Permissions](/docs/interfaces/core/permissions) |
135
- | `/guards` | `AuthUserWithPermission`, `AuthTenantOwner`, `AuthTenantMember` | [Permissions](/docs/interfaces/core/permissions) |
136
- | `/constants` | Schema names and the default tenant | [Tenancy](/docs/interfaces/core/tenancy) |
137
- | `/db` | The `Tenant`, `TenantMember`, `Role` and `UserInvite` tables and models | [Tenancy](/docs/interfaces/core/tenancy), [Invites](/docs/interfaces/core/invites) |
138
- | `/request-tenant` | `getRequestTenantId` | [Tenancy](/docs/interfaces/core/tenancy) |
139
- | `/tenant-scoped-model` | `TenantScopedModel` | [Tenancy](/docs/interfaces/core/tenancy) |
140
- | `/tenant-access` | Tenant access gates | [Tenancy](/docs/interfaces/core/tenancy) |
141
- | `/tenant-ownership` | Membership and ownership writes | [Tenancy](/docs/interfaces/core/tenancy) |
136
+ | `/permissions-resolver` | Registering and running permission resolvers | [Permissions](/docs/interfaces/core/permissions#reshape-the-effective-set) |
137
+ | `/guards` | `AuthUserWithPermission`, `AuthTenantOwner`, `AuthTenantMember` | [Permissions](/docs/interfaces/core/permissions#guard-a-route) |
138
+ | `/constants` | Schema names and the default tenant | [Tenancy](/docs/interfaces/core/tenancy#constants) |
139
+ | `/db` | The `Tenant`, `TenantMember`, `Role` and `UserInvite` tables and models | [Tenancy](/docs/interfaces/core/tenancy#the-tenancy-tables), [Invites](/docs/interfaces/core/invites#the-userinvite-table) |
140
+ | `/request-tenant` | `getRequestTenantId` | [Tenancy](/docs/interfaces/core/tenancy#resolve-the-requests-tenant) |
141
+ | `/tenant-scoped-model` | `TenantScopedModel` | [Tenancy](/docs/interfaces/core/tenancy#scope-a-model-to-the-requests-tenant) |
142
+ | `/tenant-access` | Tenant access gates | [Tenancy](/docs/interfaces/core/tenancy#tenant-access-gates) |
143
+ | `/tenant-ownership` | Membership and ownership writes | [Tenancy](/docs/interfaces/core/tenancy#memberships-and-ownership) |
142
144
  | `/tenant-lifecycle` | Producer admission and closure before tenant deletion | [Tenancy](/docs/interfaces/core/tenancy#tenant-lifecycle-admission) |
143
- | `/data-controllers` | The built-in members and roles data controllers | [Tenancy](/docs/interfaces/core/tenancy) |
145
+ | `/data-controllers` | The built-in members and roles data controllers | [Tenancy](/docs/interfaces/core/tenancy#built-in-data-controllers) |
144
146
  | `/invites` | Inviting a user into a tenant | [Invites](/docs/interfaces/core/invites) |
145
147
  | `/invite-extensions` | Invite form contributions, callbacks and availability | [Invites](/docs/interfaces/core/invites#registerinviteextension) |
146
148
  | `/invite-resolution` | Durable terminal decisions and retryable effects | [Invites](/docs/interfaces/core/invites#durable-invite-resolution) |
147
149
  | `/hooks` | The `Hook` enum, handlers and dispatch | [Hooks](/docs/interfaces/core/hooks) |
148
- | `/tenant-export` | The tenant data export archive, contribution and manifest types, re-exported from `/hooks` | [Hooks](/docs/interfaces/core/hooks) |
150
+ | `/tenant-export` | The tenant data export archive, contribution and manifest types, re-exported from `/hooks` | [Tenant data export](/docs/interfaces/core/tenant-data-export) |
149
151
  | `/realtime` | Page topics, publishing and backend subscription | [Realtime](/docs/interfaces/core/realtime) |
150
- | `/quick-actions` | Command-palette entries | [Quick Actions](/docs/interfaces/core/quick-actions) |
151
- | `/layout-banners` | Global banners under the dashboard header | [Layout Banners](/docs/interfaces/core/layout-banners) |
152
- | `/uploads` | Signed upload tokens for the file and image fields of a serialized component | [Pages and Modules](/docs/interfaces/core/pages-and-modules) |
153
- | `/types` | `MaybePromise`, the one shared type alias | [Pages and Modules](/docs/interfaces/core/pages-and-modules) |
154
- | `/api-base-url`, `/client-base-url` | `GetApiBaseUrl`, `GetClientBaseUrl`: the public origins of the API and the dashboard | [Pages and Modules](/docs/interfaces/core/pages-and-modules#public-urls) |
155
- | `/client-ip` | `getClientIp`, `ResolveClientIp`: a request's client address behind the trusted proxies | [Pages and Modules](/docs/interfaces/core/pages-and-modules#client-address) |
152
+ | `/quick-actions` | Command-palette entries | [Quick actions](/docs/interfaces/core/quick-actions) |
153
+ | `/layout-banners` | Global banners under the dashboard header | [Layout banners](/docs/interfaces/core/layout-banners) |
154
+ | `/uploads` | Signed upload tokens for the file and image fields of a serialized component | [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers#stamp-upload-tokens) |
155
+ | `/types` | `MaybePromise`, the one shared type alias | [Pages and modules](/docs/interfaces/core/pages-and-modules#page-setup-functions) |
156
+ | `/api-base-url`, `/client-base-url` | `GetApiBaseUrl` and `GetClientBaseUrl`, the public origins of the API and the dashboard | [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers#public-urls) |
157
+ | `/client-ip` | `getClientIp` and `ResolveClientIp`, the client address of a request behind the trusted proxies | [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers#client-address) |
156
158
 
157
159
  Paths under `internal/`, symbols tagged `@internal`, and `internal` namespaces are implementation wiring, not supported consumer APIs. The wildcard export does not change that boundary.
158
160
 
159
- ## Documentation Sections
160
-
161
- - [Pages and Modules](/docs/interfaces/core/pages-and-modules) - Declare pages, group them into categories, own a branch of the sidebar with a module, and extend a page from another one
162
- - [Components](/docs/interfaces/core/components) - Build serializable components, declare actions and watches
163
- - [Permissions](/docs/interfaces/core/permissions) - Register permissions, compute a user's effective set, guard routes
164
- - [Tenancy](/docs/interfaces/core/tenancy) - Schemas, the tenancy tables, tenant-scoped models and access gates
165
- - [Invites](/docs/interfaces/core/invites) - Bring a user into a tenant by email
166
- - [Hooks](/docs/interfaces/core/hooks) - React to platform events and contribute to the tenant data export
167
- - [Realtime](/docs/interfaces/core/realtime) - Bind topics to pages, publish messages and subscribe to them
168
- - [Quick Actions](/docs/interfaces/core/quick-actions) - Contribute entries to the command palette
169
- - [Layout Banners](/docs/interfaces/core/layout-banners) - Show a global banner under the dashboard header, decided per request
161
+ ## Pages in this section
162
+
163
+ - [Pages and modules](/docs/interfaces/core/pages-and-modules): Declare pages, group them into categories, and extend a page from another module.
164
+ - [Modules and dynamic menus](/docs/interfaces/core/modules-and-dynamic-menus): Own a branch of the sidebar with a module, report its state on the modules catalog, and add menu entries resolved per request.
165
+ - [Frontend modules and request helpers](/docs/interfaces/core/frontend-modules-and-request-helpers): Ship a frontend module, sign upload fields, build public links, read the client address, and save native files.
166
+ - [Components](/docs/interfaces/core/components): Build serializable components, and declare actions and watches.
167
+ - [Permissions](/docs/interfaces/core/permissions): Register permissions, compute the effective set of a user, and guard routes.
168
+ - [Tenancy](/docs/interfaces/core/tenancy): Schemas, the tenancy tables, tenant-scoped models and access gates.
169
+ - [Invites](/docs/interfaces/core/invites): Bring a user into a tenant by email.
170
+ - [Hooks](/docs/interfaces/core/hooks): React to platform events.
171
+ - [Tenant data export](/docs/interfaces/core/tenant-data-export): Contribute the data of a module to the tenant data export.
172
+ - [Realtime](/docs/interfaces/core/realtime): Bind topics to pages, publish messages and subscribe to them.
173
+ - [Quick actions](/docs/interfaces/core/quick-actions): Contribute entries to the command palette.
174
+ - [Layout banners](/docs/interfaces/core/layout-banners): Show a global banner under the dashboard header, decided per request.
@@ -1,23 +1,20 @@
1
1
  ---
2
- title: "Layout Banners"
3
- description: "A layout banner is a global message the backend adds under the dashboard header: a colored strip carrying a line of text and its link buttons, or a component of your frontend layer."
2
+ title: "Layout banners"
3
+ description: "A layout banner is a global message the backend adds under the dashboard header: a colored strip with a line of text and its link buttons, or a component of your frontend layer."
4
+ mode: reference
4
5
  ---
5
6
 
6
- # Layout Banners
7
+ A layout banner is a global message that the backend adds under the dashboard header. It is a colored strip with a line of text and its link buttons, or a component of your frontend layer. A banner renders on the pages its [`scope`](#scope) selects. By default those are the application's pages, without the module area under `/modules`. Banners stack by `order`.
7
8
 
8
- ## Overview
9
+ The server decides per request whether a banner shows, while it builds the site layout. The answer is part of the server-rendered page, so a banner never flashes in or out after hydration.
9
10
 
10
- A layout banner is a global message the backend adds under the dashboard header: a colored strip carrying a line of text and its link buttons, or a component of your frontend layer. It renders on the pages its [`scope`](#scope) selects — by default the application's pages, leaving the module area under `/modules` out — and banners stack by `order`.
11
+ Everything on this page lives in `@antelopejs/interface-dms/layout-banners`.
11
12
 
12
- Whether a banner shows is decided per request, on the server, while the site layout is built. The answer is part of the server-rendered page, so a banner never flashes in or out after hydration.
13
+ ## Register a banner
13
14
 
14
- Everything lives in `@antelopejs/interface-dms/layout-banners`.
15
+ `RegisterLayoutBanner(info)` registers the banner and returns a function that removes it. Register at import time, next to the state the banner reports on. The DMS drops the registration when your module stops.
15
16
 
16
- ## Register a Banner
17
-
18
- `RegisterLayoutBanner(info)` registers the banner and returns a function removing it. Register at import time, next to the state the banner reports on; the registration is dropped automatically when your module stops.
19
-
20
- ```typescript
17
+ ```typescript fragment
21
18
  import {
22
19
  LayoutBannerVariant,
23
20
  RegisterLayoutBanner,
@@ -34,9 +31,11 @@ RegisterLayoutBanner({
34
31
  });
35
32
  ```
36
33
 
37
- The text can be a [composed text](/docs/components/block-fundamentals#composed-texts) — an i18n key and the raw values it names, written in the reader's language — and `actions` adds link buttons after it, the last one leading:
34
+ The text can be a [composed text](/docs/components/block-fundamentals#composed-texts). A composed text is an i18n key and the raw values it names, written in the reader's language. `actions` adds link buttons after the text, and the last button is the main action:
38
35
 
39
36
  ```typescript
37
+ import { LayoutBannerVariant, RegisterLayoutBanner } from "@antelopejs/interface-dms/layout-banners";
38
+
40
39
  RegisterLayoutBanner({
41
40
  key: "my-app:maintenance",
42
41
  variant: LayoutBannerVariant.WARNING,
@@ -48,11 +47,13 @@ RegisterLayoutBanner({
48
47
  });
49
48
  ```
50
49
 
51
- ## Resolve the Content per Request
50
+ A banner with no `text`, no `component` and no `resolve` is skipped, and the server logs a warning once for it.
52
51
 
53
- When the message names the state that makes the banner show — the invoice that failed, its amount, the day the workspace is suspended — `resolve(context)` builds the text and the buttons for each request, or answers `undefined` to hide the banner. It replaces `visible`: one read decides both.
52
+ ## Resolve the content per request
54
53
 
55
- ```typescript
54
+ Some messages name the state that makes the banner show, such as the invoice that failed, its amount, or the day the workspace is suspended. For those, `resolve(context)` builds the text and the buttons for each request, or answers `undefined` to hide the banner. It replaces `visible`, so one read decides both.
55
+
56
+ ```typescript fragment
56
57
  RegisterLayoutBanner({
57
58
  key: "saas:past-due",
58
59
  variant: LayoutBannerVariant.ERROR,
@@ -74,13 +75,15 @@ RegisterLayoutBanner({
74
75
  });
75
76
  ```
76
77
 
77
- The server sends the raw values; the browser formats them for the reader's language, time zone and clock, so the resolver never formats text. A banner like this one needs no frontend component.
78
+ The server sends the raw values, and the browser formats them for the reader's language, time zone and clock. The resolver never formats text. A banner like this one needs no frontend component.
78
79
 
79
- ## Mount a Component
80
+ ## Mount a component
80
81
 
81
- A banner can mount a global component of your [frontend layer](/docs/building/frontend-layer) instead of a text. The DMS still draws the chrome around it — color, icon, close button and ARIA role — and passes `props` to the component:
82
+ A banner can mount a global component of your [frontend layer](/docs/building/frontend-layer) in place of a text. The DMS still draws the chrome around it (the color, the icon, the close button and the ARIA role) and passes `props` to the component:
82
83
 
83
84
  ```typescript
85
+ import { LayoutBannerVariant, RegisterLayoutBanner } from "@antelopejs/interface-dms/layout-banners";
86
+
84
87
  RegisterLayoutBanner({
85
88
  key: "my-app:trial",
86
89
  variant: LayoutBannerVariant.INFO,
@@ -90,15 +93,15 @@ RegisterLayoutBanner({
90
93
  });
91
94
  ```
92
95
 
93
- Re-registering a `key` replaces the banner.
96
+ A second registration with the same `key` replaces the banner.
94
97
 
95
98
  ## Scope
96
99
 
97
- A banner is about the application being built — eighteen overdue invoices, a stock alert — so by default it shows on the application's pages only, and stays out of the **module area**: every page under `MODULE_URL_PREFIX` (`/modules`), that is the modules page, the module store and each module's own back-office pages. A banner about the workspace itself, which must follow the user into a module — billing past due, a suspended workspace, a maintenance window — sets `scope: LayoutBannerScope.EVERYWHERE`.
100
+ By default, a banner shows on the application's pages only and stays out of the **module area**. A banner about the application being built, such as eighteen overdue invoices or a stock alert, has no place there. The module area is every page under `MODULE_URL_PREFIX` (`/modules`): the modules page, the module store and the back-office pages of each module. A banner about the workspace itself must follow the user into a module. Billing past due, a suspended workspace and a maintenance window are examples. Such a banner sets `scope: LayoutBannerScope.EVERYWHERE`.
98
101
 
99
- `scope` is a plain option of the banner declaration, the same on the three kinds of banner — a text banner, a resolved banner and a component banner — with the same values and the same `"app"` default:
102
+ `scope` is a plain option of the banner declaration. It is the same on the three kinds of banner (a text banner, a resolved banner and a component banner), with the same values and the same `"app"` default:
100
103
 
101
- ```typescript
104
+ ```typescript fragment
102
105
  import {
103
106
  LayoutBannerScope,
104
107
  LayoutBannerVariant,
@@ -140,49 +143,58 @@ RegisterLayoutBanner({
140
143
  | `"everywhere"` | Every page of the dashboard layout, module area included. |
141
144
  | `"modules"` | The module area only. |
142
145
 
143
- The scope is decided by the page, not by the request: the site layout is fetched once and shared by every page, so each banner carries its scope and the dashboard applies it against the current route — in the server-rendered page, so a banner never flashes in or out after hydration, and again on each client-side navigation, so moving in or out of `/modules` adds or removes it without re-fetching anything. A banner's `visible` or `resolve` therefore does not see the route; the scope is the only per-page filter. A dismissal is per key, whatever page the banner was closed on.
146
+ The page decides the scope, not the request. The client fetches the site layout once and every page shares it, so each banner carries its scope, and the dashboard applies the scope against the current route. The dashboard applies it in the server-rendered page, so a banner never flashes in or out after hydration. It applies it again on each client-side navigation, so moving in or out of `/modules` adds or removes the banner without a new fetch. A banner's `visible` or `resolve` does not see the route, and the scope is the only filter per page. The server falls back to `"app"` for a `scope` value outside the three listed.
147
+
148
+ A dismissal applies to the key, whatever page the user closed the banner on.
144
149
 
145
150
  ::warning
146
- **Behaviour change.** Before `scope` existed every banner showed on every page, module area included. A banner registered without `scope` now stays out of `/modules`: give `scope: LayoutBannerScope.EVERYWHERE` to the ones reporting a workspace-wide state.
151
+ A banner registered without `scope` stays out of `/modules`. Give `scope: LayoutBannerScope.EVERYWHERE` to the banners that report a state of the whole workspace.
147
152
  ::
148
153
 
149
154
  ## `LayoutBannerInfo`
150
155
 
151
156
  | Field | Type | Description |
152
157
  | ----- | ---- | ----------- |
153
- | `key` | `string` | Unique across the deployment. Required. Also what a dismissal remembers: give a banner a new key when it must show again to users who dismissed it. |
154
- | `variant` | `LayoutBannerVariant` | `"info"`, `"warning"` or `"error"`. Required. Picks the color, the default icon and the ARIA role. |
155
- | `text` | `string \| ComposedText` | The message. A `$`-prefixed value resolves as an i18n key; a `ComposedText` is written in the reader's language. Exclusive with `component` and `resolve`; one of the three is required. |
156
- | `actions` | `BlockLinkAction[]` | Link buttons after `text`, the last one leading. Labels follow the `$` convention. |
157
- | `component` | `string` | Name of a global component rendered as the banner's content. Exclusive with `text` and `resolve`. |
158
- | `props` | `Record<string, unknown>` | Props passed to `component`. Must be serializable. |
159
- | `order` | `number` | Stack order, ascending from the top. Defaults to `0`; ties keep the registration order. |
160
- | `icon` | `string` | Leading icon. Defaults to one matching the variant. |
158
+ | `key` | `string` | Required. Unique across the deployment. A dismissal also remembers the key, so give a banner a new key when it must show again to users who dismissed it. |
159
+ | `variant` | `LayoutBannerVariant` | Required. `"info"`, `"warning"` or `"error"`. Picks the color, the default icon and the ARIA role. |
160
+ | `text` | `string \| ComposedText` | The message. A value with the `$` prefix resolves as an i18n key. A `ComposedText` is written in the reader's language. Exclusive with `component` and `resolve`, and one of the three is required. |
161
+ | `actions` | `BlockLinkAction[]` | Link buttons after `text`. The last one is the main action. Labels follow the `$` convention. |
162
+ | `component` | `string` | The name of a global component rendered as the banner's content. Exclusive with `text` and `resolve`. |
163
+ | `props` | `{ readonly [prop: string]: JsonValue }` | Props passed to `component`, as JSON. |
164
+ | `order` | `number` | Stack order, ascending from the top. Defaults to `0`. Ties keep the registration order. |
165
+ | `icon` | `string` | Leading icon. Defaults to one that matches the variant. |
161
166
  | `dismissible` | `boolean` | Whether the user can close the banner. Defaults to `false`. |
162
- | `scope` | `LayoutBannerScope` | `"app"`, `"everywhere"` or `"modules"`: the pages the banner shows on. Defaults to `"app"`, every page outside `/modules`. See [Scope](#scope). |
163
- | `visible` | `LayoutBannerVisibility` | Decides per request whether a `text` or `component` banner shows. Absent means always. |
164
- | `resolve` | `LayoutBannerResolver` | Builds `{ text, actions? }` per request, or `undefined` to hide the banner. Exclusive with `text`, `component` and `visible`. |
167
+ | `scope` | `LayoutBannerScope` | `"app"`, `"everywhere"` or `"modules"`, the pages the banner shows on. Defaults to `"app"`, every page outside `/modules`. See [Scope](#scope). |
168
+ | `visible` | `LayoutBannerVisibility` | Decides per request whether a `text` or `component` banner shows. Without it, the banner always shows. |
169
+ | `resolve` | `LayoutBannerResolver` | Builds `{ text, actions? }` per request, or answers `undefined` to hide the banner. Exclusive with `text`, `component` and `visible`. |
165
170
 
166
171
  ## Visibility
167
172
 
168
- `visible(context)` returns a boolean, or a promise of one; `resolve(context)` returns a `LayoutBannerContent` (`{ text, actions? }`), `undefined`, or a promise of either. They run server-side for every site layout request, all resolvers together, so the request waits for the slowest one rather than for their sum. A resolver that throws or does not answer within two seconds hides its banner for that request, as does a `visible` returning anything but `true` or a `resolve` answering no text; the other banners are unaffected.
173
+ `visible(context)` returns a boolean, or a promise of one. `resolve(context)` returns a `LayoutBannerContent` (`{ text, actions? }`), `undefined`, or a promise of either. The server runs them for every site layout request, all resolvers at once, so the request waits for the slowest one and not for their sum. A banner is hidden for that request in four cases:
174
+
175
+ - Its resolver throws.
176
+ - Its resolver does not answer within two seconds.
177
+ - Its `visible` returns anything other than `true`.
178
+ - Its `resolve` answers no text.
179
+
180
+ The other banners are unaffected.
169
181
 
170
182
  ### `LayoutBannerContext`
171
183
 
172
184
  | Field | Type | Description |
173
185
  | ----- | ---- | ----------- |
174
- | `user` | `User \| undefined` | The caller; `undefined` for an unauthenticated request. |
186
+ | `user` | `User \| undefined` | The caller. `undefined` for an unauthenticated request. |
175
187
  | `tenantId` | `string` | The tenant the site layout is built for. |
176
- | `permissions` | `Set<string>` | The caller's effective permissions in the tenant. |
177
- | `isOwner` | `boolean` | Whether the caller holds the wildcard permission. |
178
- | `isTenantAccessDenied` | `boolean` | Whether a [tenant access gate](/docs/interfaces/core/tenancy) currently refuses the caller. |
188
+ | `permissions` | `Set<string>` | The caller's effective permissions in the tenant, with no tenant access gate applied. |
189
+ | `isOwner` | `boolean` | Whether the caller holds the wildcard permission, with no tenant access gate applied. |
190
+ | `isTenantAccessDenied` | `boolean` | Whether a [tenant access gate](/docs/interfaces/core/tenancy#tenant-access-gates) refuses the caller. |
179
191
 
180
- Unlike product surfaces, a banner reads the permissions a denying access gate would hide: telling a suspended or past-due workspace why is exactly what a banner is for. Check `isTenantAccessDenied` when the two situations call for different banners.
192
+ The other product surfaces lose the permissions that a denying access gate hides, but a banner still reads them. A banner is how a suspended or past-due workspace learns why. Check `isTenantAccessDenied` when the two situations call for different banners.
181
193
 
182
- The resolvers run whenever a client fetches its site layout — on a full page load and after a menu invalidation. When the state a resolver reads changes, call `NotifyMenuChanged(tenantId)` from `@antelopejs/interface-dms/page` so the connected clients of that tenant re-fetch it and the banner appears or goes without a reload.
194
+ The resolvers run each time a client fetches its site layout, which happens on a full page load and after a menu invalidation. When the state a resolver reads changes, call `NotifyMenuChanged(tenantId)` from `@antelopejs/interface-dms/page`. The connected clients of that tenant then fetch the site layout again, and the banner appears or goes away without a reload.
183
195
 
184
196
  ## Rendering
185
197
 
186
- Banners render under the header of the dashboard layout, on the pages their scope covers, full width, in `order`, a text banner's `actions` on its right. Each one is its own live region: `error` banners carry `role="alert"`, `info` and `warning` banners `role="status"`.
198
+ Banners render under the header of the dashboard layout, on the pages their scope covers, at full width, in `order`. The `actions` of a text banner sit on its right. Each banner is its own live region. An `error` banner carries `role="alert"`, and an `info` or `warning` banner carries `role="status"`.
187
199
 
188
- A dismissible banner shows a close button. The dismissal lasts for the browser session and is kept in the `dms-dismissed-banners` cookie, which the server reads too, so a dismissed banner is already absent from the server-rendered page. A banner that is not dismissible ignores any dismissal recorded under its key.
200
+ A dismissible banner shows a close button. The dismissal lasts for the browser session and is stored in the `dms-dismissed-banners` cookie. The server reads that cookie too, so a dismissed banner is already absent from the server-rendered page. A banner that is not dismissible ignores any dismissal recorded under its key.