@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
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { router as inertiaRouter } from "@inertiajs/vue3";
|
|
1
2
|
import { layoutUrlWithQuery } from "../../utils/pageQuery";
|
|
3
|
+
import { onBeforeMount, toRaw } from "vue";
|
|
2
4
|
import { withoutTrailingSlash } from "ufo";
|
|
3
5
|
|
|
4
6
|
const STALE_THRESHOLD_MS = 300_000;
|
|
7
|
+
const SITE_LAYOUT_ENDPOINT = "/dms/sitelayout";
|
|
8
|
+
const RENDERED_SITE_LAYOUT_KEY = "dms-rendered-site-layout";
|
|
5
9
|
const IN_FLIGHT_SITE_LAYOUT_KEY = "__dmsInFlightSiteLayout";
|
|
6
10
|
const IN_FLIGHT_PAGE_LAYOUTS_KEY = "__dmsInFlightPageLayouts";
|
|
7
11
|
|
|
@@ -10,28 +14,35 @@ interface PageLayoutRequest {
|
|
|
10
14
|
promise: Promise<PageLayout>;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
function getCachedLayoutUrls(
|
|
14
|
-
previousSite: SiteLayout | undefined,
|
|
15
|
-
previousCache: Record<string, PageLayout>,
|
|
16
|
-
nextSite: SiteLayout,
|
|
17
|
-
): string[] {
|
|
18
|
-
const urls = Object.entries(previousSite?.pages ?? {}).flatMap(
|
|
19
|
-
([path, page]) => {
|
|
20
|
-
const nextPage = nextSite.pages[path];
|
|
21
|
-
return previousCache[page.layoutUrl] &&
|
|
22
|
-
nextPage?.layoutUrl &&
|
|
23
|
-
nextPage.hasAccess !== false
|
|
24
|
-
? [nextPage.layoutUrl]
|
|
25
|
-
: [];
|
|
26
|
-
},
|
|
27
|
-
);
|
|
28
|
-
return [...new Set(urls)];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
17
|
interface MatchRouteOptions {
|
|
32
18
|
includeCategories: boolean;
|
|
33
19
|
}
|
|
34
20
|
|
|
21
|
+
// The categories a URL resolves against, by slug, per served layout: the
|
|
22
|
+
// layout lists them by full id, and a `urlTransparent` one answers at its
|
|
23
|
+
// parent's slug, so it is never a URL's target.
|
|
24
|
+
const navigableCategoriesByLayout = new WeakMap<
|
|
25
|
+
SiteLayout,
|
|
26
|
+
Map<string, CategoryInfo>
|
|
27
|
+
>();
|
|
28
|
+
|
|
29
|
+
/** The category of the layout a URL resolves to, by its slug. */
|
|
30
|
+
export function findNavigableCategory(
|
|
31
|
+
layout: SiteLayout,
|
|
32
|
+
slug: string,
|
|
33
|
+
): CategoryInfo | undefined {
|
|
34
|
+
let bySlug = navigableCategoriesByLayout.get(layout);
|
|
35
|
+
if (!bySlug) {
|
|
36
|
+
bySlug = new Map(
|
|
37
|
+
Object.values(layout.categories)
|
|
38
|
+
.filter((category) => !category.urlTransparent)
|
|
39
|
+
.map((category) => [category.fullSlug, category]),
|
|
40
|
+
);
|
|
41
|
+
navigableCategoriesByLayout.set(layout, bySlug);
|
|
42
|
+
}
|
|
43
|
+
return bySlug.get(slug);
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
interface MatchRouteResult {
|
|
36
47
|
pattern: string;
|
|
37
48
|
metadata: PageInfo | CategoryInfo;
|
|
@@ -99,24 +110,84 @@ export function extractRouteParams(
|
|
|
99
110
|
return buildParamBag(paramNames, match.slice(1));
|
|
100
111
|
}
|
|
101
112
|
|
|
113
|
+
/**
|
|
114
|
+
* A partial reload of the page on screen: the server sends the site layout
|
|
115
|
+
* and the page fresh, and they replace the browser's copies, the layout
|
|
116
|
+
* Inertia carries from page to page included. A failure rejects and leaves
|
|
117
|
+
* the page as it is: Inertia would otherwise show the error in its place.
|
|
118
|
+
*/
|
|
119
|
+
function reloadSiteLayoutAndPage(): Promise<void> {
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
let failure: unknown;
|
|
122
|
+
inertiaRouter.reload({
|
|
123
|
+
only: ["shared", "page"],
|
|
124
|
+
onHttpException: (response) => {
|
|
125
|
+
failure = new Error(`Site layout reload failed (${response.status})`);
|
|
126
|
+
return false;
|
|
127
|
+
},
|
|
128
|
+
onNetworkError: (error) => {
|
|
129
|
+
failure = error;
|
|
130
|
+
return false;
|
|
131
|
+
},
|
|
132
|
+
onFinish: () => (failure ? reject(failure) : resolve()),
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface SiteLayoutResponse {
|
|
138
|
+
siteLayout: SiteLayout;
|
|
139
|
+
siteLayoutTree: SiteLayoutTree;
|
|
140
|
+
quickActions: QuickActionsPayload;
|
|
141
|
+
modules: Record<string, ModuleWithAccess>;
|
|
142
|
+
isOwner: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** The shared site layout, as a page's props or `/dms/sitelayout` set it. */
|
|
146
|
+
function useSiteLayoutState() {
|
|
147
|
+
return {
|
|
148
|
+
siteLayout: useDmsState<SiteLayout | undefined>(
|
|
149
|
+
"dms-siteLayout",
|
|
150
|
+
() => undefined,
|
|
151
|
+
),
|
|
152
|
+
siteLayoutTree: useDmsState<SiteLayoutTree | undefined>(
|
|
153
|
+
"dms-pageTree",
|
|
154
|
+
() => undefined,
|
|
155
|
+
),
|
|
156
|
+
quickActions: useDmsState<QuickActionsPayload | undefined>(
|
|
157
|
+
"dms-quickActions",
|
|
158
|
+
() => undefined,
|
|
159
|
+
),
|
|
160
|
+
modules: useDmsState<Record<string, ModuleWithAccess> | undefined>(
|
|
161
|
+
"dms-modules",
|
|
162
|
+
() => undefined,
|
|
163
|
+
),
|
|
164
|
+
isOwner: useDmsState<boolean>("dms-isOwner", () => false),
|
|
165
|
+
lastRefreshTime: useDmsState<number>("dms-lastRefreshTime", () => 0),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function applySiteLayoutResponse(
|
|
170
|
+
state: ReturnType<typeof useSiteLayoutState>,
|
|
171
|
+
result: SiteLayoutResponse,
|
|
172
|
+
): void {
|
|
173
|
+
state.siteLayout.value = result.siteLayout;
|
|
174
|
+
state.siteLayoutTree.value = result.siteLayoutTree;
|
|
175
|
+
state.quickActions.value = result.quickActions;
|
|
176
|
+
state.modules.value = result.modules;
|
|
177
|
+
state.isOwner.value = result.isOwner;
|
|
178
|
+
state.lastRefreshTime.value = Date.now();
|
|
179
|
+
}
|
|
180
|
+
|
|
102
181
|
export const useSiteLayout = () => {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"dms-quickActions",
|
|
113
|
-
() => undefined,
|
|
114
|
-
);
|
|
115
|
-
const modules = useDmsState<Record<string, ModuleWithAccess> | undefined>(
|
|
116
|
-
"dms-modules",
|
|
117
|
-
() => undefined,
|
|
118
|
-
);
|
|
119
|
-
const isOwner = useDmsState<boolean>("dms-isOwner", () => false);
|
|
182
|
+
const state = useSiteLayoutState();
|
|
183
|
+
const {
|
|
184
|
+
siteLayout,
|
|
185
|
+
siteLayoutTree,
|
|
186
|
+
quickActions,
|
|
187
|
+
modules,
|
|
188
|
+
isOwner,
|
|
189
|
+
lastRefreshTime,
|
|
190
|
+
} = state;
|
|
120
191
|
|
|
121
192
|
const isLoading = useDmsState<boolean>("dms-loading", () => false);
|
|
122
193
|
const loadingError = useDmsState<string | null>("dms-error", () => null);
|
|
@@ -125,7 +196,6 @@ export const useSiteLayout = () => {
|
|
|
125
196
|
"dms-pageLayouts",
|
|
126
197
|
() => ({}),
|
|
127
198
|
);
|
|
128
|
-
const lastRefreshTime = useDmsState<number>("dms-lastRefreshTime", () => 0);
|
|
129
199
|
|
|
130
200
|
// Held on the DMS app rather than in a per-call ref: every caller of
|
|
131
201
|
// useSiteLayout writes the same shared layout state, so they have to see the
|
|
@@ -148,79 +218,40 @@ export const useSiteLayout = () => {
|
|
|
148
218
|
},
|
|
149
219
|
};
|
|
150
220
|
|
|
151
|
-
interface SiteLayoutResponse {
|
|
152
|
-
siteLayout: SiteLayout;
|
|
153
|
-
siteLayoutTree: SiteLayoutTree;
|
|
154
|
-
quickActions: QuickActionsPayload;
|
|
155
|
-
modules: Record<string, ModuleWithAccess>;
|
|
156
|
-
isOwner: boolean;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const SITE_LAYOUT_ENDPOINT = "/dms/sitelayout";
|
|
160
221
|
const SITE_LAYOUT_ERROR_MESSAGE = "Error loading siteLayout";
|
|
161
222
|
const UNKNOWN_SITE_LAYOUT_ERROR = "Unknown error loading siteLayout";
|
|
162
223
|
const HTTP_INTERNAL_ERROR = 500;
|
|
163
224
|
|
|
164
|
-
const applySiteLayoutResponse = (result: SiteLayoutResponse) => {
|
|
165
|
-
siteLayout.value = result.siteLayout;
|
|
166
|
-
siteLayoutTree.value = result.siteLayoutTree;
|
|
167
|
-
quickActions.value = result.quickActions;
|
|
168
|
-
modules.value = result.modules;
|
|
169
|
-
isOwner.value = result.isOwner;
|
|
170
|
-
lastRefreshTime.value = Date.now();
|
|
171
|
-
};
|
|
172
|
-
|
|
173
225
|
const handleSiteLayoutError = (error: unknown) => {
|
|
174
226
|
const errorMessage =
|
|
175
227
|
error instanceof Error ? error.message : UNKNOWN_SITE_LAYOUT_ERROR;
|
|
176
228
|
loadingError.value = errorMessage;
|
|
177
|
-
|
|
229
|
+
showDmsError({
|
|
178
230
|
statusCode: HTTP_INTERNAL_ERROR,
|
|
179
231
|
statusMessage: SITE_LAYOUT_ERROR_MESSAGE,
|
|
180
232
|
message: errorMessage,
|
|
181
233
|
});
|
|
182
234
|
};
|
|
183
235
|
|
|
184
|
-
const requestSiteLayout = async (
|
|
236
|
+
const requestSiteLayout = async (): Promise<boolean> => {
|
|
185
237
|
const initialLayout = siteLayout.value;
|
|
186
238
|
const initialCache = pageLayouts.value;
|
|
239
|
+
// A layout another request committed meanwhile is newer than this one.
|
|
187
240
|
const isCurrent = () =>
|
|
188
241
|
siteLayout.value === initialLayout && pageLayouts.value === initialCache;
|
|
189
242
|
const { $authFetch } = useAuthFetch();
|
|
190
243
|
try {
|
|
191
244
|
const result = await $authFetch<SiteLayoutResponse>(SITE_LAYOUT_ENDPOINT);
|
|
192
|
-
|
|
193
|
-
// Initial page loads mutate this cache in place; identity guards cannot detect those additions.
|
|
194
|
-
while (isCurrent()) {
|
|
195
|
-
const urls = fatal
|
|
196
|
-
? []
|
|
197
|
-
: getCachedLayoutUrls(
|
|
198
|
-
initialLayout,
|
|
199
|
-
initialCache,
|
|
200
|
-
result.siteLayout,
|
|
201
|
-
).filter((url) => !nextCache[url]);
|
|
202
|
-
if (!urls.length) {
|
|
203
|
-
if (!fatal) pageLayouts.value = nextCache;
|
|
204
|
-
applySiteLayoutResponse(result);
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
const layouts = await Promise.all(
|
|
208
|
-
urls.map(
|
|
209
|
-
async (url) => [url, await $authFetch<PageLayout>(url)] as const,
|
|
210
|
-
),
|
|
211
|
-
);
|
|
212
|
-
Object.assign(nextCache, Object.fromEntries(layouts));
|
|
213
|
-
}
|
|
245
|
+
if (isCurrent()) applySiteLayoutResponse(state, result);
|
|
214
246
|
return true;
|
|
215
247
|
} catch (error) {
|
|
216
|
-
|
|
217
|
-
if (fatal && isCurrent()) handleSiteLayoutError(error);
|
|
248
|
+
if (isCurrent()) handleSiteLayoutError(error);
|
|
218
249
|
throw error;
|
|
219
250
|
}
|
|
220
251
|
};
|
|
221
252
|
|
|
222
|
-
const startSiteLayoutFetch = (
|
|
223
|
-
const started = requestSiteLayout(
|
|
253
|
+
const startSiteLayoutFetch = (): Promise<boolean> => {
|
|
254
|
+
const started = requestSiteLayout().finally(() => {
|
|
224
255
|
isLoading.value = false;
|
|
225
256
|
// A waiting refresh may already have started its replacement request.
|
|
226
257
|
if (loadingPromise.value === started) loadingPromise.value = null;
|
|
@@ -246,12 +277,9 @@ export const useSiteLayout = () => {
|
|
|
246
277
|
pageLayouts.value = {};
|
|
247
278
|
}
|
|
248
279
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const refresh = async (options?: { fatal?: boolean }) => {
|
|
253
|
-
// Background refreshes stage page layouts before committing; identity refreshes clear immediately.
|
|
254
|
-
if (options?.fatal !== false) clearPageLayoutCaches();
|
|
280
|
+
// A background resync (a realtime menu invalidation) goes through `resync`.
|
|
281
|
+
const refresh = async () => {
|
|
282
|
+
clearPageLayoutCaches();
|
|
255
283
|
|
|
256
284
|
// A fetch already in flight was started before whatever prompted this
|
|
257
285
|
// call, so its answer cannot contain the change: joining it would report
|
|
@@ -270,11 +298,26 @@ export const useSiteLayout = () => {
|
|
|
270
298
|
if (!loadingPromise.value) {
|
|
271
299
|
isLoading.value = true;
|
|
272
300
|
loadingError.value = null;
|
|
273
|
-
loadingPromise.value = startSiteLayoutFetch(
|
|
301
|
+
loadingPromise.value = startSiteLayoutFetch();
|
|
274
302
|
}
|
|
275
303
|
await loadingPromise.value;
|
|
276
304
|
};
|
|
277
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Re-reads the menu and the page on screen from the server, for a change
|
|
308
|
+
* the backend announced (a realtime menu invalidation) or a switch of
|
|
309
|
+
* session. The pages prefetched on hover are dropped first: each carries
|
|
310
|
+
* the layout and the access of before. A navigation that starts meanwhile
|
|
311
|
+
* drops the reload's answer, and the page it opens still carries the layout
|
|
312
|
+
* the reload meant to replace: that page is reloaded in turn.
|
|
313
|
+
*/
|
|
314
|
+
const resync = async (): Promise<void> => {
|
|
315
|
+
inertiaRouter.flushAll();
|
|
316
|
+
const path = window.location.pathname;
|
|
317
|
+
await reloadSiteLayoutAndPage();
|
|
318
|
+
if (window.location.pathname !== path) await reloadSiteLayoutAndPage();
|
|
319
|
+
};
|
|
320
|
+
|
|
278
321
|
const refreshIfStale = async () => {
|
|
279
322
|
const elapsed = Date.now() - lastRefreshTime.value;
|
|
280
323
|
if (elapsed < STALE_THRESHOLD_MS) {
|
|
@@ -335,12 +378,11 @@ export const useSiteLayout = () => {
|
|
|
335
378
|
};
|
|
336
379
|
}
|
|
337
380
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
};
|
|
381
|
+
const category = options.includeCategories
|
|
382
|
+
? findNavigableCategory(layout, normalizedPath)
|
|
383
|
+
: undefined;
|
|
384
|
+
if (category) {
|
|
385
|
+
return { pattern: normalizedPath, metadata: category, params: {} };
|
|
344
386
|
}
|
|
345
387
|
|
|
346
388
|
for (const [pattern, metadata] of Object.entries(layout.pages)) {
|
|
@@ -420,7 +462,7 @@ export const useSiteLayout = () => {
|
|
|
420
462
|
return false;
|
|
421
463
|
}
|
|
422
464
|
clearPageLayoutCaches();
|
|
423
|
-
applySiteLayoutResponse(result);
|
|
465
|
+
applySiteLayoutResponse(state, result);
|
|
424
466
|
return true;
|
|
425
467
|
} catch {
|
|
426
468
|
return false;
|
|
@@ -440,9 +482,48 @@ export const useSiteLayout = () => {
|
|
|
440
482
|
loadSiteLayout,
|
|
441
483
|
loadPageLayout,
|
|
442
484
|
refresh,
|
|
485
|
+
resync,
|
|
443
486
|
refreshIfStale,
|
|
444
487
|
findMatchingRoute,
|
|
445
488
|
findMatchingRouteOrCategory,
|
|
446
489
|
probeAndCommitRoute,
|
|
447
490
|
};
|
|
448
491
|
};
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* The site layout for the component rendering it (the sidebar), called in
|
|
495
|
+
* its setup. A page the backend describes brings it with its props; a page
|
|
496
|
+
* only a frontend layer knows (a custom page) does not, and this loads it
|
|
497
|
+
* with the page then: a server render waits for it before rendering the
|
|
498
|
+
* component, and hands it to the browser, which takes it over before the
|
|
499
|
+
* component mounts instead of asking again.
|
|
500
|
+
*/
|
|
501
|
+
export function useRenderedSiteLayout(): void {
|
|
502
|
+
const state = useSiteLayoutState();
|
|
503
|
+
if (state.siteLayout.value) return;
|
|
504
|
+
const layout = useSiteLayout();
|
|
505
|
+
// Through `loadSiteLayout`, which sets the state: a middleware loading it
|
|
506
|
+
// at the same time (the auth guard of a custom page) joins this request.
|
|
507
|
+
const { data } = useApiData<SiteLayoutResponse | null>(
|
|
508
|
+
RENDERED_SITE_LAYOUT_KEY,
|
|
509
|
+
async () => {
|
|
510
|
+
await layout.loadSiteLayout();
|
|
511
|
+
const { siteLayout, siteLayoutTree, quickActions, modules, isOwner } =
|
|
512
|
+
state;
|
|
513
|
+
// What the page payload carries: the plain values, not the state.
|
|
514
|
+
return siteLayout.value
|
|
515
|
+
? {
|
|
516
|
+
siteLayout: toRaw(siteLayout.value),
|
|
517
|
+
siteLayoutTree: toRaw(siteLayoutTree.value!),
|
|
518
|
+
quickActions: toRaw(quickActions.value!),
|
|
519
|
+
modules: toRaw(modules.value!),
|
|
520
|
+
isOwner: isOwner.value,
|
|
521
|
+
}
|
|
522
|
+
: null;
|
|
523
|
+
},
|
|
524
|
+
);
|
|
525
|
+
onBeforeMount(() => {
|
|
526
|
+
if (data.value && !state.siteLayout.value)
|
|
527
|
+
applySiteLayoutResponse(state, data.value);
|
|
528
|
+
});
|
|
529
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { pageRoutePath } from "#dms-core/app/utils/pageRoutes";
|
|
2
|
+
const PROFILE_ENDPOINT = pageRoutePath("/settings/user/profile");
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Switches the interface language and stores it on the user's profile, then
|
|
@@ -9,7 +10,7 @@ const PROFILE_ENDPOINT = "/settings/user/profile";
|
|
|
9
10
|
export function useUserLanguage() {
|
|
10
11
|
const dmsApp = useDmsApp();
|
|
11
12
|
const { $authFetch } = useAuthFetch();
|
|
12
|
-
const { user, fetch: refreshUser } =
|
|
13
|
+
const { user, fetch: refreshUser } = useDmsUserSession();
|
|
13
14
|
|
|
14
15
|
async function changeLanguage(language: string): Promise<void> {
|
|
15
16
|
await dmsApp.$i18n.setLocale(language);
|