@antelopejs/dms 0.8.3 → 0.9.1
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 +36 -0
- package/data/module-store/catalog.json +71 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/implementations/dms/frontend-backend-proxies.d.ts +3 -0
- package/dist/implementations/dms/frontend-backend-proxies.js +39 -0
- package/dist/implementations/dms/frontend-backend-proxies.js.map +1 -0
- package/dist/implementations/dms/frontend-bootstrap.d.ts +1 -0
- package/dist/implementations/dms/frontend-bootstrap.js +13 -0
- package/dist/implementations/dms/frontend-bootstrap.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +6 -2
- package/dist/implementations/dms/frontend-modules.js +37 -8
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +8 -0
- package/dist/implementations/dms/frontend-ready.js +34 -0
- package/dist/implementations/dms/frontend-ready.js.map +1 -0
- package/dist/implementations/dms/manifest.d.ts +7 -0
- package/dist/implementations/dms/manifest.js +13 -0
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/menu-categories.d.ts +16 -0
- package/dist/implementations/dms/menu-categories.js +30 -0
- package/dist/implementations/dms/menu-categories.js.map +1 -0
- package/dist/implementations/dms/nav-badges.d.ts +0 -8
- package/dist/implementations/dms/nav-badges.js +0 -16
- package/dist/implementations/dms/nav-badges.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +13 -5
- package/dist/implementations/dms/page.js +72 -41
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms-html-render/index.js +5 -2
- package/dist/implementations/dms-html-render/index.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +4 -3
- package/dist/implementations/dms-notifications/index.js +14 -6
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/pages/settings/settings-index.js +3 -2
- package/dist/pages/settings/settings-index.js.map +1 -1
- package/dist/pages/settings/users/invites.js +2 -2
- package/dist/pages/settings/users/invites.js.map +1 -1
- package/dist/pages/settings/users/member-change-notifications.js +17 -6
- package/dist/pages/settings/users/member-change-notifications.js.map +1 -1
- package/dist/pages/settings/users/member-invite-form.d.ts +3 -2
- package/dist/pages/settings/users/member-invite-form.js +7 -4
- package/dist/pages/settings/users/member-invite-form.js.map +1 -1
- package/dist/pages/settings/users/member-roles-field.js +2 -1
- package/dist/pages/settings/users/member-roles-field.js.map +1 -1
- package/dist/pages/settings/users/members.js +4 -1
- package/dist/pages/settings/users/members.js.map +1 -1
- package/dist/pages/settings/users/notifications.d.ts +6 -0
- package/dist/pages/settings/users/notifications.js +23 -15
- package/dist/pages/settings/users/notifications.js.map +1 -1
- package/dist/pages/settings/users/profile.js +1 -1
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/region-form.d.ts +1 -1
- package/dist/pages/settings/users/region-form.js +2 -1
- package/dist/pages/settings/users/region-form.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.d.ts +3 -1
- package/dist/pages/settings/users/role-editor-store.js +17 -4
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/roles.js +1 -0
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/realtime/registry.d.ts +1 -0
- package/dist/realtime/registry.js +5 -0
- package/dist/realtime/registry.js.map +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +5 -1
- package/dist/routes/realtime.js +16 -9
- package/dist/routes/realtime.js.map +1 -1
- package/dist/routes/store.d.ts +21 -0
- package/dist/routes/store.js +130 -0
- package/dist/routes/store.js.map +1 -0
- package/dist/store/activity.d.ts +2 -0
- package/dist/store/activity.js +12 -0
- package/dist/store/activity.js.map +1 -0
- package/dist/store/cache.d.ts +8 -0
- package/dist/store/cache.js +29 -0
- package/dist/store/cache.js.map +1 -0
- package/dist/store/catalog.d.ts +4 -0
- package/dist/store/catalog.js +69 -0
- package/dist/store/catalog.js.map +1 -0
- package/dist/store/compatibility.d.ts +3 -0
- package/dist/store/compatibility.js +45 -0
- package/dist/store/compatibility.js.map +1 -0
- package/dist/store/declarations.d.ts +18 -0
- package/dist/store/declarations.js +116 -0
- package/dist/store/declarations.js.map +1 -0
- package/dist/store/frontend-compatibility.d.ts +18 -0
- package/dist/store/frontend-compatibility.js +93 -0
- package/dist/store/frontend-compatibility.js.map +1 -0
- package/dist/store/interfaces.d.ts +6 -0
- package/dist/store/interfaces.js +126 -0
- package/dist/store/interfaces.js.map +1 -0
- package/dist/store/listing.d.ts +2 -0
- package/dist/store/listing.js +180 -0
- package/dist/store/listing.js.map +1 -0
- package/dist/store/operations.d.ts +8 -0
- package/dist/store/operations.js +254 -0
- package/dist/store/operations.js.map +1 -0
- package/dist/store/registry.d.ts +4 -0
- package/dist/store/registry.js +61 -0
- package/dist/store/registry.js.map +1 -0
- package/dist/store/requirements.d.ts +14 -0
- package/dist/store/requirements.js +81 -0
- package/dist/store/requirements.js.map +1 -0
- package/dist/store/runtime.d.ts +11 -0
- package/dist/store/runtime.js +78 -0
- package/dist/store/runtime.js.map +1 -0
- package/dist/store/tarball.d.ts +2 -0
- package/dist/store/tarball.js +80 -0
- package/dist/store/tarball.js.map +1 -0
- package/dist/store/types.d.ts +98 -0
- package/dist/store/types.js +3 -0
- package/dist/store/types.js.map +1 -0
- package/dist/test/integration/account-deletion.test.js +2 -2
- package/dist/test/integration/account-deletion.test.js.map +1 -1
- package/dist/test/integration/auth/auth-key-rotation.test.js +2 -1
- package/dist/test/integration/auth/auth-key-rotation.test.js.map +1 -1
- package/dist/test/integration/auth/current-password.test.js +2 -1
- package/dist/test/integration/auth/current-password.test.js.map +1 -1
- package/dist/test/integration/auth/session-revocation.test.js +2 -1
- package/dist/test/integration/auth/session-revocation.test.js.map +1 -1
- package/dist/test/integration/auth/sign-in-country.test.js +2 -1
- package/dist/test/integration/auth/sign-in-country.test.js.map +1 -1
- package/dist/test/integration/auth/two-factor-codes.test.js +2 -1
- package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -1
- package/dist/test/integration/auth/two-factor-password.test.js +3 -2
- package/dist/test/integration/auth/two-factor-password.test.js.map +1 -1
- package/dist/test/integration/email-change.test.js +2 -1
- package/dist/test/integration/email-change.test.js.map +1 -1
- package/dist/test/integration/files/component-files.test.js +2 -2
- package/dist/test/integration/files/component-files.test.js.map +1 -1
- package/dist/test/integration/member-settings-access.test.js +8 -7
- package/dist/test/integration/member-settings-access.test.js.map +1 -1
- package/dist/test/integration/menu-access-events.test.d.ts +1 -0
- package/dist/test/integration/menu-access-events.test.js +148 -0
- package/dist/test/integration/menu-access-events.test.js.map +1 -0
- package/dist/test/integration/notification-inbox.test.js +4 -1
- package/dist/test/integration/notification-inbox.test.js.map +1 -1
- package/dist/test/integration/notification-locked-subjects.test.js +3 -2
- package/dist/test/integration/notification-locked-subjects.test.js.map +1 -1
- package/dist/test/integration/notification-unread-badge.test.js +51 -5
- package/dist/test/integration/notification-unread-badge.test.js.map +1 -1
- package/dist/test/integration/page-layout-route-guard.test.d.ts +1 -0
- package/dist/test/integration/page-layout-route-guard.test.js +56 -0
- package/dist/test/integration/page-layout-route-guard.test.js.map +1 -0
- package/dist/test/integration/permission-warnings.test.js +3 -2
- package/dist/test/integration/permission-warnings.test.js.map +1 -1
- package/dist/test/integration/removed-member-notifications.test.js +3 -2
- package/dist/test/integration/removed-member-notifications.test.js.map +1 -1
- package/dist/test/integration/role-delete-reassign.test.js +2 -1
- package/dist/test/integration/role-delete-reassign.test.js.map +1 -1
- package/dist/test/integration/role-permission-ancestors.test.js +2 -1
- package/dist/test/integration/role-permission-ancestors.test.js.map +1 -1
- package/dist/test/unit/frontend-bootstrap.test.js +13 -0
- package/dist/test/unit/frontend-bootstrap.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/category-slug-registry.test.js +14 -5
- package/dist/test/unit/implementations/dms/category-slug-registry.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/frontend-backend-proxies.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/frontend-backend-proxies.test.js +66 -0
- package/dist/test/unit/implementations/dms/frontend-backend-proxies.test.js.map +1 -0
- package/dist/test/unit/implementations/dms/manifest-strip.test.js +26 -0
- package/dist/test/unit/implementations/dms/manifest-strip.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/nav-badges.test.js +23 -9
- package/dist/test/unit/implementations/dms/nav-badges.test.js.map +1 -1
- package/dist/test/unit/implementations/dms-html-render/generate-html.test.js +22 -4
- package/dist/test/unit/implementations/dms-html-render/generate-html.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/page-layout-query.test.js +12 -0
- package/dist/test/unit/interfaces/dms/page-layout-query.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/page-teardown.test.js +1 -1
- package/dist/test/unit/interfaces/dms/page-teardown.test.js.map +1 -1
- package/dist/test/unit/pages/settings/member-roles-field.test.js +1 -1
- package/dist/test/unit/pages/settings/member-roles-field.test.js.map +1 -1
- package/dist/test/unit/pages/settings/role-delete-confirm.test.js.map +1 -1
- package/dist/test/unit/realtime/menu-topics.test.d.ts +1 -0
- package/dist/test/unit/realtime/menu-topics.test.js +26 -0
- package/dist/test/unit/realtime/menu-topics.test.js.map +1 -0
- package/dist/test/unit/store/store.test.d.ts +1 -0
- package/dist/test/unit/store/store.test.js +127 -0
- package/dist/test/unit/store/store.test.js.map +1 -0
- package/dist/validation/store.schema.d.ts +39 -0
- package/dist/validation/store.schema.js +27 -0
- package/dist/validation/store.schema.js.map +1 -0
- package/frontend-vue/deferred-plugins.ts +3 -4
- package/frontend-vue/dms.email.ts +5 -1
- package/frontend-vue/dms.frontend.ts +15 -5
- package/frontend-vue/dms.server.ts +74 -0
- package/frontend-vue/layers/dms-auth/app/composables/useLogout.ts +1 -1
- package/frontend-vue/layers/dms-auth/app/composables/usePostLoginRedirect.ts +16 -3
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/2fa.vue +3 -1
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/backup.vue +3 -1
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/forgot-validation.vue +1 -1
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/oauth-complete.vue +26 -3
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/recover.vue +1 -1
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +22 -25
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/validate.vue +1 -1
- package/frontend-vue/layers/dms-auth/app/middleware/auth.ts +5 -7
- package/frontend-vue/layers/dms-auth/app/plugins/permissions-preload.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +135 -0
- package/frontend-vue/layers/dms-auth/server/actions.ts +251 -0
- package/frontend-vue/layers/dms-auth/server/oauth.ts +260 -0
- package/frontend-vue/layers/dms-auth/server/session.ts +158 -0
- package/frontend-vue/layers/dms-core/app/build/utils/asyncDataScope.ts +47 -0
- package/frontend-vue/layers/dms-core/app/build/utils/permission-preview.ts +6 -2
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +148 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useAuthFetch.ts +7 -20
- package/frontend-vue/layers/dms-core/app/composables/auth/useCurrentUser.ts +2 -2
- package/frontend-vue/layers/dms-core/app/composables/auth/useMultiAccount.ts +18 -5
- package/frontend-vue/layers/dms-core/app/composables/auth/usePermissions.ts +35 -6
- package/frontend-vue/layers/dms-core/app/composables/auth/useSessionRecovery.ts +1 -1
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +20 -14
- package/frontend-vue/layers/dms-core/app/composables/period/periodClock.ts +121 -0
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +42 -0
- package/frontend-vue/layers/dms-core/app/composables/period/periodTimeZone.ts +31 -0
- package/frontend-vue/layers/dms-core/app/composables/period/presetResolvers.ts +48 -19
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +33 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +78 -25
- package/frontend-vue/layers/dms-core/app/composables/realtime/usePageRealtime.ts +3 -0
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +36 -6
- package/frontend-vue/layers/dms-core/app/composables/user/useUserRegionalPreferences.ts +1 -1
- package/frontend-vue/layers/dms-core/app/plugins/async-data-scope.ts +26 -0
- package/frontend-vue/layers/dms-core/app/utils/pageRoutes.ts +22 -0
- package/frontend-vue/layers/dms-core/app/utils/regional.ts +36 -3
- package/frontend-vue/layers/dms-core/app/utils/trailingDeduper.ts +10 -1
- package/frontend-vue/layers/dms-core/shared/types/app-config.ts +48 -4
- package/frontend-vue/layers/dms-layout/app/app.config.ts +42 -23
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +72 -20
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardFrame.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +0 -3
- package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +9 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreDependencyPicker.vue +136 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +98 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +247 -29
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +19 -2
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/members/MemberRolePicker.vue +13 -12
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +17 -7
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationPreferencesForm.vue +0 -1
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfilePersonalInfo.vue +36 -33
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfileSecuritySummary.vue +1 -2
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-types.ts +5 -4
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecuritySessions.vue +35 -28
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityStatus.vue +0 -1
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityTwoFactor.vue +1 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/dev-reload/useDevReloadHolder.ts +7 -6
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/sidePanelState.ts +1 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/navigation/useVisitNavBadges.ts +26 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationCatalog.ts +25 -23
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationPreferences.ts +44 -23
- package/frontend-vue/layers/dms-layout/app/build/composables/security/useSessionHandoff.ts +1 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/preferencesSummary.ts +1 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useAccountData.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfileAvatar.ts +1 -18
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfilePreferences.ts +19 -23
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityFormat.ts +6 -3
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityOverview.ts +13 -18
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +186 -120
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-install.ts +146 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +8 -6
- package/frontend-vue/layers/dms-layout/app/build/utils/publicErrorMessage.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/components/navigation/CollapsedMenuItem.vue +0 -11
- package/frontend-vue/layers/dms-layout/app/components/navigation/NavigationMenu.vue +3 -13
- package/frontend-vue/layers/dms-layout/app/composables/general/useSystemState.ts +7 -11
- package/frontend-vue/layers/dms-layout/app/composables/notification/useNotifications.ts +103 -22
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +109 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useModulesListing.ts +25 -102
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +0 -10
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +177 -96
- package/frontend-vue/layers/dms-layout/app/composables/profile/useUserLanguage.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +341 -62
- package/frontend-vue/layers/dms-layout/app/emails/components/EmailLayout.vue +31 -11
- package/frontend-vue/layers/dms-layout/app/error.vue +5 -2
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +1 -1
- package/frontend-vue/layers/dms-layout/app/middleware/page-leave-guard.global.ts +2 -2
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +12 -9
- package/frontend-vue/layers/dms-layout/app/plugins/dms-menu-sync.client.ts +31 -3
- package/frontend-vue/layers/dms-layout/app/plugins/favicon.ts +58 -0
- package/frontend-vue/layers/dms-layout/app/plugins/notification-stream.client.ts +15 -7
- package/frontend-vue/layers/dms-layout/app/plugins/profile-sync.client.ts +5 -1
- package/frontend-vue/layers/dms-layout/app/plugins/regional-preferences.ts +10 -4
- package/frontend-vue/layers/dms-layout/app/plugins/time-zone-cookie.client.ts +12 -0
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +134 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +13 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +107 -9
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +107 -9
- package/frontend-vue/layers/dms-layout/server/html-render.ts +58 -0
- package/frontend-vue/layers/dms-layout/server/render-token.ts +95 -0
- package/frontend-vue/layers/dms-onboarding/app/composables/onboarding/useOnboarding.ts +25 -21
- package/frontend-vue/layers/dms-onboarding/app/middleware/onboarding.global.ts +1 -1
- package/frontend-vue/layers/dms-onboarding/app/plugins/onboarding-preload.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +4 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/files/useFileMetadata.ts +162 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +23 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageDataRefresh.ts +101 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/navigation/useNavBadges.ts +33 -6
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +19 -16
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodQuery.ts +40 -20
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +6 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableListData.ts +42 -14
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +19 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +5 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +9 -9
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +20 -18
- package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/File.vue +26 -132
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +40 -105
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +2 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +4 -4
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +9 -13
- package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/FilePreview.vue +12 -24
- package/frontend-vue/layers/dms-ui/app/components/table-view/ImagePreview.vue +17 -29
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +7 -3
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +20 -8
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +8 -11
- package/frontend-vue/layers/dms-ui/app/composables/chart/useChartFetch.ts +146 -182
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLiveRefresh.ts +8 -2
- package/frontend-vue/layers/dms-ui/app/composables/useFileReadUrls.ts +11 -99
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +32 -3
- package/frontend-vue/package.json +3 -3
- package/frontend-vue/pnpm-lock.yaml +16 -22
- package/frontend-vue/server/private-options.ts +27 -0
- package/frontend-vue/tests/async-data-scope.test.ts +121 -0
- package/frontend-vue/tests/auth-middleware-error.test.ts +3 -3
- package/frontend-vue/tests/banner-block-fetch.test.ts +3 -0
- package/frontend-vue/tests/block-fetch-options-forwarding.test.ts +3 -0
- package/frontend-vue/tests/block-items-period-realtime.test.ts +3 -0
- package/frontend-vue/tests/block-not-found.test.ts +16 -2
- package/frontend-vue/tests/block-page-refresh.test.ts +3 -0
- package/frontend-vue/tests/block-route-params.test.ts +3 -0
- package/frontend-vue/tests/branding-defaults.test.ts +34 -0
- package/frontend-vue/tests/builtin-emails.test.ts +23 -2
- package/frontend-vue/tests/chart-live-pause.test.ts +4 -1
- package/frontend-vue/tests/chart-value-propagation.test.ts +4 -1
- package/frontend-vue/tests/composed-text-blocks.test.ts +3 -0
- package/frontend-vue/tests/email-layout.test.ts +66 -4
- package/frontend-vue/tests/error-page-message.test.ts +25 -2
- package/frontend-vue/tests/favicon.test.ts +131 -0
- package/frontend-vue/tests/file-fields-ssr.test.ts +145 -0
- package/frontend-vue/tests/file-read-urls.test.ts +145 -34
- package/frontend-vue/tests/file-unavailable.test.ts +5 -1
- package/frontend-vue/tests/fixtures/dataEngine.ts +44 -0
- package/frontend-vue/tests/form-load-error.test.ts +55 -1
- package/frontend-vue/tests/helpers/api-data-runtime.ts +77 -0
- package/frontend-vue/tests/image-hydration-ids.test.ts +21 -16
- package/frontend-vue/tests/image-reference-preservation.test.ts +59 -53
- package/frontend-vue/tests/input-number-adjust.test.ts +14 -0
- package/frontend-vue/tests/key-value-list-copy.test.ts +3 -0
- package/frontend-vue/tests/member-role-picker.test.ts +4 -2
- package/frontend-vue/tests/menu-sync-reconnect.test.ts +47 -0
- package/frontend-vue/tests/metadata-retry.test.ts +5 -1
- package/frontend-vue/tests/module-routing.test.ts +2 -5
- package/frontend-vue/tests/module-store-catalog.test.ts +270 -51
- package/frontend-vue/tests/modules-catalog.test.ts +17 -4
- package/frontend-vue/tests/modules-listing-transfer.test.ts +95 -0
- package/frontend-vue/tests/multi-account-validate.test.ts +23 -1
- package/frontend-vue/tests/nav-badge-tones.test.ts +66 -3
- package/frontend-vue/tests/notification-counts-from-writes.test.ts +223 -0
- package/frontend-vue/tests/notification-counts-transfer.test.ts +88 -0
- package/frontend-vue/tests/notification-inbox-display.test.ts +57 -5
- package/frontend-vue/tests/notification-popover-errors.test.ts +21 -1
- package/frontend-vue/tests/oauth-complete-handoff.test.ts +209 -0
- package/frontend-vue/tests/onboarding-middleware.test.ts +1 -1
- package/frontend-vue/tests/onboarding-transfer.test.ts +106 -0
- package/frontend-vue/tests/page-data-refresh.test.ts +141 -0
- package/frontend-vue/tests/page-fill-height.test.ts +16 -3
- package/frontend-vue/tests/page-no-visible-blocks.test.ts +12 -2
- package/frontend-vue/tests/page-realtime-remount.test.ts +1 -1
- package/frontend-vue/tests/page-record-label.test.ts +0 -7
- package/frontend-vue/tests/page-validation-redirect.test.ts +12 -2
- package/frontend-vue/tests/period-hydration-now.test.ts +185 -0
- package/frontend-vue/tests/period-live-pause.test.ts +3 -0
- package/frontend-vue/tests/period-reader-zone.test.ts +137 -0
- package/frontend-vue/tests/period-scope-first-fetch.test.ts +17 -1
- package/frontend-vue/tests/period-ssr.test.ts +195 -0
- package/frontend-vue/tests/permission-preview-partial.test.ts +0 -2
- package/frontend-vue/tests/permissions-transfer.test.ts +194 -0
- package/frontend-vue/tests/post-login-redirect.test.ts +10 -5
- package/frontend-vue/tests/profile-personal-info-ssr.test.ts +150 -0
- package/frontend-vue/tests/profile-preferences-summary.test.ts +15 -11
- package/frontend-vue/tests/realtime-reconnect.test.ts +22 -3
- package/frontend-vue/tests/roles-name-errors.test.ts +1 -1
- package/frontend-vue/tests/row-side-panel.test.ts +1 -1
- package/frontend-vue/tests/security-sessions-load-error.test.ts +3 -1
- package/frontend-vue/tests/server-routes-vs-pages.test.ts +26 -0
- package/frontend-vue/tests/server-routes.test.ts +582 -0
- package/frontend-vue/tests/session-handoff.test.ts +1 -1
- package/frontend-vue/tests/settings-reads-ssr.test.ts +232 -0
- package/frontend-vue/tests/side-panels.test.ts +8 -1
- package/frontend-vue/tests/sign-in-exit-history.test.ts +219 -0
- package/frontend-vue/tests/signup-invitation-link.test.ts +56 -8
- package/frontend-vue/tests/site-layout-categories.test.ts +42 -0
- package/frontend-vue/tests/site-layout-hydration.test.ts +3 -3
- package/frontend-vue/tests/site-layout-rendered.test.ts +103 -0
- package/frontend-vue/tests/site-layout-resync.test.ts +87 -0
- package/frontend-vue/tests/ssr-guard-preload.test.ts +188 -0
- package/frontend-vue/tests/table-cell-tones.test.ts +36 -1
- package/frontend-vue/tests/table-data-ssr.test.ts +195 -0
- package/frontend-vue/tests/table-list-data-requests.test.ts +154 -0
- package/frontend-vue/tests/table-retry-loading.test.ts +37 -0
- package/frontend-vue/tests/table-source-navigation.test.ts +0 -1
- package/frontend-vue/tests/table-source-period-scope.test.ts +0 -1
- package/frontend-vue/tests/table-view-views.test.ts +1 -1
- package/frontend-vue/tests/top-list-card-actions.test.ts +3 -0
- package/frontend-vue/tests/top-list-card-period-badge-ssr.test.ts +212 -0
- package/frontend-vue/tests/top-list-card-period-badge.test.ts +79 -0
- package/frontend-vue/tests/top-list-card-value-suffix.test.ts +3 -0
- package/frontend-vue/tests/trailing-deduper.test.ts +22 -0
- package/frontend-vue/tests/use-api-data-update.test.ts +119 -0
- package/frontend-vue/tests/use-api-data.test.ts +410 -0
- package/frontend-vue/tests/user-language.test.ts +8 -5
- package/frontend-vue/tests/widget-label-i18n.test.ts +4 -1
- package/frontend-vue/vitest.config.ts +6 -0
- package/package.json +2 -2
- package/skills/dms/SKILL.md +2 -1
- package/skills/dms-module/SKILL.md +1 -1
- package/skills/dms-pages/SKILL.md +4 -1
- package/frontend-vue/layers/dms-core/app/build/composables/page/usePageRecordLabel.ts +0 -9
- package/frontend-vue/layers/dms-layout/app/composables/page/usePrefetch.ts +0 -21
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useControlError.ts +0 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useServerRenderedAsyncData.ts +0 -23
- package/frontend-vue/tests/control-error-path.test.ts +0 -11
- package/frontend-vue/tests/modules-listing-per-request.test.ts +0 -104
- package/frontend-vue/tests/page-layout-background-refresh.test.ts +0 -321
|
@@ -3,6 +3,7 @@ import { withoutTrailingSlash } from "ufo";
|
|
|
3
3
|
import { holdPageHeaderActions } from "../composables/layout/usePageHeaderActions";
|
|
4
4
|
import { useDevReloading } from "../build/composables/dev-reload/useDevReloadHolder";
|
|
5
5
|
import { usePageLiveHost } from "#dms-ui/app/build/composables/live/usePageLiveHost";
|
|
6
|
+
import { usePageDataRefresh } from "#dms-ui/app/build/composables/live/usePageDataRefresh";
|
|
6
7
|
import { pageValidationRedirect } from "../build/utils/pageValidationRedirect";
|
|
7
8
|
|
|
8
9
|
defineOptions({ inheritAttrs: false });
|
|
@@ -42,7 +43,7 @@ async function checkPageMetadata(
|
|
|
42
43
|
if (import.meta.env.DEV && devReloading.value) {
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
|
-
throw
|
|
46
|
+
throw showDmsError({
|
|
46
47
|
statusCode: HTTP_NOT_FOUND,
|
|
47
48
|
statusMessage: "Page not found",
|
|
48
49
|
});
|
|
@@ -76,7 +77,7 @@ async function recheckAccessWithFreshSession(): Promise<void> {
|
|
|
76
77
|
if (import.meta.env.DEV && devReloading.value) {
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
|
-
throw
|
|
80
|
+
throw showDmsError({
|
|
80
81
|
statusCode: HTTP_NOT_FOUND,
|
|
81
82
|
statusMessage: "Page not found",
|
|
82
83
|
});
|
|
@@ -90,7 +91,7 @@ async function recheckAccessWithFreshSession(): Promise<void> {
|
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
throw
|
|
94
|
+
throw showDmsError({
|
|
94
95
|
statusCode: HTTP_FORBIDDEN,
|
|
95
96
|
statusMessage: "Access denied",
|
|
96
97
|
});
|
|
@@ -140,7 +141,7 @@ async function enforcePageValidation(): Promise<void> {
|
|
|
140
141
|
routeQuery: query,
|
|
141
142
|
});
|
|
142
143
|
if (!redirect) {
|
|
143
|
-
throw
|
|
144
|
+
throw createDmsError({
|
|
144
145
|
statusCode: HTTP_NOT_FOUND,
|
|
145
146
|
statusMessage: "Page not found",
|
|
146
147
|
});
|
|
@@ -172,7 +173,7 @@ const pagelayoutMetadata = computed(() => routeMatch.value?.metadata);
|
|
|
172
173
|
const routeParams = computed(() => routeMatch.value?.params || {});
|
|
173
174
|
|
|
174
175
|
if (siteLayout.loadingError && siteLayout.loadingError.value) {
|
|
175
|
-
throw
|
|
176
|
+
throw createDmsError({
|
|
176
177
|
statusCode: HTTP_INTERNAL_SERVER_ERROR,
|
|
177
178
|
statusMessage: "Error loading site layout",
|
|
178
179
|
message: siteLayout.loadingError.value || "Unknown error occurred",
|
|
@@ -186,7 +187,7 @@ await checkPageMetadata(pagelayoutMetadata.value);
|
|
|
186
187
|
// flight the page is unregistered for a moment, and the plugin is already
|
|
187
188
|
// waiting for it to come back.
|
|
188
189
|
if (!pagelayoutMetadata.value && !(import.meta.env.DEV && devReloading.value)) {
|
|
189
|
-
throw
|
|
190
|
+
throw createDmsError({
|
|
190
191
|
statusCode: HTTP_NOT_FOUND,
|
|
191
192
|
statusMessage: "Page not found",
|
|
192
193
|
});
|
|
@@ -202,9 +203,9 @@ if (import.meta.env.DEV) {
|
|
|
202
203
|
// the flag back with nobody watching.
|
|
203
204
|
watch(devReloading, (reloading) => {
|
|
204
205
|
if (!reloading && !pagelayoutMetadata.value) {
|
|
205
|
-
// `
|
|
206
|
+
// `showDmsError` commits the error itself; throwing on top of it would only
|
|
206
207
|
// add a second report of the same thing.
|
|
207
|
-
|
|
208
|
+
showDmsError({
|
|
208
209
|
statusCode: HTTP_NOT_FOUND,
|
|
209
210
|
statusMessage: "Page not found",
|
|
210
211
|
});
|
|
@@ -246,6 +247,8 @@ usePageLiveHost(
|
|
|
246
247
|
}),
|
|
247
248
|
{ isStreamConnected: () => !!realtime.sessionId.value },
|
|
248
249
|
);
|
|
250
|
+
// The page's `useApiData` reads follow its refreshes and its realtime events.
|
|
251
|
+
usePageDataRefresh(realtime);
|
|
249
252
|
|
|
250
253
|
function buildPageSetupContext(
|
|
251
254
|
pageInfo: PageInfo,
|
|
@@ -495,7 +498,7 @@ if (import.meta.env.DEV) {
|
|
|
495
498
|
void navigateDms(moved[0]);
|
|
496
499
|
return;
|
|
497
500
|
}
|
|
498
|
-
|
|
501
|
+
showDmsError({
|
|
499
502
|
statusCode: HTTP_NOT_FOUND,
|
|
500
503
|
statusMessage: "Page not found",
|
|
501
504
|
});
|
|
@@ -1,8 +1,34 @@
|
|
|
1
|
+
import { type Ref, watch } from "vue";
|
|
2
|
+
|
|
1
3
|
const MENU_CHANGED_EVENT_TYPE = "menu-changed";
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Calls `onReconnect` each time the realtime stream opens again after it was
|
|
7
|
+
* lost: the events sent meanwhile never arrived. Not on its first opening,
|
|
8
|
+
* which follows the page load that brought the current menu.
|
|
9
|
+
*
|
|
10
|
+
* @param sessionId The stream's session id, unset while it is closed
|
|
11
|
+
* @param onReconnect What to run once it is back
|
|
12
|
+
*/
|
|
13
|
+
export function watchRealtimeReconnects(
|
|
14
|
+
sessionId: Ref<string | undefined>,
|
|
15
|
+
onReconnect: () => void,
|
|
16
|
+
): void {
|
|
17
|
+
let hasConnected = !!sessionId.value;
|
|
18
|
+
watch(sessionId, (next, previous) => {
|
|
19
|
+
if (!next || next === previous) return;
|
|
20
|
+
if (hasConnected) onReconnect();
|
|
21
|
+
hasConnected = true;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
3
25
|
// A module signalled that the data behind the menu changed (a project created,
|
|
4
|
-
// an access scope edited
|
|
5
|
-
//
|
|
26
|
+
// an access scope edited, a role or a membership changed): on the workspace's
|
|
27
|
+
// topic, or on this member's own when only their access changed. The event
|
|
28
|
+
// carries no data: the site layout, the page on screen and the permission set
|
|
29
|
+
// are re-fetched, each resolved server-side against this user. The layout
|
|
30
|
+
// comes back through Inertia, so the copy each visit carries over is the new
|
|
31
|
+
// one. A stream that reconnects resyncs too: it missed what was sent meanwhile.
|
|
6
32
|
export default defineDmsPlugin(() => {
|
|
7
33
|
const realtime = useUserRealtime();
|
|
8
34
|
const siteLayout = useSiteLayout();
|
|
@@ -16,7 +42,7 @@ export default defineDmsPlugin(() => {
|
|
|
16
42
|
await Promise.all([
|
|
17
43
|
// Background resync: a transient failure is logged below, never
|
|
18
44
|
// escalated to the fatal error page over a working session.
|
|
19
|
-
siteLayout.
|
|
45
|
+
siteLayout.resync(),
|
|
20
46
|
permissions.fetchPermissions(),
|
|
21
47
|
]);
|
|
22
48
|
})
|
|
@@ -30,6 +56,8 @@ export default defineDmsPlugin(() => {
|
|
|
30
56
|
void refresh();
|
|
31
57
|
};
|
|
32
58
|
|
|
59
|
+
watchRealtimeReconnects(realtime.sessionId, () => void refresh());
|
|
60
|
+
|
|
33
61
|
const unsubscribes: Array<() => void> = [];
|
|
34
62
|
|
|
35
63
|
watch(
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import type { DmsLogoSources } from "#dms-core/shared/types/app-config";
|
|
3
|
+
|
|
4
|
+
const ICON_TYPES: Record<string, string> = {
|
|
5
|
+
svg: "image/svg+xml",
|
|
6
|
+
png: "image/png",
|
|
7
|
+
ico: "image/x-icon",
|
|
8
|
+
webp: "image/webp",
|
|
9
|
+
};
|
|
10
|
+
const FILE_EXTENSION = /\.([a-z0-9]+)(?:[?#]|$)/i;
|
|
11
|
+
const LIGHT_SCHEME_MEDIA = "(prefers-color-scheme: light)";
|
|
12
|
+
const DARK_SCHEME_MEDIA = "(prefers-color-scheme: dark)";
|
|
13
|
+
|
|
14
|
+
// A type rather than an interface: unhead's link type carries an index
|
|
15
|
+
// signature (`data-*`), which only a type alias satisfies implicitly.
|
|
16
|
+
type IconLink = {
|
|
17
|
+
rel: "icon";
|
|
18
|
+
href: string;
|
|
19
|
+
type?: string;
|
|
20
|
+
media?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function iconLink(href: string, media?: string): IconLink {
|
|
24
|
+
const extension = FILE_EXTENSION.exec(href)?.[1].toLowerCase() ?? "";
|
|
25
|
+
const type = ICON_TYPES[extension];
|
|
26
|
+
return {
|
|
27
|
+
rel: "icon",
|
|
28
|
+
href,
|
|
29
|
+
...(type ? { type } : {}),
|
|
30
|
+
...(media ? { media } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function faviconLinks(favicon: Partial<DmsLogoSources> = {}): IconLink[] {
|
|
35
|
+
const { light, dark } = favicon;
|
|
36
|
+
if (light && dark && light !== dark)
|
|
37
|
+
return [
|
|
38
|
+
iconLink(light, LIGHT_SCHEME_MEDIA),
|
|
39
|
+
iconLink(dark, DARK_SCHEME_MEDIA),
|
|
40
|
+
];
|
|
41
|
+
const icon = light || dark;
|
|
42
|
+
return icon ? [iconLink(icon)] : [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The browser tab icon, `branding.logo.favicon`. Its light and dark files
|
|
47
|
+
* follow the operating system's scheme: the browser draws the tab outside the
|
|
48
|
+
* page, where the dashboard's color mode does not reach. The app config is
|
|
49
|
+
* read inside the computed, so an edit applied in development without a
|
|
50
|
+
* reload replaces the icon too.
|
|
51
|
+
*/
|
|
52
|
+
export default defineDmsPlugin(() => {
|
|
53
|
+
useHead(
|
|
54
|
+
computed(() => ({
|
|
55
|
+
link: faviconLinks(useDmsAppConfig().branding.logo?.favicon),
|
|
56
|
+
})),
|
|
57
|
+
);
|
|
58
|
+
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
FeedCounts,
|
|
3
|
+
UserNotification,
|
|
4
|
+
} from "../composables/notification/useNotifications";
|
|
2
5
|
|
|
3
6
|
const NOTIFICATION_TOPIC_PREFIX = "notifications:user:";
|
|
4
7
|
const NOTIFICATION_NEW_TYPE = "notification:new";
|
|
@@ -9,6 +12,8 @@ const NOTIFICATION_UNREAD_TYPE = "notification:unread";
|
|
|
9
12
|
interface IncomingPayload {
|
|
10
13
|
notification?: UserNotification;
|
|
11
14
|
ids?: string[];
|
|
15
|
+
/** The whole feed's counts after a read state change. */
|
|
16
|
+
counts?: FeedCounts;
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
const isNotificationEvent = (
|
|
@@ -21,7 +26,7 @@ const isNotificationEvent = (
|
|
|
21
26
|
type Handler = (payload: IncomingPayload | undefined) => void | Promise<void>;
|
|
22
27
|
|
|
23
28
|
export default defineDmsPlugin(() => {
|
|
24
|
-
const { user, loggedIn } =
|
|
29
|
+
const { user, loggedIn } = useDmsUserSession();
|
|
25
30
|
const {
|
|
26
31
|
handleIncomingNotification,
|
|
27
32
|
handleRemoteRead,
|
|
@@ -32,16 +37,19 @@ export default defineDmsPlugin(() => {
|
|
|
32
37
|
|
|
33
38
|
const handlers: Record<string, Handler> = {
|
|
34
39
|
[NOTIFICATION_NEW_TYPE]: (payload) => {
|
|
35
|
-
if (payload?.notification)
|
|
40
|
+
if (payload?.notification)
|
|
41
|
+
handleIncomingNotification(payload.notification);
|
|
36
42
|
},
|
|
37
43
|
[NOTIFICATION_READ_TYPE]: async (payload) => {
|
|
38
|
-
if (Array.isArray(payload?.ids))
|
|
44
|
+
if (Array.isArray(payload?.ids))
|
|
45
|
+
await handleRemoteRead(payload.ids, payload.counts);
|
|
39
46
|
},
|
|
40
47
|
[NOTIFICATION_UNREAD_TYPE]: async (payload) => {
|
|
41
|
-
if (Array.isArray(payload?.ids))
|
|
48
|
+
if (Array.isArray(payload?.ids))
|
|
49
|
+
await handleRemoteUnread(payload.ids, payload.counts);
|
|
42
50
|
},
|
|
43
|
-
[NOTIFICATION_ALL_READ_TYPE]: async () => {
|
|
44
|
-
await handleRemoteAllRead();
|
|
51
|
+
[NOTIFICATION_ALL_READ_TYPE]: async (payload) => {
|
|
52
|
+
await handleRemoteAllRead(payload?.counts);
|
|
45
53
|
},
|
|
46
54
|
};
|
|
47
55
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pageRoutePath } from "#dms-core/app/utils/pageRoutes";
|
|
1
2
|
import { FormEvents } from "#dms-ui/app/composables/form/types/events";
|
|
2
3
|
import type { ComponentEventData } from "#dms-core/app/types/component";
|
|
3
4
|
|
|
@@ -5,7 +6,10 @@ interface FormSubmitSuccessPayload {
|
|
|
5
6
|
submitUrl?: string;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
const REGION_PREFERENCES_ROUTE =
|
|
9
|
+
const REGION_PREFERENCES_ROUTE = pageRoutePath(
|
|
10
|
+
"/settings/user/region",
|
|
11
|
+
"/preferences",
|
|
12
|
+
);
|
|
9
13
|
|
|
10
14
|
/** The forms that edit the signed-in user's own record. */
|
|
11
15
|
const SESSION_FORM_ROUTES = new Set([PROFILE_ROUTE, REGION_PREFERENCES_ROUTE]);
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readRegionalPreferences,
|
|
3
3
|
type RegionalPreferenceFields,
|
|
4
|
+
setReaderTimeZoneSource,
|
|
4
5
|
setRegionalPreferencesSource,
|
|
5
6
|
} from "#dms-core/app/utils/regional";
|
|
7
|
+
import { useTimeZoneCookie } from "#dms-core/app/composables/period/periodTimeZone";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Points the shared date formatters at the signed-in user's regional
|
|
9
|
-
* preferences (time zone, clock, date format, first day of the week)
|
|
10
|
-
*
|
|
11
|
-
* HTML and the browser agree and a
|
|
11
|
+
* preferences (time zone, clock, date format, first day of the week), and a
|
|
12
|
+
* server render at the browser's time zone. Read on every format, from the
|
|
13
|
+
* request being rendered, so the server HTML and the browser agree and a
|
|
14
|
+
* saved preference applies at once.
|
|
12
15
|
*/
|
|
13
16
|
export default defineDmsPlugin(() => {
|
|
14
17
|
setRegionalPreferencesSource(() =>
|
|
15
18
|
readRegionalPreferences(
|
|
16
|
-
|
|
19
|
+
useDmsUserSession<RegionalPreferenceFields>().user.value,
|
|
17
20
|
),
|
|
18
21
|
);
|
|
22
|
+
// A server render writes dates, and resolves periods, in the zone of the
|
|
23
|
+
// browser it renders for (its cookie), as the browser will.
|
|
24
|
+
setReaderTimeZoneSource(() => useTimeZoneCookie().value);
|
|
19
25
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useTimeZoneCookie } from "#dms-core/app/composables/period/periodTimeZone";
|
|
2
|
+
import { browserTimeZone } from "#dms-core/app/utils/regional";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Keeps the browser's time zone in its cookie, so that the next server render
|
|
6
|
+
* resolves the dashboards' periods in it (see `usePeriodScope`).
|
|
7
|
+
*/
|
|
8
|
+
export default defineDmsPlugin(() => {
|
|
9
|
+
const cookie = useTimeZoneCookie();
|
|
10
|
+
const zone = browserTimeZone();
|
|
11
|
+
if (cookie.value !== zone) cookie.value = zone;
|
|
12
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror of the backend's module store listing (`GET /dms/store/listing`,
|
|
3
|
+
* `src/store/types.ts` in `@antelopejs/dms`).
|
|
4
|
+
*/
|
|
5
|
+
export type StoreModuleState =
|
|
6
|
+
| "available"
|
|
7
|
+
| "busy"
|
|
8
|
+
| "active"
|
|
9
|
+
| "disabled"
|
|
10
|
+
| "error"
|
|
11
|
+
| "pending";
|
|
12
|
+
|
|
13
|
+
export type StoreFrontendState = "none" | "synced" | "pending" | "unknown";
|
|
14
|
+
|
|
15
|
+
export type StoreOperationKind =
|
|
16
|
+
| "install"
|
|
17
|
+
| "update"
|
|
18
|
+
| "enable"
|
|
19
|
+
| "disable"
|
|
20
|
+
| "uninstall"
|
|
21
|
+
| "apply";
|
|
22
|
+
|
|
23
|
+
export type StoreOperationStep =
|
|
24
|
+
| "resolve"
|
|
25
|
+
| "dependencies"
|
|
26
|
+
| "unload"
|
|
27
|
+
| "load"
|
|
28
|
+
| "save";
|
|
29
|
+
|
|
30
|
+
export interface StoreOperation {
|
|
31
|
+
moduleId: string;
|
|
32
|
+
kind: StoreOperationKind;
|
|
33
|
+
step: StoreOperationStep;
|
|
34
|
+
targetVersion?: string;
|
|
35
|
+
startedAt: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A module of the AntelopeJS interfaces registry that implements an interface. */
|
|
39
|
+
export interface InterfaceImplementation {
|
|
40
|
+
/** Name the registry gives it, such as `redis`. */
|
|
41
|
+
name: string;
|
|
42
|
+
/** npm package it is installed from. */
|
|
43
|
+
package: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** An interface the release to install needs and no running module implements. */
|
|
47
|
+
export interface MissingInterface {
|
|
48
|
+
interfacePackage: string;
|
|
49
|
+
/** Registry modules that implement it, npm packages only. */
|
|
50
|
+
candidates: InterfaceImplementation[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A frontend layer that would stop loading on another dms-frontend. */
|
|
54
|
+
export interface FrontendBreak {
|
|
55
|
+
name: string;
|
|
56
|
+
/** The dms-frontend range the layer supports. */
|
|
57
|
+
range: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Why a release cannot load on the running dms-frontend, and what moving it would take. */
|
|
61
|
+
export interface FrontendRequirement {
|
|
62
|
+
/** The dms-frontend range the release supports. */
|
|
63
|
+
range: string;
|
|
64
|
+
/** The dms-frontend version that runs. */
|
|
65
|
+
running: string;
|
|
66
|
+
/** Latest published dms-frontend in the range, when there is one. */
|
|
67
|
+
target?: string;
|
|
68
|
+
/** Command that moves the project to `target`. */
|
|
69
|
+
command?: string;
|
|
70
|
+
/** Layers already loaded that `target` would refuse. */
|
|
71
|
+
breaks: FrontendBreak[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Where the store read the running dms-frontend version. */
|
|
75
|
+
export type FrontendVersionSource = "reported" | "project";
|
|
76
|
+
|
|
77
|
+
export interface StoreListingEntry {
|
|
78
|
+
id: string;
|
|
79
|
+
package: string;
|
|
80
|
+
icon: string;
|
|
81
|
+
/** Store category key, under `modules.store.category`. */
|
|
82
|
+
category: string;
|
|
83
|
+
/** `$i18n.key` */
|
|
84
|
+
title: string;
|
|
85
|
+
/** `$i18n.key` */
|
|
86
|
+
description: string;
|
|
87
|
+
state: StoreModuleState;
|
|
88
|
+
installedVersion?: string;
|
|
89
|
+
/** The version range antelope.config.ts declares. */
|
|
90
|
+
declaredRange?: string;
|
|
91
|
+
latestVersion?: string;
|
|
92
|
+
updateAvailable: boolean;
|
|
93
|
+
compatible: boolean;
|
|
94
|
+
requiredInterfaceRange?: string;
|
|
95
|
+
error?: string;
|
|
96
|
+
operation?: StoreOperation;
|
|
97
|
+
frontend: StoreFrontendState;
|
|
98
|
+
/** The dms-frontend range the release to install declares, when it does. */
|
|
99
|
+
frontendRange?: string;
|
|
100
|
+
/** Set when that range excludes the running dms-frontend. */
|
|
101
|
+
frontendRequirement?: FrontendRequirement;
|
|
102
|
+
/** Interfaces the release to install needs and nothing implements. */
|
|
103
|
+
missingInterfaces: MissingInterface[];
|
|
104
|
+
/** Running modules that need an interface only this one implements. */
|
|
105
|
+
dependents: string[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface StoreListing {
|
|
109
|
+
enabled: boolean;
|
|
110
|
+
modules: StoreListingEntry[];
|
|
111
|
+
busy: boolean;
|
|
112
|
+
interfaceVersion: string;
|
|
113
|
+
dev: boolean;
|
|
114
|
+
/** Why antelope.config.ts cannot be read or edited, when it cannot. */
|
|
115
|
+
configError?: string;
|
|
116
|
+
/** The dms-frontend version that runs, when the store can tell. */
|
|
117
|
+
frontendVersion?: string;
|
|
118
|
+
frontendVersionSource?: FrontendVersionSource;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** A module the owner picked to implement a missing interface. */
|
|
122
|
+
export interface StoreDependencyChoice {
|
|
123
|
+
interfacePackage: string;
|
|
124
|
+
/** npm package, never a git or local source. */
|
|
125
|
+
package: string;
|
|
126
|
+
/** Config written to its antelope.config.ts entry. */
|
|
127
|
+
config?: Record<string, unknown>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Body of `POST /dms/store/<kind>`; only an install carries dependencies. */
|
|
131
|
+
export interface StoreActionBody {
|
|
132
|
+
id: string;
|
|
133
|
+
dependencies?: StoreDependencyChoice[];
|
|
134
|
+
}
|
|
@@ -41,6 +41,13 @@ export interface CategoryInfo extends Omit<MenuOptions, "category"> {
|
|
|
41
41
|
fullSlug: string;
|
|
42
42
|
hasAccess?: boolean;
|
|
43
43
|
isModuleRoot?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The full id of the category this entry sits in, listed once in
|
|
46
|
+
* `SiteLayout.categories`; none at the root.
|
|
47
|
+
*/
|
|
48
|
+
categoryId?: string;
|
|
49
|
+
/** Answers at its parent's slug: never the target of a URL of its own. */
|
|
50
|
+
urlTransparent?: boolean;
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
// Mirror of ModuleInfo and MODULE_URL_PREFIX from @antelopejs/interface-dms/page.
|
|
@@ -120,7 +127,13 @@ export interface LayoutBanner {
|
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
export type SiteLayout = {
|
|
130
|
+
/** By slug, the key a URL is resolved against. */
|
|
123
131
|
pages: Record<string, PageInfo>;
|
|
132
|
+
/**
|
|
133
|
+
* Every category, once, by full id: pages and categories name theirs by
|
|
134
|
+
* `categoryId`. A URL resolves against the ones that are not
|
|
135
|
+
* `urlTransparent`, by `fullSlug`.
|
|
136
|
+
*/
|
|
124
137
|
categories: Record<string, CategoryInfo>;
|
|
125
138
|
/** Absent when the backend predates layout banners. */
|
|
126
139
|
banners?: LayoutBanner[];
|
|
@@ -735,18 +735,85 @@
|
|
|
735
735
|
},
|
|
736
736
|
"store": {
|
|
737
737
|
"title": "Module store",
|
|
738
|
-
"description": "Official AntelopeJS modules
|
|
739
|
-
"
|
|
740
|
-
|
|
741
|
-
"
|
|
742
|
-
"
|
|
738
|
+
"description": "Official AntelopeJS modules: install, update, pause or remove them without touching the project’s code.",
|
|
739
|
+
"scope": {
|
|
740
|
+
"label": "Show",
|
|
741
|
+
"all": "All · {count}",
|
|
742
|
+
"available": "Available · {count}",
|
|
743
|
+
"installed": "Installed · {count}"
|
|
743
744
|
},
|
|
745
|
+
"state": {
|
|
746
|
+
"available": "Available",
|
|
747
|
+
"busy": "Working",
|
|
748
|
+
"active": "Active",
|
|
749
|
+
"disabled": "Paused",
|
|
750
|
+
"error": "Failed",
|
|
751
|
+
"pending": "Not applied",
|
|
752
|
+
"update_available": "Update"
|
|
753
|
+
},
|
|
754
|
+
"actions": {
|
|
755
|
+
"install": "Install",
|
|
756
|
+
"update": "Update",
|
|
757
|
+
"enable": "Resume",
|
|
758
|
+
"disable": "Pause",
|
|
759
|
+
"uninstall": "Uninstall",
|
|
760
|
+
"apply": "Apply",
|
|
761
|
+
"manage": "Manage"
|
|
762
|
+
},
|
|
763
|
+
"steps": {
|
|
764
|
+
"resolve": "Find the latest release",
|
|
765
|
+
"unload": "Stop the running version",
|
|
766
|
+
"load": "Download and start",
|
|
767
|
+
"save": "Write antelope.config.ts",
|
|
768
|
+
"dependencies": "Install the required modules"
|
|
769
|
+
},
|
|
770
|
+
"progress": {
|
|
771
|
+
"install": "Installing",
|
|
772
|
+
"update": "Updating",
|
|
773
|
+
"enable": "Resuming",
|
|
774
|
+
"disable": "Pausing",
|
|
775
|
+
"uninstall": "Uninstalling",
|
|
776
|
+
"apply": "Applying"
|
|
777
|
+
},
|
|
778
|
+
"more_actions": "More actions",
|
|
779
|
+
"incompatible": "Needs {'@'}antelopejs/interface-dms {range}: update the DMS first",
|
|
780
|
+
"no_release": "The npm registry has no release of it this platform can read",
|
|
781
|
+
"locked": "Another module is being changed",
|
|
782
|
+
"pending_hint": "antelope.config.ts and the running platform disagree: Apply brings them in line.",
|
|
783
|
+
"uninstall_confirm": {
|
|
784
|
+
"title": "Uninstall {module}?",
|
|
785
|
+
"description": "{module} stops and leaves the menu. Its data (collections, files, settings) stays in place and comes back if you install it again."
|
|
786
|
+
},
|
|
787
|
+
"action_failed": "{module} could not be changed",
|
|
788
|
+
"errors": {
|
|
789
|
+
"store_busy": "Another module is being changed. Try again once it is done.",
|
|
790
|
+
"store_module_unknown": "This module is not in the catalog.",
|
|
791
|
+
"store_disabled": "The store is read-only on this platform.",
|
|
792
|
+
"store_invalid_state": "The module changed in the meantime. The list is up to date again.",
|
|
793
|
+
"unauthorized": "Only platform owners manage modules.",
|
|
794
|
+
"store_module_required": "Other running modules need this one. Remove them first."
|
|
795
|
+
},
|
|
796
|
+
"frontend": {
|
|
797
|
+
"dev": {
|
|
798
|
+
"title": "Reloading the interface for {modules}",
|
|
799
|
+
"description": "The dev frontend picks up the change and the page reloads by itself."
|
|
800
|
+
},
|
|
801
|
+
"production": {
|
|
802
|
+
"title": "{modules}: rebuild the frontend",
|
|
803
|
+
"description": "The module runs on the backend. Run {command} and restart the frontend to show its pages."
|
|
804
|
+
},
|
|
805
|
+
"unknown": {
|
|
806
|
+
"title": "{modules}: restart the frontend",
|
|
807
|
+
"description": "The module runs on the backend, but no frontend server reported what it serves. Restart it ({command} in production) to show the module's pages."
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
"disabled": {
|
|
811
|
+
"title": "The store is read-only here",
|
|
812
|
+
"description": "Modules are installed from development, which writes them to antelope.config.ts; this platform loads what that file declares. Set store.enabled to true in the DMS configuration to change them from here."
|
|
813
|
+
},
|
|
814
|
+
"load_error": "The module store could not be loaded",
|
|
744
815
|
"search_placeholder": "Search the store",
|
|
745
816
|
"category_label": "Store category",
|
|
746
|
-
"available_soon": "Available soon",
|
|
747
|
-
"install": "Install",
|
|
748
|
-
"install_soon": "Coming soon",
|
|
749
|
-
"command_label": "Install command",
|
|
750
817
|
"no_result": {
|
|
751
818
|
"title": "No module in the store matches “{query}”",
|
|
752
819
|
"title_filtered": "No module in the store matches these filters"
|
|
@@ -809,6 +876,37 @@
|
|
|
809
876
|
"title": "SaaS",
|
|
810
877
|
"description": "Plans, workspaces, billing with Stripe and customer lifecycle."
|
|
811
878
|
}
|
|
879
|
+
},
|
|
880
|
+
"config_error": "antelope.config.ts cannot be edited from here",
|
|
881
|
+
"frontend_requirement": {
|
|
882
|
+
"needs": "Needs dms-frontend {range}, this project runs {running}.",
|
|
883
|
+
"run": "To move the project to dms-frontend {target}, run:",
|
|
884
|
+
"breaks": "dms-frontend {target} would refuse these installed layers:",
|
|
885
|
+
"supports": "supports {range}",
|
|
886
|
+
"no_target": "No published dms-frontend matches this range."
|
|
887
|
+
},
|
|
888
|
+
"requires": "Requires: {interfaces}",
|
|
889
|
+
"requires_first": "Needs {interfaces}, which no running module implements: install a module that does first.",
|
|
890
|
+
"used_by": "Used by: {modules}. Remove them first.",
|
|
891
|
+
"frontend_version": {
|
|
892
|
+
"label": "dms-frontend {version}",
|
|
893
|
+
"reported": "Reported by the running frontend server",
|
|
894
|
+
"project": "Read from the project’s dependencies: no frontend server reported its version"
|
|
895
|
+
},
|
|
896
|
+
"install_dialog": {
|
|
897
|
+
"title": "Install {module}",
|
|
898
|
+
"description": "{module} needs interfaces that no running module implements. Pick a module for each: it is installed first.",
|
|
899
|
+
"other": "Other npm package",
|
|
900
|
+
"package_label": "npm package",
|
|
901
|
+
"package_placeholder": "{'@'}scope/package",
|
|
902
|
+
"config_label": "Config (JSON)",
|
|
903
|
+
"config_hint": "Optional",
|
|
904
|
+
"note": "These modules are added to antelope.config.ts as their own entries, where their config can be edited later.",
|
|
905
|
+
"errors": {
|
|
906
|
+
"package_required": "Enter an npm package name.",
|
|
907
|
+
"package_invalid": "Not an npm package name: git and local sources are not allowed.",
|
|
908
|
+
"config_invalid": "Must be a JSON object."
|
|
909
|
+
}
|
|
812
910
|
}
|
|
813
911
|
},
|
|
814
912
|
"sort": {
|