@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
|
@@ -13,22 +13,32 @@ import type {
|
|
|
13
13
|
ConfirmValues,
|
|
14
14
|
} from "../../../composables/confirm/types";
|
|
15
15
|
import { resolveResponseToast } from "../../utils/responseWarning";
|
|
16
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
ContainerInstance,
|
|
18
|
+
DrawerOptions,
|
|
19
|
+
} from "../../../composables/containers/types";
|
|
20
|
+
import DmsRowHeader from "../../components/containers/row/RowHeader.vue";
|
|
21
|
+
import { drawerRowHeaderProps } from "../../components/containers/row/drawerRowHeader";
|
|
22
|
+
import DmsRowNotFound from "../../components/containers/row/RowNotFound.vue";
|
|
17
23
|
import {
|
|
18
24
|
type BulkSelection,
|
|
19
25
|
bulkSelectionQuery,
|
|
26
|
+
isBulkAction,
|
|
27
|
+
isUrlTarget,
|
|
28
|
+
targetForRow,
|
|
20
29
|
targetWithSelection,
|
|
21
30
|
withQuery,
|
|
22
31
|
} from "./bulkSelection";
|
|
23
32
|
import {
|
|
24
33
|
listenRowSteps,
|
|
25
|
-
type RowNavigation,
|
|
26
34
|
type RowNavigationSource,
|
|
27
|
-
rowNavigation,
|
|
28
35
|
type ShowRow,
|
|
36
|
+
trackRowNavigation,
|
|
29
37
|
} from "./rowNavigation";
|
|
38
|
+
import type { RowNavigation } from "../../../types/row-navigation";
|
|
30
39
|
import {
|
|
31
40
|
clearWrittenRecord,
|
|
41
|
+
hasMissingRowState,
|
|
32
42
|
isDeepLinkAction,
|
|
33
43
|
resolveDeepLinkedRow,
|
|
34
44
|
writeRecordId,
|
|
@@ -57,8 +67,17 @@ import {
|
|
|
57
67
|
resolveTextVariables,
|
|
58
68
|
} from "../../utils/urlVariables";
|
|
59
69
|
import { currentPageUrlValues } from "../page/pageUrlValues";
|
|
70
|
+
import { readBulkCount } from "../table-view/utils/bulkActions";
|
|
60
71
|
import { type DownloadFetch, saveDownload } from "../../utils/fileDownload";
|
|
61
|
-
import {
|
|
72
|
+
import {
|
|
73
|
+
interpolateRowText,
|
|
74
|
+
namesRowField,
|
|
75
|
+
} from "#dms-core/app/utils/url-interpolation";
|
|
76
|
+
import { dropRowTokens } from "../../utils/urlVariables";
|
|
77
|
+
import { fillRowChildren, fillRowOptions } from "./rowComponentOptions";
|
|
78
|
+
import { resolveComponentChildren } from "../../../utils/componentTree";
|
|
79
|
+
import TargetComponentTree from "../../components/containers/TargetComponentTree.vue";
|
|
80
|
+
import { dmsOwnDrawer } from "../containers/context";
|
|
62
81
|
|
|
63
82
|
/** Runs a confirmed action from inside its dialog (see `onConfirm`). */
|
|
64
83
|
type ConfirmedRun = NonNullable<ConfirmOptions["onConfirm"]>;
|
|
@@ -128,10 +147,17 @@ interface TargetRunExtras {
|
|
|
128
147
|
selection?: BulkSelection;
|
|
129
148
|
/** The open row is reflected in the URL. */
|
|
130
149
|
deepLink?: boolean;
|
|
150
|
+
/** Fill-ins of the confirmation's texts besides the row's: `{ count }`. */
|
|
151
|
+
textParams?: Data;
|
|
152
|
+
/** A bulk action run from a row: its drawer, modal or panel gets the row too. */
|
|
153
|
+
keepsRow?: boolean;
|
|
131
154
|
}
|
|
132
155
|
|
|
133
156
|
type SidePanelTarget = ActionTarget & { type: "sidePanel" };
|
|
157
|
+
type DrawerTarget = ActionTarget & { type: "drawer" };
|
|
134
158
|
type DownloadTarget = ActionTarget & { type: "download" };
|
|
159
|
+
/** A target opening a row with the DMS's row header and not-found state. */
|
|
160
|
+
type RowTarget = SidePanelTarget | DrawerTarget;
|
|
135
161
|
|
|
136
162
|
/** A side panel to open, and on what. */
|
|
137
163
|
interface SidePanelTargetRun extends TargetRunExtras {
|
|
@@ -165,6 +191,17 @@ interface ComponentTargetRun extends TargetRunExtras {
|
|
|
165
191
|
description: string;
|
|
166
192
|
containerId: string;
|
|
167
193
|
rowData?: Data;
|
|
194
|
+
/** Id of a row the link names but the route answered 404 for (a drawer). */
|
|
195
|
+
missingId?: string;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Whether a drawer draws the DMS's row header (the title naming the row, its
|
|
200
|
+
* position, previous / next): asked for, or implied by the texts it words.
|
|
201
|
+
*/
|
|
202
|
+
function hasRowHeader(target: ComponentTargetRun["target"]): boolean {
|
|
203
|
+
if (target.type !== "drawer") return false;
|
|
204
|
+
return target.rowHeader ?? !!(target.rowTitle || target.positionLabel);
|
|
168
205
|
}
|
|
169
206
|
|
|
170
207
|
/**
|
|
@@ -184,12 +221,17 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
184
221
|
const { handleApiError } = config;
|
|
185
222
|
const fetchRaw = useAuthFetch().$authFetch.raw as unknown as DownloadFetch;
|
|
186
223
|
|
|
187
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Calls an `api` target and tells how it went (rejects on a failure). On a
|
|
226
|
+
* selection, the toast counts the rows the route says it changed, or every
|
|
227
|
+
* selected row when it does not say.
|
|
228
|
+
*/
|
|
188
229
|
const requestApiTarget = async (
|
|
189
230
|
target: ActionTarget & { type: "api" },
|
|
190
231
|
url: string,
|
|
191
232
|
rowData?: Data,
|
|
192
233
|
values: ConfirmValues = {},
|
|
234
|
+
selection?: BulkSelection,
|
|
193
235
|
) => {
|
|
194
236
|
// The confirmation's values join the declared body, the input winning.
|
|
195
237
|
const body = { ...target.body, ...values };
|
|
@@ -203,6 +245,9 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
203
245
|
if (target.copy) {
|
|
204
246
|
await copyToClipboard(String(response?.[target.copy] ?? ""));
|
|
205
247
|
}
|
|
248
|
+
const toastParams = selection
|
|
249
|
+
? { ...rowData, count: readBulkCount(response) ?? selection.count }
|
|
250
|
+
: (rowData ?? {});
|
|
206
251
|
toast.add(
|
|
207
252
|
resolveResponseToast(
|
|
208
253
|
response,
|
|
@@ -211,7 +256,7 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
211
256
|
// Pluralized on a bulk action's `{ count }`, like its dialog.
|
|
212
257
|
title: resolveConfirmText(
|
|
213
258
|
target.successMessage,
|
|
214
|
-
|
|
259
|
+
toastParams,
|
|
215
260
|
t as ConfirmTranslate,
|
|
216
261
|
),
|
|
217
262
|
},
|
|
@@ -229,9 +274,10 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
229
274
|
url: string,
|
|
230
275
|
label: string,
|
|
231
276
|
rowData?: Data,
|
|
277
|
+
selection?: BulkSelection,
|
|
232
278
|
) => {
|
|
233
279
|
try {
|
|
234
|
-
await requestApiTarget(target, url, rowData);
|
|
280
|
+
await requestApiTarget(target, url, rowData, {}, selection);
|
|
235
281
|
} catch (error: unknown) {
|
|
236
282
|
handleApiError(error, label ? processI18n(label, rowData) : undefined);
|
|
237
283
|
}
|
|
@@ -307,26 +353,51 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
307
353
|
}
|
|
308
354
|
};
|
|
309
355
|
|
|
356
|
+
// A drawer remembers the size the user gives it per action: per table and
|
|
357
|
+
// component, whatever row it opens on.
|
|
310
358
|
const openContainer = (
|
|
311
359
|
run: ComponentTargetRun,
|
|
312
360
|
component: Component,
|
|
313
|
-
|
|
361
|
+
options: Pick<
|
|
362
|
+
DrawerOptions,
|
|
363
|
+
"title" | "componentOptions" | "headerComponentOptions"
|
|
364
|
+
>,
|
|
314
365
|
): ContainerInstance => {
|
|
315
|
-
const
|
|
316
|
-
|
|
366
|
+
const containerOptions = {
|
|
367
|
+
...options,
|
|
317
368
|
description: run.description,
|
|
318
369
|
containerId: run.containerId,
|
|
319
370
|
component,
|
|
320
|
-
componentOptions,
|
|
321
371
|
};
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
372
|
+
if (run.target.type === "modal") {
|
|
373
|
+
return openModal({ ...containerOptions, size: run.target.size });
|
|
374
|
+
}
|
|
375
|
+
return openDrawer(
|
|
376
|
+
dmsOwnDrawer({
|
|
377
|
+
...containerOptions,
|
|
378
|
+
direction: run.target.direction,
|
|
379
|
+
size: run.target.size,
|
|
380
|
+
sizeKey: `${config.pageId}-${config.componentId}-${run.target.component?.componentName}`,
|
|
381
|
+
...(options.headerComponentOptions && {
|
|
382
|
+
headerComponent: DmsRowHeader,
|
|
383
|
+
}),
|
|
384
|
+
}),
|
|
385
|
+
);
|
|
325
386
|
};
|
|
326
387
|
|
|
327
388
|
const resolveTargetComponent = (componentName: string): Component =>
|
|
328
389
|
(resolveDmsComponent(componentName) || componentName) as Component;
|
|
329
390
|
|
|
391
|
+
// A container block (a Card, a VStack, a Tab) mounts its children as a
|
|
392
|
+
// page does; a single block is mounted as it is.
|
|
393
|
+
const targetComponentOf = (
|
|
394
|
+
componentName: string,
|
|
395
|
+
info: ComponentInfo,
|
|
396
|
+
): Component =>
|
|
397
|
+
info.children?.length
|
|
398
|
+
? TargetComponentTree
|
|
399
|
+
: resolveTargetComponent(componentName);
|
|
400
|
+
|
|
330
401
|
const rowIdOf = (row?: Data): string | undefined => {
|
|
331
402
|
if (!row) return undefined;
|
|
332
403
|
const idKey =
|
|
@@ -377,18 +448,41 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
377
448
|
};
|
|
378
449
|
};
|
|
379
450
|
|
|
451
|
+
// The target's component options for the row shown, its `{{row.X}}`
|
|
452
|
+
// tokens filled (`{{row.id}}` being the row's id); without a row (a bulk
|
|
453
|
+
// selection, a toolbar button) they are handed as declared.
|
|
454
|
+
const targetOptionsFor = (target: ActionTarget, row?: Data): Data => {
|
|
455
|
+
const { component } = target as { component?: ComponentInfo<Data> };
|
|
456
|
+
const id = rowIdOf(row);
|
|
457
|
+
const tokens = row && id !== undefined ? { ...row, id } : row;
|
|
458
|
+
const declared = component?.options ?? {};
|
|
459
|
+
const options = tokens ? fillRowOptions(declared, tokens) : declared;
|
|
460
|
+
const children = component?.children;
|
|
461
|
+
if (!component?.componentName || !children?.length) return options;
|
|
462
|
+
// The container's children read the row through the same tokens.
|
|
463
|
+
const targetTree: ResolvedComponentInfo = {
|
|
464
|
+
id: component.componentName,
|
|
465
|
+
component: resolveTargetComponent(component.componentName),
|
|
466
|
+
componentName: component.componentName,
|
|
467
|
+
children: resolveComponentChildren(
|
|
468
|
+
tokens ? fillRowChildren(children, tokens) : children,
|
|
469
|
+
),
|
|
470
|
+
};
|
|
471
|
+
return { ...options, targetTree };
|
|
472
|
+
};
|
|
473
|
+
|
|
380
474
|
const rowRecorder = (deepLink?: boolean) => {
|
|
381
475
|
const recordId = recordRecorder(deepLink);
|
|
382
476
|
return (row?: Data): void => recordId(rowIdOf(row));
|
|
383
477
|
};
|
|
384
478
|
|
|
385
479
|
// The header names the open row when the target words it from its fields.
|
|
386
|
-
const rowTitleOf = (target:
|
|
480
|
+
const rowTitleOf = (target: RowTarget, row?: Data) =>
|
|
387
481
|
row && target.rowTitle
|
|
388
482
|
? resolveConfirmText(target.rowTitle, row, t as ConfirmTranslate)
|
|
389
483
|
: undefined;
|
|
390
484
|
|
|
391
|
-
const notFoundOf = (target:
|
|
485
|
+
const notFoundOf = (target: RowTarget) => ({
|
|
392
486
|
title: processI18n(target.notFound?.title || `$${NOT_FOUND_TITLE_KEY}`),
|
|
393
487
|
description: processI18n(
|
|
394
488
|
target.notFound?.description || `$${NOT_FOUND_DESCRIPTION_KEY}`,
|
|
@@ -407,15 +501,16 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
407
501
|
const componentName = run.target.component?.componentName;
|
|
408
502
|
if (!componentName) return;
|
|
409
503
|
const session = Symbol(componentName);
|
|
410
|
-
const recordId = recordRecorder(
|
|
504
|
+
const recordId = recordRecorder(
|
|
505
|
+
run.deepLink && (!run.selection || run.keepsRow),
|
|
506
|
+
);
|
|
411
507
|
const panel = {
|
|
412
508
|
session,
|
|
413
509
|
ownerKey,
|
|
414
510
|
title: run.title,
|
|
415
511
|
positionLabel: run.target.positionLabel,
|
|
416
|
-
component:
|
|
512
|
+
component: targetComponentOf(componentName, run.target.component),
|
|
417
513
|
componentOptions: {
|
|
418
|
-
...run.target.component?.options,
|
|
419
514
|
pageId: config.pageId,
|
|
420
515
|
componentId: config.componentId,
|
|
421
516
|
containerId: run.containerId,
|
|
@@ -434,16 +529,30 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
434
529
|
function showRow(row?: Data) {
|
|
435
530
|
openRowSidePanel({
|
|
436
531
|
...panel,
|
|
532
|
+
componentOptions: {
|
|
533
|
+
...targetOptionsFor(run.target, row),
|
|
534
|
+
...panel.componentOptions,
|
|
535
|
+
},
|
|
437
536
|
rowTitle: rowTitleOf(run.target, row),
|
|
438
537
|
row,
|
|
439
538
|
rowKey: rowIdOf(row),
|
|
440
539
|
source: row ? config.rowNavigation : undefined,
|
|
441
|
-
|
|
540
|
+
// A step that loads a page first lands after it: not on a panel
|
|
541
|
+
// closed or replaced meanwhile.
|
|
542
|
+
showRow: whileShown(session, showRow),
|
|
442
543
|
});
|
|
443
544
|
recordId(rowIdOf(row));
|
|
444
545
|
}
|
|
445
546
|
function showMissing(id: string) {
|
|
446
|
-
openRowSidePanel({
|
|
547
|
+
openRowSidePanel({
|
|
548
|
+
...panel,
|
|
549
|
+
componentOptions: {
|
|
550
|
+
...targetOptionsFor(run.target),
|
|
551
|
+
...panel.componentOptions,
|
|
552
|
+
},
|
|
553
|
+
notFound: notFoundOf(run.target),
|
|
554
|
+
showRow,
|
|
555
|
+
});
|
|
447
556
|
recordId(id);
|
|
448
557
|
}
|
|
449
558
|
if (run.missingId) return showMissing(run.missingId);
|
|
@@ -456,21 +565,49 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
456
565
|
const handleComponentTarget = (run: ComponentTargetRun) => {
|
|
457
566
|
const componentName = run.target.component?.componentName;
|
|
458
567
|
if (!componentName) return;
|
|
459
|
-
|
|
568
|
+
if (run.missingId) return showMissingInDrawer(run, run.missingId);
|
|
569
|
+
const component = targetComponentOf(componentName, run.target.component);
|
|
460
570
|
const source = config.rowNavigation;
|
|
571
|
+
const drawerTarget = run.target.type === "drawer" ? run.target : undefined;
|
|
572
|
+
const withRowHeader = hasRowHeader(run.target) && !run.selection;
|
|
461
573
|
let instance: ContainerInstance | undefined;
|
|
462
574
|
let navigation: RowNavigation | undefined;
|
|
575
|
+
let stopNavigation: (() => void) | undefined;
|
|
463
576
|
// Set once the container closes: a row read that resolves later neither
|
|
464
577
|
// writes `?record=` back nor patches the closed container.
|
|
465
578
|
let closed = false;
|
|
466
|
-
const
|
|
579
|
+
const showRowOpen = (row: Data) => {
|
|
467
580
|
if (!closed) showRow(row);
|
|
468
|
-
}
|
|
581
|
+
};
|
|
582
|
+
const showRowById = rowShower(showRowOpen);
|
|
583
|
+
// The position and the steps follow the table (a reload, live rows, the
|
|
584
|
+
// row located past the page loaded): the open container is patched with
|
|
585
|
+
// them.
|
|
586
|
+
const trackNavigation = (row?: Data) => {
|
|
587
|
+
stopNavigation?.();
|
|
588
|
+
stopNavigation = undefined;
|
|
589
|
+
navigation = undefined;
|
|
590
|
+
if (!row || !source) return;
|
|
591
|
+
// The first navigation goes out with the row's own options.
|
|
592
|
+
let isShowing = true;
|
|
593
|
+
// A step that loads a page first lands after it, maybe closed by then.
|
|
594
|
+
stopNavigation = trackRowNavigation(source, row, showRowOpen, (next) => {
|
|
595
|
+
navigation = next;
|
|
596
|
+
if (isShowing || !instance || closed) return;
|
|
597
|
+
instance.patch({
|
|
598
|
+
componentOptions: optionsOf(row),
|
|
599
|
+
...(withRowHeader && { headerComponentOptions: headerFor(row) }),
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
isShowing = false;
|
|
603
|
+
};
|
|
469
604
|
const optionsFor = (row?: Data) => {
|
|
470
|
-
|
|
471
|
-
|
|
605
|
+
trackNavigation(row);
|
|
606
|
+
return optionsOf(row);
|
|
607
|
+
};
|
|
608
|
+
const optionsOf = (row?: Data) => {
|
|
472
609
|
return {
|
|
473
|
-
...run.target
|
|
610
|
+
...targetOptionsFor(run.target, row),
|
|
474
611
|
pageId: config.pageId,
|
|
475
612
|
componentId: config.componentId,
|
|
476
613
|
containerId: run.containerId,
|
|
@@ -484,26 +621,64 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
484
621
|
},
|
|
485
622
|
};
|
|
486
623
|
};
|
|
624
|
+
// A drawer words its title from the row (`rowTitle`); with the row
|
|
625
|
+
// header, the DMS draws it with the position and previous / next. Read
|
|
626
|
+
// after `optionsFor`, which sets the row's navigation.
|
|
627
|
+
const titleFor = (row?: Data) =>
|
|
628
|
+
(drawerTarget && rowTitleOf(drawerTarget, row)) || run.title;
|
|
629
|
+
const headerFor = (row?: Data) =>
|
|
630
|
+
withRowHeader
|
|
631
|
+
? drawerRowHeaderProps(
|
|
632
|
+
{ positionLabel: drawerTarget?.positionLabel, navigation },
|
|
633
|
+
titleFor(row),
|
|
634
|
+
)
|
|
635
|
+
: undefined;
|
|
487
636
|
const recordRow = rowRecorder(run.deepLink);
|
|
488
637
|
function showRow(row: Data) {
|
|
638
|
+
const componentOptions = optionsFor(row);
|
|
489
639
|
instance?.patch({
|
|
490
|
-
|
|
640
|
+
title: titleFor(row),
|
|
641
|
+
componentOptions,
|
|
491
642
|
componentKey: rowIdOf(row),
|
|
643
|
+
...(withRowHeader && { headerComponentOptions: headerFor(row) }),
|
|
492
644
|
});
|
|
493
645
|
recordRow(row);
|
|
494
646
|
}
|
|
495
|
-
|
|
647
|
+
const componentOptions = optionsFor(run.rowData);
|
|
648
|
+
instance = openContainer(run, component, {
|
|
649
|
+
title: titleFor(run.rowData),
|
|
650
|
+
componentOptions,
|
|
651
|
+
headerComponentOptions: headerFor(run.rowData),
|
|
652
|
+
});
|
|
496
653
|
recordRow(run.rowData);
|
|
497
654
|
// `showRow` may move an unlisted row's container onto a listed one.
|
|
498
655
|
const stopSteps = source ? listenRowSteps(() => navigation) : undefined;
|
|
499
656
|
const settle = () => {
|
|
500
657
|
closed = true;
|
|
501
658
|
stopSteps?.();
|
|
659
|
+
stopNavigation?.();
|
|
502
660
|
recordRow(undefined);
|
|
503
661
|
};
|
|
504
662
|
instance.result.then(settle, settle);
|
|
505
663
|
};
|
|
506
664
|
|
|
665
|
+
// A drawer opened on a row its link names but its route answered 404 for:
|
|
666
|
+
// under its title, the state in place of the component, a close button.
|
|
667
|
+
// Closing it removes the link, as closing it on a row does.
|
|
668
|
+
function showMissingInDrawer(run: ComponentTargetRun, id: string): void {
|
|
669
|
+
if (run.target.type !== "drawer") return;
|
|
670
|
+
const recordId = recordRecorder(run.deepLink);
|
|
671
|
+
let instance: ContainerInstance | undefined;
|
|
672
|
+
const notFound = notFoundOf(run.target);
|
|
673
|
+
instance = openContainer(run, DmsRowNotFound, {
|
|
674
|
+
title: run.title,
|
|
675
|
+
componentOptions: { ...notFound, onClose: () => instance?.close() },
|
|
676
|
+
});
|
|
677
|
+
recordId(id);
|
|
678
|
+
const settle = () => recordId(undefined);
|
|
679
|
+
instance.result.then(settle, settle);
|
|
680
|
+
}
|
|
681
|
+
|
|
507
682
|
type TargetHandler = (
|
|
508
683
|
target: ActionTarget,
|
|
509
684
|
label: string,
|
|
@@ -520,7 +695,7 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
520
695
|
(target as { description?: string }).description || "",
|
|
521
696
|
),
|
|
522
697
|
containerId: `${config.pageId}-${config.componentId}-${target.type}`,
|
|
523
|
-
rowData: extras?.selection ? undefined : rowData,
|
|
698
|
+
rowData: extras?.selection && !extras.keepsRow ? undefined : rowData,
|
|
524
699
|
...extras,
|
|
525
700
|
});
|
|
526
701
|
|
|
@@ -529,7 +704,7 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
529
704
|
target: target as SidePanelTarget,
|
|
530
705
|
title: processI18n((target as SidePanelTarget).title || label),
|
|
531
706
|
containerId: `${config.pageId}-${config.componentId}-${target.type}`,
|
|
532
|
-
rowData: extras?.selection ? undefined : rowData,
|
|
707
|
+
rowData: extras?.selection && !extras.keepsRow ? undefined : rowData,
|
|
533
708
|
...extras,
|
|
534
709
|
});
|
|
535
710
|
|
|
@@ -548,10 +723,10 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
548
723
|
}
|
|
549
724
|
window.location.href = url;
|
|
550
725
|
},
|
|
551
|
-
api: async (target, label, rowData) => {
|
|
726
|
+
api: async (target, label, rowData, extras) => {
|
|
552
727
|
const apiTarget = target as ActionTarget & { type: "api" };
|
|
553
728
|
const url = targetUrl(apiTarget.url, rowData);
|
|
554
|
-
await handleApiTarget(apiTarget, url, label, rowData);
|
|
729
|
+
await handleApiTarget(apiTarget, url, label, rowData, extras?.selection);
|
|
555
730
|
},
|
|
556
731
|
exportJob: async (target, _label, rowData) => {
|
|
557
732
|
const jobTarget = target as ActionTarget & { type: "exportJob" };
|
|
@@ -581,16 +756,21 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
581
756
|
const confirmedRuns: Partial<
|
|
582
757
|
Record<
|
|
583
758
|
ActionTarget["type"],
|
|
584
|
-
(
|
|
759
|
+
(
|
|
760
|
+
target: ActionTarget,
|
|
761
|
+
rowData?: Data,
|
|
762
|
+
extras?: TargetRunExtras,
|
|
763
|
+
) => ConfirmedRun
|
|
585
764
|
>
|
|
586
765
|
> = {
|
|
587
|
-
api: (target, rowData) => (values) => {
|
|
766
|
+
api: (target, rowData, extras) => (values) => {
|
|
588
767
|
const apiTarget = target as ActionTarget & { type: "api" };
|
|
589
768
|
return requestApiTarget(
|
|
590
769
|
apiTarget,
|
|
591
770
|
targetUrl(apiTarget.url, rowData),
|
|
592
771
|
rowData,
|
|
593
772
|
values,
|
|
773
|
+
extras?.selection,
|
|
594
774
|
);
|
|
595
775
|
},
|
|
596
776
|
};
|
|
@@ -621,9 +801,9 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
621
801
|
await handler(target, label, rowData, extras);
|
|
622
802
|
return;
|
|
623
803
|
}
|
|
624
|
-
const runInside = confirmedRuns[target.type]?.(target, rowData);
|
|
804
|
+
const runInside = confirmedRuns[target.type]?.(target, rowData, extras);
|
|
625
805
|
const isConfirmed = await confirmAction(declared, {
|
|
626
|
-
row: rowData,
|
|
806
|
+
row: extras?.textParams ? { ...rowData, ...extras.textParams } : rowData,
|
|
627
807
|
urlParams: rowUrlParams(rowData),
|
|
628
808
|
run: runInside,
|
|
629
809
|
});
|
|
@@ -653,14 +833,45 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
653
833
|
);
|
|
654
834
|
};
|
|
655
835
|
|
|
836
|
+
// A bulk action offered on a row runs on that row as the selection bar runs
|
|
837
|
+
// on several: a URL target, and a `from` confirmation, carry `?ids=<id>` —
|
|
838
|
+
// unless the URL names the row itself (`{{row._id}}`), which fills it.
|
|
839
|
+
const rowRun = (action: CustomRowAction, rowData?: Data) => {
|
|
840
|
+
const id = rowIdOf(rowData);
|
|
841
|
+
if (!isBulkAction(action) || id === undefined) {
|
|
842
|
+
return { target: action.target, confirm: action.confirm, row: rowData };
|
|
843
|
+
}
|
|
844
|
+
const selection: BulkSelection = { ids: [id], count: 1 };
|
|
845
|
+
const query = bulkSelectionQuery(selection);
|
|
846
|
+
const { confirm } = action;
|
|
847
|
+
// Its texts count one row, as the bar's count the selection ("Resolve
|
|
848
|
+
// this ticket?"): its dialog, and the toast of a URL target. A drawer,
|
|
849
|
+
// modal or side panel receives the row as it is, and the selection of
|
|
850
|
+
// that row as from the bar.
|
|
851
|
+
const textParams = { count: selection.count };
|
|
852
|
+
return {
|
|
853
|
+
target: targetForRow(action.target, query),
|
|
854
|
+
textParams,
|
|
855
|
+
selection: isUrlTarget(action.target) ? undefined : selection,
|
|
856
|
+
row: isUrlTarget(action.target) ? { ...rowData, ...textParams } : rowData,
|
|
857
|
+
confirm:
|
|
858
|
+
confirm && isConfirmFrom(confirm) && !namesRowField(confirm.from)
|
|
859
|
+
? { from: withQuery(confirm.from, query) }
|
|
860
|
+
: confirm,
|
|
861
|
+
};
|
|
862
|
+
};
|
|
863
|
+
|
|
656
864
|
const handleCustomRowAction = (action: CustomRowAction, rowData?: Data) => {
|
|
657
|
-
|
|
658
|
-
action
|
|
659
|
-
action.label,
|
|
865
|
+
const { target, confirm, row, textParams, selection } = rowRun(
|
|
866
|
+
action,
|
|
660
867
|
rowData,
|
|
661
|
-
action.confirm,
|
|
662
|
-
{ deepLink: isDeepLinkAction(action) },
|
|
663
868
|
);
|
|
869
|
+
void handleActionTarget(target, action.label, row, confirm, {
|
|
870
|
+
deepLink: isDeepLinkAction(action),
|
|
871
|
+
textParams,
|
|
872
|
+
selection,
|
|
873
|
+
keepsRow: !!selection,
|
|
874
|
+
});
|
|
664
875
|
};
|
|
665
876
|
|
|
666
877
|
/**
|
|
@@ -675,7 +886,7 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
675
886
|
const query = bulkSelectionQuery(selection);
|
|
676
887
|
const declared =
|
|
677
888
|
action.confirm && isConfirmFrom(action.confirm)
|
|
678
|
-
? { from: withQuery(action.confirm.from, query) }
|
|
889
|
+
? { from: withQuery(dropRowTokens(action.confirm.from), query) }
|
|
679
890
|
: action.confirm;
|
|
680
891
|
void handleActionTarget(
|
|
681
892
|
targetWithSelection(action.target, query),
|
|
@@ -687,11 +898,24 @@ export function useActionTargets(config: ActionTargetsConfig) {
|
|
|
687
898
|
};
|
|
688
899
|
|
|
689
900
|
/**
|
|
690
|
-
* Opens a side panel action
|
|
691
|
-
*
|
|
692
|
-
*
|
|
901
|
+
* Opens a side panel action, or a drawer wording its `notFound` state, on a
|
|
902
|
+
* row its link names but its route answered 404 for: the container says the
|
|
903
|
+
* row is gone, and closing it removes the link. Another target opens
|
|
904
|
+
* nothing: no row, no container.
|
|
693
905
|
*/
|
|
694
906
|
const handleMissingRow = (action: CustomRowAction, id: string) => {
|
|
907
|
+
if (!hasMissingRowState(action)) return;
|
|
908
|
+
if (action.target.type === "drawer") {
|
|
909
|
+
handleComponentTarget({
|
|
910
|
+
target: action.target,
|
|
911
|
+
title: processI18n(action.target.title || action.label),
|
|
912
|
+
description: processI18n(action.target.description || ""),
|
|
913
|
+
containerId: `${config.pageId}-${config.componentId}-${action.target.type}`,
|
|
914
|
+
deepLink: isDeepLinkAction(action),
|
|
915
|
+
missingId: id,
|
|
916
|
+
});
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
695
919
|
if (action.target.type !== "sidePanel") return;
|
|
696
920
|
handleSidePanelTarget({
|
|
697
921
|
target: action.target,
|
|
@@ -125,6 +125,8 @@ export function resolveConfirmDialog(
|
|
|
125
125
|
description: text(dialog.description),
|
|
126
126
|
confirmLabel: text(dialog.confirmLabel),
|
|
127
127
|
cancelLabel: text(dialog.cancelLabel),
|
|
128
|
+
// The text to type, the row's name more often than not ("{name}").
|
|
129
|
+
confirmText: text(dialog.confirmText),
|
|
128
130
|
impact: dialog.impact?.map((entry) => ({
|
|
129
131
|
...entry,
|
|
130
132
|
label: text(entry.label) ?? "",
|