@antelopejs/dms 0.9.8 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +171 -0
- package/README.md +1 -1
- package/data/module-store/catalog.json +2 -2
- package/dist/attachments/table-view.js +2 -2
- package/dist/attachments/table-view.js.map +1 -1
- package/dist/automation/actions.d.ts +2 -0
- package/dist/automation/actions.js +116 -71
- package/dist/automation/actions.js.map +1 -1
- package/dist/automation/i18n.d.ts +4 -0
- package/dist/automation/i18n.js +19 -0
- package/dist/automation/i18n.js.map +1 -0
- package/dist/automation/send-notification.d.ts +21 -0
- package/dist/automation/send-notification.js +163 -0
- package/dist/automation/send-notification.js.map +1 -0
- package/dist/automation/triggers.js +19 -25
- package/dist/automation/triggers.js.map +1 -1
- package/dist/client-origin-cors.d.ts +1 -0
- package/dist/client-origin-cors.js +19 -0
- package/dist/client-origin-cors.js.map +1 -0
- package/dist/config.d.ts +3 -2
- package/dist/config.js +5 -7
- package/dist/config.js.map +1 -1
- package/dist/frontend-module.d.ts +4 -0
- package/dist/frontend-module.js +37 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/implementations/dms/client-ip.js +1 -1
- package/dist/implementations/dms/client-ip.js.map +1 -1
- package/dist/implementations/dms/dev-reload.d.ts +5 -0
- package/dist/implementations/dms/dev-reload.js +23 -3
- package/dist/implementations/dms/dev-reload.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -4
- package/dist/implementations/dms/frontend-modules.js +38 -94
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +12 -2
- package/dist/implementations/dms/frontend-ready.js +34 -4
- package/dist/implementations/dms/frontend-ready.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +2 -1
- package/dist/implementations/dms/layout-banners.js +9 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/manifest.d.ts +7 -2
- package/dist/implementations/dms/manifest.js +12 -7
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +4 -3
- package/dist/implementations/dms/page.js +49 -18
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
- package/dist/implementations/dms/permissions-resolver.js +2 -2
- package/dist/implementations/dms/permissions-resolver.js.map +1 -1
- package/dist/implementations/dms/realtime.js +1 -0
- package/dist/implementations/dms/realtime.js.map +1 -1
- package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
- package/dist/implementations/dms-base/bulk-selection.js +23 -1
- package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
- package/dist/implementations/dms-base/filter-tokens.js +5 -3
- package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
- package/dist/implementations/dms-base/search-route.d.ts +1 -0
- package/dist/implementations/dms-base/search-route.js +35 -13
- package/dist/implementations/dms-base/search-route.js.map +1 -1
- package/dist/implementations/dms-base/table-view.js +11 -6
- package/dist/implementations/dms-base/table-view.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +2 -2
- package/dist/implementations/dms-notifications/index.js +5 -5
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/index.js +32 -55
- package/dist/index.js.map +1 -1
- package/dist/pages/modules/index.d.ts +1 -0
- package/dist/pages/modules/index.js +1 -0
- package/dist/pages/modules/index.js.map +1 -1
- package/dist/pages/modules/modules-store.d.ts +9 -0
- package/dist/pages/modules/modules-store.js +30 -0
- package/dist/pages/modules/modules-store.js.map +1 -0
- package/dist/pages/settings/users/account-credentials.js +2 -2
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/account-data-store.js +25 -8
- package/dist/pages/settings/users/account-data-store.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.js +9 -3
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
- package/dist/pages/settings/users/member-management.js +13 -14
- package/dist/pages/settings/users/member-management.js.map +1 -1
- package/dist/pages/settings/users/profile.d.ts +1 -4
- package/dist/pages/settings/users/profile.js +0 -35
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +26 -18
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +0 -1
- package/dist/pages/settings/users/role-editor.js +1 -2
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +1 -2
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +2 -2
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/realtime/broker.d.ts +6 -0
- package/dist/realtime/broker.js +8 -1
- package/dist/realtime/broker.js.map +1 -1
- package/dist/realtime/presence.d.ts +8 -3
- package/dist/realtime/presence.js +8 -4
- package/dist/realtime/presence.js.map +1 -1
- package/dist/realtime/sessions.d.ts +11 -1
- package/dist/realtime/sessions.js +21 -3
- package/dist/realtime/sessions.js.map +1 -1
- package/dist/realtime/table-view.d.ts +2 -2
- package/dist/realtime/table-view.js +4 -3
- package/dist/realtime/table-view.js.map +1 -1
- package/dist/routes/auth/client-ip.d.ts +1 -0
- package/dist/routes/auth/client-ip.js +18 -0
- package/dist/routes/auth/client-ip.js.map +1 -1
- package/dist/routes/auth/oauth/config.d.ts +2 -1
- package/dist/routes/auth/oauth/config.js +5 -1
- package/dist/routes/auth/oauth/config.js.map +1 -1
- package/dist/routes/auth/session-handoff.d.ts +0 -1
- package/dist/routes/auth/session-handoff.js +0 -2
- package/dist/routes/auth/session-handoff.js.map +1 -1
- package/dist/routes/auth.js +3 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +13 -1
- package/dist/routes/realtime.js +114 -29
- package/dist/routes/realtime.js.map +1 -1
- package/dist/startup-config.d.ts +2 -0
- package/dist/startup-config.js +62 -0
- package/dist/startup-config.js.map +1 -0
- package/dist/store/interfaces.d.ts +3 -2
- package/dist/store/interfaces.js +16 -6
- package/dist/store/interfaces.js.map +1 -1
- package/dist/store/listing.js +25 -15
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +5 -2
- package/dist/store/operations.js.map +1 -1
- package/dist/store/requirements.js +3 -2
- package/dist/store/requirements.js.map +1 -1
- package/dist/store/runtime.d.ts +10 -1
- package/dist/store/runtime.js +33 -6
- package/dist/store/runtime.js.map +1 -1
- package/dist/store/types.d.ts +10 -0
- package/dist/utils/ensure-default-tenant.d.ts +2 -1
- package/dist/utils/ensure-default-tenant.js +13 -1
- package/dist/utils/ensure-default-tenant.js.map +1 -1
- package/dist/utils/export-jobs.js +2 -1
- package/dist/utils/export-jobs.js.map +1 -1
- package/dist/validation/auth.schema.d.ts +2 -2
- package/dist/validation/member-invite.schema.d.ts +2 -10
- package/dist/validation/member-invite.schema.js +2 -15
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +24 -5
- package/frontend-vue/dms.server.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
- package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +33 -0
- package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
- package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
- package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
- package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
- package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
- package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +25 -5
- package/frontend-vue/layers/dms-core/app/composables/useApiError.ts +3 -5
- package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +61 -26
- package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
- package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +134 -35
- package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +136 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +136 -2
- package/frontend-vue/layers/dms-core/shared/types/app-config.ts +0 -2
- package/frontend-vue/layers/dms-layout/app/app.config.ts +0 -1
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +11 -1
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -107
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +4 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
- package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +2 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +49 -11
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +59 -4
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageRecordDeletion.ts +162 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +13 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +22 -52
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-quick-actions.client.ts +7 -7
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-session.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- package/frontend-vue/layers/dms-layout/app/theme/actions.ts +5 -4
- package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
- package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
- package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +45 -18
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +44 -17
- package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
- package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
- package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +48 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
- package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
- package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/actionError.ts +6 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +44 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +123 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +92 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +11 -5
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formValidation.ts +36 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +97 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +90 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/writeError.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/codeHighlight.ts +67 -29
- package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
- package/frontend-vue/layers/dms-ui/app/build/utils/htmlGrammar.ts +79 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/shellParser.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/utils/streamHighlight.ts +90 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
- package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
- package/frontend-vue/layers/dms-ui/app/components/code-snippet/CodeSnippet.vue +23 -12
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
- package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +119 -36
- package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +53 -22
- package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +226 -65
- package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
- package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +210 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
- package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
- package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
- package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
- package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
- package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +74 -25
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +48 -44
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +426 -97
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
- package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
- package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +16 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +189 -28
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +29 -12
- package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
- package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
- package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
- package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
- package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +94 -3
- package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +20 -5
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +20 -5
- package/frontend-vue/package.json +6 -2
- package/package.json +11 -10
- package/skills/dms/SKILL.md +1 -1
- package/skills/dms-auth/SKILL.md +5 -3
- package/skills/dms-best-practices/REFERENCE.md +2 -0
- package/skills/dms-best-practices/SKILL.md +4 -0
- package/skills/dms-module/SKILL.md +3 -2
- package/skills/dms-pages/REFERENCE.md +129 -16
- package/skills/dms-pages/SKILL.md +1 -1
- package/skills/dms-project/DEV-SERVERS.md +23 -1
- package/skills/dms-project/REFERENCE.md +1 -1
- package/skills/dms-project/SKILL.md +4 -1
- package/skills/dms-project/scripts/dms-dev.sh +205 -17
- package/dist/hooks/tenant-instances.d.ts +0 -1
- package/dist/hooks/tenant-instances.js +0 -13
- package/dist/hooks/tenant-instances.js.map +0 -1
- package/dist/routes/startup-gate.d.ts +0 -7
- package/dist/routes/startup-gate.js +0 -39
- package/dist/routes/startup-gate.js.map +0 -1
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { FormSubmitEvent } from "@nuxt/ui";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { onMounted, unref } from "vue";
|
|
3
|
+
import { nextTick, onMounted, onScopeDispose, unref } from "vue";
|
|
4
4
|
import type { FormProps, FormFetchResponse, FormSubmitResponse } from "./types";
|
|
5
5
|
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
6
6
|
import { FormEvents } from "./types/events";
|
|
7
7
|
import type { FormData, FormFieldValue } from "./types/value";
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
FieldCondition,
|
|
10
|
+
FormField,
|
|
11
|
+
FormFieldOrGroup,
|
|
12
|
+
} from "./types/field";
|
|
9
13
|
import { isFieldGroup } from "./types/field";
|
|
10
14
|
import { resolveResponseToast } from "../../build/utils/responseWarning";
|
|
11
15
|
import { processFieldI18n } from "../../build/utils/fieldOptionsI18n";
|
|
@@ -35,14 +39,17 @@ interface FormSubmitNotice {
|
|
|
35
39
|
import type { DataType } from "#dms-core/app/composables/data-types/useDataType";
|
|
36
40
|
import {
|
|
37
41
|
type ApiFieldError,
|
|
42
|
+
apiErrorStatus,
|
|
38
43
|
apiErrorText,
|
|
39
44
|
resolveFieldErrors,
|
|
40
45
|
} from "#dms-core/app/composables/useFieldErrors";
|
|
46
|
+
import { HTTP_NOT_FOUND } from "#dms-core/app/utils/http-status";
|
|
41
47
|
import { isBlankValue } from "#dms-core/app/composables/useFormValidation";
|
|
42
48
|
import {
|
|
43
49
|
isPlainObject,
|
|
44
50
|
sameFormValue,
|
|
45
51
|
} from "../../build/composables/unsaved-changes/formValue";
|
|
52
|
+
import { createStartingValueTracker } from "../../build/composables/form/fieldValueRule";
|
|
46
53
|
|
|
47
54
|
/** A server error shown under its field, translated. */
|
|
48
55
|
export interface FormServerFieldError {
|
|
@@ -361,6 +368,26 @@ export function resolveSubmitDefaults(
|
|
|
361
368
|
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
362
369
|
}
|
|
363
370
|
|
|
371
|
+
/**
|
|
372
|
+
* The values a form's fields start from among its submit defaults: a field
|
|
373
|
+
* the form submits under anyway (the parent a table is filtered on by a route
|
|
374
|
+
* parameter) shows it from the start, and a mandatory one is filled. A
|
|
375
|
+
* default with no field of the form is only submitted.
|
|
376
|
+
*/
|
|
377
|
+
export function fieldValuesOfSubmitDefaults(
|
|
378
|
+
fields: ReadonlyArray<{ id: string }>,
|
|
379
|
+
submitDefaults: Record<string, unknown> | undefined,
|
|
380
|
+
): FormData {
|
|
381
|
+
const values: FormData = {};
|
|
382
|
+
if (!submitDefaults) return values;
|
|
383
|
+
for (const { id } of fields) {
|
|
384
|
+
if (id in submitDefaults) {
|
|
385
|
+
values[id] = submitDefaults[id] as FormFieldValue;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return values;
|
|
389
|
+
}
|
|
390
|
+
|
|
364
391
|
export function makeFieldSchemaRequired(schema: z.ZodTypeAny): z.ZodTypeAny {
|
|
365
392
|
if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable) {
|
|
366
393
|
return makeFieldSchemaRequired(schema.unwrap());
|
|
@@ -451,6 +478,34 @@ export function isFieldMarkedRequired(
|
|
|
451
478
|
return !!field.required || (required?.has(field.id) ?? false);
|
|
452
479
|
}
|
|
453
480
|
|
|
481
|
+
const meetsCondition = (
|
|
482
|
+
condition: FieldCondition,
|
|
483
|
+
values: Record<string, unknown>,
|
|
484
|
+
): boolean => condition.in.includes(values[condition.field] ?? null);
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* The fields the values hide (`visibleWhen` not met) or disable
|
|
488
|
+
* (`disabledWhen` met), added to those the watches hide or disable: the
|
|
489
|
+
* conditions hold from the values the form opens with, without a watch.
|
|
490
|
+
*/
|
|
491
|
+
export function withConditionFields(
|
|
492
|
+
fields: ReadonlyArray<Pick<FormField, "id" | "visibleWhen" | "disabledWhen">>,
|
|
493
|
+
values: Record<string, unknown>,
|
|
494
|
+
watched: { disabled?: Set<string>; hidden?: Set<string> },
|
|
495
|
+
): { disabled: Set<string>; hidden: Set<string> } {
|
|
496
|
+
const disabled = new Set(watched.disabled);
|
|
497
|
+
const hidden = new Set(watched.hidden);
|
|
498
|
+
for (const field of fields) {
|
|
499
|
+
if (field.visibleWhen && !meetsCondition(field.visibleWhen, values)) {
|
|
500
|
+
hidden.add(field.id);
|
|
501
|
+
}
|
|
502
|
+
if (field.disabledWhen && meetsCondition(field.disabledWhen, values)) {
|
|
503
|
+
disabled.add(field.id);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return { disabled, hidden };
|
|
507
|
+
}
|
|
508
|
+
|
|
454
509
|
function watchFieldChanges(
|
|
455
510
|
state: Ref<Record<string, unknown>>,
|
|
456
511
|
componentId: string | undefined,
|
|
@@ -459,10 +514,14 @@ function watchFieldChanges(
|
|
|
459
514
|
componentId: string,
|
|
460
515
|
payload?: unknown,
|
|
461
516
|
) => void,
|
|
517
|
+
isStartingValue: (fieldId: string, value: unknown) => boolean,
|
|
462
518
|
): void {
|
|
463
519
|
if (!componentId) return;
|
|
464
520
|
const id = componentId;
|
|
465
521
|
const previousValuesJson: Record<string, string> = {};
|
|
522
|
+
// `initial` on each change: a watch writing values (SetFieldValue) leaves
|
|
523
|
+
// the values the form started from to the record it loaded.
|
|
524
|
+
const isInitial = createStartingValueTracker(isStartingValue);
|
|
466
525
|
|
|
467
526
|
// From mount, once `useWatch` listens: the values the form starts from
|
|
468
527
|
// (defaults, loaded row) reach the watch rules too, not only later edits.
|
|
@@ -485,6 +544,7 @@ function watchFieldChanges(
|
|
|
485
544
|
fieldId,
|
|
486
545
|
value: newState[fieldId],
|
|
487
546
|
formValues: newState,
|
|
547
|
+
initial: isInitial(fieldId, newState[fieldId]),
|
|
488
548
|
});
|
|
489
549
|
previousValuesJson[fieldId] = newJson;
|
|
490
550
|
}
|
|
@@ -544,15 +604,41 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
544
604
|
const initialValues = ref<FormData>({});
|
|
545
605
|
const submitSucceeded = ref(false);
|
|
546
606
|
|
|
547
|
-
|
|
607
|
+
const allFields = computed(() => flattenFields(props.fields));
|
|
608
|
+
|
|
609
|
+
// Whether a field holds the value the form started from: its default or
|
|
610
|
+
// the loaded record's, compared as its data type does (a joined row is
|
|
611
|
+
// the same as the id the picker holds).
|
|
612
|
+
const isStartingValue = (fieldId: string, value: unknown): boolean => {
|
|
613
|
+
const field = allFields.value.find((entry) => entry.id === fieldId);
|
|
614
|
+
const initial = initialValues.value[fieldId];
|
|
615
|
+
return field
|
|
616
|
+
? isSameFieldValue(field, value, initial)
|
|
617
|
+
: sameFormValue(value, initial);
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
watchFieldChanges(
|
|
621
|
+
state,
|
|
622
|
+
props.componentId,
|
|
623
|
+
sendComponentEvent,
|
|
624
|
+
isStartingValue,
|
|
625
|
+
);
|
|
548
626
|
|
|
549
627
|
// A successful submit leaves the form at its saved state; a later edit makes
|
|
550
628
|
// it dirty again, so clear `submitSucceeded` to re-arm the unsaved-changes
|
|
551
629
|
// guard (and the realtime release-on-unmount) for the new edits. Without this
|
|
552
630
|
// the guard would stay permanently disabled after the first save.
|
|
631
|
+
// Set while the record a save stored reaches the state: what the server
|
|
632
|
+
// stored is no edit made since.
|
|
633
|
+
let isApplyingSavedRecord = false;
|
|
634
|
+
let isDisposed = false;
|
|
635
|
+
onScopeDispose(() => {
|
|
636
|
+
isDisposed = true;
|
|
637
|
+
});
|
|
553
638
|
watch(
|
|
554
639
|
() => state.value,
|
|
555
640
|
() => {
|
|
641
|
+
if (isApplyingSavedRecord) return;
|
|
556
642
|
if (submitSucceeded.value) {
|
|
557
643
|
submitSucceeded.value = false;
|
|
558
644
|
}
|
|
@@ -560,15 +646,16 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
560
646
|
{ deep: true },
|
|
561
647
|
);
|
|
562
648
|
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
649
|
+
const inactiveFields = computed(() =>
|
|
650
|
+
withConditionFields(allFields.value, state.value, {
|
|
651
|
+
disabled: state.value.disabledFields as Set<string> | undefined,
|
|
652
|
+
hidden: state.value.hiddenFields as Set<string> | undefined,
|
|
653
|
+
}),
|
|
567
654
|
);
|
|
568
655
|
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
);
|
|
656
|
+
const disabledFields = computed(() => inactiveFields.value.disabled);
|
|
657
|
+
|
|
658
|
+
const hiddenFields = computed(() => inactiveFields.value.hidden);
|
|
572
659
|
|
|
573
660
|
const requiredFields = computed(
|
|
574
661
|
() => state.value.requiredFields as Set<string> | undefined,
|
|
@@ -607,32 +694,39 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
607
694
|
const isRecordUpdate = computed(
|
|
608
695
|
() => !!resolvedFetchUrl.value && props.submitUrlMethod !== HttpMethod.post,
|
|
609
696
|
);
|
|
697
|
+
// A create form (a table view's add form, the duplicate it opens) makes a
|
|
698
|
+
// new row: what it holds is new as a whole, nothing "changed" in it.
|
|
699
|
+
const createsRecord = props.kind === "create";
|
|
610
700
|
|
|
611
|
-
|
|
701
|
+
/** Reads the record at `fetchUrl`: its values, mapped for the fields. */
|
|
702
|
+
const loadRecord = async () => {
|
|
612
703
|
if (!props.fetchUrl) return undefined;
|
|
704
|
+
const processedUrl = resolveUrlVariables(props.fetchUrl, buildUrlContext());
|
|
705
|
+
if (processedUrl === undefined) return undefined;
|
|
706
|
+
|
|
707
|
+
const fetchedData = await $authFetch<FormFetchResponse>(processedUrl, {
|
|
708
|
+
method: props.fetchUrlMethod || "GET",
|
|
709
|
+
headers: { [CONTENT_LANGUAGE_HEADER]: "*" },
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
initialValues.value = {
|
|
713
|
+
...initialValues.value,
|
|
714
|
+
...JSON.parse(JSON.stringify(fetchedData)),
|
|
715
|
+
};
|
|
716
|
+
return processBeforeStateMappers(fetchedData, props.fields, getDataType);
|
|
717
|
+
};
|
|
613
718
|
|
|
719
|
+
const fetchData = async () => {
|
|
614
720
|
try {
|
|
615
|
-
|
|
616
|
-
props.fetchUrl,
|
|
617
|
-
buildUrlContext(),
|
|
618
|
-
);
|
|
619
|
-
if (processedUrl === undefined) return undefined;
|
|
620
|
-
|
|
621
|
-
const fetchedData = await $authFetch<FormFetchResponse>(processedUrl, {
|
|
622
|
-
method: props.fetchUrlMethod || "GET",
|
|
623
|
-
headers: { [CONTENT_LANGUAGE_HEADER]: "*" },
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
initialValues.value = {
|
|
627
|
-
...initialValues.value,
|
|
628
|
-
...JSON.parse(JSON.stringify(fetchedData)),
|
|
629
|
-
};
|
|
630
|
-
return processBeforeStateMappers(fetchedData, props.fields, getDataType);
|
|
721
|
+
return await loadRecord();
|
|
631
722
|
} catch (error) {
|
|
632
723
|
// A server render shows the failure in the form (FormLoadError) and
|
|
633
724
|
// hands it to the browser; a toast it added would show in its HTML
|
|
634
725
|
// alone, which the browser's toasts never hold.
|
|
635
|
-
|
|
726
|
+
// A 404 is no error either: the form says the record is not found.
|
|
727
|
+
if (!import.meta.env.SSR && apiErrorStatus(error) !== HTTP_NOT_FOUND) {
|
|
728
|
+
showFetchErrorToast(error);
|
|
729
|
+
}
|
|
636
730
|
throw error;
|
|
637
731
|
}
|
|
638
732
|
};
|
|
@@ -767,6 +861,63 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
767
861
|
options.onSaved?.();
|
|
768
862
|
};
|
|
769
863
|
|
|
864
|
+
/** Puts the record a save stored in the state: no edit made since. */
|
|
865
|
+
const applyStoredRecord = async (stored: FormData): Promise<void> => {
|
|
866
|
+
isApplyingSavedRecord = true;
|
|
867
|
+
Object.assign(state.value, stored);
|
|
868
|
+
options.onSaved?.();
|
|
869
|
+
await nextTick();
|
|
870
|
+
isApplyingSavedRecord = false;
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Reads the record back from `fetchUrl` once its update went through, for
|
|
875
|
+
* a route that does not answer it. An edit made meanwhile is kept, and a
|
|
876
|
+
* failed read leaves the values as they were sent.
|
|
877
|
+
*/
|
|
878
|
+
const refreshSavedRecord = async (): Promise<void> => {
|
|
879
|
+
let stored: FormData | undefined;
|
|
880
|
+
try {
|
|
881
|
+
stored = (await loadRecord()) as FormData | undefined;
|
|
882
|
+
} catch {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
if (isDisposed || !submitSucceeded.value) return;
|
|
886
|
+
if (!stored || Object.keys(stored).length === 0) return;
|
|
887
|
+
await applyStoredRecord(stored);
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Shows the record its update stored rather than what was typed: the
|
|
892
|
+
* server may store what it was sent normalized (a VAT number stripped of
|
|
893
|
+
* its spaces, the empty rows of a list dropped). A route that answers the
|
|
894
|
+
* record (a table view's edit route, interface-data-api 0.3) is read
|
|
895
|
+
* without a second request: its answer holds the record when it carries
|
|
896
|
+
* one of the form's fields, and only those are taken. Any other answer
|
|
897
|
+
* (`{ success: true }`, nothing) has the form read `fetchUrl` again. The
|
|
898
|
+
* form stays saved.
|
|
899
|
+
*/
|
|
900
|
+
const showSavedRecord = async (
|
|
901
|
+
response: FormSubmitResponse | undefined,
|
|
902
|
+
): Promise<void> => {
|
|
903
|
+
if (!submitSucceeded.value) return;
|
|
904
|
+
const fieldIds = new Set(allFields.value.map((field) => field.id));
|
|
905
|
+
// The route answers JSON, as `fetchUrl` does: field values.
|
|
906
|
+
const record: FormData = isPlainObject(response)
|
|
907
|
+
? (Object.fromEntries(
|
|
908
|
+
Object.entries(response).filter(([key]) => fieldIds.has(key)),
|
|
909
|
+
) as FormData)
|
|
910
|
+
: {};
|
|
911
|
+
if (Object.keys(record).length === 0) return refreshSavedRecord();
|
|
912
|
+
initialValues.value = {
|
|
913
|
+
...initialValues.value,
|
|
914
|
+
...JSON.parse(JSON.stringify(record)),
|
|
915
|
+
};
|
|
916
|
+
await applyStoredRecord(
|
|
917
|
+
processBeforeStateMappers(record, props.fields, getDataType) as FormData,
|
|
918
|
+
);
|
|
919
|
+
};
|
|
920
|
+
|
|
770
921
|
const handleSubmitSuccess = async (
|
|
771
922
|
response: FormSubmitResponse | undefined,
|
|
772
923
|
plainData: FormData,
|
|
@@ -854,6 +1005,14 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
854
1005
|
try {
|
|
855
1006
|
const response = await sendSubmit(target.url, plainData, markSubmitSaved);
|
|
856
1007
|
await handleSubmitSuccess(response, plainData);
|
|
1008
|
+
// A redirect leaves the form, an action form starts over.
|
|
1009
|
+
if (
|
|
1010
|
+
isRecordUpdate.value &&
|
|
1011
|
+
props.kind !== "action" &&
|
|
1012
|
+
!props.redirectOnSuccess
|
|
1013
|
+
) {
|
|
1014
|
+
await showSavedRecord(response);
|
|
1015
|
+
}
|
|
857
1016
|
} catch (error) {
|
|
858
1017
|
reportSubmitError(error);
|
|
859
1018
|
} finally {
|
|
@@ -914,5 +1073,7 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
914
1073
|
isFieldGroup,
|
|
915
1074
|
submitSucceeded,
|
|
916
1075
|
resolvedFetchUrl,
|
|
1076
|
+
createsRecord,
|
|
1077
|
+
effectiveSubmitDefaults,
|
|
917
1078
|
};
|
|
918
1079
|
};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computed,
|
|
3
3
|
getCurrentScope,
|
|
4
|
+
onMounted,
|
|
4
5
|
onScopeDispose,
|
|
6
|
+
shallowRef,
|
|
5
7
|
type ComputedRef,
|
|
6
8
|
} from "vue";
|
|
7
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
currentPageLive,
|
|
11
|
+
isServerPageLive,
|
|
12
|
+
} from "../../build/composables/live/currentPageLive";
|
|
8
13
|
import type { PageLiveController } from "../../build/composables/live/pageLiveController";
|
|
9
14
|
import type { PageLiveNote, PageLiveNoteInput } from "../../types/live";
|
|
10
15
|
|
|
@@ -68,8 +73,16 @@ export interface PageLiveState {
|
|
|
68
73
|
* paused, show what was missed, offer its own switch, hold the page while the
|
|
69
74
|
* user types.
|
|
70
75
|
*
|
|
71
|
-
* On a page without `live`,
|
|
72
|
-
*
|
|
76
|
+
* On a page without `live`, `isEnabled` is false, the page reads as live and
|
|
77
|
+
* never paused, and its actions do nothing. A server render reads the page as
|
|
78
|
+
* live and never paused too, but `isEnabled` says whether it declares `live`:
|
|
79
|
+
* the browser hydrates the page's blocks with its controller installed, so
|
|
80
|
+
* the server draws them as it will. The rest of the state is born in the
|
|
81
|
+
* browser (the realtime stream, the page's reads, a pause): a component
|
|
82
|
+
* hydrating the server's HTML reads it as the server did (live, not polling,
|
|
83
|
+
* never read, nothing missed) until its own `onMounted`, then follows the
|
|
84
|
+
* page. A component mounted afresh, after a client navigation, reads the page
|
|
85
|
+
* at once.
|
|
73
86
|
*
|
|
74
87
|
* ```ts
|
|
75
88
|
* const { isPaused, missedCount, resume, hold, release } = usePageLive();
|
|
@@ -80,25 +93,29 @@ export interface PageLiveState {
|
|
|
80
93
|
* `realtimeTopic` are.
|
|
81
94
|
*/
|
|
82
95
|
export function usePageLive(): PageLiveState {
|
|
83
|
-
|
|
96
|
+
// An async block hydrates after the page has installed its controller and
|
|
97
|
+
// read its data: until mounted, it draws the state the server drew.
|
|
98
|
+
const isHydrating = shallowRef(isDmsHydrating());
|
|
99
|
+
if (isHydrating.value) onMounted(() => (isHydrating.value = false));
|
|
100
|
+
const shown = () => (isHydrating.value ? null : currentPageLive());
|
|
101
|
+
const isPaused = computed(() => shown()?.isPaused.value ?? false);
|
|
84
102
|
const hold = usePageLiveHold();
|
|
103
|
+
const isServerLive = isServerPageLive();
|
|
85
104
|
return {
|
|
86
|
-
isEnabled: computed(() => currentPageLive() !== null),
|
|
105
|
+
isEnabled: computed(() => currentPageLive() !== null || isServerLive),
|
|
87
106
|
isLive: computed(() => !isPaused.value),
|
|
88
107
|
isPaused,
|
|
89
|
-
pauseReason: computed(() =>
|
|
108
|
+
pauseReason: computed(() => shown()?.pauseReason.value ?? null),
|
|
90
109
|
pause: () => currentPageLive()?.pause(),
|
|
91
110
|
resume: () => currentPageLive()?.resume(),
|
|
92
111
|
toggle: () => currentPageLive()?.toggle(),
|
|
93
112
|
hold: hold.hold,
|
|
94
113
|
release: hold.release,
|
|
95
|
-
lastUpdatedAt: computed(
|
|
96
|
-
|
|
97
|
-
),
|
|
98
|
-
missedCount: computed(() => currentPageLive()?.missedCount.value ?? 0),
|
|
99
|
-
missedDetail: computed(() => currentPageLive()?.missedDetail.value ?? null),
|
|
114
|
+
lastUpdatedAt: computed(() => shown()?.lastUpdatedAt.value ?? null),
|
|
115
|
+
missedCount: computed(() => shown()?.missedCount.value ?? 0),
|
|
116
|
+
missedDetail: computed(() => shown()?.missedDetail.value ?? null),
|
|
100
117
|
setMissedDetail: (detail) => currentPageLive()?.setMissedDetail(detail),
|
|
101
|
-
isPolling: computed(() =>
|
|
118
|
+
isPolling: computed(() => shown()?.isPolling.value ?? false),
|
|
102
119
|
};
|
|
103
120
|
}
|
|
104
121
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed, type ComputedRef } from "vue";
|
|
2
|
+
import { usePageToolbar } from "../../build/composables/page-toolbar/pageToolbarContext";
|
|
3
|
+
import type { PageToolbarSize } from "../../types/page-toolbar";
|
|
4
|
+
import { PAGE_TOOLBAR_CONTROL_HEIGHT_CLASSES } from "../../build/composables/page-toolbar/toolbarControlHeight";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_SIZE: PageToolbarSize = "sm";
|
|
7
|
+
|
|
8
|
+
/** The size of the `PageToolbar` holding a component (see {@link usePageToolbarSize}). */
|
|
9
|
+
export interface PageToolbarSizeState {
|
|
10
|
+
/** The toolbar's size, `sm` outside one. */
|
|
11
|
+
size: ComputedRef<PageToolbarSize>;
|
|
12
|
+
/** The height class its controls share at that size (`h-7` at `sm`). */
|
|
13
|
+
heightClass: ComputedRef<string>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The size of the `PageToolbar` a module's component sits in, for a leading
|
|
18
|
+
* block (a scope chip, a picker) to stand as tall as the toggle and the
|
|
19
|
+
* period beside it.
|
|
20
|
+
*/
|
|
21
|
+
export function usePageToolbarSize(): PageToolbarSizeState {
|
|
22
|
+
const toolbar = usePageToolbar();
|
|
23
|
+
const size = computed(() => toolbar?.size.value ?? DEFAULT_SIZE);
|
|
24
|
+
return {
|
|
25
|
+
size,
|
|
26
|
+
heightClass: computed(
|
|
27
|
+
() => PAGE_TOOLBAR_CONTROL_HEIGHT_CLASSES[size.value],
|
|
28
|
+
),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -4,8 +4,8 @@ import type { TableViewColumn } from "./types";
|
|
|
4
4
|
/**
|
|
5
5
|
* The few inputs the (unchanged) KanbanBoard needs beyond the generic
|
|
6
6
|
* {@link TableViewDisplayContext}: the two-way group-by field shared with the
|
|
7
|
-
* options-menu selector,
|
|
8
|
-
* evaluation. Everything else (query, componentId, pageId, labelKey) is read from
|
|
7
|
+
* options-menu selector, the raw edit/delete action configs for per-row rule
|
|
8
|
+
* evaluation, and the callback told of a saved move. Everything else (query, componentId, pageId, labelKey) is read from
|
|
9
9
|
* the generic context. Provided by TableView and injected by the kanban adapter
|
|
10
10
|
* — slotted content is a descendant of TableView, so a native inject reaches it.
|
|
11
11
|
*/
|
|
@@ -13,6 +13,8 @@ export interface KanbanDisplayBridge {
|
|
|
13
13
|
groupByField: Ref<string>;
|
|
14
14
|
editAction?: boolean | RowActionConfig;
|
|
15
15
|
deleteAction?: boolean | RowActionConfig;
|
|
16
|
+
/** A card was moved to another column and saved: the counts read again. */
|
|
17
|
+
onCardMoved?: () => void;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export const KANBAN_DISPLAY_BRIDGE_KEY: InjectionKey<KanbanDisplayBridge> =
|
|
@@ -19,12 +19,31 @@ export interface SidePanelTargetOptions {
|
|
|
19
19
|
* `{ index }` (from 1) and `{ total }`.
|
|
20
20
|
*/
|
|
21
21
|
positionLabel?: string;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* The open row is kept in the URL (`?record=`): on unless `false` for a
|
|
24
|
+
* side panel, off unless `true` for a drawer.
|
|
25
|
+
*/
|
|
23
26
|
deepLink?: boolean;
|
|
24
27
|
/** The state drawn on a row that no longer exists (a 404). */
|
|
25
28
|
notFound?: SidePanelNotFoundTexts;
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
/**
|
|
32
|
+
* What a `drawer` target sets besides its component (backend
|
|
33
|
+
* `DrawerTargetOptions`): the row options of a side panel, for a drawer
|
|
34
|
+
* opened on a row, and its size.
|
|
35
|
+
*/
|
|
36
|
+
export interface DrawerTargetOptions
|
|
37
|
+
extends Omit<SidePanelTargetOptions, "title"> {
|
|
38
|
+
/** Width of a `left` / `right` drawer: a modal's at that size; 600px without one. */
|
|
39
|
+
size?: ModalSize;
|
|
40
|
+
/**
|
|
41
|
+
* The DMS draws the row header (title, position, previous / next): on when
|
|
42
|
+
* `rowTitle` or `positionLabel` is set, unless `false`.
|
|
43
|
+
*/
|
|
44
|
+
rowHeader?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
28
47
|
/**
|
|
29
48
|
* Fetches a file with the user's session and saves it (backend
|
|
30
49
|
* `DownloadActionTarget`).
|
|
@@ -38,14 +57,14 @@ export interface DownloadActionTarget {
|
|
|
38
57
|
}
|
|
39
58
|
|
|
40
59
|
export type ActionTarget =
|
|
41
|
-
| {
|
|
60
|
+
| ({
|
|
42
61
|
type: "drawer";
|
|
43
62
|
component: ComponentInfo;
|
|
44
63
|
title?: string;
|
|
45
64
|
description?: string;
|
|
46
65
|
/** Edge the drawer slides in from (`bottom` by default). */
|
|
47
66
|
direction?: DrawerDirection;
|
|
48
|
-
}
|
|
67
|
+
} & DrawerTargetOptions)
|
|
49
68
|
| {
|
|
50
69
|
type: "modal";
|
|
51
70
|
size?: ModalSize;
|
|
@@ -274,6 +274,8 @@ export interface TableViewConfig<T extends Data>
|
|
|
274
274
|
location: string;
|
|
275
275
|
enableTableExport?: boolean;
|
|
276
276
|
archiveMode?: boolean;
|
|
277
|
+
/** Caption count while the archived rows show; "Archived: {count}" else. */
|
|
278
|
+
archivedCountLabel?: string;
|
|
277
279
|
defaultFilters?: TableFilter[];
|
|
278
280
|
columns: TableViewColumn[];
|
|
279
281
|
labelKey?: string;
|
|
@@ -298,6 +300,8 @@ export interface TableViewConfig<T extends Data>
|
|
|
298
300
|
displays?: TableViewDisplayConfig[];
|
|
299
301
|
/** Display shown by default when the user has no saved preference. Defaults to the first display. */
|
|
300
302
|
defaultDisplay?: string;
|
|
303
|
+
/** Display a phone opens on when the user has no saved choice; one of `displays`. */
|
|
304
|
+
mobileDisplay?: string;
|
|
301
305
|
/** Expandable rows: caret column + detail band. */
|
|
302
306
|
expandable?: TableViewExpandableConfig;
|
|
303
307
|
/** How much the table draws around its rows. */
|
|
@@ -87,7 +87,11 @@ export interface TableViewDisplayActions<T> {
|
|
|
87
87
|
canDeleteRow: (item: T) => boolean;
|
|
88
88
|
add: () => void;
|
|
89
89
|
edit: (item: T) => void;
|
|
90
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Deletes the rows once confirmed. A display drawing rows the grid does not
|
|
92
|
+
* list (a kanban card) hands them in `rows`, so a dialog can name them.
|
|
93
|
+
*/
|
|
94
|
+
delete: (ids: string[], rows?: T[]) => void;
|
|
91
95
|
duplicate: (id: string) => void;
|
|
92
96
|
details: (item: T) => void;
|
|
93
97
|
/** What a click on the row does in the grid: its default action. */
|
|
@@ -150,6 +154,10 @@ export interface TableViewCardReorder {
|
|
|
150
154
|
export interface TableViewCardConfig {
|
|
151
155
|
fields?: string[];
|
|
152
156
|
component?: ComponentInfo;
|
|
157
|
+
/** `cards` only: the narrowest a card gets, a CSS length (`230px` left out). */
|
|
158
|
+
minWidth?: string;
|
|
159
|
+
/** `cards` only: the height of a placeholder card, a CSS length. */
|
|
160
|
+
skeletonHeight?: string;
|
|
153
161
|
}
|
|
154
162
|
|
|
155
163
|
/**
|
|
@@ -180,6 +188,13 @@ export interface TableViewCardProps<T = Record<string, unknown>> {
|
|
|
180
188
|
* caller who may edit: the card's move handle, to draw somewhere on it.
|
|
181
189
|
*/
|
|
182
190
|
reorder?: TableViewCardReorder;
|
|
191
|
+
/**
|
|
192
|
+
* `cards` only: the row's actions as the grid row offers them (its inline
|
|
193
|
+
* buttons and its … menu, with their rules and confirmations), to draw
|
|
194
|
+
* with `<component :is="rowActions" />`. It draws nothing for a table with
|
|
195
|
+
* no row action, and stops its clicks from reaching the card.
|
|
196
|
+
*/
|
|
197
|
+
rowActions?: Component;
|
|
183
198
|
}
|
|
184
199
|
|
|
185
200
|
/**
|
|
@@ -239,6 +254,14 @@ export interface TableViewDisplayContext<T = Record<string, unknown>> {
|
|
|
239
254
|
pageId?: string;
|
|
240
255
|
/** Per-instance options declared for this display in the backend config. */
|
|
241
256
|
options?: Record<string, unknown>;
|
|
257
|
+
/**
|
|
258
|
+
* A self-managed display hands the rows it shows, in the order the user
|
|
259
|
+
* reads them (a board: column by column), each time they change: a row
|
|
260
|
+
* opened from it steps through them in its drawer or side panel ("3 of
|
|
261
|
+
* 12", previous / next, J and K). Without it, a self-managed display's row
|
|
262
|
+
* opens without steps. The shared list's displays need not call it.
|
|
263
|
+
*/
|
|
264
|
+
setShownRows?: (rows: T[]) => void;
|
|
242
265
|
/** Re-fetch the table view (shared list + tab counts + active display). */
|
|
243
266
|
refresh: () => Promise<void> | void;
|
|
244
267
|
/**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { watchClosingLayers } from "../build/composables/containers/closingLayers";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Every dialog the DMS or a module renders lets the page be clicked as soon
|
|
5
|
+
* as it starts closing: one place for UModal, USlideover, UDrawer, the
|
|
6
|
+
* confirm dialogs and DynamicDrawer / DynamicModal alike.
|
|
7
|
+
*/
|
|
8
|
+
export default defineDmsPlugin(() => {
|
|
9
|
+
watchClosingLayers(document);
|
|
10
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LIVE_PAUSE_SOURCE } from "#dms-core/app/composables/live/livePauseSource";
|
|
2
|
+
import { currentPageLive } from "../build/composables/live/currentPageLive";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gives the core layer the pause of the page on screen (its live
|
|
6
|
+
* controller), so a component's own polling (`useApiData`'s
|
|
7
|
+
* `refreshInterval`) stops with the page's blocks. The server renders no
|
|
8
|
+
* poll and installs no controller: it reads as never paused.
|
|
9
|
+
*/
|
|
10
|
+
export default defineDmsPlugin(({ vueApp }) => {
|
|
11
|
+
vueApp.provide(
|
|
12
|
+
LIVE_PAUSE_SOURCE,
|
|
13
|
+
() => currentPageLive()?.isPaused.value ?? false,
|
|
14
|
+
);
|
|
15
|
+
});
|
|
@@ -2,10 +2,12 @@ import { registerDefaultDataTypes } from "../build/composables/data-types/regist
|
|
|
2
2
|
import { registerDefaultFunctions } from "../build/composables/table-view/registerDefaultFunctions";
|
|
3
3
|
import { registerFormFunctions } from "../build/composables/form/registerFormFunctions";
|
|
4
4
|
import { registerBlockFunctions } from "../build/composables/blocks/registerBlockFunctions";
|
|
5
|
+
import { trackPageArrivals } from "../build/composables/table-view/utils/pageArrival";
|
|
5
6
|
|
|
6
7
|
export default defineDmsPlugin(() => {
|
|
7
8
|
registerDefaultDataTypes();
|
|
8
9
|
registerDefaultFunctions();
|
|
9
10
|
registerFormFunctions();
|
|
10
11
|
registerBlockFunctions();
|
|
12
|
+
trackPageArrivals();
|
|
11
13
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Why a number field keeps another value than the one typed: above its `max`,
|
|
3
|
-
* below its `min`, or off its `step
|
|
3
|
+
* below its `min`, or off its `step` (when it snaps to it: `stepSnapping`).
|
|
4
4
|
*/
|
|
5
5
|
export type InputNumberAdjustmentReason = "min" | "max" | "step";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* What `DmsInputNumber` emits as `adjust` when it settles a typed number on
|
|
9
9
|
* another value (on leaving the field, or on Enter): 1020 typed in a field of
|
|
10
|
-
* steps of 50
|
|
10
|
+
* steps of 50 that snaps to them gives
|
|
11
|
+
* `{ typed: 1020, value: 1000, reason: "step" }`.
|
|
11
12
|
*/
|
|
12
13
|
export interface InputNumberAdjustment {
|
|
13
14
|
/** The number as typed. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sizes a `PageToolbar` draws its controls at (`xs` 24px, `sm` 28px,
|
|
3
|
+
* `md` 32px tall), as `usePageToolbarSize()` reports them to a module's
|
|
4
|
+
* leading block. The same values as `PageToolbarSize` of
|
|
5
|
+
* `@antelopejs/interface-dms/base/page-toolbar`.
|
|
6
|
+
*/
|
|
7
|
+
export type PageToolbarSize = "xs" | "sm" | "md";
|
|
@@ -24,8 +24,6 @@ export interface CustomRowAction {
|
|
|
24
24
|
rule?: RowActionRule;
|
|
25
25
|
/** Inline button instead of a menu entry (the backend serializes `isVisible`). */
|
|
26
26
|
isVisible?: boolean;
|
|
27
|
-
/** Legacy spelling of `isVisible`, still honoured. */
|
|
28
|
-
visible?: boolean;
|
|
29
27
|
/**
|
|
30
28
|
* Preferred row-click target when its rule accepts the row: a double-click,
|
|
31
29
|
* or a single click on a table with `rowClick: "single"`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a drawer or modal opened on a row receives to step through the rows
|
|
3
|
+
* of the table (`navigation` prop): J and K do the same. The steps follow the
|
|
4
|
+
* open row's neighbours in the table's current order, past the rows loaded:
|
|
5
|
+
* rows arriving or leaving meanwhile (a live table) never make a step skip
|
|
6
|
+
* or revisit one.
|
|
7
|
+
*/
|
|
8
|
+
export interface RowNavigation {
|
|
9
|
+
/** Position of the row among all the rows the table lists, from 0. */
|
|
10
|
+
index: number;
|
|
11
|
+
/** The rows the table lists: its count, beyond the page loaded. */
|
|
12
|
+
total: number;
|
|
13
|
+
hasPrev: boolean;
|
|
14
|
+
hasNext: boolean;
|
|
15
|
+
prev: () => void;
|
|
16
|
+
next: () => void;
|
|
17
|
+
}
|