@antelopejs/dms 0.9.8 → 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 (420) hide show
  1. package/CHANGELOG.md +102 -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 -48
  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 +24 -13
  129. package/dist/store/listing.js.map +1 -1
  130. package/dist/store/operations.js +4 -0
  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/validation/auth.schema.d.ts +2 -2
  139. package/dist/validation/member-invite.schema.d.ts +2 -10
  140. package/dist/validation/member-invite.schema.js +2 -15
  141. package/dist/validation/member-invite.schema.js.map +1 -1
  142. package/frontend-vue/dms.frontend.ts +24 -5
  143. package/frontend-vue/dms.server.ts +17 -0
  144. package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
  145. package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +34 -0
  146. package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
  147. package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
  148. package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
  149. package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
  150. package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
  151. package/frontend-vue/layers/dms-core/app/composables/hydration/isHydratingComponent.ts +29 -0
  152. package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
  153. package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
  154. package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
  155. package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
  156. package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
  157. package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
  158. package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +22 -5
  159. package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
  160. package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
  161. package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
  162. package/frontend-vue/layers/dms-core/app/utils/formatter.ts +166 -35
  163. package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
  164. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +134 -2
  165. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +134 -2
  166. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
  167. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
  168. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +9 -0
  169. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
  170. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -3
  171. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
  172. package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionBar.vue +8 -0
  173. package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +14 -0
  174. package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
  175. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
  176. package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
  177. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
  178. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
  179. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
  180. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
  181. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
  182. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
  183. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
  184. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
  185. package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
  186. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
  187. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
  188. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
  189. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
  190. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
  191. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
  192. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
  193. package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
  194. package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
  195. package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
  196. package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
  197. package/frontend-vue/layers/dms-layout/app/composables/layout/usePageRecord.ts +50 -0
  198. package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +25 -7
  199. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
  200. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +51 -4
  201. package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
  202. package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
  203. package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
  204. package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
  205. package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +9 -0
  206. package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +9 -0
  207. package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
  208. package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
  209. package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
  210. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +6 -22
  211. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +2 -1
  212. package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +14 -44
  213. package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
  214. package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
  215. package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
  216. package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
  217. package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
  218. package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
  219. package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
  220. package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
  221. package/frontend-vue/layers/dms-layout/app/utils/pageRecord.ts +71 -0
  222. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +39 -14
  223. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +38 -13
  224. package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
  225. package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
  226. package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
  227. package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
  228. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
  229. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
  230. package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
  231. package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
  232. package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
  233. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
  234. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
  235. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
  236. package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
  237. package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
  238. package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
  239. package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +38 -1
  240. package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
  241. package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
  242. package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
  243. package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
  244. package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
  245. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
  246. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
  247. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
  248. package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
  249. package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
  250. package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
  251. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
  252. package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
  253. package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
  254. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
  255. package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
  256. package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
  257. package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
  258. package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
  259. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
  260. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +47 -0
  261. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +99 -24
  262. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
  263. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
  264. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +71 -0
  265. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
  266. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
  267. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
  268. package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
  269. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
  270. package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
  271. package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
  272. package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
  273. package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
  274. package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
  275. package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
  276. package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
  277. package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +65 -0
  278. package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
  279. package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
  280. package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
  281. package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
  282. package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
  283. package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
  284. package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
  285. package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
  286. package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
  287. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
  288. package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
  289. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
  290. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
  291. package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
  292. package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
  293. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +73 -0
  294. package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
  295. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
  296. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
  297. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
  298. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
  299. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
  300. package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
  301. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
  302. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
  303. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
  304. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
  305. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
  306. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
  307. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
  308. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +77 -32
  309. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
  310. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
  311. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
  312. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
  313. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
  314. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
  315. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
  316. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
  317. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
  318. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
  319. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
  320. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
  321. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
  322. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
  323. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
  324. package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
  325. package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
  326. package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
  327. package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
  328. package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
  329. package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
  330. package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
  331. package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
  332. package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
  333. package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
  334. package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
  335. package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
  336. package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
  337. package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
  338. package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
  339. package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
  340. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
  341. package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
  342. package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
  343. package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
  344. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +118 -36
  345. package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
  346. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
  347. package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
  348. package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
  349. package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
  350. package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
  351. package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
  352. package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
  353. package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
  354. package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
  355. package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +205 -65
  356. package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
  357. package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +203 -0
  358. package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
  359. package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
  360. package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
  361. package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
  362. package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
  363. package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
  364. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
  365. package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
  366. package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
  367. package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
  368. package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
  369. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +45 -35
  370. package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
  371. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +410 -96
  372. package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
  373. package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
  374. package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
  375. package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
  376. package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
  377. package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
  378. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
  379. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
  380. package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
  381. package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
  382. package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
  383. package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +4 -0
  384. package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
  385. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +142 -21
  386. package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +11 -4
  387. package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
  388. package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
  389. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
  390. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
  391. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
  392. package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
  393. package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
  394. package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
  395. package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
  396. package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
  397. package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
  398. package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
  399. package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
  400. package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
  401. package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
  402. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -4
  403. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -4
  404. package/frontend-vue/package.json +2 -2
  405. package/package.json +7 -6
  406. package/skills/dms/SKILL.md +1 -1
  407. package/skills/dms-auth/SKILL.md +5 -3
  408. package/skills/dms-best-practices/REFERENCE.md +2 -0
  409. package/skills/dms-best-practices/SKILL.md +4 -0
  410. package/skills/dms-module/SKILL.md +3 -2
  411. package/skills/dms-pages/REFERENCE.md +125 -16
  412. package/skills/dms-pages/SKILL.md +1 -1
  413. package/skills/dms-project/DEV-SERVERS.md +23 -1
  414. package/skills/dms-project/REFERENCE.md +1 -1
  415. package/skills/dms-project/SKILL.md +4 -1
  416. package/skills/dms-project/scripts/dms-dev.sh +205 -17
  417. package/dist/routes/startup-gate.d.ts +0 -7
  418. package/dist/routes/startup-gate.js +0 -39
  419. package/dist/routes/startup-gate.js.map +0 -1
  420. package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
@@ -1,6 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import ModuleTile from "./ModuleTile.vue";
3
- import type { Tone } from "#dms-ui/app/types/tone";
3
+ import ModuleManageMenu from "./ModuleManageMenu.vue";
4
+ import ModuleSourceLabel from "./ModuleSourceLabel.vue";
5
+ import ModuleStoreOperation from "./ModuleStoreOperation.vue";
6
+ import ModuleStoreRequirements from "./ModuleStoreRequirements.vue";
4
7
  import type {
5
8
  CheckListItem,
6
9
  CheckListState,
@@ -8,27 +11,52 @@ import type {
8
11
  import type {
9
12
  ModuleCatalogEntry,
10
13
  ModuleReadoutTone,
11
- ModuleStatus,
12
14
  } from "../../../../types/page";
13
- import { moduleCategory, moduleStatus } from "../../../utils/modules-catalog";
15
+ import type { StoreOperationKind } from "../../../../types/module-store";
16
+ import { moduleCategory } from "../../../utils/modules-catalog";
17
+ import {
18
+ type ModuleStoreEntry,
19
+ type StoreAction,
20
+ installedTileStatus,
21
+ storeActions,
22
+ storeBlockMessage,
23
+ } from "../../../utils/module-store-catalog";
24
+
25
+ // An installed module: its state, a live readout, and the one place it is
26
+ // managed. Its button opens it on its landing page, or resumes it while it
27
+ // is paused; the store actions it offers are in its Manage menu.
14
28
 
15
29
  interface ModuleCatalogTileProps {
16
30
  entry: ModuleCatalogEntry;
17
- /** Where the tile leads: the last page visited in the module, or its landing page. */
18
- to: string;
31
+ /** Where Open leads: the module's landing page, when it has pages. */
32
+ to?: string;
33
+ /** What the module store says of it, when the store lists it. */
34
+ storeEntry?: ModuleStoreEntry;
35
+ /** Another module's operation runs, or the store is read-only. */
36
+ isLocked?: boolean;
37
+ }
38
+
39
+ interface ModuleCatalogTileEmits {
40
+ action: [kind: StoreOperationKind];
19
41
  }
20
42
 
21
- const props = defineProps<ModuleCatalogTileProps>();
43
+ const props = withDefaults(defineProps<ModuleCatalogTileProps>(), {
44
+ to: undefined,
45
+ storeEntry: undefined,
46
+ isLocked: false,
47
+ });
48
+ const emit = defineEmits<ModuleCatalogTileEmits>();
22
49
  const { t } = useI18n();
23
50
  const { processI18n } = useTranslation();
24
51
 
25
- // v2 .module-tile__state: a mono uppercase pill with a leading dot.
26
- const STATUS_TONES: Record<ModuleStatus, Tone> = {
27
- live: "success",
28
- beta: "secondary",
29
- update: "warning",
30
- attention: "error",
31
- };
52
+ const TOOLTIP_CONTENT = { side: "top", sideOffset: 6 } as const;
53
+ // Takes what the actions leave rather than wrapping them under it: the band
54
+ // stays one line, and only the category is cut when even that is too short.
55
+ // The facts never shrink below the version and the source (the category's
56
+ // zero width keeps its text out of that floor): a tile too narrow for those
57
+ // and the actions drops the actions to a second line rather than run the
58
+ // source under them.
59
+ const FOOTER_FACTS_CLASS = "flex grow basis-0 items-center gap-2";
32
60
 
33
61
  // v2 .module-tile__viz: each readout line opens with a tone glyph.
34
62
  const READOUT_STATES: Record<ModuleReadoutTone, CheckListState> = {
@@ -38,7 +66,9 @@ const READOUT_STATES: Record<ModuleReadoutTone, CheckListState> = {
38
66
  error: "error",
39
67
  };
40
68
 
41
- const status = computed(() => moduleStatus(props.entry));
69
+ const status = computed(() =>
70
+ installedTileStatus(props.entry, props.storeEntry),
71
+ );
42
72
  const readout = computed<CheckListItem[]>(() =>
43
73
  (props.entry.readout ?? []).map((line, index) => ({
44
74
  id: String(index),
@@ -47,18 +77,41 @@ const readout = computed<CheckListItem[]>(() =>
47
77
  })),
48
78
  );
49
79
  const title = computed(() => processI18n(props.entry.title));
80
+ const category = computed(() => processI18n(moduleCategory(props.entry)));
81
+
82
+ const actions = computed<StoreAction[]>(() =>
83
+ props.storeEntry ? storeActions(props.storeEntry) : [],
84
+ );
85
+ /** The store action the button runs when there is nothing to open. */
86
+ const primary = computed<StoreAction | undefined>(() =>
87
+ props.to ? undefined : actions.value.find((action) => !action.isMenuOnly),
88
+ );
89
+ const menuActions = computed(() =>
90
+ actions.value.filter((action) => action !== primary.value),
91
+ );
92
+ const isOperating = computed(() => props.storeEntry?.operation !== undefined);
93
+
94
+ /** Why the button waits, when it does. */
95
+ const blockedReason = computed(() => {
96
+ if (!primary.value || !props.storeEntry) return undefined;
97
+ if (props.isLocked) return t("modules.store.locked");
98
+ return storeBlockMessage(props.storeEntry, primary.value.kind, t);
99
+ });
100
+ const isBlocked = computed(() => blockedReason.value !== undefined);
50
101
  </script>
51
102
 
52
103
  <template>
53
104
  <ModuleTile
54
- :to="props.to"
105
+ :id="`module-${props.entry.id}`"
55
106
  :icon="props.entry.icon"
56
107
  :title="title"
57
108
  :description="processI18n(props.entry.description)"
58
109
  :status="{
59
- tone: STATUS_TONES[status],
60
- label: t(`modules.status.${status}`),
110
+ tone: status.tone,
111
+ dot: status.dot,
112
+ label: t(status.labelKey),
61
113
  }"
114
+ is-solid
62
115
  >
63
116
  <template #readout>
64
117
  <DmsCheckList
@@ -72,26 +125,70 @@ const title = computed(() => processI18n(props.entry.title));
72
125
  />
73
126
  </template>
74
127
 
128
+ <template v-if="props.storeEntry">
129
+ <ModuleStoreOperation :entry="props.storeEntry" />
130
+ <p
131
+ v-if="!isOperating && props.storeEntry.state === 'pending'"
132
+ class="text-xs text-(--ui-warning)"
133
+ >
134
+ {{ t("modules.store.pending_hint") }}
135
+ </p>
136
+ <ModuleStoreRequirements v-if="!isOperating" :entry="props.storeEntry" />
137
+ </template>
138
+
75
139
  <template #footer>
76
- <span v-if="props.entry.version" class="whitespace-nowrap">
77
- v{{ props.entry.version }}
140
+ <!-- v0.5.0 · [icon] npm · Content, as the store tile says it: the
141
+ state is the pill's to say. Only the category gives way to Open
142
+ and Manage; the version and the source stay whole. -->
143
+ <span :class="FOOTER_FACTS_CLASS">
144
+ <span v-if="props.entry.version" class="shrink-0 whitespace-nowrap">
145
+ v{{ props.entry.version }}
146
+ </span>
147
+ <template v-if="props.entry.source">
148
+ <span v-if="props.entry.version" aria-hidden="true">·</span>
149
+ <ModuleSourceLabel :source="props.entry.source" />
150
+ </template>
151
+ <span class="w-0 min-w-0 grow truncate" :title="category">
152
+ <template v-if="props.entry.version || props.entry.source">
153
+ ·
154
+ </template>
155
+ {{ category }}
156
+ </span>
78
157
  </span>
79
- <span v-if="status === 'update'" class="text-warning truncate">
80
- <template v-if="props.entry.version">·</template>
81
- {{ t("modules.update_available") }}
82
- </span>
83
- <span v-else class="truncate">
84
- <template v-if="props.entry.version">·</template>
85
- {{ processI18n(moduleCategory(props.entry)) }}
86
- </span>
87
- <span
88
- class="text-primary ms-auto inline-flex shrink-0 items-center gap-1 font-sans text-xs font-semibold"
89
- >
90
- {{ t("modules.open") }}
91
- <UIcon
92
- name="i-ph-arrow-right"
93
- class="size-3.5 transition-transform group-hover:translate-x-0.5"
94
- :aria-hidden="true"
158
+ <span class="ms-auto flex shrink-0 items-center gap-1 font-sans">
159
+ <UButton
160
+ v-if="props.to"
161
+ :to="props.to"
162
+ size="xs"
163
+ color="primary"
164
+ variant="soft"
165
+ trailing-icon="i-ph-arrow-right"
166
+ :label="t('modules.open')"
167
+ />
168
+ <UTooltip
169
+ v-else-if="primary"
170
+ :text="blockedReason"
171
+ :disabled="!blockedReason"
172
+ :content="TOOLTIP_CONTENT"
173
+ >
174
+ <!-- aria-disabled rather than disabled: the button keeps its
175
+ tooltip, which says why it waits. -->
176
+ <UButton
177
+ size="xs"
178
+ :color="primary.kind === 'update' ? 'warning' : 'neutral'"
179
+ variant="outline"
180
+ :icon="primary.icon"
181
+ :label="t(`modules.store.actions.${primary.labelKey}`)"
182
+ :aria-disabled="isBlocked ? 'true' : undefined"
183
+ :class="{ 'cursor-not-allowed opacity-50': isBlocked }"
184
+ @click="!isBlocked && emit('action', primary.kind)"
185
+ />
186
+ </UTooltip>
187
+ <ModuleManageMenu
188
+ v-if="props.storeEntry && !props.isLocked"
189
+ :entry="props.storeEntry"
190
+ :actions="menuActions"
191
+ @action="emit('action', $event)"
95
192
  />
96
193
  </span>
97
194
  </template>
@@ -0,0 +1,59 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ type ModuleStoreEntry,
4
+ type StoreAction,
5
+ storeBlockMessage,
6
+ } from "../../../utils/module-store-catalog";
7
+ import type { StoreOperationKind } from "../../../../types/module-store";
8
+
9
+ // The Manage menu of an installed module: the store actions its tile does
10
+ // not show as its button. One that cannot run stays listed, disabled, with
11
+ // why under it.
12
+
13
+ interface ModuleManageMenuProps {
14
+ entry: ModuleStoreEntry;
15
+ actions: StoreAction[];
16
+ }
17
+
18
+ interface ModuleManageMenuEmits {
19
+ action: [kind: StoreOperationKind];
20
+ }
21
+
22
+ const props = defineProps<ModuleManageMenuProps>();
23
+ const emit = defineEmits<ModuleManageMenuEmits>();
24
+ const { t } = useI18n();
25
+
26
+ const items = computed(() =>
27
+ props.actions.map((action) => {
28
+ const blocked = storeBlockMessage(props.entry, action.kind, t);
29
+ return {
30
+ label: t(`modules.store.actions.${action.labelKey}`),
31
+ description: blocked,
32
+ icon: action.icon,
33
+ color: action.kind === "uninstall" ? ("error" as const) : undefined,
34
+ disabled: blocked !== undefined,
35
+ onSelect: () => emit("action", action.kind),
36
+ };
37
+ }),
38
+ );
39
+ </script>
40
+
41
+ <template>
42
+ <UDropdownMenu
43
+ v-if="items.length > 0"
44
+ :items="items"
45
+ :content="{ align: 'end' }"
46
+ :ui="{
47
+ content: 'max-w-72',
48
+ itemDescription: 'whitespace-normal text-muted text-xs',
49
+ }"
50
+ >
51
+ <UButton
52
+ size="xs"
53
+ color="neutral"
54
+ variant="outline"
55
+ trailing-icon="i-ph-caret-down"
56
+ :label="t('modules.store.actions.manage')"
57
+ />
58
+ </UDropdownMenu>
59
+ </template>
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ import type { ModuleSourceKind } from "../../../../types/module-store";
3
+ import { MODULE_SOURCE_ICONS } from "../../../utils/module-store-catalog";
4
+
5
+ // Where a module's code comes from, as a tile's footer names it: an icon
6
+ // and a short name (npm, GitHub, GitLab, Git, Local).
7
+
8
+ interface ModuleSourceLabelProps {
9
+ source: ModuleSourceKind;
10
+ }
11
+
12
+ const props = defineProps<ModuleSourceLabelProps>();
13
+ const { t } = useI18n();
14
+ </script>
15
+
16
+ <template>
17
+ <span class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap">
18
+ <UIcon
19
+ :name="MODULE_SOURCE_ICONS[props.source]"
20
+ class="size-3.5"
21
+ :aria-hidden="true"
22
+ />
23
+ {{ t(`modules.source.${props.source}`) }}
24
+ </span>
25
+ </template>
@@ -0,0 +1,73 @@
1
+ <script setup lang="ts">
2
+ import { MONO_CHIP_CLASS } from "#dms-ui/app/build/utils/monoChip";
3
+ import { FRONTEND_BUILD_COMMAND } from "../../../utils/module-store-catalog";
4
+ import type { StoreListing } from "../../../../types/module-store";
5
+ import type { StoreFrontendNotice } from "../../../../composables/page/useModuleStoreActions";
6
+
7
+ // What keeps the store from changing modules here, and what follows a
8
+ // change while the interface lags behind the backend: shown above the
9
+ // installed modules and the store alike.
10
+
11
+ interface ModuleStoreBannersProps {
12
+ listing: StoreListing | undefined;
13
+ frontendNotice: StoreFrontendNotice | null;
14
+ }
15
+
16
+ const props = defineProps<ModuleStoreBannersProps>();
17
+ const { t } = useI18n();
18
+ </script>
19
+
20
+ <template>
21
+ <DmsBanner
22
+ v-if="props.listing?.configError"
23
+ class="mb-4"
24
+ tone="error"
25
+ size="sm"
26
+ icon="i-ph-file-x"
27
+ :title="t('modules.store.config_error')"
28
+ :description="props.listing.configError"
29
+ />
30
+ <DmsBanner
31
+ v-else-if="props.listing && !props.listing.enabled"
32
+ class="mb-4"
33
+ tone="info"
34
+ size="sm"
35
+ icon="i-ph-lock-simple"
36
+ :title="t('modules.store.disabled.title')"
37
+ :description="t('modules.store.disabled.description')"
38
+ />
39
+
40
+ <!-- The interface lags behind the backend: say what follows. -->
41
+ <DmsBanner
42
+ v-if="props.frontendNotice"
43
+ class="mb-4"
44
+ :tone="props.frontendNotice.key === 'dev' ? 'info' : 'warning'"
45
+ size="sm"
46
+ :icon="
47
+ props.frontendNotice.key === 'dev'
48
+ ? 'i-ph-circle-notch'
49
+ : 'i-ph-arrows-clockwise'
50
+ "
51
+ :title="
52
+ t(`modules.store.frontend.${props.frontendNotice.key}.title`, {
53
+ modules: props.frontendNotice.names,
54
+ })
55
+ "
56
+ >
57
+ <template #description>
58
+ <i18n-t
59
+ :keypath="`modules.store.frontend.${props.frontendNotice.key}.description`"
60
+ scope="global"
61
+ tag="span"
62
+ >
63
+ <template #command>
64
+ <code
65
+ :class="[MONO_CHIP_CLASS, 'bg-elevated text-highlighted text-xs']"
66
+ >
67
+ {{ FRONTEND_BUILD_COMMAND }}
68
+ </code>
69
+ </template>
70
+ </i18n-t>
71
+ </template>
72
+ </DmsBanner>
73
+ </template>
@@ -0,0 +1,116 @@
1
+ <script setup lang="ts">
2
+ import type { ModuleStoreEntry } from "../../../utils/module-store-catalog";
3
+ import type {
4
+ StoreOperationKind,
5
+ StoreOperationStep,
6
+ } from "../../../../types/module-store";
7
+
8
+ // What the store is doing to a module, on whichever tile shows it: the steps
9
+ // of the running operation, the current one spinning, or the error the last
10
+ // one left.
11
+
12
+ interface ModuleStoreOperationProps {
13
+ entry: ModuleStoreEntry;
14
+ }
15
+
16
+ const props = defineProps<ModuleStoreOperationProps>();
17
+ const { t } = useI18n();
18
+
19
+ /** The steps an operation shows, in the order they run. */
20
+ const PROGRESS_STEPS: StoreOperationStep[] = [
21
+ "resolve",
22
+ "dependencies",
23
+ "unload",
24
+ "load",
25
+ "save",
26
+ ];
27
+ /**
28
+ * Steps an operation of this kind goes through. The file is written last:
29
+ * it only ever names a module that loaded.
30
+ */
31
+ const KIND_STEPS: Record<StoreOperationKind, StoreOperationStep[]> = {
32
+ install: ["resolve", "dependencies", "load", "save"],
33
+ update: ["resolve", "unload", "load", "save"],
34
+ enable: ["load", "save"],
35
+ disable: ["unload", "save"],
36
+ uninstall: ["unload", "save"],
37
+ apply: ["load"],
38
+ };
39
+
40
+ const STEP_ICONS: Record<string, string> = {
41
+ done: "i-ph-check-circle-fill",
42
+ running: "i-ph-circle-notch",
43
+ todo: "i-ph-circle",
44
+ };
45
+
46
+ const operation = computed(() => props.entry.operation);
47
+ /**
48
+ * Whether the running install loads modules for missing interfaces. Kept
49
+ * for the whole operation: once they run, the listing no longer misses them.
50
+ */
51
+ const isInstallingDependencies = ref(false);
52
+ watch(
53
+ operation,
54
+ (running) => {
55
+ if (!running) {
56
+ isInstallingDependencies.value = false;
57
+ return;
58
+ }
59
+ if (
60
+ running.step === "dependencies" ||
61
+ (running.kind === "install" && props.entry.missingInterfaces.length > 0)
62
+ ) {
63
+ isInstallingDependencies.value = true;
64
+ }
65
+ },
66
+ { immediate: true },
67
+ );
68
+
69
+ const steps = computed(() => {
70
+ const kind = operation.value?.kind;
71
+ if (!kind) return [];
72
+ const current = PROGRESS_STEPS.indexOf(operation.value.step);
73
+ const kindSteps = KIND_STEPS[kind].filter(
74
+ (step) => step !== "dependencies" || isInstallingDependencies.value,
75
+ );
76
+ return kindSteps.map((step) => {
77
+ const index = PROGRESS_STEPS.indexOf(step);
78
+ const state =
79
+ index < current ? "done" : index === current ? "running" : "todo";
80
+ return { step, state };
81
+ });
82
+ });
83
+ </script>
84
+
85
+ <template>
86
+ <ol
87
+ v-if="steps.length > 0"
88
+ class="flex flex-col gap-1 text-xs"
89
+ :aria-label="t(`modules.store.progress.${operation?.kind}`)"
90
+ >
91
+ <li
92
+ v-for="{ step, state } in steps"
93
+ :key="step"
94
+ class="flex items-center gap-1.5"
95
+ :class="state === 'todo' ? 'text-dimmed' : 'text-toned'"
96
+ >
97
+ <UIcon
98
+ :name="STEP_ICONS[state]"
99
+ class="size-3.5 shrink-0"
100
+ :class="{
101
+ 'animate-spin text-(--ui-primary)': state === 'running',
102
+ 'text-(--ui-success)': state === 'done',
103
+ }"
104
+ />
105
+ {{ t(`modules.store.steps.${step}`) }}
106
+ </li>
107
+ </ol>
108
+
109
+ <p
110
+ v-else-if="props.entry.state === 'error' && props.entry.error"
111
+ class="rounded-[8px] bg-(--ui-error)/8 px-2.5 py-1.5 text-xs text-(--ui-error)"
112
+ :title="props.entry.error"
113
+ >
114
+ <span class="line-clamp-3 break-words">{{ props.entry.error }}</span>
115
+ </p>
116
+ </template>
@@ -18,7 +18,10 @@ const missingInterfaces = computed(() =>
18
18
  .map((missing) => missing.interfacePackage)
19
19
  .join(LIST_SEPARATOR),
20
20
  );
21
- const dependents = computed(() => props.entry.dependents.join(LIST_SEPARATOR));
21
+ // A working copy offers no action, so who uses it changes nothing there.
22
+ const dependents = computed(() =>
23
+ props.entry.isWorkingCopy ? "" : props.entry.dependents.join(LIST_SEPARATOR),
24
+ );
22
25
  </script>
23
26
 
24
27
  <template>
@@ -92,7 +95,9 @@ const dependents = computed(() => props.entry.dependents.join(LIST_SEPARATOR));
92
95
  {{ t("modules.store.requires", { interfaces: missingInterfaces }) }}
93
96
  </p>
94
97
 
95
- <p v-if="dependents" class="text-xs text-(--ui-warning)">
96
- {{ t("modules.store.used_by", { modules: dependents }) }}
98
+ <!-- Informative only: what it takes to pause or remove the module is
99
+ said in the Manage menu, where those actions are. -->
100
+ <p v-if="dependents" class="text-dimmed truncate text-xs" :title="dependents">
101
+ {{ t("modules.store.dependents", { modules: dependents }) }}
97
102
  </p>
98
103
  </template>