@antelopejs/dms 0.9.8 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +171 -0
- package/README.md +1 -1
- package/data/module-store/catalog.json +2 -2
- package/dist/attachments/table-view.js +2 -2
- package/dist/attachments/table-view.js.map +1 -1
- package/dist/automation/actions.d.ts +2 -0
- package/dist/automation/actions.js +116 -71
- package/dist/automation/actions.js.map +1 -1
- package/dist/automation/i18n.d.ts +4 -0
- package/dist/automation/i18n.js +19 -0
- package/dist/automation/i18n.js.map +1 -0
- package/dist/automation/send-notification.d.ts +21 -0
- package/dist/automation/send-notification.js +163 -0
- package/dist/automation/send-notification.js.map +1 -0
- package/dist/automation/triggers.js +19 -25
- package/dist/automation/triggers.js.map +1 -1
- package/dist/client-origin-cors.d.ts +1 -0
- package/dist/client-origin-cors.js +19 -0
- package/dist/client-origin-cors.js.map +1 -0
- package/dist/config.d.ts +3 -2
- package/dist/config.js +5 -7
- package/dist/config.js.map +1 -1
- package/dist/frontend-module.d.ts +4 -0
- package/dist/frontend-module.js +37 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/implementations/dms/client-ip.js +1 -1
- package/dist/implementations/dms/client-ip.js.map +1 -1
- package/dist/implementations/dms/dev-reload.d.ts +5 -0
- package/dist/implementations/dms/dev-reload.js +23 -3
- package/dist/implementations/dms/dev-reload.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -4
- package/dist/implementations/dms/frontend-modules.js +38 -94
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +12 -2
- package/dist/implementations/dms/frontend-ready.js +34 -4
- package/dist/implementations/dms/frontend-ready.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +2 -1
- package/dist/implementations/dms/layout-banners.js +9 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/manifest.d.ts +7 -2
- package/dist/implementations/dms/manifest.js +12 -7
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +4 -3
- package/dist/implementations/dms/page.js +49 -18
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
- package/dist/implementations/dms/permissions-resolver.js +2 -2
- package/dist/implementations/dms/permissions-resolver.js.map +1 -1
- package/dist/implementations/dms/realtime.js +1 -0
- package/dist/implementations/dms/realtime.js.map +1 -1
- package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
- package/dist/implementations/dms-base/bulk-selection.js +23 -1
- package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
- package/dist/implementations/dms-base/filter-tokens.js +5 -3
- package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
- package/dist/implementations/dms-base/search-route.d.ts +1 -0
- package/dist/implementations/dms-base/search-route.js +35 -13
- package/dist/implementations/dms-base/search-route.js.map +1 -1
- package/dist/implementations/dms-base/table-view.js +11 -6
- package/dist/implementations/dms-base/table-view.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +2 -2
- package/dist/implementations/dms-notifications/index.js +5 -5
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/index.js +32 -55
- package/dist/index.js.map +1 -1
- package/dist/pages/modules/index.d.ts +1 -0
- package/dist/pages/modules/index.js +1 -0
- package/dist/pages/modules/index.js.map +1 -1
- package/dist/pages/modules/modules-store.d.ts +9 -0
- package/dist/pages/modules/modules-store.js +30 -0
- package/dist/pages/modules/modules-store.js.map +1 -0
- package/dist/pages/settings/users/account-credentials.js +2 -2
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/account-data-store.js +25 -8
- package/dist/pages/settings/users/account-data-store.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.js +9 -3
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
- package/dist/pages/settings/users/member-management.js +13 -14
- package/dist/pages/settings/users/member-management.js.map +1 -1
- package/dist/pages/settings/users/profile.d.ts +1 -4
- package/dist/pages/settings/users/profile.js +0 -35
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +26 -18
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +0 -1
- package/dist/pages/settings/users/role-editor.js +1 -2
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +1 -2
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +2 -2
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/realtime/broker.d.ts +6 -0
- package/dist/realtime/broker.js +8 -1
- package/dist/realtime/broker.js.map +1 -1
- package/dist/realtime/presence.d.ts +8 -3
- package/dist/realtime/presence.js +8 -4
- package/dist/realtime/presence.js.map +1 -1
- package/dist/realtime/sessions.d.ts +11 -1
- package/dist/realtime/sessions.js +21 -3
- package/dist/realtime/sessions.js.map +1 -1
- package/dist/realtime/table-view.d.ts +2 -2
- package/dist/realtime/table-view.js +4 -3
- package/dist/realtime/table-view.js.map +1 -1
- package/dist/routes/auth/client-ip.d.ts +1 -0
- package/dist/routes/auth/client-ip.js +18 -0
- package/dist/routes/auth/client-ip.js.map +1 -1
- package/dist/routes/auth/oauth/config.d.ts +2 -1
- package/dist/routes/auth/oauth/config.js +5 -1
- package/dist/routes/auth/oauth/config.js.map +1 -1
- package/dist/routes/auth/session-handoff.d.ts +0 -1
- package/dist/routes/auth/session-handoff.js +0 -2
- package/dist/routes/auth/session-handoff.js.map +1 -1
- package/dist/routes/auth.js +3 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +13 -1
- package/dist/routes/realtime.js +114 -29
- package/dist/routes/realtime.js.map +1 -1
- package/dist/startup-config.d.ts +2 -0
- package/dist/startup-config.js +62 -0
- package/dist/startup-config.js.map +1 -0
- package/dist/store/interfaces.d.ts +3 -2
- package/dist/store/interfaces.js +16 -6
- package/dist/store/interfaces.js.map +1 -1
- package/dist/store/listing.js +25 -15
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +5 -2
- package/dist/store/operations.js.map +1 -1
- package/dist/store/requirements.js +3 -2
- package/dist/store/requirements.js.map +1 -1
- package/dist/store/runtime.d.ts +10 -1
- package/dist/store/runtime.js +33 -6
- package/dist/store/runtime.js.map +1 -1
- package/dist/store/types.d.ts +10 -0
- package/dist/utils/ensure-default-tenant.d.ts +2 -1
- package/dist/utils/ensure-default-tenant.js +13 -1
- package/dist/utils/ensure-default-tenant.js.map +1 -1
- package/dist/utils/export-jobs.js +2 -1
- package/dist/utils/export-jobs.js.map +1 -1
- package/dist/validation/auth.schema.d.ts +2 -2
- package/dist/validation/member-invite.schema.d.ts +2 -10
- package/dist/validation/member-invite.schema.js +2 -15
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +24 -5
- package/frontend-vue/dms.server.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
- package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +33 -0
- package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
- package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
- package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
- package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
- package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
- package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +25 -5
- package/frontend-vue/layers/dms-core/app/composables/useApiError.ts +3 -5
- package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +61 -26
- package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
- package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +134 -35
- package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +136 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +136 -2
- package/frontend-vue/layers/dms-core/shared/types/app-config.ts +0 -2
- package/frontend-vue/layers/dms-layout/app/app.config.ts +0 -1
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +11 -1
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -107
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +4 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
- package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +2 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +49 -11
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +59 -4
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageRecordDeletion.ts +162 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +13 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +22 -52
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-quick-actions.client.ts +7 -7
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-session.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- package/frontend-vue/layers/dms-layout/app/theme/actions.ts +5 -4
- package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
- package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
- package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +45 -18
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +44 -17
- package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
- package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
- package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +48 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
- package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
- package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/actionError.ts +6 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +44 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +123 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +92 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +11 -5
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formValidation.ts +36 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +97 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +90 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/writeError.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/codeHighlight.ts +67 -29
- package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
- package/frontend-vue/layers/dms-ui/app/build/utils/htmlGrammar.ts +79 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/shellParser.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/utils/streamHighlight.ts +90 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
- package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
- package/frontend-vue/layers/dms-ui/app/components/code-snippet/CodeSnippet.vue +23 -12
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
- package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +119 -36
- package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +53 -22
- package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +226 -65
- package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
- package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +210 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
- package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
- package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
- package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
- package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
- package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +74 -25
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +48 -44
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +426 -97
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
- package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
- package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +16 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +189 -28
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +29 -12
- package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
- package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
- package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
- package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
- package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +94 -3
- package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +20 -5
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +20 -5
- package/frontend-vue/package.json +6 -2
- package/package.json +11 -10
- package/skills/dms/SKILL.md +1 -1
- package/skills/dms-auth/SKILL.md +5 -3
- package/skills/dms-best-practices/REFERENCE.md +2 -0
- package/skills/dms-best-practices/SKILL.md +4 -0
- package/skills/dms-module/SKILL.md +3 -2
- package/skills/dms-pages/REFERENCE.md +129 -16
- package/skills/dms-pages/SKILL.md +1 -1
- package/skills/dms-project/DEV-SERVERS.md +23 -1
- package/skills/dms-project/REFERENCE.md +1 -1
- package/skills/dms-project/SKILL.md +4 -1
- package/skills/dms-project/scripts/dms-dev.sh +205 -17
- package/dist/hooks/tenant-instances.d.ts +0 -1
- package/dist/hooks/tenant-instances.js +0 -13
- package/dist/hooks/tenant-instances.js.map +0 -1
- package/dist/routes/startup-gate.d.ts +0 -7
- package/dist/routes/startup-gate.js +0 -39
- package/dist/routes/startup-gate.js.map +0 -1
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onMounted, ref } from "vue";
|
|
3
|
+
import { usePageLive } from "../../composables/live/usePageLive";
|
|
4
|
+
import { pageReadAt } from "../../build/composables/live/pageReadClock";
|
|
5
|
+
import { useUpdatedLabel } from "../../build/composables/live/useUpdatedLabel";
|
|
6
|
+
import {
|
|
7
|
+
type PageToolbarSize,
|
|
8
|
+
providePageToolbar,
|
|
9
|
+
} from "../../build/composables/page-toolbar/pageToolbarContext";
|
|
10
|
+
import { PAGE_TOOLBAR_CONTROL_HEIGHT_CLASSES } from "../../build/composables/page-toolbar/toolbarControlHeight";
|
|
11
|
+
import { refreshPageBlocks } from "../../utils/blockRefresh";
|
|
12
|
+
import type { DefaultComponentProps } from "../../../../dms-core/app/types/component";
|
|
13
|
+
|
|
14
|
+
// Its ids are optional: a component may draw it by hand around controls of
|
|
15
|
+
// its own, outside the page's block tree.
|
|
16
|
+
interface PageToolbarBlockProps extends Partial<DefaultComponentProps> {
|
|
17
|
+
/** The size of its controls, unless a child sets its own. */
|
|
18
|
+
size?: PageToolbarSize;
|
|
19
|
+
/** Without a live toggle on screen: "updated N s ago". */
|
|
20
|
+
showUpdatedAt?: boolean;
|
|
21
|
+
/** Without a live toggle on screen: the button reading the page again. */
|
|
22
|
+
refresh?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const props = withDefaults(defineProps<PageToolbarBlockProps>(), {
|
|
26
|
+
size: "sm",
|
|
27
|
+
showUpdatedAt: true,
|
|
28
|
+
refresh: true,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// The updated label at the live toggle's steps, so it reads alike with or
|
|
32
|
+
// without `live`; the refresh button stands as tall as the toggle's pill.
|
|
33
|
+
const STATUS_TEXT_CLASSES: Record<PageToolbarSize, string> = {
|
|
34
|
+
xs: "text-[11.5px]",
|
|
35
|
+
sm: "text-[12.5px]",
|
|
36
|
+
md: "text-[13px]",
|
|
37
|
+
};
|
|
38
|
+
const REFRESH_ICON = "i-ph-arrow-clockwise";
|
|
39
|
+
|
|
40
|
+
useComponentEvent(props.componentId);
|
|
41
|
+
useWatch(props.watchActions || [], props.componentId);
|
|
42
|
+
|
|
43
|
+
const { t } = useI18n();
|
|
44
|
+
const toolbar = providePageToolbar(computed(() => props.size));
|
|
45
|
+
const live = usePageLive();
|
|
46
|
+
const statusTextClass = computed(() => STATUS_TEXT_CLASSES[props.size]);
|
|
47
|
+
const heightClass = computed(
|
|
48
|
+
() => PAGE_TOOLBAR_CONTROL_HEIGHT_CLASSES[props.size],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// The browser's clock: the server and the hydrating render draw no status.
|
|
52
|
+
const isMounted = ref(false);
|
|
53
|
+
onMounted(() => (isMounted.value = true));
|
|
54
|
+
|
|
55
|
+
// A live page's own clock, else the page's last read.
|
|
56
|
+
const updatedLabel = useUpdatedLabel(
|
|
57
|
+
() => live.lastUpdatedAt.value ?? pageReadAt.value,
|
|
58
|
+
props.showUpdatedAt,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// The live toggle says when the page was updated, and more: the toolbar
|
|
62
|
+
// only does where there is none to see.
|
|
63
|
+
const showsStatus = computed(
|
|
64
|
+
() =>
|
|
65
|
+
isMounted.value &&
|
|
66
|
+
(props.showUpdatedAt || props.refresh) &&
|
|
67
|
+
!(live.isEnabled.value && toolbar.hasLiveToggle.value),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const isRefreshing = ref(false);
|
|
71
|
+
async function refreshPage() {
|
|
72
|
+
if (isRefreshing.value) return;
|
|
73
|
+
isRefreshing.value = true;
|
|
74
|
+
try {
|
|
75
|
+
await refreshPageBlocks();
|
|
76
|
+
} finally {
|
|
77
|
+
isRefreshing.value = false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<template>
|
|
83
|
+
<div
|
|
84
|
+
class="dms-page-toolbar flex w-full flex-wrap items-center justify-end gap-x-3 gap-y-2"
|
|
85
|
+
>
|
|
86
|
+
<slot />
|
|
87
|
+
<span class="dms-page-toolbar__spacer" aria-hidden="true" />
|
|
88
|
+
<div
|
|
89
|
+
v-if="showsStatus"
|
|
90
|
+
class="dms-page-toolbar__status flex items-center gap-1"
|
|
91
|
+
>
|
|
92
|
+
<span
|
|
93
|
+
v-if="props.showUpdatedAt && updatedLabel"
|
|
94
|
+
class="text-muted tabular-nums"
|
|
95
|
+
:class="statusTextClass"
|
|
96
|
+
aria-live="off"
|
|
97
|
+
>
|
|
98
|
+
{{ updatedLabel }}
|
|
99
|
+
</span>
|
|
100
|
+
<UButton
|
|
101
|
+
v-if="props.refresh"
|
|
102
|
+
data-action="refresh"
|
|
103
|
+
color="neutral"
|
|
104
|
+
variant="ghost"
|
|
105
|
+
square
|
|
106
|
+
:size="props.size"
|
|
107
|
+
:class="heightClass"
|
|
108
|
+
:icon="REFRESH_ICON"
|
|
109
|
+
:loading="isRefreshing"
|
|
110
|
+
:aria-label="t('dms.live.refresh')"
|
|
111
|
+
:title="t('dms.live.refresh')"
|
|
112
|
+
@click="refreshPage"
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</template>
|
|
117
|
+
|
|
118
|
+
<style>
|
|
119
|
+
/* One order whatever the children's: the leading blocks, the spacer, the
|
|
120
|
+
updated label or the live toggle, then the period. A child is matched by
|
|
121
|
+
the block it draws, through the wrappers a role preview may add. Wrapped
|
|
122
|
+
onto more lines, the trailing controls stay on the right. */
|
|
123
|
+
.dms-page-toolbar > * {
|
|
124
|
+
order: 0;
|
|
125
|
+
}
|
|
126
|
+
.dms-page-toolbar > .dms-page-toolbar__spacer {
|
|
127
|
+
order: 1;
|
|
128
|
+
flex: 1 1 0%;
|
|
129
|
+
}
|
|
130
|
+
.dms-page-toolbar > .dms-page-toolbar__status,
|
|
131
|
+
.dms-page-toolbar > :is(.dms-live-toggle, :has(.dms-live-toggle)) {
|
|
132
|
+
order: 2;
|
|
133
|
+
}
|
|
134
|
+
.dms-page-toolbar > :is(.dms-period-selector, :has(.dms-period-selector)) {
|
|
135
|
+
order: 3;
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import DmsStatGroup, {
|
|
4
|
+
type StatGroupColumnsFrom,
|
|
4
5
|
type StatGroupItem,
|
|
5
6
|
type StatGroupLayout,
|
|
6
7
|
} from "../stat-group/StatGroup.vue";
|
|
@@ -27,6 +28,8 @@ interface StatGroupBlockProps extends DefaultComponentProps {
|
|
|
27
28
|
items?: StatGroupBlockItem[];
|
|
28
29
|
layout?: StatGroupLayout;
|
|
29
30
|
columns?: number;
|
|
31
|
+
/** The group's width from which all `columns` sit side by side. */
|
|
32
|
+
columnsFrom?: StatGroupColumnsFrom;
|
|
30
33
|
/** Accessible name of the group. */
|
|
31
34
|
label?: string;
|
|
32
35
|
fetchUrl?: string;
|
|
@@ -48,6 +51,7 @@ const props = withDefaults(defineProps<StatGroupBlockProps>(), {
|
|
|
48
51
|
items: () => [],
|
|
49
52
|
layout: "joined",
|
|
50
53
|
columns: undefined,
|
|
54
|
+
columnsFrom: undefined,
|
|
51
55
|
label: undefined,
|
|
52
56
|
fetchUrl: undefined,
|
|
53
57
|
fetchUrlMethod: undefined,
|
|
@@ -100,6 +104,7 @@ const resolvedItems = computed<StatGroupItem[]>(() =>
|
|
|
100
104
|
:items="resolvedItems"
|
|
101
105
|
:layout="props.layout"
|
|
102
106
|
:columns="props.columns"
|
|
107
|
+
:columns-from="props.columnsFrom"
|
|
103
108
|
:loading="isPending"
|
|
104
109
|
:skeleton-count="
|
|
105
110
|
props.skeletonCount ?? props.columns ?? DEFAULT_SKELETON_COUNT
|
|
@@ -117,11 +117,24 @@ function pushOptionsWithoutGroupBroadcast(
|
|
|
117
117
|
.catch(() => undefined);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
function axisTypeOf(options: Record<string, unknown>): unknown {
|
|
121
|
+
return (options.xaxis as Record<string, unknown> | undefined)?.type;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Apex merges an update into the options it holds: an option the update no
|
|
126
|
+
* longer sets stays. A category axis drawing calendar buckets carries its own
|
|
127
|
+
* label and tooltip formatters, which a datetime axis would keep writing raw
|
|
128
|
+
* timestamps with (and the reverse leaves Apex's datetime state behind), so a
|
|
129
|
+
* chart whose X axis changes type is drawn anew rather than updated.
|
|
130
|
+
*/
|
|
131
|
+
const axisType = computed(() => String(axisTypeOf(props.options) ?? ""));
|
|
132
|
+
|
|
120
133
|
watch(
|
|
121
134
|
() => props.options,
|
|
122
|
-
(next) => {
|
|
135
|
+
(next, previous) => {
|
|
123
136
|
const instance = chartRef.value;
|
|
124
|
-
if (!instance) {
|
|
137
|
+
if (!instance || axisTypeOf(next) !== axisTypeOf(previous)) {
|
|
125
138
|
pinnedOptions.value = rawApexInput(next);
|
|
126
139
|
return;
|
|
127
140
|
}
|
|
@@ -158,6 +171,7 @@ function redrawIfResizedWhileAnimating() {
|
|
|
158
171
|
<template>
|
|
159
172
|
<div ref="hostRef" class="dms-apex">
|
|
160
173
|
<ApexChart
|
|
174
|
+
:key="axisType"
|
|
161
175
|
ref="chartRef"
|
|
162
176
|
:type="apexType"
|
|
163
177
|
:height="height"
|
|
@@ -11,6 +11,10 @@ import { useChartFetch } from "../../composables/chart/useChartFetch";
|
|
|
11
11
|
import { useThemeRevision } from "../../composables/chart/useThemeRevision";
|
|
12
12
|
import { formatValue } from "../../composables/chart/formatValue";
|
|
13
13
|
import { toDonutRecords } from "../../composables/chart/donutRecords";
|
|
14
|
+
import {
|
|
15
|
+
localizeDonutRecords,
|
|
16
|
+
localizeSeries,
|
|
17
|
+
} from "../../composables/chart/localizeSeries";
|
|
14
18
|
import {
|
|
15
19
|
CHART_EVENT_NAMES,
|
|
16
20
|
isSegmentChart,
|
|
@@ -117,16 +121,26 @@ const themeRevision = useThemeRevision();
|
|
|
117
121
|
|
|
118
122
|
const isCircular = computed(() => CIRCULAR_CHART_TYPES.includes(props.type));
|
|
119
123
|
|
|
124
|
+
// A bare chart's own series and slices are translated like a card's: the
|
|
125
|
+
// `$` keys of a name, a category or a label reach Apex in the reader's
|
|
126
|
+
// language. A nested chart receives its card's series already translated.
|
|
127
|
+
function localized(series: ChartSeries[]): ChartSeries[] {
|
|
128
|
+
return series.map((entry) => localizeSeries(entry, processI18n));
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
const staticSeries = computed<ChartSeries[]>(() => {
|
|
121
132
|
if (isCircular.value) return [];
|
|
122
133
|
if (!props.staticDataset) return [];
|
|
123
|
-
return props.staticDataset as ChartSeries[];
|
|
134
|
+
return localized(props.staticDataset as ChartSeries[]);
|
|
124
135
|
});
|
|
125
136
|
|
|
126
137
|
const staticDonut = computed<DonutRecord[]>(() => {
|
|
127
138
|
if (!isCircular.value) return [];
|
|
128
139
|
if (!props.staticDataset) return [];
|
|
129
|
-
return
|
|
140
|
+
return localizeDonutRecords(
|
|
141
|
+
props.staticDataset as DonutRecord[],
|
|
142
|
+
processI18n,
|
|
143
|
+
);
|
|
130
144
|
});
|
|
131
145
|
|
|
132
146
|
const isNested = computed(() => !!nestedContext);
|
|
@@ -148,7 +162,7 @@ const seriesFromCtx = computed<ChartSeries[]>(() => {
|
|
|
148
162
|
|
|
149
163
|
const fetchSeries = computed<ChartSeries[]>(() => {
|
|
150
164
|
if (!data.value) return [];
|
|
151
|
-
return data.value.series ?? [];
|
|
165
|
+
return localized(data.value.series ?? []);
|
|
152
166
|
});
|
|
153
167
|
|
|
154
168
|
const finalSeries = computed<ChartSeries[]>(() => {
|
|
@@ -185,14 +199,18 @@ function buildXyClickPayload(opts: {
|
|
|
185
199
|
seriesIndex: number;
|
|
186
200
|
}): ChartClickPayload {
|
|
187
201
|
const series = finalSeries.value[opts.seriesIndex];
|
|
188
|
-
const
|
|
202
|
+
const dataPointIndex = apex.sourcePointIndex(
|
|
203
|
+
opts.seriesIndex,
|
|
204
|
+
opts.dataPointIndex,
|
|
205
|
+
);
|
|
206
|
+
const point = series?.data[dataPointIndex];
|
|
189
207
|
const pointValue = readPointValue(point);
|
|
190
208
|
const label =
|
|
191
209
|
typeof point === "object" && point !== null && "label" in point
|
|
192
210
|
? (point as { label?: string }).label
|
|
193
211
|
: undefined;
|
|
194
212
|
return {
|
|
195
|
-
dataPointIndex
|
|
213
|
+
dataPointIndex,
|
|
196
214
|
seriesIndex: opts.seriesIndex,
|
|
197
215
|
...pointValue,
|
|
198
216
|
seriesName: series?.name ?? "",
|
|
@@ -276,6 +294,7 @@ const apex = useApexChart(() => ({
|
|
|
276
294
|
xAxis: props.xAxis,
|
|
277
295
|
xAxisFormatter: props.xAxisFormatter,
|
|
278
296
|
yAxisFormatter: yAxisFormatter.value,
|
|
297
|
+
locale: locale.value,
|
|
279
298
|
onDataPointClick: emitDataClick,
|
|
280
299
|
}));
|
|
281
300
|
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
} from "../../composables/chart/formatValue";
|
|
13
13
|
import { resolveChartColor } from "../../composables/chart/useChartTheme";
|
|
14
14
|
import { useThemeRevision } from "../../composables/chart/useThemeRevision";
|
|
15
|
+
import { usePeriodComparisonDisplay } from "../../build/composables/period/periodComparison";
|
|
16
|
+
import { localizeSeries } from "../../composables/chart/localizeSeries";
|
|
15
17
|
import {
|
|
16
18
|
NESTED_CHART_INJECT_KEY,
|
|
17
19
|
type ChartCardResponse,
|
|
@@ -34,6 +36,8 @@ interface Props extends DefaultComponentProps {
|
|
|
34
36
|
currencyCode?: string;
|
|
35
37
|
valuePrecision?: ValuePrecision;
|
|
36
38
|
showDelta?: boolean;
|
|
39
|
+
/** A rising value is the bad outcome: the delta's colours swap. */
|
|
40
|
+
invert?: boolean;
|
|
37
41
|
showLegend?: boolean;
|
|
38
42
|
/** The wrapped chart draws its own legend, naming each series. */
|
|
39
43
|
showSeriesLegend?: boolean;
|
|
@@ -80,26 +84,35 @@ const { data, isLoading } = useChartFetch<ChartCardResponse>({
|
|
|
80
84
|
watchSource: () => watchKey.value,
|
|
81
85
|
});
|
|
82
86
|
|
|
87
|
+
// With no comparison selected on the scope, whatever comparison the data
|
|
88
|
+
// still carries is not drawn: no change, no "vs" figure, no second series.
|
|
89
|
+
const comparison = usePeriodComparisonDisplay(props.periodScope);
|
|
83
90
|
const value = computed(() => data.value?.value);
|
|
84
|
-
const previousValue = computed(() =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
const previousValue = computed(() =>
|
|
92
|
+
comparison.isOff.value ? undefined : data.value?.previousValue,
|
|
93
|
+
);
|
|
94
|
+
const delta = computed(() =>
|
|
95
|
+
comparison.isOff.value ? null : (data.value?.delta ?? null),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// ApexCharts prints names, categories and slice labels verbatim, so a
|
|
99
|
+
// route's `$` keys are resolved here, before the array reaches the nested
|
|
100
|
+
// chart and the default slot.
|
|
101
|
+
function localized(entry: ChartSeries): ChartSeries {
|
|
102
|
+
return localizeSeries(entry, processI18n);
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
const cardSeries = computed<ChartSeries[]>(() =>
|
|
95
|
-
(data.value?.series ?? []).map(
|
|
106
|
+
(data.value?.series ?? []).map(localized),
|
|
96
107
|
);
|
|
97
108
|
|
|
98
109
|
const cardComparisonSeries = computed<ChartSeries[]>(() =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
comparison.isOff.value
|
|
111
|
+
? []
|
|
112
|
+
: (data.value?.comparisonSeries ?? []).map((entry) => ({
|
|
113
|
+
...localized(entry),
|
|
114
|
+
color: entry.color ?? comparisonColor.value,
|
|
115
|
+
})),
|
|
103
116
|
);
|
|
104
117
|
|
|
105
118
|
const formatted = computed(() =>
|
|
@@ -116,13 +129,15 @@ const formatted = computed(() =>
|
|
|
116
129
|
|
|
117
130
|
const previousFormatted = computed(() =>
|
|
118
131
|
previousValue.value !== undefined
|
|
119
|
-
?
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
? t("dms.chart.versus_value", {
|
|
133
|
+
value: formatValue(
|
|
134
|
+
previousValue.value,
|
|
135
|
+
props.valueFormat,
|
|
136
|
+
locale.value,
|
|
137
|
+
props.currencyCode,
|
|
138
|
+
props.valuePrecision,
|
|
139
|
+
),
|
|
140
|
+
})
|
|
126
141
|
: null,
|
|
127
142
|
);
|
|
128
143
|
|
|
@@ -155,10 +170,13 @@ const primaryLegendLabel = computed(() =>
|
|
|
155
170
|
? processI18n(props.primaryLabel)
|
|
156
171
|
: t(DEFAULT_PRIMARY_LABEL_KEY, "Period"),
|
|
157
172
|
);
|
|
173
|
+
// The comparison the scope selects names its series ("Previous year"),
|
|
174
|
+
// unless the card names it itself.
|
|
158
175
|
const comparisonLegendLabel = computed(() =>
|
|
159
176
|
props.comparisonLabel
|
|
160
177
|
? processI18n(props.comparisonLabel)
|
|
161
|
-
:
|
|
178
|
+
: (comparison.legendLabel.value ??
|
|
179
|
+
t(DEFAULT_COMPARISON_LABEL_KEY, "Comparison")),
|
|
162
180
|
);
|
|
163
181
|
|
|
164
182
|
const isFirstLoad = computed(() => isLoading.value && data.value === null);
|
|
@@ -215,9 +233,9 @@ const hasMeta = computed(
|
|
|
215
233
|
class="mt-1.5 flex flex-wrap items-center gap-2 transition-opacity"
|
|
216
234
|
:class="isRefreshing && 'opacity-55'"
|
|
217
235
|
>
|
|
218
|
-
<DmsTrendBadge v-if="showTrend" :delta="delta" />
|
|
236
|
+
<DmsTrendBadge v-if="showTrend" :delta="delta" :invert="invert" />
|
|
219
237
|
<span v-if="previousFormatted" class="text-dimmed text-xs">
|
|
220
|
-
|
|
238
|
+
{{ previousFormatted }}
|
|
221
239
|
</span>
|
|
222
240
|
<span v-else-if="description" class="text-dimmed text-xs">
|
|
223
241
|
{{ processI18n(description) }}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, onMounted, shallowRef } from "vue";
|
|
2
|
+
import { computed, onMounted, shallowRef, watch } from "vue";
|
|
3
3
|
import DmsCopyButton from "../copy/CopyButton.vue";
|
|
4
4
|
import {
|
|
5
5
|
codeLanguageLabel,
|
|
6
6
|
PLAIN_CODE_LANGUAGE,
|
|
7
7
|
resolveCodeLanguage,
|
|
8
8
|
} from "../../build/utils/codeLanguages";
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
CodeHighlighter,
|
|
11
|
+
CodeToken,
|
|
12
|
+
} from "../../build/utils/codeHighlight";
|
|
10
13
|
|
|
11
14
|
// Read-only code in the editor's look: a head with the title, the language
|
|
12
15
|
// and a copy button, then the code highlighted by the editor's languages.
|
|
13
16
|
// Without a title or a language there is no head: the copy button floats in
|
|
14
|
-
// the code's corner. Until
|
|
15
|
-
// code shows as is.
|
|
17
|
+
// the code's corner. Until its language's grammar loads (and on the server)
|
|
18
|
+
// the code shows as is.
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* How long lines break: `false` scrolls them sideways, `true` wraps them
|
|
@@ -63,7 +66,7 @@ const WRAP_CLASSES: Record<"false" | "true" | "anywhere", string> = {
|
|
|
63
66
|
anywhere: "whitespace-pre-wrap [overflow-wrap:anywhere]",
|
|
64
67
|
};
|
|
65
68
|
|
|
66
|
-
const highlight = shallowRef<
|
|
69
|
+
const highlight = shallowRef<CodeHighlighter | null>(null);
|
|
67
70
|
|
|
68
71
|
const language = computed(() => resolveCodeLanguage(props.language));
|
|
69
72
|
// A language given, even `text`, is named in a head; without a title either,
|
|
@@ -79,9 +82,7 @@ const wrapClass = computed(
|
|
|
79
82
|
() => WRAP_CLASSES[String(props.wrap) as keyof typeof WRAP_CLASSES],
|
|
80
83
|
);
|
|
81
84
|
const tokens = computed<CodeToken[]>(() =>
|
|
82
|
-
highlight.value
|
|
83
|
-
? highlight.value(props.code, language.value)
|
|
84
|
-
: [{ text: props.code }],
|
|
85
|
+
highlight.value ? highlight.value(props.code) : [{ text: props.code }],
|
|
85
86
|
);
|
|
86
87
|
const sizeStyle = computed(() => {
|
|
87
88
|
if (props.maxLines)
|
|
@@ -91,10 +92,20 @@ const sizeStyle = computed(() => {
|
|
|
91
92
|
return props.maxHeight ? { maxHeight: props.maxHeight } : undefined;
|
|
92
93
|
});
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
// Only the grammar of the language shown loads. A language changed while
|
|
96
|
+
// one loads drops it: the code stays plain until its own grammar is in.
|
|
97
|
+
async function loadHighlighter(): Promise<void> {
|
|
98
|
+
const requested = language.value;
|
|
99
|
+
highlight.value = null;
|
|
100
|
+
const { loadCodeHighlighter } = await import(
|
|
101
|
+
"../../build/utils/codeHighlight"
|
|
102
|
+
);
|
|
103
|
+
const highlighter = await loadCodeHighlighter(requested);
|
|
104
|
+
if (language.value === requested) highlight.value = highlighter;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
onMounted(loadHighlighter);
|
|
108
|
+
watch(language, loadHighlighter);
|
|
98
109
|
</script>
|
|
99
110
|
|
|
100
111
|
<template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The footer band of a drawer's or a modal's body component: its buttons
|
|
4
|
+
* under a hairline, flush with the container's edges. It sticks to the
|
|
5
|
+
* bottom of the container while the content runs past it. In a drawer, whose
|
|
6
|
+
* body is a flex column, a body component whose root grows (`flex-1`, and
|
|
7
|
+
* `flex flex-col` to lay its own content out) keeps it at the bottom of the
|
|
8
|
+
* drawer while its content is short.
|
|
9
|
+
*/
|
|
10
|
+
interface ContainerFooterProps {
|
|
11
|
+
/** Where the buttons sit along the band; `end` by default. */
|
|
12
|
+
justify?: "start" | "end" | "between";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<ContainerFooterProps>(), {
|
|
16
|
+
justify: "end",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Same band as a form's footer in a container (FORM_SURFACE_CLASSES), but
|
|
20
|
+
// pushed to the bottom (`mt-auto`) rather than set under the fields.
|
|
21
|
+
const FOOTER_CLASS =
|
|
22
|
+
"border-default bg-default sticky bottom-[calc(var(--dms-form-foot-pb,0px)*-1)] z-10 mt-auto -mx-[var(--dms-form-foot-px,0px)] -mb-[var(--dms-form-foot-pb,0px)] flex flex-wrap items-center gap-2 border-t px-[var(--dms-form-foot-px,0px)] pt-3 pb-[var(--dms-form-foot-pb,12px)]";
|
|
23
|
+
const JUSTIFY_CLASSES = {
|
|
24
|
+
start: "justify-start",
|
|
25
|
+
end: "justify-end",
|
|
26
|
+
between: "justify-between",
|
|
27
|
+
} as const;
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<footer :class="[FOOTER_CLASS, JUSTIFY_CLASSES[props.justify]]">
|
|
32
|
+
<slot />
|
|
33
|
+
</footer>
|
|
34
|
+
</template>
|
|
@@ -8,9 +8,10 @@ export type FieldRowLayout = "inline" | "form" | "stack";
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* `row`: the row pads itself and draws a hairline above the next one (rows
|
|
11
|
-
* of a card). `
|
|
11
|
+
* of a card). `dense`: the same, tighter, for a form in a drawer or a modal.
|
|
12
|
+
* `list`: the list around it spaces the rows (a stacked form).
|
|
12
13
|
*/
|
|
13
|
-
export type FieldRowSpacing = "row" | "list";
|
|
14
|
+
export type FieldRowSpacing = "row" | "dense" | "list";
|
|
14
15
|
|
|
15
16
|
// The renderer's props are optional: DmsFieldRow is both the backend
|
|
16
17
|
// `FieldRow` block (`dms-field-row-block`) and a template component.
|
|
@@ -34,6 +35,12 @@ interface FieldRowProps extends Partial<DefaultComponentProps> {
|
|
|
34
35
|
required?: boolean;
|
|
35
36
|
/** Dims the whole row. */
|
|
36
37
|
disabled?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* `stack` only: the row and its control fill the height their flex parent
|
|
40
|
+
* leaves them (a drawer's body), handing it to a control that fills it
|
|
41
|
+
* (`DmsInputCode fill`).
|
|
42
|
+
*/
|
|
43
|
+
fill?: boolean;
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
interface FieldRowSlots {
|
|
@@ -56,6 +63,7 @@ const props = withDefaults(defineProps<FieldRowProps>(), {
|
|
|
56
63
|
spacing: "row",
|
|
57
64
|
required: false,
|
|
58
65
|
disabled: false,
|
|
66
|
+
fill: false,
|
|
59
67
|
});
|
|
60
68
|
const slots = defineSlots<FieldRowSlots>();
|
|
61
69
|
|
|
@@ -102,11 +110,25 @@ const theme = tv({
|
|
|
102
110
|
},
|
|
103
111
|
spacing: {
|
|
104
112
|
row: { root: "border-t border-muted first:border-t-0", body: "py-4" },
|
|
113
|
+
// 12px above and below a 32px control, 6px from a label set above it.
|
|
114
|
+
dense: {
|
|
115
|
+
root: "border-t border-muted first:border-t-0",
|
|
116
|
+
body: "py-3 gap-y-1.5",
|
|
117
|
+
},
|
|
105
118
|
list: { body: "gap-y-1.5" },
|
|
106
119
|
},
|
|
107
120
|
disabled: {
|
|
108
121
|
true: { root: "opacity-55" },
|
|
109
122
|
},
|
|
123
|
+
// Flex columns down to the control, which grows: their minimum stays
|
|
124
|
+
// their content's (the control's floor), the parent scrolling below it.
|
|
125
|
+
fill: {
|
|
126
|
+
true: {
|
|
127
|
+
root: "flex flex-1 flex-col",
|
|
128
|
+
body: "flex flex-1 flex-col",
|
|
129
|
+
control: "flex flex-1 flex-col",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
110
132
|
// Without a label cell, the control is the grid's only child: it spans
|
|
111
133
|
// both columns instead of falling into the form's 240px label column.
|
|
112
134
|
labeled: {
|
|
@@ -124,6 +146,7 @@ const ui = computed(() =>
|
|
|
124
146
|
inset: props.inset,
|
|
125
147
|
spacing: props.spacing,
|
|
126
148
|
disabled: props.disabled,
|
|
149
|
+
fill: props.fill && props.layout === "stack",
|
|
127
150
|
labeled: hasText.value,
|
|
128
151
|
}),
|
|
129
152
|
);
|
|
@@ -313,8 +313,8 @@ defineExpose(flow);
|
|
|
313
313
|
type="button"
|
|
314
314
|
class="dms-flow-canvas__delete-button"
|
|
315
315
|
:style="{ left: `${affordance.x}px`, top: `${affordance.y}px` }"
|
|
316
|
-
title="
|
|
317
|
-
aria-label="
|
|
316
|
+
:title="$t('dms.flow_canvas.delete_node')"
|
|
317
|
+
:aria-label="$t('dms.flow_canvas.delete_node')"
|
|
318
318
|
@click.stop="emitDelete([affordance.id])"
|
|
319
319
|
>
|
|
320
320
|
<svg
|