@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.
- package/CHANGELOG.md +102 -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 -0
- package/dist/config.js +5 -3
- 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 +22 -89
- 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 +1 -2
- package/dist/implementations/dms/manifest.js +2 -0
- 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 +28 -48
- 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 +24 -13
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +4 -0
- 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/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 +34 -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/hydration/isHydratingComponent.ts +29 -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 +22 -5
- 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 +166 -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 +134 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +134 -2
- 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 +9 -0
- 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 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionBar.vue +8 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +14 -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/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/usePageRecord.ts +50 -0
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +25 -7
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +51 -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/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +9 -0
- 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 +6 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +14 -44
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- 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/app/utils/pageRecord.ts +71 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +39 -14
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +38 -13
- 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/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 +38 -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/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 +47 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +99 -24
- 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 +71 -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/formSections.ts +32 -0
- 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 +65 -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 +73 -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 +77 -32
- 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/utils/addressSuggestions.ts +49 -0
- 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/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/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/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 +118 -36
- 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 +205 -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 +203 -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/KanbanBoard.vue +45 -35
- 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 +410 -96
- 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 +4 -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 +142 -21
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +11 -4
- 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/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -4
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -4
- package/frontend-vue/package.json +2 -2
- package/package.json +7 -6
- 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 +125 -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/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
|
@@ -5,6 +5,7 @@ import { useDevReloading } from "../build/composables/dev-reload/useDevReloadHol
|
|
|
5
5
|
import { usePageLiveHost } from "#dms-ui/app/build/composables/live/usePageLiveHost";
|
|
6
6
|
import { usePageDataRefresh } from "#dms-ui/app/build/composables/live/usePageDataRefresh";
|
|
7
7
|
import { pageValidationRedirect } from "../build/utils/pageValidationRedirect";
|
|
8
|
+
import { resolveComponentChildren } from "#dms-ui/app/utils/componentTree";
|
|
8
9
|
|
|
9
10
|
defineOptions({ inheritAttrs: false });
|
|
10
11
|
|
|
@@ -215,9 +216,10 @@ if (import.meta.env.DEV) {
|
|
|
215
216
|
|
|
216
217
|
const { pageLayout } = await usePageLayout();
|
|
217
218
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
// A client navigation shows the page once its blocks' code is there: a lazy
|
|
220
|
+
// block draws nothing until its chunk lands, then pushes the page down.
|
|
221
|
+
await preloadPageLayoutComponents(pageLayout.value);
|
|
222
|
+
watch(pageLayout, (layout) => void preloadPageLayoutComponents(layout));
|
|
221
223
|
|
|
222
224
|
const { refreshIfStale: refreshPermissionsIfStale } = usePermissions();
|
|
223
225
|
|
|
@@ -345,24 +347,6 @@ watch(
|
|
|
345
347
|
onMounted(runPageSetup);
|
|
346
348
|
onUnmounted(tearDownPageSetup);
|
|
347
349
|
|
|
348
|
-
const processChildren = (
|
|
349
|
-
children: ComponentChild[],
|
|
350
|
-
): ResolvedComponentInfo[] => {
|
|
351
|
-
return children.map((child) => {
|
|
352
|
-
const { id, component, ...additionalProps } = child;
|
|
353
|
-
return {
|
|
354
|
-
id,
|
|
355
|
-
options: component.options,
|
|
356
|
-
component: component.componentName
|
|
357
|
-
? resolveDmsComponent(component.componentName) || "div"
|
|
358
|
-
: "div",
|
|
359
|
-
componentName: component.componentName,
|
|
360
|
-
children: component.children ? processChildren(component.children) : [],
|
|
361
|
-
...additionalProps,
|
|
362
|
-
};
|
|
363
|
-
});
|
|
364
|
-
};
|
|
365
|
-
|
|
366
350
|
const components = computed(() =>
|
|
367
351
|
Object.keys(pageLayout.value?.components || {}).map((field) => {
|
|
368
352
|
const componentInfo = pageLayout.value?.components[field];
|
|
@@ -374,7 +358,7 @@ const components = computed(() =>
|
|
|
374
358
|
: "div",
|
|
375
359
|
componentName: componentInfo?.componentName,
|
|
376
360
|
children: componentInfo?.children
|
|
377
|
-
?
|
|
361
|
+
? resolveComponentChildren(componentInfo.children)
|
|
378
362
|
: [],
|
|
379
363
|
} as ResolvedComponentInfo;
|
|
380
364
|
}),
|
|
@@ -22,7 +22,8 @@ function collectNavigationItems(
|
|
|
22
22
|
|
|
23
23
|
const label = resolveI18nKey(translate, child.displayName);
|
|
24
24
|
const to = buildMenuItemTarget(child);
|
|
25
|
-
|
|
25
|
+
// The account entries (Settings, Profile) are the session group's.
|
|
26
|
+
if (to && child.fullSlug && !isAccountMenuRoute(to)) {
|
|
26
27
|
items.push({
|
|
27
28
|
label,
|
|
28
29
|
suffix:
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { CommandPaletteGroup
|
|
1
|
+
import type { CommandPaletteGroup } from "@nuxt/ui";
|
|
2
|
+
import {
|
|
3
|
+
type RecentModule,
|
|
4
|
+
recentModules,
|
|
5
|
+
} from "../build/utils/modules-catalog";
|
|
2
6
|
|
|
3
7
|
const PERSONAL_PAGES_SOURCE_ID = "dms-personal-pages";
|
|
4
8
|
const PERSONAL_PAGES_SOURCE_ORDER = 20;
|
|
5
9
|
const FAVORITES_GROUP_ID = "favorite-pages";
|
|
6
10
|
const RECENT_MODULES_GROUP_ID = "recent-modules";
|
|
7
11
|
|
|
8
|
-
type AccessibleModules = Record<string, ModuleWithAccess> | undefined;
|
|
9
|
-
|
|
10
|
-
type PathLabelResolver = (path: string) => string | undefined;
|
|
11
|
-
|
|
12
12
|
function buildFavoritesGroup(
|
|
13
13
|
favorites: FavoritePage[],
|
|
14
14
|
translate: I18nTranslate,
|
|
@@ -26,42 +26,20 @@ function buildFavoritesGroup(
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function buildRecentModuleItem(
|
|
30
|
-
entry: ModuleHistoryEntry,
|
|
31
|
-
modules: AccessibleModules,
|
|
32
|
-
translate: I18nTranslate,
|
|
33
|
-
resolvePathLabel: PathLabelResolver,
|
|
34
|
-
): CommandPaletteItem | null {
|
|
35
|
-
const module = modules?.[entry.moduleId];
|
|
36
|
-
if (!module?.hasAccess) return null;
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
label: resolveI18nKey(translate, module.title),
|
|
40
|
-
suffix: resolvePathLabel(entry.path),
|
|
41
|
-
icon: module.icon,
|
|
42
|
-
to: entry.path,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
29
|
function buildRecentModulesGroup(
|
|
47
|
-
|
|
48
|
-
modules: AccessibleModules,
|
|
30
|
+
modules: RecentModule[],
|
|
49
31
|
translate: I18nTranslate,
|
|
50
|
-
resolvePathLabel: PathLabelResolver,
|
|
51
32
|
): CommandPaletteGroup | null {
|
|
52
|
-
|
|
53
|
-
.slice()
|
|
54
|
-
.reverse()
|
|
55
|
-
.map((entry) =>
|
|
56
|
-
buildRecentModuleItem(entry, modules, translate, resolvePathLabel),
|
|
57
|
-
)
|
|
58
|
-
.filter((item): item is CommandPaletteItem => item !== null);
|
|
59
|
-
if (items.length === 0) return null;
|
|
33
|
+
if (modules.length === 0) return null;
|
|
60
34
|
|
|
61
35
|
return {
|
|
62
36
|
id: RECENT_MODULES_GROUP_ID,
|
|
63
37
|
label: translate("commandPalette.groups.recentModules", {}),
|
|
64
|
-
items
|
|
38
|
+
items: modules.map((module) => ({
|
|
39
|
+
label: resolveI18nKey(translate, module.title),
|
|
40
|
+
icon: module.icon,
|
|
41
|
+
to: module.to,
|
|
42
|
+
})),
|
|
65
43
|
};
|
|
66
44
|
}
|
|
67
45
|
|
|
@@ -69,22 +47,14 @@ export default defineDmsPlugin(() => {
|
|
|
69
47
|
const { translate } = getPluginI18n();
|
|
70
48
|
const { sortedFavorites } = useFavoritePages();
|
|
71
49
|
const { entries } = useModuleHistory();
|
|
72
|
-
const { modules,
|
|
73
|
-
|
|
74
|
-
const resolvePathLabel: PathLabelResolver = (path) => {
|
|
75
|
-
const match = findMatchingRoute(path);
|
|
76
|
-
if (!match) return undefined;
|
|
77
|
-
return resolveI18nKey(translate, match.metadata.displayName);
|
|
78
|
-
};
|
|
50
|
+
const { modules, siteLayoutTree } = useSiteLayout();
|
|
79
51
|
|
|
80
52
|
const groups = computed<CommandPaletteGroup[]>(() =>
|
|
81
53
|
[
|
|
82
54
|
buildFavoritesGroup(sortedFavorites.value, translate),
|
|
83
55
|
buildRecentModulesGroup(
|
|
84
|
-
entries.value,
|
|
85
|
-
modules.value,
|
|
56
|
+
recentModules(entries.value, modules.value, siteLayoutTree.value),
|
|
86
57
|
translate,
|
|
87
|
-
resolvePathLabel,
|
|
88
58
|
),
|
|
89
59
|
].filter((group): group is CommandPaletteGroup => group !== null),
|
|
90
60
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useDevReloadHolder } from "../build/composables/dev-reload/useDevReloadHolder";
|
|
2
|
-
import {
|
|
2
|
+
import { followDevReload } from "../build/utils/dev-reload-stream";
|
|
3
3
|
|
|
4
4
|
const RELOAD_ENDPOINT_PATH = "/dms/dev/reload";
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ function resolveBackendBase(): string | null {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Dev-only: turn the backend's
|
|
14
|
+
* Dev-only: turn the backend's reload signal into a soft refresh.
|
|
15
15
|
*
|
|
16
16
|
* All the waiting lives in the dev-reload coordinator (see `useDevReloadHolder`), so
|
|
17
17
|
* this plugin and the `useDevReload().awaitRoute` module frontends call
|
|
@@ -25,14 +25,19 @@ export default defineDmsPlugin(() => {
|
|
|
25
25
|
|
|
26
26
|
const endpoint = `${backendBase}${RELOAD_ENDPOINT_PATH}`;
|
|
27
27
|
const { coordinator } = useDevReloadHolder();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
// Carried by the user's realtime stream while it is open, by a stream of
|
|
29
|
+
// its own otherwise (the sign-in page).
|
|
30
|
+
const stream = followDevReload(
|
|
31
|
+
{
|
|
32
|
+
endpoint,
|
|
33
|
+
onReload: () => {
|
|
34
|
+
void coordinator.requestRefresh().catch((err: unknown) => {
|
|
35
|
+
console.error("[dms-dev-reload] Reload handler failed:", err);
|
|
36
|
+
});
|
|
37
|
+
},
|
|
34
38
|
},
|
|
35
|
-
|
|
39
|
+
useUserRealtime(),
|
|
40
|
+
);
|
|
36
41
|
|
|
37
42
|
if (import.meta.hot) {
|
|
38
43
|
import.meta.hot.dispose(() => {
|
|
@@ -117,11 +117,16 @@ const inputTheme = {
|
|
|
117
117
|
],
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Select-like triggers: the input scale with explicit line heights, so a
|
|
122
|
+
* select is as tall as the text field beside it. Below md they keep the
|
|
123
|
+
* input's 16px (14px for sm), as a text field does, so a form on a phone
|
|
124
|
+
* reads in one size.
|
|
125
|
+
*/
|
|
121
126
|
const SELECT_TRIGGER_SIZES = {
|
|
122
|
-
sm: { base: "px-2 text-[12.5px]/4" },
|
|
123
|
-
md: { base: "text-[13px]/5" },
|
|
124
|
-
xl: { base: "text-[15px]/6" },
|
|
127
|
+
sm: { base: "px-2 text-sm/4 md:text-[12.5px]/4" },
|
|
128
|
+
md: { base: "text-base/5 md:text-[13px]/5" },
|
|
129
|
+
xl: { base: "text-base/6 md:text-[15px]/6" },
|
|
125
130
|
};
|
|
126
131
|
|
|
127
132
|
/**
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { EYEBROW_CLASS } from "#dms-ui/app/build/utils/eyebrow";
|
|
12
|
+
import {
|
|
13
|
+
CLOSING_OVERLAY_CLASS,
|
|
14
|
+
UNCOVERED_PANEL_CLASS,
|
|
15
|
+
} from "#dms-ui/app/build/components/containers/constants";
|
|
12
16
|
|
|
13
17
|
/** Floating panels (menus, popovers, toasts): accented hairline and the pop shadow. */
|
|
14
18
|
const FLOATING_SURFACE =
|
|
@@ -18,7 +22,15 @@ const FLOATING_SURFACE =
|
|
|
18
22
|
const OVERLAY_SURFACE =
|
|
19
23
|
"bg-default ring-(--dms-border-top) shadow-(--dms-shadow-modal)";
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Every modal, slideover and drawer, the DMS's or a module's: its backdrop
|
|
27
|
+
* lets clicks through as soon as it starts closing and fades out quickly,
|
|
28
|
+
* and the panel animating out no longer catches them either (reka keeps
|
|
29
|
+
* `pointer-events: auto` inline on both). The panel a closing dialog
|
|
30
|
+
* uncovered (a drawer under a confirm) takes clicks again at once.
|
|
31
|
+
*/
|
|
32
|
+
const BACKDROP = `bg-(--dms-overlay) backdrop-blur-[2px] ${CLOSING_OVERLAY_CLASS}`;
|
|
33
|
+
const CLOSING_PANEL = `data-[state=closed]:pointer-events-none! ${UNCOVERED_PANEL_CLASS}`;
|
|
22
34
|
|
|
23
35
|
const cardTheme = {
|
|
24
36
|
slots: {
|
|
@@ -90,7 +102,7 @@ const tooltipTheme = {
|
|
|
90
102
|
|
|
91
103
|
const modalTheme = {
|
|
92
104
|
slots: {
|
|
93
|
-
content:
|
|
105
|
+
content: `bg-default divide-y-0 ${CLOSING_PANEL}`,
|
|
94
106
|
header: "items-start gap-3 min-h-0 px-5 pt-[18px] pb-0 sm:px-5",
|
|
95
107
|
title: "text-[17px] leading-[1.3] font-[650] tracking-[-0.02em]",
|
|
96
108
|
description: "mt-1 text-[13px]",
|
|
@@ -116,7 +128,7 @@ const modalTheme = {
|
|
|
116
128
|
const slideoverTheme = {
|
|
117
129
|
slots: {
|
|
118
130
|
overlay: BACKDROP,
|
|
119
|
-
content: `${OVERLAY_SURFACE} sm:shadow-(--dms-shadow-modal)`,
|
|
131
|
+
content: `${OVERLAY_SURFACE} sm:shadow-(--dms-shadow-modal) ${CLOSING_PANEL}`,
|
|
120
132
|
header: "px-5 sm:px-5",
|
|
121
133
|
title: "text-[17px] leading-[1.3] font-[650] tracking-[-0.02em]",
|
|
122
134
|
description: "text-[13px]",
|
|
@@ -138,7 +150,7 @@ const DRAWER_EDGE_COMPOUNDS = [
|
|
|
138
150
|
const drawerTheme = {
|
|
139
151
|
slots: {
|
|
140
152
|
overlay: BACKDROP,
|
|
141
|
-
content: OVERLAY_SURFACE
|
|
153
|
+
content: `${OVERLAY_SURFACE} ${CLOSING_PANEL}`,
|
|
142
154
|
},
|
|
143
155
|
compoundVariants: DRAWER_EDGE_COMPOUNDS,
|
|
144
156
|
};
|
|
@@ -178,7 +190,10 @@ const toastTheme = {
|
|
|
178
190
|
* New toasts rise 16px into place instead of sliding in from a full toast
|
|
179
191
|
* height below: that slide started off-screen, so a toast whose animation
|
|
180
192
|
* had not run yet (background tab, throttled frame) sat cut off under the
|
|
181
|
-
* bottom edge.
|
|
193
|
+
* bottom edge. A bottom stack rises above a save bar on the bottom edge (the
|
|
194
|
+
* floating bar, a drawer's footer band): the bar sets how far it reaches
|
|
195
|
+
* (`--dms-toaster-clearance`, see `toasterClearance.ts`), so a toast never
|
|
196
|
+
* covers its buttons, and the stack drops back once the bar hides.
|
|
182
197
|
*/
|
|
183
198
|
const toasterTheme = {
|
|
184
199
|
slots: {
|
|
@@ -203,7 +218,8 @@ const toasterTheme = {
|
|
|
203
218
|
{
|
|
204
219
|
position: ["bottom-left", "bottom-center", "bottom-right"],
|
|
205
220
|
class: {
|
|
206
|
-
viewport:
|
|
221
|
+
viewport:
|
|
222
|
+
"bottom-[calc(var(--dms-toaster-clearance,0px)+1.25rem)] transition-[bottom] duration-200 ease-out motion-reduce:transition-none",
|
|
207
223
|
base: "data-[state=open]:animate-none starting:translate-y-4",
|
|
208
224
|
},
|
|
209
225
|
},
|
|
@@ -10,6 +10,9 @@ export type StoreModuleState =
|
|
|
10
10
|
| "error"
|
|
11
11
|
| "pending";
|
|
12
12
|
|
|
13
|
+
/** Where a module's code comes from (`ModuleSourceKind` on the backend). */
|
|
14
|
+
export type ModuleSourceKind = "npm" | "github" | "gitlab" | "git" | "local";
|
|
15
|
+
|
|
13
16
|
export type StoreFrontendState = "none" | "synced" | "pending" | "unknown";
|
|
14
17
|
|
|
15
18
|
export type StoreOperationKind =
|
|
@@ -86,6 +89,10 @@ export interface StoreListingEntry {
|
|
|
86
89
|
description: string;
|
|
87
90
|
state: StoreModuleState;
|
|
88
91
|
installedVersion?: string;
|
|
92
|
+
/** Where its code comes from. */
|
|
93
|
+
source: ModuleSourceKind;
|
|
94
|
+
/** Runs from a local or git working copy: active, but no store action. */
|
|
95
|
+
isWorkingCopy?: boolean;
|
|
89
96
|
/** The version range antelope.config.ts declares. */
|
|
90
97
|
declaredRange?: string;
|
|
91
98
|
latestVersion?: string;
|
|
@@ -103,6 +110,8 @@ export interface StoreListingEntry {
|
|
|
103
110
|
missingInterfaces: MissingInterface[];
|
|
104
111
|
/** Running modules that need an interface only this one implements. */
|
|
105
112
|
dependents: string[];
|
|
113
|
+
/** The project's own code needs an interface only this module implements. */
|
|
114
|
+
usedByProject: boolean;
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
export interface StoreListing {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BlockText } from "#dms-core/app/types/composed-text";
|
|
2
2
|
import type { BlockAction } from "#dms-ui/app/build/components/blocks/BlockActions.vue";
|
|
3
3
|
import type { PageLiveOptions } from "#dms-ui/app/types/live";
|
|
4
|
+
import type { ModuleSourceKind } from "./module-store";
|
|
4
5
|
|
|
5
6
|
export type MenuItemType = "label" | "link";
|
|
6
7
|
// MenuItemVariant / MenuItemStatus / MenuItemQuery live in dms-core, the layer
|
|
@@ -88,12 +89,19 @@ export type ModuleCatalogEntry = ModuleWithAccess & {
|
|
|
88
89
|
landingSlug: string;
|
|
89
90
|
status?: ModuleStatus;
|
|
90
91
|
readout?: ModuleReadoutLine[];
|
|
92
|
+
/**
|
|
93
|
+
* Where its code comes from, read from the module store; absent for a
|
|
94
|
+
* module the store does not list.
|
|
95
|
+
*/
|
|
96
|
+
source?: ModuleSourceKind;
|
|
91
97
|
};
|
|
92
98
|
|
|
93
99
|
export const MODULE_URL_PREFIX = "/modules";
|
|
94
100
|
|
|
95
101
|
export interface PageInfo extends Omit<CategoryInfo, "category"> {
|
|
96
102
|
layoutUrl: string;
|
|
103
|
+
/** Full slug of the page this one is a detail of (`MenuOptions.parent`). */
|
|
104
|
+
parentSlug?: string;
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
export type SiteLayoutTree = Omit<PageInfo, "layoutUrl"> & {
|
|
@@ -107,15 +115,21 @@ export type SiteLayoutTree = Omit<PageInfo, "layoutUrl"> & {
|
|
|
107
115
|
// Mirror of LayoutBannerVariant from @antelopejs/interface-dms/layout-banners.
|
|
108
116
|
export type LayoutBannerVariant = "info" | "warning" | "error";
|
|
109
117
|
|
|
118
|
+
// Mirror of LayoutBannerScope from @antelopejs/interface-dms/layout-banners.
|
|
119
|
+
export type LayoutBannerScope = "app" | "modules" | "everywhere";
|
|
120
|
+
|
|
110
121
|
/**
|
|
111
122
|
* Mirror of the backend's serialized layout banner. The payload only carries
|
|
112
123
|
* the banners whose visibility resolver passed for this request, so there is
|
|
113
|
-
* nothing left to decide here but the
|
|
124
|
+
* nothing left to decide here but the current route against `scope` and the
|
|
125
|
+
* user's own dismissals.
|
|
114
126
|
*/
|
|
115
127
|
export interface LayoutBanner {
|
|
116
128
|
key: string;
|
|
117
129
|
variant: LayoutBannerVariant;
|
|
118
130
|
order: number;
|
|
131
|
+
/** The pages it shows on, the backend's `app` unless it says otherwise. */
|
|
132
|
+
scope: LayoutBannerScope;
|
|
119
133
|
dismissible: boolean;
|
|
120
134
|
icon?: string;
|
|
121
135
|
/** A string (`$` for an i18n key) or a composed text. */
|
|
@@ -5,6 +5,8 @@ export interface AccountMenuEntry {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export const PROFILE_ROUTE = "/settings/user/profile";
|
|
8
|
+
// The account menu is the only way to the settings: the sidebar footer has no
|
|
9
|
+
// Settings entry, so this one opens all of them, not just the user's own.
|
|
8
10
|
export const SETTINGS_ROUTE = "/settings";
|
|
9
11
|
export const SWITCH_ACCOUNT_ROUTE = "/auth/accounts";
|
|
10
12
|
|
|
@@ -26,3 +28,12 @@ export const ACCOUNT_MENU_ENTRIES: AccountMenuEntry[] = [
|
|
|
26
28
|
to: SWITCH_ACCOUNT_ROUTE,
|
|
27
29
|
},
|
|
28
30
|
];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Whether `to` is the destination of an account menu entry. The command
|
|
34
|
+
* palette lists those entries in its session group, so its navigation group
|
|
35
|
+
* skips their pages instead of offering the same destination twice.
|
|
36
|
+
*/
|
|
37
|
+
export function isAccountMenuRoute(to: string): boolean {
|
|
38
|
+
return ACCOUNT_MENU_ENTRIES.some((entry) => entry.to === to);
|
|
39
|
+
}
|
|
@@ -49,3 +49,60 @@ export function buildBreadcrumbTarget(
|
|
|
49
49
|
|
|
50
50
|
return buildPageTarget(path, metadata.validation, currentQuery);
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
/** The crumb a folded breadcrumb shows for the crumbs it hides. */
|
|
54
|
+
export interface FoldedCrumbs<T> {
|
|
55
|
+
isFolded: true;
|
|
56
|
+
slot: string;
|
|
57
|
+
children: T[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isFoldedCrumbs<T>(
|
|
61
|
+
crumb: T | FoldedCrumbs<T>,
|
|
62
|
+
): crumb is FoldedCrumbs<T> {
|
|
63
|
+
return (crumb as Partial<FoldedCrumbs<T>>).isFolded === true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A phone's breadcrumb: the first and the last crumb, the ones between
|
|
68
|
+
* folded into one `slot` crumb. A single crumb between them stays as it is,
|
|
69
|
+
* a "…" holding one name only hid it.
|
|
70
|
+
*/
|
|
71
|
+
export function foldBreadcrumb<T>(
|
|
72
|
+
crumbs: readonly T[],
|
|
73
|
+
slot: string,
|
|
74
|
+
): (T | FoldedCrumbs<T>)[] {
|
|
75
|
+
if (crumbs.length <= 3) return [...crumbs];
|
|
76
|
+
return [
|
|
77
|
+
crumbs[0]!,
|
|
78
|
+
{ isFolded: true, slot, children: crumbs.slice(1, -1) },
|
|
79
|
+
crumbs.at(-1)!,
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** What a crumb is compared on: the URL it opens. */
|
|
84
|
+
interface LinkedCrumb {
|
|
85
|
+
to?: unknown;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* `crumbs` with the crumb of the page the current one is a detail of
|
|
90
|
+
* (`MenuOptions.parent`) before the last, unless a crumb already opens it:
|
|
91
|
+
* a hidden detail page then leads back to its list.
|
|
92
|
+
*/
|
|
93
|
+
export function withParentCrumb<T extends object>(
|
|
94
|
+
crumbs: readonly T[],
|
|
95
|
+
parent: T | null | undefined,
|
|
96
|
+
): T[] {
|
|
97
|
+
if (!parent || crumbs.length < 2) return [...crumbs];
|
|
98
|
+
const parentTo = (parent as LinkedCrumb).to;
|
|
99
|
+
if (
|
|
100
|
+
crumbs.some(
|
|
101
|
+
(crumb) =>
|
|
102
|
+
parentTo !== undefined && (crumb as LinkedCrumb).to === parentTo,
|
|
103
|
+
)
|
|
104
|
+
) {
|
|
105
|
+
return [...crumbs];
|
|
106
|
+
}
|
|
107
|
+
return [...crumbs.slice(0, -1), parent, crumbs.at(-1)!];
|
|
108
|
+
}
|
|
@@ -57,3 +57,29 @@ export function layoutUrlWithQuery(
|
|
|
57
57
|
const search = new URLSearchParams(query).toString();
|
|
58
58
|
return search ? `${layoutUrl}?${search}` : layoutUrl;
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A page path or layout URL with its `:name` segments filled from `params`;
|
|
63
|
+
* a segment `params` has no value for stays as it is. The page's layout route
|
|
64
|
+
* reads them as the page URL's own.
|
|
65
|
+
*/
|
|
66
|
+
export function fillRouteParams(
|
|
67
|
+
layoutUrl: string,
|
|
68
|
+
params: Record<string, string>,
|
|
69
|
+
): string {
|
|
70
|
+
return layoutUrl.replace(/:([^/]+)/g, (segment, name: string) =>
|
|
71
|
+
name in params ? params[name]! : segment,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Whether two sets of route parameters hold the same values. */
|
|
76
|
+
export function isSameRouteParams(
|
|
77
|
+
left: Record<string, string>,
|
|
78
|
+
right: Record<string, string>,
|
|
79
|
+
): boolean {
|
|
80
|
+
const names = Object.keys(left);
|
|
81
|
+
return (
|
|
82
|
+
names.length === Object.keys(right).length &&
|
|
83
|
+
names.every((name) => left[name] === right[name])
|
|
84
|
+
);
|
|
85
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { get } from "@nuxt/ui/runtime/utils/index.js";
|
|
2
|
+
import type { ActionTarget } from "#dms-ui/app/composables/table-view/types/action-target";
|
|
3
|
+
|
|
4
|
+
// The record a page shows (`DefaultLayout({ record })`), as its header
|
|
5
|
+
// buttons read it: `{{record.X}}` in a target, a button acting on it.
|
|
6
|
+
|
|
7
|
+
/** The record of the page as the header knows it. */
|
|
8
|
+
export type PageRecord =
|
|
9
|
+
| { status: "loading" }
|
|
10
|
+
| { status: "loaded"; values: Record<string, unknown> }
|
|
11
|
+
/** Not found, refused, or its URL names a value the page does not carry. */
|
|
12
|
+
| { status: "missing" };
|
|
13
|
+
|
|
14
|
+
/** What the header needs of a button to bind it to the page's record. */
|
|
15
|
+
export interface RecordBoundButton {
|
|
16
|
+
target?: ActionTarget;
|
|
17
|
+
requiresRecord?: boolean;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const RECORD_TOKEN = /\{\{\s*record\.([\w.-]+)\s*\}\}/g;
|
|
22
|
+
const NAMES_RECORD = /\{\{\s*record\./;
|
|
23
|
+
|
|
24
|
+
const targetUrl = (target: ActionTarget | undefined): string | undefined => {
|
|
25
|
+
const url = (target as { url?: unknown } | undefined)?.url;
|
|
26
|
+
return typeof url === "string" ? url : undefined;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Whether a button acts on the page's record. */
|
|
30
|
+
export function isRecordBound(button: RecordBoundButton): boolean {
|
|
31
|
+
if (button.requiresRecord) return true;
|
|
32
|
+
const url = targetUrl(button.target);
|
|
33
|
+
return !!url && NAMES_RECORD.test(url);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A URL with its `{{record.X}}` tokens filled in, each value percent-encoded
|
|
38
|
+
* (an address is one query value). A token the record has no value for is
|
|
39
|
+
* left as written.
|
|
40
|
+
*/
|
|
41
|
+
export function fillRecordTokens(
|
|
42
|
+
url: string,
|
|
43
|
+
record: Record<string, unknown>,
|
|
44
|
+
): string {
|
|
45
|
+
return url.replace(RECORD_TOKEN, (match, key: string) => {
|
|
46
|
+
const value: unknown = get(record, key);
|
|
47
|
+
return typeof value === "string" || typeof value === "number"
|
|
48
|
+
? encodeURIComponent(String(value))
|
|
49
|
+
: match;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The button as the page's record leaves it: unchanged when it does not act
|
|
55
|
+
* on the record; disabled while the record loads; left out (`null`) when the
|
|
56
|
+
* record is missing; its target's `{{record.X}}` filled in once loaded.
|
|
57
|
+
*/
|
|
58
|
+
export function withPageRecord<T extends RecordBoundButton>(
|
|
59
|
+
button: T,
|
|
60
|
+
record: PageRecord | undefined,
|
|
61
|
+
): T | null {
|
|
62
|
+
if (!record || !isRecordBound(button)) return button;
|
|
63
|
+
if (record.status === "missing") return null;
|
|
64
|
+
if (record.status === "loading") return { ...button, disabled: true };
|
|
65
|
+
const url = targetUrl(button.target);
|
|
66
|
+
if (!url) return button;
|
|
67
|
+
return {
|
|
68
|
+
...button,
|
|
69
|
+
target: { ...button.target, url: fillRecordTokens(url, record.values) },
|
|
70
|
+
} as T;
|
|
71
|
+
}
|