@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
@@ -4,7 +4,9 @@ import { holdPageHeaderActions } from "../composables/layout/usePageHeaderAction
4
4
  import { useDevReloading } from "../build/composables/dev-reload/useDevReloadHolder";
5
5
  import { usePageLiveHost } from "#dms-ui/app/build/composables/live/usePageLiveHost";
6
6
  import { usePageDataRefresh } from "#dms-ui/app/build/composables/live/usePageDataRefresh";
7
+ import { usePageRecordDeletion } from "../composables/page/usePageRecordDeletion";
7
8
  import { pageValidationRedirect } from "../build/utils/pageValidationRedirect";
9
+ import { resolveComponentChildren } from "#dms-ui/app/utils/componentTree";
8
10
 
9
11
  defineOptions({ inheritAttrs: false });
10
12
 
@@ -215,9 +217,10 @@ if (import.meta.env.DEV) {
215
217
 
216
218
  const { pageLayout } = await usePageLayout();
217
219
 
218
- watch(pageLayout, (layout) => preloadPageLayoutComponents(layout), {
219
- immediate: true,
220
- });
220
+ // A client navigation shows the page once its blocks' code is there: a lazy
221
+ // block draws nothing until its chunk lands, then pushes the page down.
222
+ await preloadPageLayoutComponents(pageLayout.value);
223
+ watch(pageLayout, (layout) => void preloadPageLayoutComponents(layout));
221
224
 
222
225
  const { refreshIfStale: refreshPermissionsIfStale } = usePermissions();
223
226
 
@@ -249,6 +252,12 @@ usePageLiveHost(
249
252
  );
250
253
  // The page's `useApiData` reads follow its refreshes and its realtime events.
251
254
  usePageDataRefresh(realtime);
255
+ // A detail page leaves for its list once its record is deleted.
256
+ usePageRecordDeletion({
257
+ pageLayout: () => pageLayout.value,
258
+ pageTopics: realtime.pageTopics,
259
+ subscribe: realtime.subscribe,
260
+ });
252
261
 
253
262
  function buildPageSetupContext(
254
263
  pageInfo: PageInfo,
@@ -345,24 +354,6 @@ watch(
345
354
  onMounted(runPageSetup);
346
355
  onUnmounted(tearDownPageSetup);
347
356
 
348
- const processChildren = (
349
- children: ComponentChild[],
350
- ): ResolvedComponentInfo[] => {
351
- return children.map((child) => {
352
- const { id, component, ...additionalProps } = child;
353
- return {
354
- id,
355
- options: component.options,
356
- component: component.componentName
357
- ? resolveDmsComponent(component.componentName) || "div"
358
- : "div",
359
- componentName: component.componentName,
360
- children: component.children ? processChildren(component.children) : [],
361
- ...additionalProps,
362
- };
363
- });
364
- };
365
-
366
357
  const components = computed(() =>
367
358
  Object.keys(pageLayout.value?.components || {}).map((field) => {
368
359
  const componentInfo = pageLayout.value?.components[field];
@@ -374,7 +365,7 @@ const components = computed(() =>
374
365
  : "div",
375
366
  componentName: componentInfo?.componentName,
376
367
  children: componentInfo?.children
377
- ? processChildren(componentInfo.children)
368
+ ? resolveComponentChildren(componentInfo.children)
378
369
  : [],
379
370
  } as ResolvedComponentInfo;
380
371
  }),
@@ -13,16 +13,17 @@ function isHiddenFromNavigation(node: SiteLayoutTree): boolean {
13
13
  function collectNavigationItems(
14
14
  node: SiteLayoutTree,
15
15
  ancestors: string[],
16
- translate: I18nTranslate,
16
+ translation: AppTranslation,
17
17
  items: CommandPaletteItem[],
18
18
  ): void {
19
19
  for (const childId of node.childrenOrders) {
20
20
  const child = node.children[childId];
21
21
  if (!child || isHiddenFromNavigation(child)) continue;
22
22
 
23
- const label = resolveI18nKey(translate, child.displayName);
23
+ const label = translation.processI18n(child.displayName);
24
24
  const to = buildMenuItemTarget(child);
25
- if (to && child.fullSlug) {
25
+ // The account entries (Settings, Profile) are the session group's.
26
+ if (to && child.fullSlug && !isAccountMenuRoute(to)) {
26
27
  items.push({
27
28
  label,
28
29
  suffix:
@@ -32,40 +33,40 @@ function collectNavigationItems(
32
33
  icon: child.icon ?? DEFAULT_PAGE_ICON,
33
34
  to,
34
35
  [COMMAND_PALETTE_SEARCH_TEXT_KEY]: resolveOptionalI18nKey(
35
- translate,
36
+ translation.t,
36
37
  child.description,
37
38
  ),
38
39
  });
39
40
  }
40
- collectNavigationItems(child, [...ancestors, label], translate, items);
41
+ collectNavigationItems(child, [...ancestors, label], translation, items);
41
42
  }
42
43
  }
43
44
 
44
45
  function buildNavigationGroups(
45
46
  tree: SiteLayoutTree | undefined,
46
- translate: I18nTranslate,
47
+ translation: AppTranslation,
47
48
  ): CommandPaletteGroup[] {
48
49
  if (!tree) return [];
49
50
 
50
51
  const items: CommandPaletteItem[] = [];
51
- collectNavigationItems(tree, [], translate, items);
52
+ collectNavigationItems(tree, [], translation, items);
52
53
  if (items.length === 0) return [];
53
54
 
54
55
  return [
55
56
  {
56
57
  id: NAVIGATION_GROUP_ID,
57
- label: translate("commandPalette.groups.navigation", {}),
58
+ label: translation.t("commandPalette.groups.navigation"),
58
59
  items,
59
60
  },
60
61
  ];
61
62
  }
62
63
 
63
64
  export default defineDmsPlugin(() => {
64
- const { translate } = getPluginI18n();
65
+ const translation = getAppTranslation();
65
66
  const { siteLayoutTree } = useSiteLayout();
66
67
 
67
68
  const groups = computed<CommandPaletteGroup[]>(() =>
68
- buildNavigationGroups(siteLayoutTree.value, translate),
69
+ buildNavigationGroups(siteLayoutTree.value, translation),
69
70
  );
70
71
 
71
72
  registerCommandPaletteSource({
@@ -1,90 +1,60 @@
1
- import type { CommandPaletteGroup, CommandPaletteItem } from "@nuxt/ui";
1
+ import type { CommandPaletteGroup } from "@nuxt/ui";
2
+ import {
3
+ type RecentModule,
4
+ recentModules,
5
+ } from "../build/utils/modules-catalog";
2
6
 
3
7
  const PERSONAL_PAGES_SOURCE_ID = "dms-personal-pages";
4
8
  const PERSONAL_PAGES_SOURCE_ORDER = 20;
5
9
  const FAVORITES_GROUP_ID = "favorite-pages";
6
10
  const RECENT_MODULES_GROUP_ID = "recent-modules";
7
11
 
8
- type AccessibleModules = Record<string, ModuleWithAccess> | undefined;
9
-
10
- type PathLabelResolver = (path: string) => string | undefined;
11
-
12
12
  function buildFavoritesGroup(
13
13
  favorites: FavoritePage[],
14
- translate: I18nTranslate,
14
+ translation: AppTranslation,
15
15
  ): CommandPaletteGroup | null {
16
16
  if (favorites.length === 0) return null;
17
17
 
18
18
  return {
19
19
  id: FAVORITES_GROUP_ID,
20
- label: translate("menu.favorites", {}),
20
+ label: translation.t("menu.favorites"),
21
21
  items: favorites.map((favorite) => ({
22
- label: resolveI18nKey(translate, favorite.title),
22
+ label: translation.processI18n(favorite.title),
23
23
  icon: favorite.icon ?? DEFAULT_PAGE_ICON,
24
24
  to: favorite.path,
25
25
  })),
26
26
  };
27
27
  }
28
28
 
29
- function buildRecentModuleItem(
30
- entry: ModuleHistoryEntry,
31
- modules: AccessibleModules,
32
- translate: I18nTranslate,
33
- resolvePathLabel: PathLabelResolver,
34
- ): CommandPaletteItem | null {
35
- const module = modules?.[entry.moduleId];
36
- if (!module?.hasAccess) return null;
37
-
38
- return {
39
- label: resolveI18nKey(translate, module.title),
40
- suffix: resolvePathLabel(entry.path),
41
- icon: module.icon,
42
- to: entry.path,
43
- };
44
- }
45
-
46
29
  function buildRecentModulesGroup(
47
- entries: ModuleHistoryEntry[],
48
- modules: AccessibleModules,
49
- translate: I18nTranslate,
50
- resolvePathLabel: PathLabelResolver,
30
+ modules: RecentModule[],
31
+ translation: AppTranslation,
51
32
  ): CommandPaletteGroup | null {
52
- const items = entries
53
- .slice()
54
- .reverse()
55
- .map((entry) =>
56
- buildRecentModuleItem(entry, modules, translate, resolvePathLabel),
57
- )
58
- .filter((item): item is CommandPaletteItem => item !== null);
59
- if (items.length === 0) return null;
33
+ if (modules.length === 0) return null;
60
34
 
61
35
  return {
62
36
  id: RECENT_MODULES_GROUP_ID,
63
- label: translate("commandPalette.groups.recentModules", {}),
64
- items,
37
+ label: translation.t("commandPalette.groups.recentModules"),
38
+ items: modules.map((module) => ({
39
+ label: translation.processI18n(module.title),
40
+ icon: module.icon,
41
+ to: module.to,
42
+ })),
65
43
  };
66
44
  }
67
45
 
68
46
  export default defineDmsPlugin(() => {
69
- const { translate } = getPluginI18n();
47
+ const translation = getAppTranslation();
70
48
  const { sortedFavorites } = useFavoritePages();
71
49
  const { entries } = useModuleHistory();
72
- const { modules, findMatchingRoute } = useSiteLayout();
73
-
74
- const resolvePathLabel: PathLabelResolver = (path) => {
75
- const match = findMatchingRoute(path);
76
- if (!match) return undefined;
77
- return resolveI18nKey(translate, match.metadata.displayName);
78
- };
50
+ const { modules, siteLayoutTree } = useSiteLayout();
79
51
 
80
52
  const groups = computed<CommandPaletteGroup[]>(() =>
81
53
  [
82
- buildFavoritesGroup(sortedFavorites.value, translate),
54
+ buildFavoritesGroup(sortedFavorites.value, translation),
83
55
  buildRecentModulesGroup(
84
- entries.value,
85
- modules.value,
86
- translate,
87
- resolvePathLabel,
56
+ recentModules(entries.value, modules.value, siteLayoutTree.value),
57
+ translation,
88
58
  ),
89
59
  ].filter((group): group is CommandPaletteGroup => group !== null),
90
60
  );
@@ -6,10 +6,10 @@ const QUICK_ACTIONS_GROUP_PREFIX = "quick-actions";
6
6
 
7
7
  function buildActionItem(
8
8
  action: QuickActionInfo,
9
- translate: I18nTranslate,
9
+ translation: AppTranslation,
10
10
  ): CommandPaletteItem {
11
11
  return {
12
- label: resolveI18nKey(translate, action.displayName),
12
+ label: translation.processI18n(action.displayName),
13
13
  icon: action.icon,
14
14
  onSelect: () => {
15
15
  void dispatchQuickActionTarget(action.target);
@@ -19,21 +19,21 @@ function buildActionItem(
19
19
 
20
20
  function buildQuickActionGroups(
21
21
  categoryGroups: QuickActionCategoryGroup[],
22
- translate: I18nTranslate,
22
+ translation: AppTranslation,
23
23
  ): CommandPaletteGroup[] {
24
24
  return categoryGroups.map((group) => ({
25
25
  id: `${QUICK_ACTIONS_GROUP_PREFIX}-${group.category.id}`,
26
- label: resolveI18nKey(translate, group.category.displayName),
27
- items: group.actions.map((action) => buildActionItem(action, translate)),
26
+ label: translation.processI18n(group.category.displayName),
27
+ items: group.actions.map((action) => buildActionItem(action, translation)),
28
28
  }));
29
29
  }
30
30
 
31
31
  export default defineDmsPlugin(() => {
32
- const { translate } = getPluginI18n();
32
+ const translation = getAppTranslation();
33
33
  const { categoryGroups } = useQuickActions();
34
34
 
35
35
  const groups = computed<CommandPaletteGroup[]>(() =>
36
- buildQuickActionGroups(categoryGroups.value, translate),
36
+ buildQuickActionGroups(categoryGroups.value, translation),
37
37
  );
38
38
 
39
39
  registerCommandPaletteSource({
@@ -22,16 +22,17 @@ function uniqueByCode<T extends LocaleOption>(locales: T[]): T[] {
22
22
  });
23
23
  }
24
24
 
25
- function buildAccountItems(translate: I18nTranslate): CommandPaletteItem[] {
25
+ function buildAccountItems(t: AppTranslation["t"]): CommandPaletteItem[] {
26
26
  return ACCOUNT_MENU_ENTRIES.map((entry) => ({
27
- label: translate(entry.labelKey, {}),
27
+ label: t(entry.labelKey),
28
28
  icon: entry.icon,
29
29
  to: entry.to,
30
30
  }));
31
31
  }
32
32
 
33
33
  export default defineDmsPlugin(() => {
34
- const { i18n, translate } = getPluginI18n();
34
+ const { $i18n: i18n } = useDmsApp();
35
+ const { t } = getAppTranslation();
35
36
  const toast = useToast();
36
37
  const { logout } = useLogout();
37
38
  const { changeLanguage } = useUserLanguage();
@@ -49,10 +50,10 @@ export default defineDmsPlugin(() => {
49
50
  async function copyCurrentUrl(): Promise<void> {
50
51
  try {
51
52
  await copy(window.location.href);
52
- toast.add({ title: translate("commandPalette.session.urlCopied", {}) });
53
+ toast.add({ title: t("commandPalette.session.urlCopied") });
53
54
  } catch {
54
55
  toast.add({
55
- title: translate("commandPalette.session.copyFailed", {}),
56
+ title: t("commandPalette.session.copyFailed"),
56
57
  color: "error",
57
58
  });
58
59
  }
@@ -61,23 +62,23 @@ export default defineDmsPlugin(() => {
61
62
  function buildSessionGroup(): CommandPaletteGroup {
62
63
  return {
63
64
  id: SESSION_GROUP_ID,
64
- label: translate("commandPalette.groups.session", {}),
65
+ label: t("commandPalette.groups.session"),
65
66
  items: [
66
- ...buildAccountItems(translate),
67
+ ...buildAccountItems(t),
67
68
  {
68
- label: translate("commandPalette.session.changeLanguage", {}),
69
+ label: t("commandPalette.session.changeLanguage"),
69
70
  icon: LANGUAGE_ICON,
70
71
  children: localeItems(),
71
72
  },
72
73
  {
73
- label: translate("commandPalette.session.copyUrl", {}),
74
+ label: t("commandPalette.session.copyUrl"),
74
75
  icon: COPY_URL_ICON,
75
76
  onSelect: () => {
76
77
  void copyCurrentUrl();
77
78
  },
78
79
  },
79
80
  {
80
- label: translate("button.logout", {}),
81
+ label: t("button.logout"),
81
82
  icon: LOGOUT_ICON,
82
83
  onSelect: () => {
83
84
  void logout();
@@ -1,5 +1,5 @@
1
1
  import { useDevReloadHolder } from "../build/composables/dev-reload/useDevReloadHolder";
2
- import { openDevReloadStream } from "../build/utils/dev-reload-stream";
2
+ import { followDevReload } from "../build/utils/dev-reload-stream";
3
3
 
4
4
  const RELOAD_ENDPOINT_PATH = "/dms/dev/reload";
5
5
 
@@ -11,7 +11,7 @@ function resolveBackendBase(): string | null {
11
11
  }
12
12
 
13
13
  /**
14
- * Dev-only: turn the backend's `reload` stream into a soft refresh.
14
+ * Dev-only: turn the backend's reload signal into a soft refresh.
15
15
  *
16
16
  * All the waiting lives in the dev-reload coordinator (see `useDevReloadHolder`), so
17
17
  * this plugin and the `useDevReload().awaitRoute` module frontends call
@@ -25,14 +25,19 @@ export default defineDmsPlugin(() => {
25
25
 
26
26
  const endpoint = `${backendBase}${RELOAD_ENDPOINT_PATH}`;
27
27
  const { coordinator } = useDevReloadHolder();
28
- const stream = openDevReloadStream({
29
- endpoint,
30
- onReload: () => {
31
- void coordinator.requestRefresh().catch((err: unknown) => {
32
- console.error("[dms-dev-reload] Reload handler failed:", err);
33
- });
28
+ // Carried by the user's realtime stream while it is open, by a stream of
29
+ // its own otherwise (the sign-in page).
30
+ const stream = followDevReload(
31
+ {
32
+ endpoint,
33
+ onReload: () => {
34
+ void coordinator.requestRefresh().catch((err: unknown) => {
35
+ console.error("[dms-dev-reload] Reload handler failed:", err);
36
+ });
37
+ },
34
38
  },
35
- });
39
+ useUserRealtime(),
40
+ );
36
41
 
37
42
  if (import.meta.hot) {
38
43
  import.meta.hot.dispose(() => {
@@ -330,14 +330,15 @@ const tabsTheme = {
330
330
  trigger: "data-[state=active]:font-semibold",
331
331
  // Counts as mono chips, tinted with the accent on the active tab.
332
332
  trailingBadge:
333
- "font-mono text-[10.5px] h-4 px-[5px] rounded-[4px] ring-0 bg-elevated text-dimmed group-data-[state=active]:bg-(--dms-accent-tint) group-data-[state=active]:text-primary",
333
+ "font-mono text-[10.5px] h-4 px-[5px] rounded-(--dms-radius-tab-badge) ring-0 bg-elevated text-dimmed group-data-[state=active]:bg-(--dms-accent-tint) group-data-[state=active]:text-primary",
334
334
  },
335
335
  variants: {
336
336
  variant: {
337
337
  pill: {
338
- list: "bg-(--dms-bg-muted) ring ring-inset ring-default p-[3px] gap-0.5 rounded-[10px]",
339
- indicator: "ring ring-accented shadow-(--shadow-sm) rounded-[7px]",
340
- trigger: "rounded-[7px] before:rounded-[7px]",
338
+ list: "bg-(--dms-bg-muted) ring ring-inset ring-default p-[3px] gap-0.5 rounded-(--dms-radius-tab-list)",
339
+ indicator:
340
+ "ring ring-accented shadow-(--shadow-sm) rounded-(--dms-radius-tab)",
341
+ trigger: "rounded-(--dms-radius-tab) before:rounded-(--dms-radius-tab)",
341
342
  },
342
343
  },
343
344
  // A vertical list sits at the top of its panel, not centred beside it.
@@ -117,11 +117,16 @@ const inputTheme = {
117
117
  ],
118
118
  };
119
119
 
120
- /** Select-like triggers: the input scale with explicit line heights. */
120
+ /**
121
+ * Select-like triggers: the input scale with explicit line heights, so a
122
+ * select is as tall as the text field beside it. Below md they keep the
123
+ * input's 16px (14px for sm), as a text field does, so a form on a phone
124
+ * reads in one size.
125
+ */
121
126
  const SELECT_TRIGGER_SIZES = {
122
- sm: { base: "px-2 text-[12.5px]/4" },
123
- md: { base: "text-[13px]/5" },
124
- xl: { base: "text-[15px]/6" },
127
+ sm: { base: "px-2 text-sm/4 md:text-[12.5px]/4" },
128
+ md: { base: "text-base/5 md:text-[13px]/5" },
129
+ xl: { base: "text-base/6 md:text-[15px]/6" },
125
130
  };
126
131
 
127
132
  /**
@@ -9,6 +9,10 @@
9
9
  */
10
10
 
11
11
  import { EYEBROW_CLASS } from "#dms-ui/app/build/utils/eyebrow";
12
+ import {
13
+ CLOSING_OVERLAY_CLASS,
14
+ UNCOVERED_PANEL_CLASS,
15
+ } from "#dms-ui/app/build/components/containers/constants";
12
16
 
13
17
  /** Floating panels (menus, popovers, toasts): accented hairline and the pop shadow. */
14
18
  const FLOATING_SURFACE =
@@ -18,7 +22,15 @@ const FLOATING_SURFACE =
18
22
  const OVERLAY_SURFACE =
19
23
  "bg-default ring-(--dms-border-top) shadow-(--dms-shadow-modal)";
20
24
 
21
- const BACKDROP = "bg-(--dms-overlay) backdrop-blur-[2px]";
25
+ /**
26
+ * Every modal, slideover and drawer, the DMS's or a module's: its backdrop
27
+ * lets clicks through as soon as it starts closing and fades out quickly,
28
+ * and the panel animating out no longer catches them either (reka keeps
29
+ * `pointer-events: auto` inline on both). The panel a closing dialog
30
+ * uncovered (a drawer under a confirm) takes clicks again at once.
31
+ */
32
+ const BACKDROP = `bg-(--dms-overlay) backdrop-blur-[2px] ${CLOSING_OVERLAY_CLASS}`;
33
+ const CLOSING_PANEL = `data-[state=closed]:pointer-events-none! ${UNCOVERED_PANEL_CLASS}`;
22
34
 
23
35
  const cardTheme = {
24
36
  slots: {
@@ -90,7 +102,7 @@ const tooltipTheme = {
90
102
 
91
103
  const modalTheme = {
92
104
  slots: {
93
- content: "bg-default divide-y-0",
105
+ content: `bg-default divide-y-0 ${CLOSING_PANEL}`,
94
106
  header: "items-start gap-3 min-h-0 px-5 pt-[18px] pb-0 sm:px-5",
95
107
  title: "text-[17px] leading-[1.3] font-[650] tracking-[-0.02em]",
96
108
  description: "mt-1 text-[13px]",
@@ -116,7 +128,7 @@ const modalTheme = {
116
128
  const slideoverTheme = {
117
129
  slots: {
118
130
  overlay: BACKDROP,
119
- content: `${OVERLAY_SURFACE} sm:shadow-(--dms-shadow-modal)`,
131
+ content: `${OVERLAY_SURFACE} sm:shadow-(--dms-shadow-modal) ${CLOSING_PANEL}`,
120
132
  header: "px-5 sm:px-5",
121
133
  title: "text-[17px] leading-[1.3] font-[650] tracking-[-0.02em]",
122
134
  description: "text-[13px]",
@@ -138,7 +150,7 @@ const DRAWER_EDGE_COMPOUNDS = [
138
150
  const drawerTheme = {
139
151
  slots: {
140
152
  overlay: BACKDROP,
141
- content: OVERLAY_SURFACE,
153
+ content: `${OVERLAY_SURFACE} ${CLOSING_PANEL}`,
142
154
  },
143
155
  compoundVariants: DRAWER_EDGE_COMPOUNDS,
144
156
  };
@@ -178,7 +190,10 @@ const toastTheme = {
178
190
  * New toasts rise 16px into place instead of sliding in from a full toast
179
191
  * height below: that slide started off-screen, so a toast whose animation
180
192
  * had not run yet (background tab, throttled frame) sat cut off under the
181
- * bottom edge.
193
+ * bottom edge. A bottom stack rises above a save bar on the bottom edge (the
194
+ * floating bar, a drawer's footer band): the bar sets how far it reaches
195
+ * (`--dms-toaster-clearance`, see `toasterClearance.ts`), so a toast never
196
+ * covers its buttons, and the stack drops back once the bar hides.
182
197
  */
183
198
  const toasterTheme = {
184
199
  slots: {
@@ -203,7 +218,8 @@ const toasterTheme = {
203
218
  {
204
219
  position: ["bottom-left", "bottom-center", "bottom-right"],
205
220
  class: {
206
- viewport: "bottom-5",
221
+ viewport:
222
+ "bottom-[calc(var(--dms-toaster-clearance,0px)+1.25rem)] transition-[bottom] duration-200 ease-out motion-reduce:transition-none",
207
223
  base: "data-[state=open]:animate-none starting:translate-y-4",
208
224
  },
209
225
  },
@@ -10,6 +10,9 @@ export type StoreModuleState =
10
10
  | "error"
11
11
  | "pending";
12
12
 
13
+ /** Where a module's code comes from (`ModuleSourceKind` on the backend). */
14
+ export type ModuleSourceKind = "npm" | "github" | "gitlab" | "git" | "local";
15
+
13
16
  export type StoreFrontendState = "none" | "synced" | "pending" | "unknown";
14
17
 
15
18
  export type StoreOperationKind =
@@ -86,6 +89,10 @@ export interface StoreListingEntry {
86
89
  description: string;
87
90
  state: StoreModuleState;
88
91
  installedVersion?: string;
92
+ /** Where its code comes from. */
93
+ source: ModuleSourceKind;
94
+ /** Runs from a local or git working copy: active, but no store action. */
95
+ isWorkingCopy?: boolean;
89
96
  /** The version range antelope.config.ts declares. */
90
97
  declaredRange?: string;
91
98
  latestVersion?: string;
@@ -103,6 +110,8 @@ export interface StoreListingEntry {
103
110
  missingInterfaces: MissingInterface[];
104
111
  /** Running modules that need an interface only this one implements. */
105
112
  dependents: string[];
113
+ /** The project's own code needs an interface only this module implements. */
114
+ usedByProject: boolean;
106
115
  }
107
116
 
108
117
  export interface StoreListing {
@@ -1,6 +1,7 @@
1
1
  import type { BlockText } from "#dms-core/app/types/composed-text";
2
2
  import type { BlockAction } from "#dms-ui/app/build/components/blocks/BlockActions.vue";
3
3
  import type { PageLiveOptions } from "#dms-ui/app/types/live";
4
+ import type { ModuleSourceKind } from "./module-store";
4
5
 
5
6
  export type MenuItemType = "label" | "link";
6
7
  // MenuItemVariant / MenuItemStatus / MenuItemQuery live in dms-core, the layer
@@ -88,12 +89,19 @@ export type ModuleCatalogEntry = ModuleWithAccess & {
88
89
  landingSlug: string;
89
90
  status?: ModuleStatus;
90
91
  readout?: ModuleReadoutLine[];
92
+ /**
93
+ * Where its code comes from, read from the module store; absent for a
94
+ * module the store does not list.
95
+ */
96
+ source?: ModuleSourceKind;
91
97
  };
92
98
 
93
99
  export const MODULE_URL_PREFIX = "/modules";
94
100
 
95
101
  export interface PageInfo extends Omit<CategoryInfo, "category"> {
96
102
  layoutUrl: string;
103
+ /** Full slug of the page this one is a detail of (`MenuOptions.parent`). */
104
+ parentSlug?: string;
97
105
  }
98
106
 
99
107
  export type SiteLayoutTree = Omit<PageInfo, "layoutUrl"> & {
@@ -107,15 +115,21 @@ export type SiteLayoutTree = Omit<PageInfo, "layoutUrl"> & {
107
115
  // Mirror of LayoutBannerVariant from @antelopejs/interface-dms/layout-banners.
108
116
  export type LayoutBannerVariant = "info" | "warning" | "error";
109
117
 
118
+ // Mirror of LayoutBannerScope from @antelopejs/interface-dms/layout-banners.
119
+ export type LayoutBannerScope = "app" | "modules" | "everywhere";
120
+
110
121
  /**
111
122
  * Mirror of the backend's serialized layout banner. The payload only carries
112
123
  * the banners whose visibility resolver passed for this request, so there is
113
- * nothing left to decide here but the user's own dismissals.
124
+ * nothing left to decide here but the current route against `scope` and the
125
+ * user's own dismissals.
114
126
  */
115
127
  export interface LayoutBanner {
116
128
  key: string;
117
129
  variant: LayoutBannerVariant;
118
130
  order: number;
131
+ /** The pages it shows on, the backend's `app` unless it says otherwise. */
132
+ scope: LayoutBannerScope;
119
133
  dismissible: boolean;
120
134
  icon?: string;
121
135
  /** A string (`$` for an i18n key) or a composed text. */
@@ -5,6 +5,8 @@ export interface AccountMenuEntry {
5
5
  }
6
6
 
7
7
  export const PROFILE_ROUTE = "/settings/user/profile";
8
+ // The account menu is the only way to the settings: the sidebar footer has no
9
+ // Settings entry, so this one opens all of them, not just the user's own.
8
10
  export const SETTINGS_ROUTE = "/settings";
9
11
  export const SWITCH_ACCOUNT_ROUTE = "/auth/accounts";
10
12
 
@@ -26,3 +28,12 @@ export const ACCOUNT_MENU_ENTRIES: AccountMenuEntry[] = [
26
28
  to: SWITCH_ACCOUNT_ROUTE,
27
29
  },
28
30
  ];
31
+
32
+ /**
33
+ * Whether `to` is the destination of an account menu entry. The command
34
+ * palette lists those entries in its session group, so its navigation group
35
+ * skips their pages instead of offering the same destination twice.
36
+ */
37
+ export function isAccountMenuRoute(to: string): boolean {
38
+ return ACCOUNT_MENU_ENTRIES.some((entry) => entry.to === to);
39
+ }