@antelopejs/dms 0.9.8 → 0.11.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 (451) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/README.md +1 -1
  3. package/data/module-store/catalog.json +2 -2
  4. package/dist/attachments/table-view.js +2 -2
  5. package/dist/attachments/table-view.js.map +1 -1
  6. package/dist/automation/actions.d.ts +2 -0
  7. package/dist/automation/actions.js +116 -71
  8. package/dist/automation/actions.js.map +1 -1
  9. package/dist/automation/i18n.d.ts +4 -0
  10. package/dist/automation/i18n.js +19 -0
  11. package/dist/automation/i18n.js.map +1 -0
  12. package/dist/automation/send-notification.d.ts +21 -0
  13. package/dist/automation/send-notification.js +163 -0
  14. package/dist/automation/send-notification.js.map +1 -0
  15. package/dist/automation/triggers.js +19 -25
  16. package/dist/automation/triggers.js.map +1 -1
  17. package/dist/client-origin-cors.d.ts +1 -0
  18. package/dist/client-origin-cors.js +19 -0
  19. package/dist/client-origin-cors.js.map +1 -0
  20. package/dist/config.d.ts +3 -2
  21. package/dist/config.js +5 -7
  22. package/dist/config.js.map +1 -1
  23. package/dist/frontend-module.d.ts +4 -0
  24. package/dist/frontend-module.js +37 -0
  25. package/dist/frontend-module.js.map +1 -0
  26. package/dist/implementations/dms/client-ip.js +1 -1
  27. package/dist/implementations/dms/client-ip.js.map +1 -1
  28. package/dist/implementations/dms/dev-reload.d.ts +5 -0
  29. package/dist/implementations/dms/dev-reload.js +23 -3
  30. package/dist/implementations/dms/dev-reload.js.map +1 -1
  31. package/dist/implementations/dms/frontend-modules.d.ts +2 -4
  32. package/dist/implementations/dms/frontend-modules.js +38 -94
  33. package/dist/implementations/dms/frontend-modules.js.map +1 -1
  34. package/dist/implementations/dms/frontend-ready.d.ts +12 -2
  35. package/dist/implementations/dms/frontend-ready.js +34 -4
  36. package/dist/implementations/dms/frontend-ready.js.map +1 -1
  37. package/dist/implementations/dms/layout-banners.d.ts +2 -1
  38. package/dist/implementations/dms/layout-banners.js +9 -0
  39. package/dist/implementations/dms/layout-banners.js.map +1 -1
  40. package/dist/implementations/dms/manifest.d.ts +7 -2
  41. package/dist/implementations/dms/manifest.js +12 -7
  42. package/dist/implementations/dms/manifest.js.map +1 -1
  43. package/dist/implementations/dms/page.d.ts +4 -3
  44. package/dist/implementations/dms/page.js +49 -18
  45. package/dist/implementations/dms/page.js.map +1 -1
  46. package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
  47. package/dist/implementations/dms/permissions-resolver.js +2 -2
  48. package/dist/implementations/dms/permissions-resolver.js.map +1 -1
  49. package/dist/implementations/dms/realtime.js +1 -0
  50. package/dist/implementations/dms/realtime.js.map +1 -1
  51. package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
  52. package/dist/implementations/dms-base/bulk-selection.js +23 -1
  53. package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
  54. package/dist/implementations/dms-base/filter-tokens.js +5 -3
  55. package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
  56. package/dist/implementations/dms-base/search-route.d.ts +1 -0
  57. package/dist/implementations/dms-base/search-route.js +35 -13
  58. package/dist/implementations/dms-base/search-route.js.map +1 -1
  59. package/dist/implementations/dms-base/table-view.js +11 -6
  60. package/dist/implementations/dms-base/table-view.js.map +1 -1
  61. package/dist/implementations/dms-notifications/index.d.ts +2 -2
  62. package/dist/implementations/dms-notifications/index.js +5 -5
  63. package/dist/implementations/dms-notifications/index.js.map +1 -1
  64. package/dist/index.js +32 -55
  65. package/dist/index.js.map +1 -1
  66. package/dist/pages/modules/index.d.ts +1 -0
  67. package/dist/pages/modules/index.js +1 -0
  68. package/dist/pages/modules/index.js.map +1 -1
  69. package/dist/pages/modules/modules-store.d.ts +9 -0
  70. package/dist/pages/modules/modules-store.js +30 -0
  71. package/dist/pages/modules/modules-store.js.map +1 -0
  72. package/dist/pages/settings/users/account-credentials.js +2 -2
  73. package/dist/pages/settings/users/account-credentials.js.map +1 -1
  74. package/dist/pages/settings/users/account-data-store.js +25 -8
  75. package/dist/pages/settings/users/account-data-store.js.map +1 -1
  76. package/dist/pages/settings/users/invite-extension-routes.js +9 -3
  77. package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
  78. package/dist/pages/settings/users/member-management.js +13 -14
  79. package/dist/pages/settings/users/member-management.js.map +1 -1
  80. package/dist/pages/settings/users/profile.d.ts +1 -4
  81. package/dist/pages/settings/users/profile.js +0 -35
  82. package/dist/pages/settings/users/profile.js.map +1 -1
  83. package/dist/pages/settings/users/role-editor-store.js +26 -18
  84. package/dist/pages/settings/users/role-editor-store.js.map +1 -1
  85. package/dist/pages/settings/users/role-editor.d.ts +0 -1
  86. package/dist/pages/settings/users/role-editor.js +1 -2
  87. package/dist/pages/settings/users/role-editor.js.map +1 -1
  88. package/dist/pages/settings/users/role-preview.js +1 -2
  89. package/dist/pages/settings/users/role-preview.js.map +1 -1
  90. package/dist/pages/settings/users/roles.js +2 -2
  91. package/dist/pages/settings/users/roles.js.map +1 -1
  92. package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
  93. package/dist/realtime/broker.d.ts +6 -0
  94. package/dist/realtime/broker.js +8 -1
  95. package/dist/realtime/broker.js.map +1 -1
  96. package/dist/realtime/presence.d.ts +8 -3
  97. package/dist/realtime/presence.js +8 -4
  98. package/dist/realtime/presence.js.map +1 -1
  99. package/dist/realtime/sessions.d.ts +11 -1
  100. package/dist/realtime/sessions.js +21 -3
  101. package/dist/realtime/sessions.js.map +1 -1
  102. package/dist/realtime/table-view.d.ts +2 -2
  103. package/dist/realtime/table-view.js +4 -3
  104. package/dist/realtime/table-view.js.map +1 -1
  105. package/dist/routes/auth/client-ip.d.ts +1 -0
  106. package/dist/routes/auth/client-ip.js +18 -0
  107. package/dist/routes/auth/client-ip.js.map +1 -1
  108. package/dist/routes/auth/oauth/config.d.ts +2 -1
  109. package/dist/routes/auth/oauth/config.js +5 -1
  110. package/dist/routes/auth/oauth/config.js.map +1 -1
  111. package/dist/routes/auth/session-handoff.d.ts +0 -1
  112. package/dist/routes/auth/session-handoff.js +0 -2
  113. package/dist/routes/auth/session-handoff.js.map +1 -1
  114. package/dist/routes/auth.js +3 -2
  115. package/dist/routes/auth.js.map +1 -1
  116. package/dist/routes/index.d.ts +0 -1
  117. package/dist/routes/index.js +0 -1
  118. package/dist/routes/index.js.map +1 -1
  119. package/dist/routes/realtime.d.ts +13 -1
  120. package/dist/routes/realtime.js +114 -29
  121. package/dist/routes/realtime.js.map +1 -1
  122. package/dist/startup-config.d.ts +2 -0
  123. package/dist/startup-config.js +62 -0
  124. package/dist/startup-config.js.map +1 -0
  125. package/dist/store/interfaces.d.ts +3 -2
  126. package/dist/store/interfaces.js +16 -6
  127. package/dist/store/interfaces.js.map +1 -1
  128. package/dist/store/listing.js +25 -15
  129. package/dist/store/listing.js.map +1 -1
  130. package/dist/store/operations.js +5 -2
  131. package/dist/store/operations.js.map +1 -1
  132. package/dist/store/requirements.js +3 -2
  133. package/dist/store/requirements.js.map +1 -1
  134. package/dist/store/runtime.d.ts +10 -1
  135. package/dist/store/runtime.js +33 -6
  136. package/dist/store/runtime.js.map +1 -1
  137. package/dist/store/types.d.ts +10 -0
  138. package/dist/utils/ensure-default-tenant.d.ts +2 -1
  139. package/dist/utils/ensure-default-tenant.js +13 -1
  140. package/dist/utils/ensure-default-tenant.js.map +1 -1
  141. package/dist/utils/export-jobs.js +2 -1
  142. package/dist/utils/export-jobs.js.map +1 -1
  143. package/dist/validation/auth.schema.d.ts +2 -2
  144. package/dist/validation/member-invite.schema.d.ts +2 -10
  145. package/dist/validation/member-invite.schema.js +2 -15
  146. package/dist/validation/member-invite.schema.js.map +1 -1
  147. package/frontend-vue/dms.frontend.ts +24 -5
  148. package/frontend-vue/dms.server.ts +17 -0
  149. package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
  150. package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +33 -0
  151. package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
  152. package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
  153. package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
  154. package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
  155. package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
  156. package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
  157. package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
  158. package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
  159. package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
  160. package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
  161. package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
  162. package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +25 -5
  163. package/frontend-vue/layers/dms-core/app/composables/useApiError.ts +3 -5
  164. package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +61 -26
  165. package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
  166. package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
  167. package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
  168. package/frontend-vue/layers/dms-core/app/utils/formatter.ts +134 -35
  169. package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
  170. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +136 -2
  171. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +136 -2
  172. package/frontend-vue/layers/dms-core/shared/types/app-config.ts +0 -2
  173. package/frontend-vue/layers/dms-layout/app/app.config.ts +0 -1
  174. package/frontend-vue/layers/dms-layout/app/assets/css/main.css +11 -1
  175. package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Italic-Variable.woff2 +0 -0
  176. package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Variable.woff2 +0 -0
  177. package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Italic-Variable.woff2 +0 -0
  178. package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Variable.woff2 +0 -0
  179. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
  180. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
  181. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +6 -2
  182. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
  183. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -107
  184. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
  185. package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +4 -0
  186. package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
  187. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
  188. package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
  189. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
  190. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
  191. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
  192. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
  193. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
  194. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
  195. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
  196. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
  197. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
  198. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
  199. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
  200. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
  201. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
  202. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
  203. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
  204. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
  205. package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
  206. package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +2 -2
  207. package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
  208. package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
  209. package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
  210. package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +49 -11
  211. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
  212. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +59 -4
  213. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
  214. package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
  215. package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
  216. package/frontend-vue/layers/dms-layout/app/composables/page/usePageRecordDeletion.ts +162 -0
  217. package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
  218. package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +6 -2
  219. package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +6 -2
  220. package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
  221. package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
  222. package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
  223. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +13 -22
  224. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +11 -10
  225. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +22 -52
  226. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-quick-actions.client.ts +7 -7
  227. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-session.client.ts +11 -10
  228. package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
  229. package/frontend-vue/layers/dms-layout/app/theme/actions.ts +5 -4
  230. package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
  231. package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
  232. package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
  233. package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
  234. package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
  235. package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
  236. package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
  237. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +45 -18
  238. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +44 -17
  239. package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
  240. package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
  241. package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
  242. package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
  243. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
  244. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
  245. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
  246. package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
  247. package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
  248. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
  249. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
  250. package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +5 -1
  251. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
  252. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
  253. package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
  254. package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
  255. package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +48 -1
  256. package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
  257. package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
  258. package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
  259. package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
  260. package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
  261. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
  262. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
  263. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
  264. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
  265. package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
  266. package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
  267. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
  268. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
  269. package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
  270. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/actionError.ts +6 -1
  271. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
  272. package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
  273. package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
  274. package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
  275. package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
  276. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
  277. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +44 -0
  278. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +123 -27
  279. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
  280. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
  281. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +92 -0
  282. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
  283. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
  284. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
  285. package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
  286. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
  287. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
  288. package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
  289. package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
  290. package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
  291. package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +11 -5
  292. package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
  293. package/frontend-vue/layers/dms-ui/app/build/composables/form/formValidation.ts +36 -4
  294. package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
  295. package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
  296. package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +78 -0
  297. package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
  298. package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
  299. package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
  300. package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
  301. package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
  302. package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
  303. package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
  304. package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
  305. package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
  306. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
  307. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
  308. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
  309. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
  310. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
  311. package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
  312. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +97 -0
  313. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
  314. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
  315. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
  316. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
  317. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
  318. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
  319. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
  320. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
  321. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
  322. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
  323. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
  324. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
  325. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
  326. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
  327. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +90 -35
  328. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
  329. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
  330. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
  331. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
  332. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
  333. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
  334. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
  335. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
  336. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
  337. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
  338. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
  339. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
  340. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
  341. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
  342. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
  343. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/writeError.ts +21 -0
  344. package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
  345. package/frontend-vue/layers/dms-ui/app/build/utils/codeHighlight.ts +67 -29
  346. package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
  347. package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
  348. package/frontend-vue/layers/dms-ui/app/build/utils/htmlGrammar.ts +79 -0
  349. package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
  350. package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
  351. package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
  352. package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
  353. package/frontend-vue/layers/dms-ui/app/build/utils/shellParser.ts +1 -1
  354. package/frontend-vue/layers/dms-ui/app/build/utils/streamHighlight.ts +90 -0
  355. package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
  356. package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
  357. package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
  358. package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
  359. package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
  360. package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
  361. package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
  362. package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
  363. package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
  364. package/frontend-vue/layers/dms-ui/app/components/code-snippet/CodeSnippet.vue +23 -12
  365. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
  366. package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
  367. package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
  368. package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
  369. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +119 -36
  370. package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +53 -22
  371. package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
  372. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
  373. package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
  374. package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
  375. package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
  376. package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
  377. package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
  378. package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
  379. package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
  380. package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
  381. package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +226 -65
  382. package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
  383. package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +210 -0
  384. package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
  385. package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
  386. package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
  387. package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
  388. package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
  389. package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
  390. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
  391. package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
  392. package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
  393. package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
  394. package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
  395. package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +74 -25
  396. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +48 -44
  397. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
  398. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +426 -97
  399. package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
  400. package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
  401. package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
  402. package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
  403. package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
  404. package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
  405. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
  406. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
  407. package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
  408. package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
  409. package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
  410. package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +16 -0
  411. package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
  412. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +189 -28
  413. package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +29 -12
  414. package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
  415. package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
  416. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
  417. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
  418. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
  419. package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
  420. package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
  421. package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
  422. package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
  423. package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
  424. package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
  425. package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
  426. package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
  427. package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
  428. package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +94 -3
  429. package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
  430. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +20 -5
  431. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +20 -5
  432. package/frontend-vue/package.json +6 -2
  433. package/package.json +11 -10
  434. package/skills/dms/SKILL.md +1 -1
  435. package/skills/dms-auth/SKILL.md +5 -3
  436. package/skills/dms-best-practices/REFERENCE.md +2 -0
  437. package/skills/dms-best-practices/SKILL.md +4 -0
  438. package/skills/dms-module/SKILL.md +3 -2
  439. package/skills/dms-pages/REFERENCE.md +129 -16
  440. package/skills/dms-pages/SKILL.md +1 -1
  441. package/skills/dms-project/DEV-SERVERS.md +23 -1
  442. package/skills/dms-project/REFERENCE.md +1 -1
  443. package/skills/dms-project/SKILL.md +4 -1
  444. package/skills/dms-project/scripts/dms-dev.sh +205 -17
  445. package/dist/hooks/tenant-instances.d.ts +0 -1
  446. package/dist/hooks/tenant-instances.js +0 -13
  447. package/dist/hooks/tenant-instances.js.map +0 -1
  448. package/dist/routes/startup-gate.d.ts +0 -7
  449. package/dist/routes/startup-gate.js +0 -39
  450. package/dist/routes/startup-gate.js.map +0 -1
  451. package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
@@ -10,5 +10,6 @@ export interface TableQueryParams {
10
10
  sortKey?: string;
11
11
  sortDirection?: SortDirection;
12
12
  showArchived?: boolean;
13
- [key: `filter_${string}`]: string | number | undefined;
13
+ /** A list sends the key once per filter, which a row must all pass. */
14
+ [key: `filter_${string}`]: string | string[] | number | undefined;
14
15
  }
@@ -1,3 +1,5 @@
1
+ import { markPageRead } from "../build/composables/live/pageReadClock";
2
+
1
3
  /**
2
4
  * The window event a data block (StatGroup, KeyValueList, NavCardGrid,
3
5
  * ActivityFeed, KPI, top list, meter, chart, a tab set's badges, table view)
@@ -43,7 +45,7 @@ export function refreshPageBlocks(): Promise<void> {
43
45
  waitUntil: (work) => void pending.push(work),
44
46
  };
45
47
  window.dispatchEvent(new CustomEvent(BLOCK_REFRESH_EVENT, { detail }));
46
- return Promise.allSettled(pending).then(() => undefined);
48
+ return Promise.allSettled(pending).then(() => markPageRead());
47
49
  }
48
50
 
49
51
  /**
@@ -27,6 +27,7 @@ export interface CascaderTreeOptions {
27
27
 
28
28
  export const CASCADER_PATH_SEPARATOR = " / ";
29
29
 
30
+ /** How many rows the picker's open menu lists to browse the tree. */
30
31
  export const CASCADER_FETCH_LIMIT = 1000;
31
32
 
32
33
  export const DEFAULT_CASCADER_KEY_MAPPING: CascaderKeyMapping = {
@@ -220,10 +221,100 @@ export function cascaderValuePath(
220
221
  ): string[] {
221
222
  const row = asPickedRow(item);
222
223
  const ownLabel = row ? rowValue(row, keyMapping.label) : undefined;
223
- const id = row
224
- ? rowValue(row, keyMapping.value)
225
- : rowValue({ id: item }, "id");
224
+ const id = cascaderValueId(item, keyMapping);
226
225
  if (!id) return ownLabel ? [ownLabel] : [];
227
226
  const labels = rows ? buildCascaderPathLabels(rows, keyMapping, id) : [];
228
227
  return labels.length > 0 ? labels : [ownLabel ?? id];
229
228
  }
229
+
230
+ /** Reads the rows of the given ids from the cascader's `select` route. */
231
+ export type CascaderRowsReader = (ids: string[]) => Promise<CascaderRow[]>;
232
+
233
+ /** The rows a path is drawn from, and the picked ids none of them answer. */
234
+ export interface CascaderAncestry {
235
+ rows: CascaderRow[];
236
+ notFound: string[];
237
+ }
238
+
239
+ /**
240
+ * The rows of the picked ids and of every ancestor above them, read with
241
+ * `?ids=` one level at a time: the picked rows, then their parents, then
242
+ * theirs, until a level names no row not read yet. A tree is as many reads as
243
+ * it is deep (a level is one request for all its ids), whatever its size, and
244
+ * a parent cycle ends because a row is never asked twice. A picked id no row
245
+ * answers (deleted, out of reach) is returned as not found.
246
+ */
247
+ export async function readCascaderAncestry(
248
+ read: CascaderRowsReader,
249
+ keyMapping: CascaderKeyMapping,
250
+ ids: string[],
251
+ ): Promise<CascaderAncestry> {
252
+ const rowsByValue = new Map<string, CascaderRow>();
253
+ const asked = new Set<string>();
254
+ let pending = [...new Set(ids)];
255
+ while (pending.length > 0) {
256
+ for (const id of pending) asked.add(id);
257
+ const rows = await read(pending);
258
+ for (const row of rows) {
259
+ const value = rowValue(row, keyMapping.value);
260
+ if (value !== undefined) rowsByValue.set(value, row);
261
+ }
262
+ pending = [
263
+ ...new Set(
264
+ rows
265
+ .map((row) => rowValue(row, keyMapping.parent))
266
+ .filter(
267
+ (parent): parent is string =>
268
+ parent !== undefined && !asked.has(parent),
269
+ ),
270
+ ),
271
+ ];
272
+ }
273
+ return {
274
+ rows: [...rowsByValue.values()],
275
+ notFound: ids.filter((id) => !rowsByValue.has(id)),
276
+ };
277
+ }
278
+
279
+ /** The id of a picked value: an id, or a row carrying its id. */
280
+ export function cascaderValueId(
281
+ item: unknown,
282
+ keyMapping: CascaderKeyMapping,
283
+ ): string | undefined {
284
+ const row = asPickedRow(item);
285
+ return row ? rowValue(row, keyMapping.value) : rowValue({ id: item }, "id");
286
+ }
287
+
288
+ /** What a cell already holds of its path, and the ids it still has to read. */
289
+ export interface CascaderValueReads {
290
+ /** The rows the server joined: each one labels itself. */
291
+ joinedRows: CascaderRow[];
292
+ /** The picked ids sent plain, and the parents of the joined rows. */
293
+ idsToRead: string[];
294
+ }
295
+
296
+ /**
297
+ * Splits a cell's picked values into the rows the list joined and the ids it
298
+ * still reads: a plain id is read, a joined row only has its parent read
299
+ * (none for a root), so a list whose route joins the relation reads nothing
300
+ * for a pick at the top of the tree.
301
+ */
302
+ export function cascaderValueReads(
303
+ values: unknown[],
304
+ keyMapping: CascaderKeyMapping,
305
+ ): CascaderValueReads {
306
+ const joinedRows = values
307
+ .map(asPickedRow)
308
+ .filter(
309
+ (row): row is CascaderRow =>
310
+ !!row && rowValue(row, keyMapping.value) !== undefined,
311
+ );
312
+ const plainIds = values
313
+ .filter((item) => !asPickedRow(item))
314
+ .map((item) => cascaderValueId(item, keyMapping))
315
+ .filter((id): id is string => id !== undefined);
316
+ const parents = joinedRows
317
+ .map((row) => rowValue(row, keyMapping.parent))
318
+ .filter((id): id is string => id !== undefined);
319
+ return { joinedRows, idsToRead: [...new Set([...plainIds, ...parents])] };
320
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The children of a layout block (a Card, a VStack, a Grid) as
3
+ * `RecursiveComponent` draws them: each child's component resolved by its
4
+ * registered name, a `div` when none matches, its own children likewise.
5
+ */
6
+ export function resolveComponentChildren(
7
+ children: ComponentChild[],
8
+ ): ResolvedComponentInfo[] {
9
+ return children.map((child) => {
10
+ const { id, component, ...additionalProps } = child;
11
+ return {
12
+ id,
13
+ options: component.options,
14
+ component: component.componentName
15
+ ? resolveDmsComponent(component.componentName) || "div"
16
+ : "div",
17
+ componentName: component.componentName,
18
+ children: component.children
19
+ ? resolveComponentChildren(component.children)
20
+ : [],
21
+ ...additionalProps,
22
+ };
23
+ });
24
+ }
@@ -85,7 +85,8 @@
85
85
  "include": "Includes",
86
86
  "exclude": "Excludes",
87
87
  "contains": "Contains",
88
- "not_contains": "Does not contain"
88
+ "not_contains": "Does not contain",
89
+ "array_contains_string": "Contains"
89
90
  },
90
91
  "filter": {
91
92
  "boolean": {
@@ -108,7 +109,7 @@
108
109
  "show_archived": "Show archived items",
109
110
  "archived": "Archived",
110
111
  "archive_toggle": "Archive",
111
- "archived_count": "{count} archived",
112
+ "archived_count": "Archived: {count}",
112
113
  "archive_strip_title": "Viewing archived items.",
113
114
  "archive_strip_description": "They are hidden from the regular list until restored.",
114
115
  "archived_empty_title": "No archived items",
@@ -177,6 +178,8 @@
177
178
  "save_as": "Save as new view",
178
179
  "save_current": "Save current view",
179
180
  "delete": "Delete view",
181
+ "delete_title": "Delete this view?",
182
+ "delete_description": "\"{view}\" will be deleted for good. The table goes back to its default state if the view is open.",
180
183
  "save_as_title": "Save as a new view",
181
184
  "save_as_description": "Keep the current filters, search, sort, columns and display under a name. Only you will see it.",
182
185
  "save_as_confirm": "Save view",
@@ -257,6 +260,7 @@
257
260
  "reset": "Reset",
258
261
  "cancel": "Cancel",
259
262
  "save_changes": "Save changes",
263
+ "create": "Create",
260
264
  "refresh_data": "Refresh data",
261
265
  "export_data": "Export data"
262
266
  },
@@ -286,12 +290,15 @@
286
290
  "forbidden_description": "Your role doesn't let you view this entry, so the form can't open on its current values. Ask an administrator for access.",
287
291
  "missing_title": "No entry selected",
288
292
  "missing_description": "This form shows one entry, and the address names none. Open it from an entry to see its values.",
293
+ "not_found_title": "Not found",
294
+ "not_found_description": "This entry does not exist, or no longer does: it may have been deleted.",
289
295
  "retry": "Try again"
290
296
  },
291
297
  "select_date": "Select date",
292
298
  "relation": {
293
299
  "selected_count": "{count} selected",
294
- "add_new": "Add new entry"
300
+ "add_new": "Add new entry",
301
+ "not_found": "Not found"
295
302
  },
296
303
  "cascader": {
297
304
  "placeholder": "Select an item",
@@ -406,7 +413,8 @@
406
413
  "invalid": "No errors | 1 field to fix | {count} fields to fix"
407
414
  },
408
415
  "error_summary": {
409
- "title": "No field to fix | 1 field needs your attention | {count} fields need your attention"
416
+ "title": "No field to fix | 1 field needs your attention | {count} fields need your attention",
417
+ "resolved": "Everything is fixed: the form can be saved."
410
418
  },
411
419
  "repeater": {
412
420
  "add": "Add a row",
@@ -515,7 +523,7 @@
515
523
  },
516
524
  "livetoggle": {
517
525
  "l": {
518
- "description": "Switch the page between Direct and Pause"
526
+ "description": "Switch the page between Live and Pause"
519
527
  }
520
528
  }
521
529
  },
@@ -687,6 +695,9 @@
687
695
  "info": "note"
688
696
  }
689
697
  },
698
+ "flow_canvas": {
699
+ "delete_node": "Delete node"
700
+ },
690
701
  "password_rules": {
691
702
  "head": "{met} of {total} met",
692
703
  "verdict": {
@@ -750,6 +761,7 @@
750
761
  "show_new": "Show",
751
762
  "paused": "Paused",
752
763
  "resume": "Resume",
764
+ "refresh": "Refresh",
753
765
  "reason_hidden": "tab hidden",
754
766
  "polling": "no realtime, polling",
755
767
  "table_held": "Table on hold",
@@ -771,6 +783,9 @@
771
783
  "invalid_state": "The preview state could not be read.",
772
784
  "empty": "Nothing to preview yet.",
773
785
  "unsafe_method": "{name} was not drawn: a preview only reads its data, and {value} writes."
786
+ },
787
+ "drawer": {
788
+ "resize": "Resize the drawer"
774
789
  }
775
790
  }
776
791
  }
@@ -85,7 +85,8 @@
85
85
  "include": "contient",
86
86
  "exclude": "ne contient pas",
87
87
  "contains": "contient",
88
- "not_contains": "ne contient pas"
88
+ "not_contains": "ne contient pas",
89
+ "array_contains_string": "contient"
89
90
  },
90
91
  "filter": {
91
92
  "boolean": {
@@ -108,7 +109,7 @@
108
109
  "show_archived": "Voir les éléments archivés",
109
110
  "archived": "Archivés",
110
111
  "archive_toggle": "Archives",
111
- "archived_count": "{count} archivés",
112
+ "archived_count": "Archives : {count}",
112
113
  "archive_strip_title": "Éléments archivés.",
113
114
  "archive_strip_description": "Ils restent masqués de la liste habituelle jusqu’à leur restauration.",
114
115
  "archived_empty_title": "Aucun élément archivé",
@@ -177,6 +178,8 @@
177
178
  "save_as": "Enregistrer comme nouvelle vue",
178
179
  "save_current": "Enregistrer la vue actuelle",
179
180
  "delete": "Supprimer la vue",
181
+ "delete_title": "Supprimer cette vue ?",
182
+ "delete_description": "« {view} » sera supprimée définitivement. Si elle est ouverte, le tableau revient à son état par défaut.",
180
183
  "save_as_title": "Enregistrer comme nouvelle vue",
181
184
  "save_as_description": "Conservez les filtres, la recherche, le tri, les colonnes et l'affichage actuels sous un nom. Vous seul la verrez.",
182
185
  "save_as_confirm": "Enregistrer la vue",
@@ -257,6 +260,7 @@
257
260
  "reset": "Réinitialiser",
258
261
  "cancel": "Annuler",
259
262
  "save_changes": "Enregistrer les modifications",
263
+ "create": "Créer",
260
264
  "refresh_data": "Actualiser les données",
261
265
  "export_data": "Exporter les données"
262
266
  },
@@ -287,12 +291,15 @@
287
291
  "forbidden_description": "Votre rôle ne vous permet pas de voir cet élément, le formulaire ne peut donc pas s'ouvrir sur ses valeurs actuelles. Demandez l'accès à un administrateur.",
288
292
  "missing_title": "Aucun élément sélectionné",
289
293
  "missing_description": "Ce formulaire affiche un élément, et l'adresse n'en désigne aucun. Ouvrez-le depuis un élément pour voir ses valeurs.",
294
+ "not_found_title": "Introuvable",
295
+ "not_found_description": "Cet élément n'existe pas, ou plus : il a peut-être été supprimé.",
290
296
  "retry": "Réessayer"
291
297
  },
292
298
  "select_date": "Sélectionner une date",
293
299
  "relation": {
294
300
  "selected_count": "{count} sélectionné(s)",
295
- "add_new": "Ajouter une nouvelle entrée"
301
+ "add_new": "Ajouter une nouvelle entrée",
302
+ "not_found": "Introuvable"
296
303
  },
297
304
  "cascader": {
298
305
  "placeholder": "Sélectionner un élément",
@@ -407,7 +414,8 @@
407
414
  "invalid": "Aucune erreur | 1 champ à corriger | {count} champs à corriger"
408
415
  },
409
416
  "error_summary": {
410
- "title": "Aucun champ à corriger | 1 champ demande votre attention | {count} champs demandent votre attention"
417
+ "title": "Aucun champ à corriger | 1 champ demande votre attention | {count} champs demandent votre attention",
418
+ "resolved": "Tout est corrigé : le formulaire peut être enregistré."
411
419
  },
412
420
  "repeater": {
413
421
  "add": "Ajouter une ligne",
@@ -688,6 +696,9 @@
688
696
  "info": "note"
689
697
  }
690
698
  },
699
+ "flow_canvas": {
700
+ "delete_node": "Supprimer le nœud"
701
+ },
691
702
  "password_rules": {
692
703
  "head": "{met} sur {total} respectées",
693
704
  "verdict": {
@@ -719,7 +730,7 @@
719
730
  },
720
731
  "save_bar": {
721
732
  "unsaved": "Modifications non enregistrées",
722
- "discard": "Annuler",
733
+ "discard": "Abandonner",
723
734
  "save": "Enregistrer",
724
735
  "saving": "Enregistrement",
725
736
  "saved": "Enregistré",
@@ -751,6 +762,7 @@
751
762
  "show_new": "Afficher",
752
763
  "paused": "En pause",
753
764
  "resume": "Reprendre",
765
+ "refresh": "Actualiser",
754
766
  "reason_hidden": "onglet masqué",
755
767
  "polling": "sans temps réel, relecture régulière",
756
768
  "table_held": "Tableau figé",
@@ -772,6 +784,9 @@
772
784
  "invalid_state": "L’état de l’aperçu est illisible.",
773
785
  "empty": "Rien à prévisualiser pour l’instant.",
774
786
  "unsafe_method": "{name} n’a pas été affiché : un aperçu ne fait que lire ses données, et {value} écrit."
787
+ },
788
+ "drawer": {
789
+ "resize": "Redimensionner le tiroir"
775
790
  }
776
791
  }
777
792
  }
@@ -11,7 +11,7 @@
11
11
  "license": "Apache-2.0",
12
12
  "packageManager": "pnpm@10.6.5",
13
13
  "engines": {
14
- "@antelopejs/dms-frontend": ">=0.6.3 <0.8.0"
14
+ "@antelopejs/dms-frontend": ">=0.9.0 <0.10.0"
15
15
  },
16
16
  "scripts": {
17
17
  "typecheck": "ajs dms verify-source --layer \"$PWD\" --local-package @antelopejs/dms=.. --local-package @antelopejs/interface-dms=../../interface-dms",
@@ -37,7 +37,11 @@
37
37
  "@iconify-json/ph": "^1.2.2",
38
38
  "@internationalized/date": "^3.10.0",
39
39
  "@lezer/common": "^1.5.3",
40
+ "@lezer/css": "^1.3.8",
40
41
  "@lezer/highlight": "^1.2.5",
42
+ "@lezer/html": "^1.3.13",
43
+ "@lezer/javascript": "^1.5.6",
44
+ "@lezer/json": "^1.0.3",
41
45
  "@tailwindcss/typography": "^0.5.19",
42
46
  "@tanstack/vue-table": "^8.21.3",
43
47
  "@tiptap/core": "^3.30.2",
@@ -75,7 +79,7 @@
75
79
  },
76
80
  "devDependencies": {
77
81
  "@antelopejs/core": ">=1.16.0 <2",
78
- "@antelopejs/dms-frontend": ">=0.6.3 <0.7.0",
82
+ "@antelopejs/dms-frontend": ">=0.9.0 <0.10.0",
79
83
  "@eslint/js": "^8.57.0",
80
84
  "@inertiajs/vue3": "^3.7.0",
81
85
  "@nuxt/ui": "4.10.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms",
3
- "version": "0.9.8",
3
+ "version": "0.11.0",
4
4
  "description": "The AntelopeJS dashboard management system: admin dashboards declared in TypeScript, with auth and tenancy, data management, file uploads, notifications and realtime.",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -22,6 +22,7 @@
22
22
  },
23
23
  "main": "dist/index.js",
24
24
  "types": "dist/index.d.ts",
25
+ "dmsFrontend": "dist/frontend-module.js",
25
26
  "files": [
26
27
  "dist",
27
28
  "!dist/.tsbuildinfo",
@@ -57,16 +58,15 @@
57
58
  "@antelopejs/interface-api": ">=0.0.15 <1.0.0",
58
59
  "@antelopejs/interface-api-util": ">=0.1.3 <1.0.0",
59
60
  "@antelopejs/interface-core": ">=0.2.4 <1.0.0",
60
- "@antelopejs/interface-data-api": ">=0.2.2 <1.0.0",
61
- "@antelopejs/interface-database": ">=0.1.10 <1.0.0",
62
- "@antelopejs/interface-database-decorators": ">=0.1.9 <1.0.0",
63
- "@antelopejs/interface-dms": ">=0.7.4 <0.8.0",
61
+ "@antelopejs/interface-data-api": ">=0.4.0 <1.0.0",
62
+ "@antelopejs/interface-database": ">=0.1.11 <1.0.0",
63
+ "@antelopejs/interface-database-decorators": ">=0.1.10 <1.0.0",
64
+ "@antelopejs/interface-dms": ">=0.9.0 <0.10.0",
64
65
  "@antelopejs/interface-email": ">=0.0.6 <1.0.0",
65
66
  "@antelopejs/interface-file-storage": ">=0.1.4 <1.0.0",
66
67
  "archiver": "^7.0.1",
67
68
  "csv-stringify": "^6.7.0",
68
69
  "defu": "^6.1.4",
69
- "ignore": "^7.0.5",
70
70
  "jsonwebtoken": "^9.0.3",
71
71
  "mmdb-lib": "^3.0.3",
72
72
  "node-cron": "^4.2.1",
@@ -77,7 +77,7 @@
77
77
  "zod": "~3.24.2"
78
78
  },
79
79
  "devDependencies": {
80
- "@antelopejs/core": ">=1.16.0 <2",
80
+ "@antelopejs/core": ">=1.17.0 <2",
81
81
  "@antelopejs/tooling-configs": ">=0.0.9 <1.0.0",
82
82
  "@types/archiver": "^6.0.4",
83
83
  "@types/chai": "^4.3.20",
@@ -116,11 +116,11 @@
116
116
  "registry": "https://registry.npmjs.org/"
117
117
  },
118
118
  "optionalDependencies": {
119
- "@antelopejs/interface-dms-automation": ">=0.2.1 <1.0.0",
119
+ "@antelopejs/interface-dms-automation": ">=0.4.0 <1.0.0",
120
120
  "@antelopejs/interface-redis": ">=0.0.9 <1.0.0"
121
121
  },
122
122
  "peerDependencies": {
123
- "@antelopejs/core": ">=1.16.0 <2"
123
+ "@antelopejs/core": ">=1.17.0 <2"
124
124
  },
125
125
  "peerDependenciesMeta": {
126
126
  "@antelopejs/core": {
@@ -145,6 +145,7 @@
145
145
  "knip:all": "knip",
146
146
  "docs:catalog": "node scripts/docs-catalog.mjs",
147
147
  "docs:catalog:check": "node scripts/docs-catalog.mjs --check",
148
- "docs:screenshots": "node scripts/docs-screenshots.mjs"
148
+ "docs:screenshots": "node scripts/docs-screenshots.mjs",
149
+ "realtime:tabs-check": "node scripts/realtime-tabs-check.mjs"
149
150
  }
150
151
  }
@@ -34,7 +34,7 @@ skill (shipped with `@antelopejs/core`).
34
34
  `pageRoutePath(slug, route)`); a plain `Controller` the frontend calls sits under
35
35
  `/api/<module>/`. A URL names the page's record with `{{params.id}}` /
36
36
  `{{query.X}}`; `periodScope` binds a block to a `PeriodSelector`; `realtimeTopic` re-fetches on a
37
- `PublishMessage`. Texts are `$` i18n keys or `ComposedText`, never formatted server-side.
37
+ `PublishMessage` (publish tenant data with `{ tenantId }`). Texts are `$` i18n keys or `ComposedText`, never formatted server-side.
38
38
  - **It's interfaces all the way down.** Everything you consume is imported from an
39
39
  `@antelopejs/interface-dms/...` subpath; a distributable module exposes its own API from a companion
40
40
  `@antelopejs/interface-<name>` package listed in `antelopeJs.implements`.
@@ -78,7 +78,7 @@ RegisterPermission("cookbook.edit", {
78
78
  title: "$dms_cookbook.perm.edit", // i18n key — add to every locale file
79
79
  icon: "i-ph-pencil",
80
80
  defaultGranted: false,
81
- // dependencies: ["cookbook.view"], // declarative metadata only — not enforced or auto-granted
81
+ // dependencies: ["cookbook.view"], // enforced by HasPermission; granted with it by the roles editor and on save
82
82
  });
83
83
  ```
84
84
 
@@ -86,7 +86,9 @@ Then gate with `@AuthUserWithPermission(...)` or the page/component permission o
86
86
  check imperatively, use `dms/permissions`: `GetEffectiveUserPermissions`, `HasPermission`,
87
87
  `GetPermission` / `GetPermissions` (`GetUserPermissions` for the base set). Two extension
88
88
  points reshape the model: `RegisterPermissionsResolver` (`dms/permissions-resolver`) rewrites
89
- a user's effective set, and `RegisterTenantAccessGate` (`dms/tenant-access`, checked via
89
+ a user's effective set (the role preview also runs it, with `context.preview` set on the
90
+ resolver's fourth argument and the viewer's user id: shape the set as for an ordinary
91
+ member there, never from the viewer's standing), and `RegisterTenantAccessGate` (`dms/tenant-access`, checked via
90
92
  `CheckTenantAccess` / `AssertTenantAccess`) can block a whole tenant. The `dms/guards`
91
93
  decorators also run the tenant access gate; routes that must stay reachable for a denied
92
94
  tenant (billing, recovery) opt out with `@AuthTenantOwner({ bypassTenantAccessGate: true })`.
@@ -102,7 +104,7 @@ there too); `RoleModel`, `UserInviteModel`, `TenantModel`, `TenantMemberModel` u
102
104
  The DMS is **multi-tenant by default** (single-tenant apps live in the `default` tenant).
103
105
  Primitives, covered in `docs/03.auth-and-tenancy/03.multi-tenant.md`: `@TenantScopedModel`
104
106
  (`dms/tenant-scoped-model`) scopes a model to the request's tenant, `getRequestTenantId`
105
- (`dms/request-tenant`) reads it, `applyTenantOwnership`
107
+ (`dms/request-tenant`) reads it (the verified credential's tenant, `default` without one), `applyTenantOwnership`
106
108
  (`dms/tenant-ownership`) upserts a user's tenant membership (roles + owner flag),
107
109
  `inviteUserToTenant` (`dms/invites`, expiry `INVITE_EXPIRY_DAYS`), and `CROSS_INSTANCE`
108
110
  (`@antelopejs/interface-database`) for cross-tenant queries. SaaS mode (Stripe billing,
@@ -13,11 +13,13 @@ Material for [SKILL.md](SKILL.md): mapping design elements to DMS blocks, the `P
13
13
  | Ranked list, leaderboard | `TopListCard` | Bar position, rank badge style |
14
14
  | Date range picker | `PeriodSelector` (`variant: "segmented"` for pills) | Preset labels |
15
15
  | Live / pause switch | `LiveToggle` | Pill vs segmented |
16
+ | Context bar of a page with a period or live data | `pageToolbar()` (a `PageToolbar` holding the `LiveToggle` and `PeriodSelector`) | Leading blocks, `size` |
16
17
  | Table, list with actions | `TableView` over a DataController (`displays` for cards / kanban) | Column widths, row height (`density`) |
17
18
  | Detail facts of a record | `KeyValueList` | Value alignment |
18
19
  | Recent events, audit log | `ActivityFeed` | Day separators vs relative times |
19
20
  | Usage bar, quota | `Meter` | Bar thickness (`size`) |
20
21
  | Notice, alert strip | `Banner` | Wash vs flat background |
22
+ | Strip under the dashboard header, across pages | `RegisterLayoutBanner` (backend): the app's pages by default, `scope: "everywhere"` for a workspace-wide state | Not inside `/modules` unless scoped `everywhere` |
21
23
  | Empty / first-run screen | `EmptyState` (or `Guard` around blocks) | Illustration vs icon well |
22
24
  | Links to sub-pages as cards | `NavCardGrid` | Card height |
23
25
  | Code snippet | `CodeBlock` | Theme of the highlighting |
@@ -73,5 +73,9 @@ The protocol is done when every visibly different component has an answer and ev
73
73
 
74
74
  - Every page field and child is a DMS block, except custom blocks the user chose through the path.
75
75
  - Every `CustomComponent` has `.meta({ name, description, icon })` with `$` keys present in every locale file.
76
+ - Every automation node a module registers names itself, its description and each schema property's `title` and `description` with `$` keys present in every locale file (`docs/02.building/06.backend-services.md`, Texts in the builder).
77
+ - An automation action with side effects (email, notification, write) declares `dryRun(input, ctx)`: it checks the input as `execute` would and acts on nothing, so a builder Test run sends nothing (`docs/02.building/06.backend-services.md`, Test runs).
78
+ - Locale values escape vue-i18n's special characters as literals (`{'@'}`, `{'{'}`, `{'}'}`, `{'|'}`): a raw `@` or brace breaks the message's compilation (`docs/02.building/07.localization.md`, Special characters).
76
79
  - Data comes from routes (`fetchUrl`) rather than options computed at registration; a custom block reads its route with `useApiData` (server-rendered, refreshed with the page) and writes with `$authFetch`.
80
+ - Publish tenant data with the tenant id: a `PublishMessage` about one workspace's data passes `{ tenantId }`, or it wakes the page of every workspace.
77
81
  - Verified live with **dms-project** (the build only typechecks `src/`).
@@ -85,7 +85,7 @@ module's frontend; without it the module is backend-only.
85
85
 
86
86
  `renderer` names the framework (Vue 3), not a loader release. The `@antelopejs/dms-frontend`
87
87
  releases the frontend module runs on go in the frontend module's own `package.json`, as
88
- `"engines": { "@antelopejs/dms-frontend": ">=0.6.0 <0.7.0" }`: the loader refuses the module
88
+ `"engines": { "@antelopejs/dms-frontend": ">=0.9.0 <0.10.0" }`: the loader refuses the module
89
89
  outside that range. Cap it below the next loader minor while the loader is 0.x.
90
90
 
91
91
  An absolute link (a public file, a snippet to copy, a mail) is built on `await GetApiBaseUrl()`
@@ -103,7 +103,8 @@ module root** (nest under what `RegisterModule` returned, or rely on `defaultCat
103
103
  module pages cannot use the Settings category, and the module must exist before a page names
104
104
  it. Pages resolve at `/modules/<moduleId>/<urlSlug>`; entering the module lands on
105
105
  `landingPage` if set, else the first page by `order` — `/modules/<id>` itself redirects there (server
106
- redirect, query and hash kept), so never register a hidden page to forward it. Access is **owner-only by design**: the
106
+ redirect, query and hash kept), so never register a hidden page to forward it. `store` is not a
107
+ module id to take: `/modules/store` is the DMS's module store. Access is **owner-only by design**: the
107
108
  Modules group is visible to the platform owner alone (the `*` holder), and the
108
109
  `modules.<moduleId>.…` permission ids are module-scoped — never grantable through Roles. On a
109
110
  SaaS deployment that means you, the maker, not your customers; a screen for end users belongs