@antelopejs/dms 0.9.8 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -0
- package/README.md +1 -1
- package/data/module-store/catalog.json +2 -2
- package/dist/attachments/table-view.js +2 -2
- package/dist/attachments/table-view.js.map +1 -1
- package/dist/automation/actions.d.ts +2 -0
- package/dist/automation/actions.js +116 -71
- package/dist/automation/actions.js.map +1 -1
- package/dist/automation/i18n.d.ts +4 -0
- package/dist/automation/i18n.js +19 -0
- package/dist/automation/i18n.js.map +1 -0
- package/dist/automation/send-notification.d.ts +21 -0
- package/dist/automation/send-notification.js +163 -0
- package/dist/automation/send-notification.js.map +1 -0
- package/dist/automation/triggers.js +19 -25
- package/dist/automation/triggers.js.map +1 -1
- package/dist/client-origin-cors.d.ts +1 -0
- package/dist/client-origin-cors.js +19 -0
- package/dist/client-origin-cors.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +5 -3
- package/dist/config.js.map +1 -1
- package/dist/frontend-module.d.ts +4 -0
- package/dist/frontend-module.js +37 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/implementations/dms/client-ip.js +1 -1
- package/dist/implementations/dms/client-ip.js.map +1 -1
- package/dist/implementations/dms/dev-reload.d.ts +5 -0
- package/dist/implementations/dms/dev-reload.js +23 -3
- package/dist/implementations/dms/dev-reload.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -4
- package/dist/implementations/dms/frontend-modules.js +22 -89
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +12 -2
- package/dist/implementations/dms/frontend-ready.js +34 -4
- package/dist/implementations/dms/frontend-ready.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +2 -1
- package/dist/implementations/dms/layout-banners.js +9 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/manifest.d.ts +1 -2
- package/dist/implementations/dms/manifest.js +2 -0
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +4 -3
- package/dist/implementations/dms/page.js +49 -18
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
- package/dist/implementations/dms/permissions-resolver.js +2 -2
- package/dist/implementations/dms/permissions-resolver.js.map +1 -1
- package/dist/implementations/dms/realtime.js +1 -0
- package/dist/implementations/dms/realtime.js.map +1 -1
- package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
- package/dist/implementations/dms-base/bulk-selection.js +23 -1
- package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
- package/dist/implementations/dms-base/filter-tokens.js +5 -3
- package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
- package/dist/implementations/dms-base/search-route.d.ts +1 -0
- package/dist/implementations/dms-base/search-route.js +35 -13
- package/dist/implementations/dms-base/search-route.js.map +1 -1
- package/dist/implementations/dms-base/table-view.js +11 -6
- package/dist/implementations/dms-base/table-view.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +2 -2
- package/dist/implementations/dms-notifications/index.js +5 -5
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/index.js +28 -48
- package/dist/index.js.map +1 -1
- package/dist/pages/modules/index.d.ts +1 -0
- package/dist/pages/modules/index.js +1 -0
- package/dist/pages/modules/index.js.map +1 -1
- package/dist/pages/modules/modules-store.d.ts +9 -0
- package/dist/pages/modules/modules-store.js +30 -0
- package/dist/pages/modules/modules-store.js.map +1 -0
- package/dist/pages/settings/users/account-credentials.js +2 -2
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/account-data-store.js +25 -8
- package/dist/pages/settings/users/account-data-store.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.js +9 -3
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
- package/dist/pages/settings/users/member-management.js +13 -14
- package/dist/pages/settings/users/member-management.js.map +1 -1
- package/dist/pages/settings/users/profile.d.ts +1 -4
- package/dist/pages/settings/users/profile.js +0 -35
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +26 -18
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +0 -1
- package/dist/pages/settings/users/role-editor.js +1 -2
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +1 -2
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +2 -2
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/realtime/broker.d.ts +6 -0
- package/dist/realtime/broker.js +8 -1
- package/dist/realtime/broker.js.map +1 -1
- package/dist/realtime/presence.d.ts +8 -3
- package/dist/realtime/presence.js +8 -4
- package/dist/realtime/presence.js.map +1 -1
- package/dist/realtime/sessions.d.ts +11 -1
- package/dist/realtime/sessions.js +21 -3
- package/dist/realtime/sessions.js.map +1 -1
- package/dist/realtime/table-view.d.ts +2 -2
- package/dist/realtime/table-view.js +4 -3
- package/dist/realtime/table-view.js.map +1 -1
- package/dist/routes/auth/client-ip.d.ts +1 -0
- package/dist/routes/auth/client-ip.js +18 -0
- package/dist/routes/auth/client-ip.js.map +1 -1
- package/dist/routes/auth/oauth/config.d.ts +2 -1
- package/dist/routes/auth/oauth/config.js +5 -1
- package/dist/routes/auth/oauth/config.js.map +1 -1
- package/dist/routes/auth/session-handoff.d.ts +0 -1
- package/dist/routes/auth/session-handoff.js +0 -2
- package/dist/routes/auth/session-handoff.js.map +1 -1
- package/dist/routes/auth.js +3 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +13 -1
- package/dist/routes/realtime.js +114 -29
- package/dist/routes/realtime.js.map +1 -1
- package/dist/startup-config.d.ts +2 -0
- package/dist/startup-config.js +62 -0
- package/dist/startup-config.js.map +1 -0
- package/dist/store/interfaces.d.ts +3 -2
- package/dist/store/interfaces.js +16 -6
- package/dist/store/interfaces.js.map +1 -1
- package/dist/store/listing.js +24 -13
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +4 -0
- package/dist/store/operations.js.map +1 -1
- package/dist/store/requirements.js +3 -2
- package/dist/store/requirements.js.map +1 -1
- package/dist/store/runtime.d.ts +10 -1
- package/dist/store/runtime.js +33 -6
- package/dist/store/runtime.js.map +1 -1
- package/dist/store/types.d.ts +10 -0
- package/dist/validation/auth.schema.d.ts +2 -2
- package/dist/validation/member-invite.schema.d.ts +2 -10
- package/dist/validation/member-invite.schema.js +2 -15
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +24 -5
- package/frontend-vue/dms.server.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
- package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +34 -0
- package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
- package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
- package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
- package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
- package/frontend-vue/layers/dms-core/app/composables/hydration/isHydratingComponent.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
- package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +22 -5
- package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
- package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +166 -35
- package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +134 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +134 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionBar.vue +8 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +14 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
- package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
- package/frontend-vue/layers/dms-layout/app/composables/layout/usePageRecord.ts +50 -0
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +25 -7
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +51 -4
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +6 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +14 -44
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
- package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
- package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageRecord.ts +71 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +39 -14
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +38 -13
- package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
- package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
- package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +38 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
- package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
- package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +47 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +99 -24
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +71 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +65 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +73 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +77 -32
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
- package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
- package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
- package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
- package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +118 -36
- package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +205 -65
- package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
- package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +203 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
- package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
- package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
- package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
- package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
- package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +45 -35
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +410 -96
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
- package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
- package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +142 -21
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +11 -4
- package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
- package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
- package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
- package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
- package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -4
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -4
- package/frontend-vue/package.json +2 -2
- package/package.json +7 -6
- package/skills/dms/SKILL.md +1 -1
- package/skills/dms-auth/SKILL.md +5 -3
- package/skills/dms-best-practices/REFERENCE.md +2 -0
- package/skills/dms-best-practices/SKILL.md +4 -0
- package/skills/dms-module/SKILL.md +3 -2
- package/skills/dms-pages/REFERENCE.md +125 -16
- package/skills/dms-pages/SKILL.md +1 -1
- package/skills/dms-project/DEV-SERVERS.md +23 -1
- package/skills/dms-project/REFERENCE.md +1 -1
- package/skills/dms-project/SKILL.md +4 -1
- package/skills/dms-project/scripts/dms-dev.sh +205 -17
- package/dist/routes/startup-gate.d.ts +0 -7
- package/dist/routes/startup-gate.js +0 -39
- package/dist/routes/startup-gate.js.map +0 -1
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
|
@@ -1,6 +1,6 @@
|
|
|
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";
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
isPlainObject,
|
|
44
44
|
sameFormValue,
|
|
45
45
|
} from "../../build/composables/unsaved-changes/formValue";
|
|
46
|
+
import { createStartingValueTracker } from "../../build/composables/form/fieldValueRule";
|
|
46
47
|
|
|
47
48
|
/** A server error shown under its field, translated. */
|
|
48
49
|
export interface FormServerFieldError {
|
|
@@ -361,6 +362,26 @@ export function resolveSubmitDefaults(
|
|
|
361
362
|
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
362
363
|
}
|
|
363
364
|
|
|
365
|
+
/**
|
|
366
|
+
* The values a form's fields start from among its submit defaults: a field
|
|
367
|
+
* the form submits under anyway (the parent a table is filtered on by a route
|
|
368
|
+
* parameter) shows it from the start, and a mandatory one is filled. A
|
|
369
|
+
* default with no field of the form is only submitted.
|
|
370
|
+
*/
|
|
371
|
+
export function fieldValuesOfSubmitDefaults(
|
|
372
|
+
fields: ReadonlyArray<{ id: string }>,
|
|
373
|
+
submitDefaults: Record<string, unknown> | undefined,
|
|
374
|
+
): FormData {
|
|
375
|
+
const values: FormData = {};
|
|
376
|
+
if (!submitDefaults) return values;
|
|
377
|
+
for (const { id } of fields) {
|
|
378
|
+
if (id in submitDefaults) {
|
|
379
|
+
values[id] = submitDefaults[id] as FormFieldValue;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return values;
|
|
383
|
+
}
|
|
384
|
+
|
|
364
385
|
export function makeFieldSchemaRequired(schema: z.ZodTypeAny): z.ZodTypeAny {
|
|
365
386
|
if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable) {
|
|
366
387
|
return makeFieldSchemaRequired(schema.unwrap());
|
|
@@ -459,10 +480,14 @@ function watchFieldChanges(
|
|
|
459
480
|
componentId: string,
|
|
460
481
|
payload?: unknown,
|
|
461
482
|
) => void,
|
|
483
|
+
isStartingValue: (fieldId: string, value: unknown) => boolean,
|
|
462
484
|
): void {
|
|
463
485
|
if (!componentId) return;
|
|
464
486
|
const id = componentId;
|
|
465
487
|
const previousValuesJson: Record<string, string> = {};
|
|
488
|
+
// `initial` on each change: a watch writing values (SetFieldValue) leaves
|
|
489
|
+
// the values the form started from to the record it loaded.
|
|
490
|
+
const isInitial = createStartingValueTracker(isStartingValue);
|
|
466
491
|
|
|
467
492
|
// From mount, once `useWatch` listens: the values the form starts from
|
|
468
493
|
// (defaults, loaded row) reach the watch rules too, not only later edits.
|
|
@@ -485,6 +510,7 @@ function watchFieldChanges(
|
|
|
485
510
|
fieldId,
|
|
486
511
|
value: newState[fieldId],
|
|
487
512
|
formValues: newState,
|
|
513
|
+
initial: isInitial(fieldId, newState[fieldId]),
|
|
488
514
|
});
|
|
489
515
|
previousValuesJson[fieldId] = newJson;
|
|
490
516
|
}
|
|
@@ -544,15 +570,41 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
544
570
|
const initialValues = ref<FormData>({});
|
|
545
571
|
const submitSucceeded = ref(false);
|
|
546
572
|
|
|
547
|
-
|
|
573
|
+
const allFields = computed(() => flattenFields(props.fields));
|
|
574
|
+
|
|
575
|
+
// Whether a field holds the value the form started from: its default or
|
|
576
|
+
// the loaded record's, compared as its data type does (a joined row is
|
|
577
|
+
// the same as the id the picker holds).
|
|
578
|
+
const isStartingValue = (fieldId: string, value: unknown): boolean => {
|
|
579
|
+
const field = allFields.value.find((entry) => entry.id === fieldId);
|
|
580
|
+
const initial = initialValues.value[fieldId];
|
|
581
|
+
return field
|
|
582
|
+
? isSameFieldValue(field, value, initial)
|
|
583
|
+
: sameFormValue(value, initial);
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
watchFieldChanges(
|
|
587
|
+
state,
|
|
588
|
+
props.componentId,
|
|
589
|
+
sendComponentEvent,
|
|
590
|
+
isStartingValue,
|
|
591
|
+
);
|
|
548
592
|
|
|
549
593
|
// A successful submit leaves the form at its saved state; a later edit makes
|
|
550
594
|
// it dirty again, so clear `submitSucceeded` to re-arm the unsaved-changes
|
|
551
595
|
// guard (and the realtime release-on-unmount) for the new edits. Without this
|
|
552
596
|
// the guard would stay permanently disabled after the first save.
|
|
597
|
+
// Set while the record a save stored reaches the state: what the server
|
|
598
|
+
// stored is no edit made since.
|
|
599
|
+
let isApplyingSavedRecord = false;
|
|
600
|
+
let isDisposed = false;
|
|
601
|
+
onScopeDispose(() => {
|
|
602
|
+
isDisposed = true;
|
|
603
|
+
});
|
|
553
604
|
watch(
|
|
554
605
|
() => state.value,
|
|
555
606
|
() => {
|
|
607
|
+
if (isApplyingSavedRecord) return;
|
|
556
608
|
if (submitSucceeded.value) {
|
|
557
609
|
submitSucceeded.value = false;
|
|
558
610
|
}
|
|
@@ -560,8 +612,6 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
560
612
|
{ deep: true },
|
|
561
613
|
);
|
|
562
614
|
|
|
563
|
-
const allFields = computed(() => flattenFields(props.fields));
|
|
564
|
-
|
|
565
615
|
const disabledFields = computed(
|
|
566
616
|
() => state.value.disabledFields as Set<string> | undefined,
|
|
567
617
|
);
|
|
@@ -607,27 +657,31 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
607
657
|
const isRecordUpdate = computed(
|
|
608
658
|
() => !!resolvedFetchUrl.value && props.submitUrlMethod !== HttpMethod.post,
|
|
609
659
|
);
|
|
660
|
+
// A create form (a table view's add form, the duplicate it opens) makes a
|
|
661
|
+
// new row: what it holds is new as a whole, nothing "changed" in it.
|
|
662
|
+
const createsRecord = props.kind === "create";
|
|
610
663
|
|
|
611
|
-
|
|
664
|
+
/** Reads the record at `fetchUrl`: its values, mapped for the fields. */
|
|
665
|
+
const loadRecord = async () => {
|
|
612
666
|
if (!props.fetchUrl) return undefined;
|
|
667
|
+
const processedUrl = resolveUrlVariables(props.fetchUrl, buildUrlContext());
|
|
668
|
+
if (processedUrl === undefined) return undefined;
|
|
669
|
+
|
|
670
|
+
const fetchedData = await $authFetch<FormFetchResponse>(processedUrl, {
|
|
671
|
+
method: props.fetchUrlMethod || "GET",
|
|
672
|
+
headers: { [CONTENT_LANGUAGE_HEADER]: "*" },
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
initialValues.value = {
|
|
676
|
+
...initialValues.value,
|
|
677
|
+
...JSON.parse(JSON.stringify(fetchedData)),
|
|
678
|
+
};
|
|
679
|
+
return processBeforeStateMappers(fetchedData, props.fields, getDataType);
|
|
680
|
+
};
|
|
613
681
|
|
|
682
|
+
const fetchData = async () => {
|
|
614
683
|
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);
|
|
684
|
+
return await loadRecord();
|
|
631
685
|
} catch (error) {
|
|
632
686
|
// A server render shows the failure in the form (FormLoadError) and
|
|
633
687
|
// hands it to the browser; a toast it added would show in its HTML
|
|
@@ -767,6 +821,63 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
767
821
|
options.onSaved?.();
|
|
768
822
|
};
|
|
769
823
|
|
|
824
|
+
/** Puts the record a save stored in the state: no edit made since. */
|
|
825
|
+
const applyStoredRecord = async (stored: FormData): Promise<void> => {
|
|
826
|
+
isApplyingSavedRecord = true;
|
|
827
|
+
Object.assign(state.value, stored);
|
|
828
|
+
options.onSaved?.();
|
|
829
|
+
await nextTick();
|
|
830
|
+
isApplyingSavedRecord = false;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Reads the record back from `fetchUrl` once its update went through, for
|
|
835
|
+
* a route that does not answer it. An edit made meanwhile is kept, and a
|
|
836
|
+
* failed read leaves the values as they were sent.
|
|
837
|
+
*/
|
|
838
|
+
const refreshSavedRecord = async (): Promise<void> => {
|
|
839
|
+
let stored: FormData | undefined;
|
|
840
|
+
try {
|
|
841
|
+
stored = (await loadRecord()) as FormData | undefined;
|
|
842
|
+
} catch {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
if (isDisposed || !submitSucceeded.value) return;
|
|
846
|
+
if (!stored || Object.keys(stored).length === 0) return;
|
|
847
|
+
await applyStoredRecord(stored);
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Shows the record its update stored rather than what was typed: the
|
|
852
|
+
* server may store what it was sent normalized (a VAT number stripped of
|
|
853
|
+
* its spaces, the empty rows of a list dropped). A route that answers the
|
|
854
|
+
* record (a table view's edit route, interface-data-api 0.3) is read
|
|
855
|
+
* without a second request: its answer holds the record when it carries
|
|
856
|
+
* one of the form's fields, and only those are taken. Any other answer
|
|
857
|
+
* (`{ success: true }`, nothing) has the form read `fetchUrl` again. The
|
|
858
|
+
* form stays saved.
|
|
859
|
+
*/
|
|
860
|
+
const showSavedRecord = async (
|
|
861
|
+
response: FormSubmitResponse | undefined,
|
|
862
|
+
): Promise<void> => {
|
|
863
|
+
if (!submitSucceeded.value) return;
|
|
864
|
+
const fieldIds = new Set(allFields.value.map((field) => field.id));
|
|
865
|
+
// The route answers JSON, as `fetchUrl` does: field values.
|
|
866
|
+
const record: FormData = isPlainObject(response)
|
|
867
|
+
? (Object.fromEntries(
|
|
868
|
+
Object.entries(response).filter(([key]) => fieldIds.has(key)),
|
|
869
|
+
) as FormData)
|
|
870
|
+
: {};
|
|
871
|
+
if (Object.keys(record).length === 0) return refreshSavedRecord();
|
|
872
|
+
initialValues.value = {
|
|
873
|
+
...initialValues.value,
|
|
874
|
+
...JSON.parse(JSON.stringify(record)),
|
|
875
|
+
};
|
|
876
|
+
await applyStoredRecord(
|
|
877
|
+
processBeforeStateMappers(record, props.fields, getDataType) as FormData,
|
|
878
|
+
);
|
|
879
|
+
};
|
|
880
|
+
|
|
770
881
|
const handleSubmitSuccess = async (
|
|
771
882
|
response: FormSubmitResponse | undefined,
|
|
772
883
|
plainData: FormData,
|
|
@@ -854,6 +965,14 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
854
965
|
try {
|
|
855
966
|
const response = await sendSubmit(target.url, plainData, markSubmitSaved);
|
|
856
967
|
await handleSubmitSuccess(response, plainData);
|
|
968
|
+
// A redirect leaves the form, an action form starts over.
|
|
969
|
+
if (
|
|
970
|
+
isRecordUpdate.value &&
|
|
971
|
+
props.kind !== "action" &&
|
|
972
|
+
!props.redirectOnSuccess
|
|
973
|
+
) {
|
|
974
|
+
await showSavedRecord(response);
|
|
975
|
+
}
|
|
857
976
|
} catch (error) {
|
|
858
977
|
reportSubmitError(error);
|
|
859
978
|
} finally {
|
|
@@ -914,5 +1033,7 @@ export const useForm = (props: FormProps, options: UseFormOptions = {}) => {
|
|
|
914
1033
|
isFieldGroup,
|
|
915
1034
|
submitSucceeded,
|
|
916
1035
|
resolvedFetchUrl,
|
|
1036
|
+
createsRecord,
|
|
1037
|
+
effectiveSubmitDefaults,
|
|
917
1038
|
};
|
|
918
1039
|
};
|
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
onScopeDispose,
|
|
5
5
|
type ComputedRef,
|
|
6
6
|
} from "vue";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
currentPageLive,
|
|
9
|
+
isServerPageLive,
|
|
10
|
+
} from "../../build/composables/live/currentPageLive";
|
|
8
11
|
import type { PageLiveController } from "../../build/composables/live/pageLiveController";
|
|
9
12
|
import type { PageLiveNote, PageLiveNoteInput } from "../../types/live";
|
|
10
13
|
|
|
@@ -68,8 +71,11 @@ export interface PageLiveState {
|
|
|
68
71
|
* paused, show what was missed, offer its own switch, hold the page while the
|
|
69
72
|
* user types.
|
|
70
73
|
*
|
|
71
|
-
* On a page without `live`,
|
|
72
|
-
*
|
|
74
|
+
* On a page without `live`, `isEnabled` is false, the page reads as live and
|
|
75
|
+
* never paused, and its actions do nothing. A server render reads the page as
|
|
76
|
+
* live and never paused too, but `isEnabled` says whether it declares `live`:
|
|
77
|
+
* the browser hydrates the page's blocks with its controller installed, so
|
|
78
|
+
* the server draws them as it will.
|
|
73
79
|
*
|
|
74
80
|
* ```ts
|
|
75
81
|
* const { isPaused, missedCount, resume, hold, release } = usePageLive();
|
|
@@ -82,8 +88,9 @@ export interface PageLiveState {
|
|
|
82
88
|
export function usePageLive(): PageLiveState {
|
|
83
89
|
const isPaused = computed(() => currentPageLive()?.isPaused.value ?? false);
|
|
84
90
|
const hold = usePageLiveHold();
|
|
91
|
+
const isServerLive = isServerPageLive();
|
|
85
92
|
return {
|
|
86
|
-
isEnabled: computed(() => currentPageLive() !== null),
|
|
93
|
+
isEnabled: computed(() => currentPageLive() !== null || isServerLive),
|
|
87
94
|
isLive: computed(() => !isPaused.value),
|
|
88
95
|
isPaused,
|
|
89
96
|
pauseReason: computed(() => currentPageLive()?.pauseReason.value ?? null),
|
|
@@ -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
|
+
}
|
|
@@ -10,5 +10,6 @@ export interface TableQueryParams {
|
|
|
10
10
|
sortKey?: string;
|
|
11
11
|
sortDirection?: SortDirection;
|
|
12
12
|
showArchived?: boolean;
|
|
13
|
-
|
|
13
|
+
/** A list sends the key once per filter, which a row must all pass. */
|
|
14
|
+
[key: `filter_${string}`]: string | string[] | number | undefined;
|
|
14
15
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { markPageRead } from "../build/composables/live/pageReadClock";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The window event a data block (StatGroup, KeyValueList, NavCardGrid,
|
|
3
5
|
* ActivityFeed, KPI, top list, meter, chart, a tab set's badges, table view)
|
|
@@ -43,7 +45,7 @@ export function refreshPageBlocks(): Promise<void> {
|
|
|
43
45
|
waitUntil: (work) => void pending.push(work),
|
|
44
46
|
};
|
|
45
47
|
window.dispatchEvent(new CustomEvent(BLOCK_REFRESH_EVENT, { detail }));
|
|
46
|
-
return Promise.allSettled(pending).then(() =>
|
|
48
|
+
return Promise.allSettled(pending).then(() => markPageRead());
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/**
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The children of a layout block (a Card, a VStack, a Grid) as
|
|
3
|
+
* `RecursiveComponent` draws them: each child's component resolved by its
|
|
4
|
+
* registered name, a `div` when none matches, its own children likewise.
|
|
5
|
+
*/
|
|
6
|
+
export function resolveComponentChildren(
|
|
7
|
+
children: ComponentChild[],
|
|
8
|
+
): ResolvedComponentInfo[] {
|
|
9
|
+
return children.map((child) => {
|
|
10
|
+
const { id, component, ...additionalProps } = child;
|
|
11
|
+
return {
|
|
12
|
+
id,
|
|
13
|
+
options: component.options,
|
|
14
|
+
component: component.componentName
|
|
15
|
+
? resolveDmsComponent(component.componentName) || "div"
|
|
16
|
+
: "div",
|
|
17
|
+
componentName: component.componentName,
|
|
18
|
+
children: component.children
|
|
19
|
+
? resolveComponentChildren(component.children)
|
|
20
|
+
: [],
|
|
21
|
+
...additionalProps,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|