@antelopejs/dms 0.9.7 → 0.10.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 (414) hide show
  1. package/CHANGELOG.md +114 -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 -0
  21. package/dist/config.js +5 -3
  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 +22 -89
  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 +1 -2
  41. package/dist/implementations/dms/manifest.js +2 -0
  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 +28 -45
  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/realtime.d.ts +13 -1
  117. package/dist/routes/realtime.js +114 -29
  118. package/dist/routes/realtime.js.map +1 -1
  119. package/dist/startup-config.d.ts +2 -0
  120. package/dist/startup-config.js +62 -0
  121. package/dist/startup-config.js.map +1 -0
  122. package/dist/store/interfaces.d.ts +3 -2
  123. package/dist/store/interfaces.js +16 -6
  124. package/dist/store/interfaces.js.map +1 -1
  125. package/dist/store/listing.js +24 -13
  126. package/dist/store/listing.js.map +1 -1
  127. package/dist/store/operations.js +4 -0
  128. package/dist/store/operations.js.map +1 -1
  129. package/dist/store/requirements.js +3 -2
  130. package/dist/store/requirements.js.map +1 -1
  131. package/dist/store/runtime.d.ts +10 -1
  132. package/dist/store/runtime.js +33 -6
  133. package/dist/store/runtime.js.map +1 -1
  134. package/dist/store/types.d.ts +10 -0
  135. package/dist/validation/auth.schema.d.ts +2 -2
  136. package/dist/validation/member-invite.schema.d.ts +2 -10
  137. package/dist/validation/member-invite.schema.js +2 -15
  138. package/dist/validation/member-invite.schema.js.map +1 -1
  139. package/frontend-vue/dms.frontend.ts +24 -5
  140. package/frontend-vue/dms.server.ts +17 -0
  141. package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
  142. package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +34 -0
  143. package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
  144. package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
  145. package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
  146. package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
  147. package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
  148. package/frontend-vue/layers/dms-core/app/composables/hydration/isHydratingComponent.ts +29 -0
  149. package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
  150. package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
  151. package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
  152. package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
  153. package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
  154. package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
  155. package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +22 -5
  156. package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
  157. package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
  158. package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
  159. package/frontend-vue/layers/dms-core/app/utils/formatter.ts +166 -35
  160. package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
  161. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +134 -2
  162. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +134 -2
  163. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
  164. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
  165. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +9 -0
  166. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
  167. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -3
  168. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
  169. package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionBar.vue +8 -0
  170. package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +14 -0
  171. package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
  172. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
  173. package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
  174. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
  175. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
  176. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
  177. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
  178. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
  179. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
  180. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
  181. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
  182. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
  183. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
  184. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
  185. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
  186. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
  187. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
  188. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
  189. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
  190. package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
  191. package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
  192. package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
  193. package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
  194. package/frontend-vue/layers/dms-layout/app/composables/layout/usePageRecord.ts +50 -0
  195. package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +25 -7
  196. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
  197. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +51 -4
  198. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
  199. package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
  200. package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
  201. package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
  202. package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +9 -0
  203. package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +9 -0
  204. package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
  205. package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
  206. package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
  207. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +6 -22
  208. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +2 -1
  209. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +14 -44
  210. package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
  211. package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
  212. package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
  213. package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
  214. package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
  215. package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
  216. package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
  217. package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
  218. package/frontend-vue/layers/dms-layout/app/utils/pageRecord.ts +71 -0
  219. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +39 -14
  220. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +38 -13
  221. package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
  222. package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
  223. package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
  224. package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
  225. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
  226. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
  227. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
  228. package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
  229. package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
  230. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
  231. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
  232. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
  233. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
  234. package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
  235. package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
  236. package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +38 -1
  237. package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
  238. package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
  239. package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
  240. package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
  241. package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
  242. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
  243. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
  244. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
  245. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
  246. package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
  247. package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
  248. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
  249. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
  250. package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
  251. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
  252. package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
  253. package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
  254. package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
  255. package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
  256. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
  257. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +47 -0
  258. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +99 -24
  259. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
  260. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
  261. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +71 -0
  262. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
  263. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
  264. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
  265. package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
  266. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
  267. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
  268. package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
  269. package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
  270. package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
  271. package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
  272. package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
  273. package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
  274. package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +65 -0
  275. package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
  276. package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
  277. package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
  278. package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
  279. package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
  280. package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
  281. package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
  282. package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
  283. package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
  284. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
  285. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
  286. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
  287. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
  288. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
  289. package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
  290. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +73 -0
  291. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
  292. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
  293. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
  294. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
  295. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
  296. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
  297. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
  298. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
  299. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
  300. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
  301. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
  302. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
  303. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
  304. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
  305. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +77 -32
  306. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
  307. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
  308. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
  309. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
  310. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
  311. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
  312. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
  313. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
  314. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
  315. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
  316. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
  317. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
  318. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
  319. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
  320. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
  321. package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
  322. package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
  323. package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
  324. package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
  325. package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
  326. package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
  327. package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
  328. package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
  329. package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
  330. package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
  331. package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
  332. package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
  333. package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
  334. package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
  335. package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
  336. package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
  337. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
  338. package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
  339. package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
  340. package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
  341. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +118 -36
  342. package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
  343. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
  344. package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
  345. package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
  346. package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
  347. package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
  348. package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
  349. package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
  350. package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
  351. package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
  352. package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +205 -65
  353. package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
  354. package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +203 -0
  355. package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
  356. package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
  357. package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
  358. package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
  359. package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
  360. package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
  361. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
  362. package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
  363. package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
  364. package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
  365. package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
  366. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +45 -35
  367. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
  368. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +410 -96
  369. package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
  370. package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
  371. package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
  372. package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
  373. package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
  374. package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
  375. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
  376. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
  377. package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
  378. package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
  379. package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
  380. package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +4 -0
  381. package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
  382. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +142 -21
  383. package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +11 -4
  384. package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
  385. package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
  386. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
  387. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
  388. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
  389. package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
  390. package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
  391. package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
  392. package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
  393. package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
  394. package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
  395. package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
  396. package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
  397. package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
  398. package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
  399. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -4
  400. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -4
  401. package/frontend-vue/package.json +2 -2
  402. package/package.json +7 -6
  403. package/skills/dms/SKILL.md +1 -1
  404. package/skills/dms-auth/SKILL.md +5 -3
  405. package/skills/dms-best-practices/REFERENCE.md +2 -0
  406. package/skills/dms-best-practices/SKILL.md +4 -0
  407. package/skills/dms-module/SKILL.md +3 -2
  408. package/skills/dms-pages/REFERENCE.md +125 -16
  409. package/skills/dms-pages/SKILL.md +1 -1
  410. package/skills/dms-project/DEV-SERVERS.md +23 -1
  411. package/skills/dms-project/REFERENCE.md +1 -1
  412. package/skills/dms-project/SKILL.md +4 -1
  413. package/skills/dms-project/scripts/dms-dev.sh +205 -17
  414. package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
@@ -7,20 +7,7 @@ const zod_1 = require("zod");
7
7
  exports.INVITE_NAME_MAX_LENGTH = 100;
8
8
  exports.INVITE_FULL_NAME_MAX_LENGTH = exports.INVITE_NAME_MAX_LENGTH * 2;
9
9
  exports.INVITE_EMAILS_MAX = 50;
10
- const LEGACY_EMAIL_KEY = "email";
11
- const EMAILS_KEY = "emails";
12
10
  const NAME_SEPARATOR = /\s+/;
13
- function acceptLegacySingleEmail(payload) {
14
- if (typeof payload !== "object" || payload === null)
15
- return payload;
16
- const record = payload;
17
- if (record[EMAILS_KEY] !== undefined)
18
- return payload;
19
- const email = record[LEGACY_EMAIL_KEY];
20
- if (typeof email !== "string")
21
- return payload;
22
- return { ...record, [EMAILS_KEY]: [email] };
23
- }
24
11
  const inviteNamePart = zod_1.z.string().trim().max(exports.INVITE_NAME_MAX_LENGTH);
25
12
  const memberInviteObjectSchema = zod_1.z.object({
26
13
  emails: zod_1.z
@@ -34,10 +21,10 @@ const memberInviteObjectSchema = zod_1.z.object({
34
21
  language: zod_1.z.string(),
35
22
  asTenantOwner: zod_1.z.boolean(),
36
23
  });
37
- exports.memberInviteSchema = zod_1.z.preprocess(acceptLegacySingleEmail, memberInviteObjectSchema.refine((data) => data.asTenantOwner || (data.roles && data.roles.length > 0), {
24
+ exports.memberInviteSchema = memberInviteObjectSchema.refine((data) => data.asTenantOwner || (data.roles && data.roles.length > 0), {
38
25
  message: "$page.settings.members.invite.roles_required",
39
26
  path: ["roles"],
40
- }));
27
+ });
41
28
  function resolveInviteeNameParts(payload) {
42
29
  if (payload.firstname || payload.lastname || !payload.name) {
43
30
  return { firstname: payload.firstname, lastname: payload.lastname };
@@ -1 +1 @@
1
- {"version":3,"file":"member-invite.schema.js","sourceRoot":"","sources":["../../src/validation/member-invite.schema.ts"],"names":[],"mappings":";;;AA+EA,0DAQC;AAMD,gDAEC;AA/FD,6BAAwB;AAOX,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAG7B,QAAA,2BAA2B,GAAG,8BAAsB,GAAG,CAAC,CAAC;AAMzD,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACjC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,MAAM,cAAc,GAAG,KAAK,CAAC;AAM7B,SAAS,uBAAuB,CAAC,OAAgB;IAC/C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IACpE,MAAM,MAAM,GAAG,OAAkC,CAAC;IAClD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACrD,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAC9C,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,CAAC;AAOD,MAAM,cAAc,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,8BAAsB,CAAC,CAAC;AAErE,MAAM,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,OAAC;SACN,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;SAC9C,GAAG,CAAC,CAAC,EAAE,+CAA+C,CAAC;SACvD,GAAG,CAAC,yBAAiB,EAAE,+CAA+C,CAAC;IAC1E,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,mCAA2B,CAAC,CAAC,QAAQ,EAAE;IACnE,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE;IACpC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE;CAC3B,CAAC,CAAC;AAEU,QAAA,kBAAkB,GAAG,OAAC,CAAC,UAAU,CAC5C,uBAAuB,EACvB,wBAAwB,CAAC,MAAM,CAC7B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EACrE;IACE,OAAO,EAAE,8CAA8C;IACvD,IAAI,EAAE,CAAC,OAAO,CAAC;CAChB,CACF,CACF,CAAC;AAeF,SAAgB,uBAAuB,CACrC,OAAqE;IAErE,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3D,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC;IACD,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;AAC9D,CAAC;AAMD,SAAgB,kBAAkB,CAAC,MAAyB;IAC1D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"member-invite.schema.js","sourceRoot":"","sources":["../../src/validation/member-invite.schema.ts"],"names":[],"mappings":";;;AA6DA,0DAQC;AAMD,gDAEC;AA7ED,6BAAwB;AAOX,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAG7B,QAAA,2BAA2B,GAAG,8BAAsB,GAAG,CAAC,CAAC;AAMzD,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,cAAc,GAAG,KAAK,CAAC;AAO7B,MAAM,cAAc,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,8BAAsB,CAAC,CAAC;AAErE,MAAM,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,OAAC;SACN,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;SAC9C,GAAG,CAAC,CAAC,EAAE,+CAA+C,CAAC;SACvD,GAAG,CAAC,yBAAiB,EAAE,+CAA+C,CAAC;IAC1E,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,mCAA2B,CAAC,CAAC,QAAQ,EAAE;IACnE,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE;IACpC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,aAAa,EAAE,OAAC,CAAC,OAAO,EAAE;CAC3B,CAAC,CAAC;AAEU,QAAA,kBAAkB,GAAG,wBAAwB,CAAC,MAAM,CAC/D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EACrE;IACE,OAAO,EAAE,8CAA8C;IACvD,IAAI,EAAE,CAAC,OAAO,CAAC;CAChB,CACF,CAAC;AAeF,SAAgB,uBAAuB,CACrC,OAAqE;IAErE,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3D,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC;IACD,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;AAC9D,CAAC;AAMD,SAAgB,kBAAkB,CAAC,MAAyB;IAC1D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -18,8 +18,10 @@ import permissionPreviewPrepaintPlugin from "./layers/dms-layout/app/plugins/per
18
18
  import regionalPreferencesPlugin from "./layers/dms-layout/app/plugins/regional-preferences";
19
19
  import seoPlugin from "./layers/dms-layout/app/plugins/seo";
20
20
  import sidePanelHostPlugin from "./layers/dms-layout/app/plugins/side-panel-host";
21
+ import livePauseSourcePlugin from "./layers/dms-ui/app/plugins/live-pause-source";
21
22
  import onboardingMiddleware from "./layers/dms-onboarding/app/middleware/onboarding.global";
22
23
  import onboardingPreloadPlugin from "./layers/dms-onboarding/app/plugins/onboarding-preload";
24
+ import closingLayersPlugin from "./layers/dms-ui/app/plugins/closing-layers.client";
23
25
  import registerPlugin from "./layers/dms-ui/app/plugins/register";
24
26
  import shortcutsPlugin from "./layers/dms-ui/app/plugins/shortcuts";
25
27
  import tableViewDisplaysPlugin from "./layers/dms-ui/app/plugins/table-view-displays";
@@ -92,8 +94,11 @@ function lazyComponent(loader: VueLoader): Component {
92
94
  return defineAsyncComponent(async () => (await loader()).default);
93
95
  }
94
96
 
95
- // Components that render a backend block under a name of their own: the block
96
- // names (`dms-xxx-block`) resolve to the same component as the template name.
97
+ // Not a compatibility path: two current contracts name these components.
98
+ // Templates use the component's own name (`<DmsSection>`, `<DmsFieldRow>`,
99
+ // `<DmsActivityFeed>`), while the backend blocks follow the `dms-xxx-block`
100
+ // vocabulary that `block-vocabulary.test.ts` enforces. Each entry maps the
101
+ // template name to the block name, so both resolve to one component.
97
102
  const COMPONENT_ALIASES: Record<string, string> = {
98
103
  ActivityFeed: "ActivityFeedBlock",
99
104
  Section: "SectionBlock",
@@ -159,11 +164,21 @@ function registerPlugins(sdk: Parameters<DmsFrontendModule["setup"]>[0]): void {
159
164
  const clientOnly = { clientOnly: true };
160
165
  if (import.meta.env.DEV) {
161
166
  sdk.registerPlugin(async (context) => {
162
- const plugin = await import(
163
- "./layers/dms-layout/app/plugins/dms-dev-reload.client"
164
- );
167
+ const plugin =
168
+ await import("./layers/dms-layout/app/plugins/dms-dev-reload.client");
165
169
  await plugin.default(context);
166
170
  }, clientOnly);
171
+ // Browser only: the server already logs a render that fails, with its
172
+ // stack. First, so an error a later plugin's work raises is logged too.
173
+ sdk.registerPlugin(
174
+ async (context) => {
175
+ const plugin = await import(
176
+ "./layers/dms-core/app/plugins/dev-error-log"
177
+ );
178
+ await plugin.default(context);
179
+ },
180
+ { ...clientOnly, enforce: "pre" },
181
+ );
167
182
  }
168
183
  // Before any data is read, a higher-priority module's plugins included:
169
184
  // every key lives in the session's scope, and a new scope aborts the reads
@@ -183,6 +198,10 @@ function registerPlugins(sdk: Parameters<DmsFrontendModule["setup"]>[0]): void {
183
198
  sdk.registerPlugin(seoPlugin);
184
199
  sdk.registerPlugin(faviconPlugin);
185
200
  sdk.registerPlugin(sidePanelHostPlugin);
201
+ // Not deferred: a page's first poll reads it.
202
+ sdk.registerPlugin(livePauseSourcePlugin, clientOnly);
203
+ // Not deferred: the first dialog the user closes needs it.
204
+ sdk.registerPlugin(closingLayersPlugin, clientOnly);
186
205
  sdk.registerPlugin(registerPlugin);
187
206
  sdk.registerPlugin(shortcutsPlugin);
188
207
  sdk.registerPlugin(tableViewDisplaysPlugin);
@@ -8,11 +8,28 @@ import { renderHtml } from "./layers/dms-layout/server/html-render";
8
8
  // provider sign-in routes, the session logic the server runs outside them,
9
9
  // the e-mail render the backend asks for, and the backend prefixes the
10
10
  // browser reaches through it. The renderer proxies no path on its own.
11
+
12
+ // The largest upload the DMS stack signs: Media's limit, above the DMS's own
13
+ // `uploads.maxSize` default (100 MiB).
14
+ const STORAGE_UPLOAD_MAX_BYTES = 500 * 1024 * 1024;
15
+ // Named rather than inline so the renderer this repository builds against,
16
+ // which predates `maxBodyBytes`, type-checks it.
17
+ const STORAGE_UPLOADS = {
18
+ auth: "none",
19
+ maxBodyBytes: STORAGE_UPLOAD_MAX_BYTES,
20
+ } as const;
21
+
11
22
  export default defineDmsServer((server) => {
12
23
  // The backend's API and the DMS's own routes (menu, page, page layouts,
13
24
  // permissions, realtime), with the session's token added server-side.
14
25
  server.registerBackendProxy("/api/**");
15
26
  server.registerBackendProxy("/dms/**");
27
+ // The storage's signed URLs (file fields, exports, profile photos, media),
28
+ // authenticated by the token they carry, never by the member's session, so
29
+ // a backend reachable only through the frontend still takes uploads and
30
+ // serves files.
31
+ server.registerBackendProxy("/file-storage/upload/**", STORAGE_UPLOADS);
32
+ server.registerBackendProxy("/file-storage/files/**", { auth: "none" });
16
33
 
17
34
  server.registerRoute("GET", "/api/_auth/session", session.readSessionRoute);
18
35
  server.registerRoute(
@@ -38,12 +38,11 @@ interface SessionUser {
38
38
  }
39
39
 
40
40
  /**
41
- * Whether a session, or a stored account, outlives the browser. Only a login
42
- * that left "keep me signed in" unchecked says no; a cookie written before
43
- * the flag existed carries none, and keeps the lifetime it was given then.
41
+ * Whether a session, or a stored account, outlives the browser: only one a
42
+ * login that ticked "keep me signed in" wrote (`persistent: true`).
44
43
  */
45
44
  export function isPersistent(session?: { persistent?: unknown }): boolean {
46
- return session?.persistent !== false;
45
+ return session?.persistent === true;
47
46
  }
48
47
 
49
48
  function lifetime(persistent: boolean): number | undefined {
@@ -0,0 +1,34 @@
1
+ import { getCurrentInstance } from "vue";
2
+ import { isHydratingComponent } from "../../composables/hydration/isHydratingComponent";
3
+
4
+ /**
5
+ * The instant a server render reads the clock at, handed to the browser with
6
+ * the page: the periods' bounds and the relative dates read it.
7
+ */
8
+ const RENDER_NOW_STATE_KEY = "dms-render-now";
9
+
10
+ /**
11
+ * The instant, in milliseconds, a component reads the clock at while its
12
+ * text must match the server's, or `null` for the clock's.
13
+ *
14
+ * A server render reads every such clock of the request at one instant, which
15
+ * it transfers; the browser hydrating that render reads the same one, so a
16
+ * text measured from now ("3 min ago", a relative period's bounds) hydrates
17
+ * as the server wrote it, even across a minute or midnight. Anywhere else (a
18
+ * client navigation, a later render, a call outside a component) it is
19
+ * `null`: the text follows the clock.
20
+ */
21
+ export function serverRenderNow(): number | null {
22
+ if (!getCurrentInstance()) return null;
23
+ if (typeof window === "undefined") {
24
+ return useDmsState<number>(RENDER_NOW_STATE_KEY, () => Date.now(), {
25
+ transfer: true,
26
+ }).value;
27
+ }
28
+ if (!isHydratingComponent()) return null;
29
+ const transferred = useDmsState<number | null>(
30
+ RENDER_NOW_STATE_KEY,
31
+ () => null,
32
+ ).value;
33
+ return typeof transferred === "number" ? transferred : null;
34
+ }
@@ -13,7 +13,9 @@ export type ServerTableField =
13
13
  | "paginationScope"
14
14
  | "activeTab"
15
15
  | "viewMode"
16
- | "activeView";
16
+ | "activeView"
17
+ | "linkScope"
18
+ | "shownLink";
17
19
 
18
20
  /**
19
21
  * @internal
@@ -224,6 +226,8 @@ export const SERVER_TABLE_FIELDS: Record<ServerTableField, ServerFieldCodec> = {
224
226
  activeTab: plainField("t"),
225
227
  viewMode: plainField("d"),
226
228
  activeView: plainField("w"),
229
+ linkScope: plainField("l"),
230
+ shownLink: plainField("k"),
227
231
  };
228
232
 
229
233
  /** @internal Whether `field` is kept in the cookie. */
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Coordination between the tabs of one browser profile, for the long-lived
3
+ * streams a dashboard keeps open.
4
+ *
5
+ * Over HTTP/1.1 a browser opens at most six connections per host, and a
6
+ * streaming response holds one for as long as it lives: one stream per tab
7
+ * starves every other request once a few tabs are open. One tab is elected
8
+ * (a Web Lock, released by the browser when the tab goes, however it goes),
9
+ * opens the stream, and relays it to the others over a BroadcastChannel.
10
+ *
11
+ * Web Locks need a secure context (HTTPS, or localhost). Where either API is
12
+ * missing, every tab is its own leader on a bus of its own: the behaviour of a
13
+ * stream per tab, unchanged.
14
+ *
15
+ * @internal
16
+ */
17
+
18
+ const TAB_LOCK_SEPARATOR = ":tab:";
19
+
20
+ export type TabMessageHandler = (message: unknown) => void;
21
+
22
+ /** The browser APIs the coordination rides on; injected by the tests. */
23
+ export interface CrossTabEnvironment {
24
+ locks?: LockManager;
25
+ createChannel?: (name: string) => BroadcastChannel;
26
+ }
27
+
28
+ export interface TabBus {
29
+ /** Sends to every tab on the bus, this one included. */
30
+ post(message: unknown): void;
31
+ listen(handler: TabMessageHandler): () => void;
32
+ close(): void;
33
+ }
34
+
35
+ /** A lock this tab holds until it releases it or goes. */
36
+ export interface HeldLock {
37
+ /** Resolves once the lock is held: until then, nobody can wait on it. */
38
+ held: Promise<void>;
39
+ release(): void;
40
+ }
41
+
42
+ /** What the running browser offers. */
43
+ export function browserCrossTabEnvironment(): CrossTabEnvironment {
44
+ const locks = globalThis.navigator?.locks;
45
+ const canBroadcast = typeof globalThis.BroadcastChannel === "function";
46
+ if (!locks || !canBroadcast) return {};
47
+ return { locks, createChannel: (name) => new BroadcastChannel(name) };
48
+ }
49
+
50
+ /** Whether the tabs can share: without both APIs each tab stays on its own. */
51
+ export function canShareAcrossTabs(environment: CrossTabEnvironment): boolean {
52
+ return !!environment.locks && !!environment.createChannel;
53
+ }
54
+
55
+ export function openTabBus(
56
+ name: string,
57
+ environment: CrossTabEnvironment,
58
+ ): TabBus {
59
+ const listeners = new Set<TabMessageHandler>();
60
+ const deliver = (message: unknown) => {
61
+ for (const listener of [...listeners]) listener(message);
62
+ };
63
+ const channel = canShareAcrossTabs(environment)
64
+ ? environment.createChannel!(name)
65
+ : undefined;
66
+ if (channel) channel.onmessage = (event) => deliver(event.data);
67
+ return {
68
+ // A BroadcastChannel never echoes to its sender: this tab's own
69
+ // listeners hear the message directly.
70
+ post: (message) => {
71
+ channel?.postMessage(message);
72
+ deliver(message);
73
+ },
74
+ listen: (handler) => {
75
+ listeners.add(handler);
76
+ return () => listeners.delete(handler);
77
+ },
78
+ close: () => {
79
+ listeners.clear();
80
+ channel?.close();
81
+ },
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Runs `lead` in one tab at a time per `name`. When the leading tab resigns
87
+ * or goes, the next waiting tab takes over and runs its own `lead`.
88
+ *
89
+ * @param lead Starts the leader's work; returns what stops it
90
+ * @returns Resigns: stops the work when leading, or stops waiting
91
+ */
92
+ export function electLeader(
93
+ name: string,
94
+ environment: CrossTabEnvironment,
95
+ lead: () => () => void,
96
+ ): () => void {
97
+ if (!canShareAcrossTabs(environment)) return lead();
98
+ const abort = new AbortController();
99
+ let isResigned = false;
100
+ let stepDown: (() => void) | undefined;
101
+ environment
102
+ .locks!.request(name, { signal: abort.signal }, () => {
103
+ // Granted while the resignation was on its way.
104
+ if (isResigned) return;
105
+ return new Promise<void>((resolve) => {
106
+ const stop = lead();
107
+ stepDown = () => {
108
+ stop();
109
+ resolve();
110
+ };
111
+ });
112
+ })
113
+ .catch(() => {});
114
+ return () => {
115
+ isResigned = true;
116
+ abort.abort();
117
+ stepDown?.();
118
+ stepDown = undefined;
119
+ };
120
+ }
121
+
122
+ export function tabLockName(name: string, tabId: string): string {
123
+ return `${name}${TAB_LOCK_SEPARATOR}${tabId}`;
124
+ }
125
+
126
+ /** Holds `name` until released; the browser releases it when the tab goes. */
127
+ export function holdLock(
128
+ name: string,
129
+ environment: CrossTabEnvironment,
130
+ ): HeldLock {
131
+ if (!canShareAcrossTabs(environment)) {
132
+ return { held: Promise.resolve(), release: () => {} };
133
+ }
134
+ const abort = new AbortController();
135
+ let release: (() => void) | undefined;
136
+ let isReleased = false;
137
+ const held = new Promise<void>((resolveHeld) => {
138
+ environment
139
+ .locks!.request(name, { signal: abort.signal }, () => {
140
+ if (isReleased) return;
141
+ resolveHeld();
142
+ return new Promise<void>((resolve) => {
143
+ release = resolve;
144
+ });
145
+ })
146
+ .catch(() => {});
147
+ });
148
+ return {
149
+ held,
150
+ release: () => {
151
+ isReleased = true;
152
+ abort.abort();
153
+ release?.();
154
+ release = undefined;
155
+ },
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Calls `onReleased` once nobody holds `name` any more: when the tab holding
161
+ * it releases it or goes. Never called once `signal` aborts.
162
+ */
163
+ export function whenReleased(
164
+ name: string,
165
+ environment: CrossTabEnvironment,
166
+ onReleased: () => void,
167
+ signal: AbortSignal,
168
+ ): void {
169
+ if (!canShareAcrossTabs(environment)) return;
170
+ environment
171
+ .locks!.request(name, { signal }, () => {
172
+ if (!signal.aborted) onReleased();
173
+ })
174
+ .catch(() => {});
175
+ }
176
+
177
+ /**
178
+ * One source for every tab of the browser: the elected tab opens it, and what
179
+ * it emits reaches each tab's `onMessage`, the leader's included.
180
+ *
181
+ * @param open Opens the source, handing it what relays a message; returns
182
+ * what closes it
183
+ * @returns Leaves: closes the source when leading, and stops listening
184
+ */
185
+ export function shareAcrossTabs(
186
+ name: string,
187
+ open: (emit: (message: unknown) => void) => () => void,
188
+ onMessage: TabMessageHandler,
189
+ environment: CrossTabEnvironment = browserCrossTabEnvironment(),
190
+ ): () => void {
191
+ const bus = openTabBus(name, environment);
192
+ const unlisten = bus.listen(onMessage);
193
+ const resign = electLeader(name, environment, () => open(bus.post));
194
+ return () => {
195
+ resign();
196
+ unlisten();
197
+ bus.close();
198
+ };
199
+ }