@antelopejs/dms 0.9.8 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +171 -0
- package/README.md +1 -1
- package/data/module-store/catalog.json +2 -2
- package/dist/attachments/table-view.js +2 -2
- package/dist/attachments/table-view.js.map +1 -1
- package/dist/automation/actions.d.ts +2 -0
- package/dist/automation/actions.js +116 -71
- package/dist/automation/actions.js.map +1 -1
- package/dist/automation/i18n.d.ts +4 -0
- package/dist/automation/i18n.js +19 -0
- package/dist/automation/i18n.js.map +1 -0
- package/dist/automation/send-notification.d.ts +21 -0
- package/dist/automation/send-notification.js +163 -0
- package/dist/automation/send-notification.js.map +1 -0
- package/dist/automation/triggers.js +19 -25
- package/dist/automation/triggers.js.map +1 -1
- package/dist/client-origin-cors.d.ts +1 -0
- package/dist/client-origin-cors.js +19 -0
- package/dist/client-origin-cors.js.map +1 -0
- package/dist/config.d.ts +3 -2
- package/dist/config.js +5 -7
- package/dist/config.js.map +1 -1
- package/dist/frontend-module.d.ts +4 -0
- package/dist/frontend-module.js +37 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/implementations/dms/client-ip.js +1 -1
- package/dist/implementations/dms/client-ip.js.map +1 -1
- package/dist/implementations/dms/dev-reload.d.ts +5 -0
- package/dist/implementations/dms/dev-reload.js +23 -3
- package/dist/implementations/dms/dev-reload.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -4
- package/dist/implementations/dms/frontend-modules.js +38 -94
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +12 -2
- package/dist/implementations/dms/frontend-ready.js +34 -4
- package/dist/implementations/dms/frontend-ready.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +2 -1
- package/dist/implementations/dms/layout-banners.js +9 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/manifest.d.ts +7 -2
- package/dist/implementations/dms/manifest.js +12 -7
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +4 -3
- package/dist/implementations/dms/page.js +49 -18
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
- package/dist/implementations/dms/permissions-resolver.js +2 -2
- package/dist/implementations/dms/permissions-resolver.js.map +1 -1
- package/dist/implementations/dms/realtime.js +1 -0
- package/dist/implementations/dms/realtime.js.map +1 -1
- package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
- package/dist/implementations/dms-base/bulk-selection.js +23 -1
- package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
- package/dist/implementations/dms-base/filter-tokens.js +5 -3
- package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
- package/dist/implementations/dms-base/search-route.d.ts +1 -0
- package/dist/implementations/dms-base/search-route.js +35 -13
- package/dist/implementations/dms-base/search-route.js.map +1 -1
- package/dist/implementations/dms-base/table-view.js +11 -6
- package/dist/implementations/dms-base/table-view.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +2 -2
- package/dist/implementations/dms-notifications/index.js +5 -5
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/index.js +32 -55
- package/dist/index.js.map +1 -1
- package/dist/pages/modules/index.d.ts +1 -0
- package/dist/pages/modules/index.js +1 -0
- package/dist/pages/modules/index.js.map +1 -1
- package/dist/pages/modules/modules-store.d.ts +9 -0
- package/dist/pages/modules/modules-store.js +30 -0
- package/dist/pages/modules/modules-store.js.map +1 -0
- package/dist/pages/settings/users/account-credentials.js +2 -2
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/account-data-store.js +25 -8
- package/dist/pages/settings/users/account-data-store.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.js +9 -3
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
- package/dist/pages/settings/users/member-management.js +13 -14
- package/dist/pages/settings/users/member-management.js.map +1 -1
- package/dist/pages/settings/users/profile.d.ts +1 -4
- package/dist/pages/settings/users/profile.js +0 -35
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +26 -18
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +0 -1
- package/dist/pages/settings/users/role-editor.js +1 -2
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +1 -2
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +2 -2
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/realtime/broker.d.ts +6 -0
- package/dist/realtime/broker.js +8 -1
- package/dist/realtime/broker.js.map +1 -1
- package/dist/realtime/presence.d.ts +8 -3
- package/dist/realtime/presence.js +8 -4
- package/dist/realtime/presence.js.map +1 -1
- package/dist/realtime/sessions.d.ts +11 -1
- package/dist/realtime/sessions.js +21 -3
- package/dist/realtime/sessions.js.map +1 -1
- package/dist/realtime/table-view.d.ts +2 -2
- package/dist/realtime/table-view.js +4 -3
- package/dist/realtime/table-view.js.map +1 -1
- package/dist/routes/auth/client-ip.d.ts +1 -0
- package/dist/routes/auth/client-ip.js +18 -0
- package/dist/routes/auth/client-ip.js.map +1 -1
- package/dist/routes/auth/oauth/config.d.ts +2 -1
- package/dist/routes/auth/oauth/config.js +5 -1
- package/dist/routes/auth/oauth/config.js.map +1 -1
- package/dist/routes/auth/session-handoff.d.ts +0 -1
- package/dist/routes/auth/session-handoff.js +0 -2
- package/dist/routes/auth/session-handoff.js.map +1 -1
- package/dist/routes/auth.js +3 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +13 -1
- package/dist/routes/realtime.js +114 -29
- package/dist/routes/realtime.js.map +1 -1
- package/dist/startup-config.d.ts +2 -0
- package/dist/startup-config.js +62 -0
- package/dist/startup-config.js.map +1 -0
- package/dist/store/interfaces.d.ts +3 -2
- package/dist/store/interfaces.js +16 -6
- package/dist/store/interfaces.js.map +1 -1
- package/dist/store/listing.js +25 -15
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +5 -2
- package/dist/store/operations.js.map +1 -1
- package/dist/store/requirements.js +3 -2
- package/dist/store/requirements.js.map +1 -1
- package/dist/store/runtime.d.ts +10 -1
- package/dist/store/runtime.js +33 -6
- package/dist/store/runtime.js.map +1 -1
- package/dist/store/types.d.ts +10 -0
- package/dist/utils/ensure-default-tenant.d.ts +2 -1
- package/dist/utils/ensure-default-tenant.js +13 -1
- package/dist/utils/ensure-default-tenant.js.map +1 -1
- package/dist/utils/export-jobs.js +2 -1
- package/dist/utils/export-jobs.js.map +1 -1
- package/dist/validation/auth.schema.d.ts +2 -2
- package/dist/validation/member-invite.schema.d.ts +2 -10
- package/dist/validation/member-invite.schema.js +2 -15
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +24 -5
- package/frontend-vue/dms.server.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
- package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +33 -0
- package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
- package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
- package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
- package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
- package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
- package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +25 -5
- package/frontend-vue/layers/dms-core/app/composables/useApiError.ts +3 -5
- package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +61 -26
- package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
- package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +134 -35
- package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +136 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +136 -2
- package/frontend-vue/layers/dms-core/shared/types/app-config.ts +0 -2
- package/frontend-vue/layers/dms-layout/app/app.config.ts +0 -1
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +11 -1
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -107
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +4 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
- package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +2 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +49 -11
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +59 -4
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageRecordDeletion.ts +162 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +13 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +22 -52
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-quick-actions.client.ts +7 -7
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-session.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- package/frontend-vue/layers/dms-layout/app/theme/actions.ts +5 -4
- package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
- package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
- package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +45 -18
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +44 -17
- package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
- package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
- package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +48 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
- package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
- package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/actionError.ts +6 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +44 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +123 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +92 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +11 -5
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formValidation.ts +36 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +97 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +90 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/writeError.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/codeHighlight.ts +67 -29
- package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
- package/frontend-vue/layers/dms-ui/app/build/utils/htmlGrammar.ts +79 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/shellParser.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/utils/streamHighlight.ts +90 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
- package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
- package/frontend-vue/layers/dms-ui/app/components/code-snippet/CodeSnippet.vue +23 -12
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
- package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +119 -36
- package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +53 -22
- package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +226 -65
- package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
- package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +210 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
- package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
- package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
- package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
- package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
- package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +74 -25
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +48 -44
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +426 -97
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
- package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
- package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +16 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +189 -28
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +29 -12
- package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
- package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
- package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
- package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
- package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +94 -3
- package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +20 -5
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +20 -5
- package/frontend-vue/package.json +6 -2
- package/package.json +11 -10
- package/skills/dms/SKILL.md +1 -1
- package/skills/dms-auth/SKILL.md +5 -3
- package/skills/dms-best-practices/REFERENCE.md +2 -0
- package/skills/dms-best-practices/SKILL.md +4 -0
- package/skills/dms-module/SKILL.md +3 -2
- package/skills/dms-pages/REFERENCE.md +129 -16
- package/skills/dms-pages/SKILL.md +1 -1
- package/skills/dms-project/DEV-SERVERS.md +23 -1
- package/skills/dms-project/REFERENCE.md +1 -1
- package/skills/dms-project/SKILL.md +4 -1
- package/skills/dms-project/scripts/dms-dev.sh +205 -17
- package/dist/hooks/tenant-instances.d.ts +0 -1
- package/dist/hooks/tenant-instances.js +0 -13
- package/dist/hooks/tenant-instances.js.map +0 -1
- package/dist/routes/startup-gate.d.ts +0 -7
- package/dist/routes/startup-gate.js +0 -39
- package/dist/routes/startup-gate.js.map +0 -1
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { router as inertiaRouter } from "@inertiajs/vue3";
|
|
2
|
+
import { onBeforeUnmount, onMounted } from "vue";
|
|
3
|
+
import type { QueryParamFilters } from "../../../composables/table-view/types/config";
|
|
4
|
+
import { isLinkedVisit } from "./utils/linkedArrival";
|
|
5
|
+
import { queryOfUrl } from "./utils/urlFilters";
|
|
6
|
+
import type { TableUrlScope } from "./utils/views";
|
|
7
|
+
|
|
8
|
+
const URL_BASE = "http://dms.invalid";
|
|
9
|
+
|
|
10
|
+
/** What `useTableLinkedVisit` reads a visit against, and what it calls. */
|
|
11
|
+
export interface TableLinkedVisitOptions {
|
|
12
|
+
route: { path: string; query: Record<string, unknown> };
|
|
13
|
+
urlScope: TableUrlScope;
|
|
14
|
+
queryParamFilters: QueryParamFilters | undefined;
|
|
15
|
+
activeView: () => string | undefined;
|
|
16
|
+
activeTab: () => string;
|
|
17
|
+
canOpenView: (id: string) => boolean;
|
|
18
|
+
canOpenTab: (id: string) => boolean;
|
|
19
|
+
/** Opens the table on what the visit's link names, as an arrival would. */
|
|
20
|
+
follow: (query: Record<string, unknown>) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Follows a link to the page the table is already shown on (a notification,
|
|
25
|
+
* a menu entry, back and forward): Inertia keeps the page mounted, so the
|
|
26
|
+
* table reads the visit's query as an arrival would (`isLinkedVisit`). A
|
|
27
|
+
* link clicked is announced as a client visit pushed, even to the URL shown,
|
|
28
|
+
* which Inertia turns into a replace without a `navigate` event; a page
|
|
29
|
+
* control rebuilding the query replaces it, and is no link. A visit to
|
|
30
|
+
* another page is left alone: the table is about to unmount.
|
|
31
|
+
*/
|
|
32
|
+
export function useTableLinkedVisit(options: TableLinkedVisitOptions): void {
|
|
33
|
+
// The page the table is shown on, as the visit that mounted it reached it.
|
|
34
|
+
const pathname = options.route.path;
|
|
35
|
+
let previousQuery: Record<string, unknown> = { ...options.route.query };
|
|
36
|
+
// A pushed visit announces itself twice when it changes the URL.
|
|
37
|
+
let followedVisitId: string | undefined;
|
|
38
|
+
const stops: Array<() => void> = [];
|
|
39
|
+
|
|
40
|
+
const read = (
|
|
41
|
+
url: string,
|
|
42
|
+
visitId: string | undefined,
|
|
43
|
+
isLinkClick: boolean,
|
|
44
|
+
) => {
|
|
45
|
+
const query = queryOfUrl(url);
|
|
46
|
+
const lastQuery = previousQuery;
|
|
47
|
+
previousQuery = query;
|
|
48
|
+
if (new URL(url, URL_BASE).pathname !== pathname) return;
|
|
49
|
+
if (visitId !== undefined && visitId === followedVisitId) return;
|
|
50
|
+
const isLink = isLinkedVisit({
|
|
51
|
+
query,
|
|
52
|
+
isLinkClick,
|
|
53
|
+
previousQuery: lastQuery,
|
|
54
|
+
urlScope: options.urlScope,
|
|
55
|
+
queryParamFilters: options.queryParamFilters,
|
|
56
|
+
activeView: options.activeView(),
|
|
57
|
+
activeTab: options.activeTab(),
|
|
58
|
+
canOpenView: options.canOpenView,
|
|
59
|
+
canOpenTab: options.canOpenTab,
|
|
60
|
+
});
|
|
61
|
+
if (!isLink) return;
|
|
62
|
+
followedVisitId = visitId;
|
|
63
|
+
options.follow(query);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
onMounted(() => {
|
|
67
|
+
stops.push(
|
|
68
|
+
inertiaRouter.on("navigate", (event) =>
|
|
69
|
+
read(event.detail.page.url, event.detail.visitId, false),
|
|
70
|
+
),
|
|
71
|
+
inertiaRouter.on("clientVisit", (event) => {
|
|
72
|
+
if (event.detail.replace) return;
|
|
73
|
+
read(event.detail.page.url, event.detail.visitId, true);
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
onBeforeUnmount(() => stops.forEach((stop) => stop()));
|
|
78
|
+
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
getCurrentScope,
|
|
4
|
+
onMounted,
|
|
5
|
+
onScopeDispose,
|
|
6
|
+
ref,
|
|
7
|
+
watch,
|
|
8
|
+
type ComputedRef,
|
|
9
|
+
} from "vue";
|
|
2
10
|
import { usePageLive } from "../../../composables/live/usePageLive";
|
|
3
11
|
import type {
|
|
4
12
|
PageLiveNote,
|
|
5
13
|
TableViewLiveHoldOptions,
|
|
6
14
|
} from "../../../types/live";
|
|
7
15
|
import type { LiveGate } from "../live/currentPageLive";
|
|
8
|
-
import { useScrolledPastTop } from "./useScrolledPastTop";
|
|
16
|
+
import { useScrolledPastTop, useTableReached } from "./useScrolledPastTop";
|
|
9
17
|
import { LIVE_HELD_AT_QUERY_KEY } from "./useTableRows";
|
|
10
18
|
|
|
11
19
|
type Query = Record<string, unknown>;
|
|
@@ -18,7 +26,10 @@ export interface TableLiveHoldSignals {
|
|
|
18
26
|
isSearching?: () => boolean;
|
|
19
27
|
/** The rows are sorted otherwise than by the table's default. */
|
|
20
28
|
isSorted?: () => boolean;
|
|
21
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The table's element: whether it is on screen, and where its first row
|
|
31
|
+
* stands for `whileScrolled`.
|
|
32
|
+
*/
|
|
22
33
|
tableElement?: () => unknown;
|
|
23
34
|
}
|
|
24
35
|
|
|
@@ -29,6 +40,29 @@ export type TableLiveHoldReason =
|
|
|
29
40
|
| "sorted"
|
|
30
41
|
| "scrolled";
|
|
31
42
|
|
|
43
|
+
/**
|
|
44
|
+
* A table holds by itself for a reason it names, or because the user has its
|
|
45
|
+
* rows on screen (`reading`): new rows would push them down. The latter goes
|
|
46
|
+
* unsaid; the new rows wait behind the "N new · Show" pill.
|
|
47
|
+
*/
|
|
48
|
+
type LocalHoldReason = TableLiveHoldReason | "reading";
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* How a held table counts the new rows it would show: the rows its current
|
|
52
|
+
* query (tab, search, filters) matches now, less the rows it holds. Without
|
|
53
|
+
* it the pill counts every event of the table's topic, whatever row each
|
|
54
|
+
* one is about.
|
|
55
|
+
*/
|
|
56
|
+
export interface TableNewRowsCounter {
|
|
57
|
+
/**
|
|
58
|
+
* The list on screen, `null` before it arrives; read again whenever it
|
|
59
|
+
* changes (a new read, another query), which counts again.
|
|
60
|
+
*/
|
|
61
|
+
heldList: () => { total: number } | null | undefined;
|
|
62
|
+
/** How many rows the table's current query matches now, unbounded. */
|
|
63
|
+
countNow: (signal: AbortSignal) => Promise<number | undefined>;
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
export interface TableLiveHoldOptions {
|
|
33
67
|
/** The table's `liveHold`: `true` or an object enables it. */
|
|
34
68
|
liveHold: boolean | TableViewLiveHoldOptions | undefined;
|
|
@@ -40,12 +74,16 @@ export interface TableLiveHoldOptions {
|
|
|
40
74
|
*/
|
|
41
75
|
gate: () => LiveGate;
|
|
42
76
|
signals?: TableLiveHoldSignals;
|
|
77
|
+
newRows?: TableNewRowsCounter;
|
|
43
78
|
}
|
|
44
79
|
|
|
45
80
|
export interface TableLiveHold {
|
|
46
81
|
/** The rows are held: the page is paused, or the table holds by itself. */
|
|
47
82
|
isHolding: ComputedRef<boolean>;
|
|
48
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* The rows the table would add since its rows were held or last shown
|
|
85
|
+
* (`newRows`), or else the events it received meanwhile.
|
|
86
|
+
*/
|
|
49
87
|
newCount: ComputedRef<number>;
|
|
50
88
|
/**
|
|
51
89
|
* Why the table holds by itself while its page is live, `null` otherwise:
|
|
@@ -77,22 +115,26 @@ function holdOptionsOf(
|
|
|
77
115
|
}
|
|
78
116
|
|
|
79
117
|
// The table alone holds while the page is live: the user reads a row in the
|
|
80
|
-
// side panel, narrows or reorders the rows,
|
|
81
|
-
//
|
|
118
|
+
// side panel, narrows or reorders the rows, reads further down than the rows
|
|
119
|
+
// that would move, or has them on screen at all — a new row at the top would
|
|
120
|
+
// push them down. The first reason in this order is the one shown.
|
|
82
121
|
function useLocalHold(
|
|
83
122
|
holdOptions: TableViewLiveHoldOptions | null,
|
|
84
123
|
signals: TableLiveHoldSignals,
|
|
85
|
-
): ComputedRef<
|
|
124
|
+
): ComputedRef<LocalHoldReason | null> {
|
|
86
125
|
const tableElement = signals.tableElement ?? NO_ELEMENT;
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
return
|
|
90
|
-
}
|
|
91
|
-
const
|
|
126
|
+
const element = () => {
|
|
127
|
+
const target = tableElement();
|
|
128
|
+
return target instanceof HTMLElement ? target : null;
|
|
129
|
+
};
|
|
130
|
+
const isScrolled = useScrolledPastTop(element, !!holdOptions?.whileScrolled);
|
|
131
|
+
const isReached = useTableReached(element, !!holdOptions);
|
|
132
|
+
const reasons: Array<[LocalHoldReason, boolean, () => boolean]> = [
|
|
92
133
|
["rowOpen", !!holdOptions?.whileRowOpen, signals.isRowOpen ?? NEVER],
|
|
93
134
|
["searching", !!holdOptions?.whileSearching, signals.isSearching ?? NEVER],
|
|
94
135
|
["sorted", !!holdOptions?.whileSorted, signals.isSorted ?? NEVER],
|
|
95
136
|
["scrolled", !!holdOptions?.whileScrolled, () => isScrolled.value],
|
|
137
|
+
["reading", !!holdOptions, () => isReached.value],
|
|
96
138
|
];
|
|
97
139
|
return computed(
|
|
98
140
|
() =>
|
|
@@ -102,10 +144,11 @@ function useLocalHold(
|
|
|
102
144
|
}
|
|
103
145
|
|
|
104
146
|
/**
|
|
105
|
-
* The `liveHold` of a table view: while its live page is paused
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
147
|
+
* The `liveHold` of a table view: while its live page is paused, while its
|
|
148
|
+
* rows are on screen or scrolled past (rows landing at the top would move
|
|
149
|
+
* them) — or, with `whileRowOpen` / `whileSearching` / `whileSorted` /
|
|
150
|
+
* `whileScrolled`, saying so, while the user reads a row, searches, sorts or
|
|
151
|
+
* scrolled down — the table keeps its rows: the gate requests nothing on its events and counts them, and a
|
|
109
152
|
* source route is told the moment they were frozen, so the user's own
|
|
110
153
|
* search, sort and pagination list the rows as they stood.
|
|
111
154
|
* Show reads them once more without leaving the hold; the end of a hold of
|
|
@@ -132,16 +175,19 @@ export function useTableLiveHold(options: TableLiveHoldOptions): TableLiveHold {
|
|
|
132
175
|
},
|
|
133
176
|
{ flush: "sync" },
|
|
134
177
|
);
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
178
|
+
const missed = () => (isHolding.value ? options.gate().missed.value : 0);
|
|
179
|
+
const newCount = options.newRows
|
|
180
|
+
? useCountedNewRows(missed, options.newRows)
|
|
181
|
+
: computed(missed);
|
|
138
182
|
|
|
139
183
|
return {
|
|
140
184
|
isHolding,
|
|
141
185
|
newCount,
|
|
142
|
-
reason: computed(() =>
|
|
143
|
-
isHolding.value
|
|
144
|
-
|
|
186
|
+
reason: computed(() => {
|
|
187
|
+
if (!isHolding.value || isPaused.value) return null;
|
|
188
|
+
const reason = localReason.value;
|
|
189
|
+
return reason === "reading" ? null : reason;
|
|
190
|
+
}),
|
|
145
191
|
missedLabel: holdOptions?.missedLabel,
|
|
146
192
|
missedDetail: computed(() =>
|
|
147
193
|
isPaused.value && newCount.value > 0 ? missedDetail.value : null,
|
|
@@ -151,6 +197,73 @@ export function useTableLiveHold(options: TableLiveHoldOptions): TableLiveHold {
|
|
|
151
197
|
};
|
|
152
198
|
}
|
|
153
199
|
|
|
200
|
+
/** Lets a burst of events through before counting the new rows once. */
|
|
201
|
+
const NEW_ROWS_COUNT_DELAY_MS = 500;
|
|
202
|
+
|
|
203
|
+
// The new rows the table would show, counted on its source while it holds
|
|
204
|
+
// some events: a topic publishes on every row, so a "4xx" tab, a search or a
|
|
205
|
+
// filter would otherwise announce rows it never lists. Counted again on each
|
|
206
|
+
// new event or held list, a burst at a time. Rows removed meanwhile lower
|
|
207
|
+
// the count: the table answers what it lists, not what came in. A count that
|
|
208
|
+
// fails falls back to the events. Only in the browser, once mounted: the
|
|
209
|
+
// table sets up its gate and its list after its hold.
|
|
210
|
+
function useCountedNewRows(
|
|
211
|
+
missed: () => number,
|
|
212
|
+
counter: TableNewRowsCounter,
|
|
213
|
+
): ComputedRef<number> {
|
|
214
|
+
const counted = ref(0);
|
|
215
|
+
const hasFailed = ref(false);
|
|
216
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
217
|
+
let inFlight: AbortController | undefined;
|
|
218
|
+
|
|
219
|
+
const cancel = () => {
|
|
220
|
+
clearTimeout(timer);
|
|
221
|
+
timer = undefined;
|
|
222
|
+
inFlight?.abort();
|
|
223
|
+
inFlight = undefined;
|
|
224
|
+
};
|
|
225
|
+
const count = async () => {
|
|
226
|
+
timer = undefined;
|
|
227
|
+
const held = counter.heldList()?.total;
|
|
228
|
+
if (held === undefined) return;
|
|
229
|
+
inFlight?.abort();
|
|
230
|
+
const controller = new AbortController();
|
|
231
|
+
inFlight = controller;
|
|
232
|
+
try {
|
|
233
|
+
const now = await counter.countNow(controller.signal);
|
|
234
|
+
if (controller.signal.aborted) return;
|
|
235
|
+
hasFailed.value = now === undefined;
|
|
236
|
+
counted.value = Math.max(0, (now ?? held) - held);
|
|
237
|
+
} catch {
|
|
238
|
+
if (!controller.signal.aborted) hasFailed.value = true;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const scope = getCurrentScope();
|
|
243
|
+
const follow = () =>
|
|
244
|
+
watch(
|
|
245
|
+
[missed, counter.heldList],
|
|
246
|
+
([events]) => {
|
|
247
|
+
if (events === 0) {
|
|
248
|
+
cancel();
|
|
249
|
+
counted.value = 0;
|
|
250
|
+
hasFailed.value = false;
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
timer ??= setTimeout(count, NEW_ROWS_COUNT_DELAY_MS);
|
|
254
|
+
},
|
|
255
|
+
{ immediate: true },
|
|
256
|
+
);
|
|
257
|
+
onMounted(() => scope?.run(follow));
|
|
258
|
+
onScopeDispose(cancel);
|
|
259
|
+
|
|
260
|
+
return computed(() => {
|
|
261
|
+
const events = missed();
|
|
262
|
+
if (events === 0) return 0;
|
|
263
|
+
return hasFailed.value ? events : counted.value;
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
154
267
|
// The bound a source route receives while the rows are held: they are as
|
|
155
268
|
// fresh as the hold, or as the last read the user asked for since (Show, an
|
|
156
269
|
// action of theirs).
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
resolveUrlVariables,
|
|
12
12
|
} from "../../utils/urlVariables";
|
|
13
13
|
import type { RowActionRule } from "#dms-core/app/types/row-action";
|
|
14
|
-
import {
|
|
14
|
+
import { compareValues, textOf } from "./utils/compareValues";
|
|
15
|
+
import { pinRows, pinRowsBySpan } from "./utils/pinnedRows";
|
|
15
16
|
import {
|
|
16
17
|
appendPeriodToUrl,
|
|
17
18
|
usePeriodScope,
|
|
@@ -86,18 +87,6 @@ export function sourceRouteQuery(
|
|
|
86
87
|
);
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
const textOf = (value: unknown): string =>
|
|
90
|
-
value === null || value === undefined
|
|
91
|
-
? ""
|
|
92
|
-
: typeof value === "object"
|
|
93
|
-
? JSON.stringify(value)
|
|
94
|
-
: String(value);
|
|
95
|
-
|
|
96
|
-
const compareValues = (a: unknown, b: unknown): number => {
|
|
97
|
-
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
98
|
-
return textOf(a).localeCompare(textOf(b), undefined, { numeric: true });
|
|
99
|
-
};
|
|
100
|
-
|
|
101
90
|
/**
|
|
102
91
|
* The rows the browser narrows, sorts and pages itself, for what the source
|
|
103
92
|
* route left to it: a search over the listed columns' text, the sort on one
|
|
@@ -155,7 +144,10 @@ interface SharedRead<T> {
|
|
|
155
144
|
* order its keys were built in.
|
|
156
145
|
*/
|
|
157
146
|
const sourceReadKey = (url: string, query: Query): string =>
|
|
158
|
-
JSON.stringify([
|
|
147
|
+
JSON.stringify([
|
|
148
|
+
url,
|
|
149
|
+
Object.entries(query).sort(([a], [b]) => a.localeCompare(b)),
|
|
150
|
+
]);
|
|
159
151
|
|
|
160
152
|
/**
|
|
161
153
|
* Settles with `answer`, or rejects as soon as `signal` aborts, calling
|
|
@@ -173,9 +165,9 @@ function awaitUnlessAborted<R>(
|
|
|
173
165
|
};
|
|
174
166
|
if (signal.aborted) return abort();
|
|
175
167
|
signal.addEventListener("abort", abort, { once: true });
|
|
176
|
-
answer
|
|
177
|
-
|
|
178
|
-
|
|
168
|
+
answer
|
|
169
|
+
.then(resolve, reject)
|
|
170
|
+
.finally(() => signal.removeEventListener("abort", abort));
|
|
179
171
|
});
|
|
180
172
|
}
|
|
181
173
|
|
|
@@ -294,19 +286,57 @@ export function useTableRows<T extends Record<string, unknown>>(
|
|
|
294
286
|
): TableViewListResponse<T> | null =>
|
|
295
287
|
page && { ...page, results: pinRows(page.results, options.pinnedRows?.()) };
|
|
296
288
|
|
|
289
|
+
// The list the route answers, before the pinned rows lead it.
|
|
290
|
+
const listAnswered = (
|
|
291
|
+
query: Query,
|
|
292
|
+
signal?: AbortSignal,
|
|
293
|
+
): Promise<TableViewListResponse<T> | null> =>
|
|
294
|
+
source
|
|
295
|
+
? listFromSource(source, query, signal)
|
|
296
|
+
: api<TableViewListResponse<T>>(`${location}/list`, { query, signal });
|
|
297
|
+
|
|
297
298
|
// `signal` aborts the request once its answer is no longer wanted.
|
|
298
299
|
const list = async (
|
|
299
300
|
query: Query,
|
|
300
301
|
signal?: AbortSignal,
|
|
301
302
|
): Promise<TableViewListResponse<T> | null> =>
|
|
302
|
-
withPinnedRows(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
withPinnedRows(await listAnswered(query, signal));
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* The rows `query.offset` and `query.limit` name, in the order a table
|
|
307
|
+
* reading `span` rows at a time from the first shows them: the pinned
|
|
308
|
+
* rows lead each of its reads (a page), not the rows read here. The reads
|
|
309
|
+
* they fall in are read whole, then each pinned on its own. A source
|
|
310
|
+
* answering every row pins them all before its pages are cut: as `list`.
|
|
311
|
+
*/
|
|
312
|
+
const listAsShown = async (
|
|
313
|
+
query: Query,
|
|
314
|
+
span: number,
|
|
315
|
+
): Promise<TableViewListResponse<T> | null> => {
|
|
316
|
+
const pinnedRows = options.pinnedRows?.();
|
|
317
|
+
const offset = Number(query.offset) || 0;
|
|
318
|
+
const limit = Number(query.limit) || 0;
|
|
319
|
+
const isWholeSource = !!source && !source.capabilities.paginate;
|
|
320
|
+
if (!pinnedRows || span <= 0 || limit <= 0 || isWholeSource) {
|
|
321
|
+
return list(query);
|
|
322
|
+
}
|
|
323
|
+
const start = Math.floor(offset / span) * span;
|
|
324
|
+
const end = Math.ceil((offset + limit) / span) * span;
|
|
325
|
+
const page = await listAnswered({
|
|
326
|
+
...query,
|
|
327
|
+
offset: start,
|
|
328
|
+
limit: end - start,
|
|
329
|
+
});
|
|
330
|
+
if (!page) return null;
|
|
331
|
+
const shown = pinRowsBySpan(page.results, span, pinnedRows);
|
|
332
|
+
const from = offset - start;
|
|
333
|
+
return {
|
|
334
|
+
...page,
|
|
335
|
+
results: shown.slice(from, from + limit),
|
|
336
|
+
offset,
|
|
337
|
+
limit,
|
|
338
|
+
};
|
|
339
|
+
};
|
|
310
340
|
|
|
311
341
|
// A source answers its totals one list at a time.
|
|
312
342
|
const countBatch = async (
|
|
@@ -358,6 +388,7 @@ export function useTableRows<T extends Record<string, unknown>>(
|
|
|
358
388
|
sourceUrl,
|
|
359
389
|
isPeriodPending,
|
|
360
390
|
list,
|
|
391
|
+
listAsShown,
|
|
361
392
|
countBatch,
|
|
362
393
|
getRow,
|
|
363
394
|
};
|
package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts
CHANGED
|
@@ -5,7 +5,10 @@ import {
|
|
|
5
5
|
type FormPageUrls,
|
|
6
6
|
} from "./useTableViewConfig";
|
|
7
7
|
import type { FormProps } from "../../../composables/form/types";
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
QueryParamFilters,
|
|
10
|
+
TableViewColumn,
|
|
11
|
+
} from "../../../composables/table-view/types";
|
|
9
12
|
import type { LocationQuery, LocationQueryValue } from "#dms/frontend-module";
|
|
10
13
|
import {
|
|
11
14
|
TableRowAction,
|
|
@@ -33,7 +36,7 @@ import {
|
|
|
33
36
|
type BulkActionOutcome,
|
|
34
37
|
type ConfirmedBulkAction,
|
|
35
38
|
} from "./utils/bulkActions";
|
|
36
|
-
import {
|
|
39
|
+
import { describeTableWriteError } from "./utils/writeError";
|
|
37
40
|
import {
|
|
38
41
|
ConfirmActionError,
|
|
39
42
|
type ConfirmOptions,
|
|
@@ -44,6 +47,7 @@ import {
|
|
|
44
47
|
resolveFormContainerTexts,
|
|
45
48
|
type TableViewFormKind,
|
|
46
49
|
} from "./utils/formTexts";
|
|
50
|
+
import { dmsOwnDrawer } from "../containers/context";
|
|
47
51
|
|
|
48
52
|
const DEFAULT_ROW_ID_KEY = "_id";
|
|
49
53
|
const DEFAULT_MODAL_SIZE = "xl";
|
|
@@ -58,6 +62,8 @@ const getItemId = (
|
|
|
58
62
|
interface TableRowActionsConfig {
|
|
59
63
|
api: ReturnType<typeof $fetch.create>;
|
|
60
64
|
location: string;
|
|
65
|
+
/** The columns, whose labels name the fields a refused write lacks. */
|
|
66
|
+
columns: ReadonlyArray<Pick<TableViewColumn, "accessorKey" | "header">>;
|
|
61
67
|
caption?: string;
|
|
62
68
|
labelKey?: string;
|
|
63
69
|
rowIdKey?: string;
|
|
@@ -95,6 +101,12 @@ type ConfirmedRun = NonNullable<ConfirmOptions["onConfirm"]>;
|
|
|
95
101
|
/** Options of a delete: from the archive, it is a permanent one. */
|
|
96
102
|
interface DeleteRowsOptions {
|
|
97
103
|
permanently?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The rows deleted, when the caller holds them: a dialog naming the row
|
|
106
|
+
* (`{name}`) reads its fields here first. A kanban card is not among the
|
|
107
|
+
* rows the table shows.
|
|
108
|
+
*/
|
|
109
|
+
rows?: Data[];
|
|
98
110
|
}
|
|
99
111
|
|
|
100
112
|
export const useTableRowActions = <T extends Data>(
|
|
@@ -139,7 +151,12 @@ export const useTableRowActions = <T extends Data>(
|
|
|
139
151
|
color: Color.error,
|
|
140
152
|
icon: "i-ph-warning-circle",
|
|
141
153
|
title: title || t("dms.form.error_title"),
|
|
142
|
-
description:
|
|
154
|
+
description: describeTableWriteError(
|
|
155
|
+
error,
|
|
156
|
+
t,
|
|
157
|
+
config.columns,
|
|
158
|
+
processI18n,
|
|
159
|
+
),
|
|
143
160
|
});
|
|
144
161
|
};
|
|
145
162
|
|
|
@@ -249,24 +266,26 @@ export const useTableRowActions = <T extends Data>(
|
|
|
249
266
|
fetchUrl?: string,
|
|
250
267
|
submitDefaults?: Record<string, unknown>,
|
|
251
268
|
) => {
|
|
252
|
-
const drawer = openDrawer(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
component: DmsForm,
|
|
257
|
-
componentOptions: {
|
|
258
|
-
...processedOptions,
|
|
259
|
-
...(fetchUrl && { fetchUrl }),
|
|
260
|
-
...(submitDefaults && { submitDefaults }),
|
|
261
|
-
componentId: `${config.componentId}-${componentIdSuffix}`,
|
|
262
|
-
pageId: pageIdSuffix,
|
|
269
|
+
const drawer = openDrawer(
|
|
270
|
+
dmsOwnDrawer({
|
|
271
|
+
title,
|
|
272
|
+
description,
|
|
263
273
|
containerId,
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
274
|
+
component: DmsForm,
|
|
275
|
+
componentOptions: {
|
|
276
|
+
...processedOptions,
|
|
277
|
+
...(fetchUrl && { fetchUrl }),
|
|
278
|
+
...(submitDefaults && { submitDefaults }),
|
|
279
|
+
componentId: `${config.componentId}-${componentIdSuffix}`,
|
|
280
|
+
pageId: pageIdSuffix,
|
|
281
|
+
containerId,
|
|
282
|
+
onSuccessCallback: () => {
|
|
283
|
+
drawer.close();
|
|
284
|
+
config.refreshCallback?.();
|
|
285
|
+
},
|
|
267
286
|
},
|
|
268
|
-
},
|
|
269
|
-
|
|
287
|
+
}),
|
|
288
|
+
);
|
|
270
289
|
return drawer;
|
|
271
290
|
};
|
|
272
291
|
|
|
@@ -654,38 +673,65 @@ export const useTableRowActions = <T extends Data>(
|
|
|
654
673
|
};
|
|
655
674
|
};
|
|
656
675
|
|
|
657
|
-
const
|
|
658
|
-
config.
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
676
|
+
const rowIdOf = (row: Data): string =>
|
|
677
|
+
String(getItemId(row, config.rowIdKey ?? DEFAULT_ROW_ID_KEY));
|
|
678
|
+
|
|
679
|
+
const findRowIn = (rows: Data[] | undefined, id: string) =>
|
|
680
|
+
rows?.find((row) => rowIdOf(row) === id);
|
|
681
|
+
|
|
682
|
+
// A row the table does not show (a kanban card, a row deleted from a
|
|
683
|
+
// custom card) is read by id: a `from` dialog asks the server instead.
|
|
684
|
+
const readRow = async (
|
|
685
|
+
id: string,
|
|
686
|
+
declared: ActionConfirm,
|
|
687
|
+
): Promise<Data | undefined> => {
|
|
688
|
+
const getRow = config.rowNavigation?.getRow;
|
|
689
|
+
if (!getRow || isConfirmFrom(declared)) return undefined;
|
|
690
|
+
return getRow(id).catch(() => undefined);
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
/** The one row a dialog words: the caller's, the table's, else read. */
|
|
694
|
+
const findConfirmRow = async (
|
|
695
|
+
id: string,
|
|
696
|
+
declared: ActionConfirm,
|
|
697
|
+
rows?: Data[],
|
|
698
|
+
): Promise<Data | undefined> =>
|
|
699
|
+
findRowIn(rows, id) ??
|
|
700
|
+
findRowIn(config.rowNavigation?.rows(), id) ??
|
|
701
|
+
(await readRow(id, declared));
|
|
664
702
|
|
|
665
703
|
/**
|
|
666
|
-
* What a fixed dialog words: the rows' count, and for one row
|
|
667
|
-
*
|
|
668
|
-
*
|
|
704
|
+
* What a fixed dialog words: the rows' count, and for one row its own
|
|
705
|
+
* fields too (`{name}`). The count wins a clash, it is what every bulk
|
|
706
|
+
* dialog may name.
|
|
669
707
|
*/
|
|
670
|
-
const confirmRowFields = (
|
|
708
|
+
const confirmRowFields = async (
|
|
709
|
+
ids: string[],
|
|
710
|
+
declared: ActionConfirm,
|
|
711
|
+
rows?: Data[],
|
|
712
|
+
): Promise<Data> => {
|
|
671
713
|
const count = { count: ids.length };
|
|
672
|
-
const row =
|
|
714
|
+
const row =
|
|
715
|
+
ids.length === 1
|
|
716
|
+
? await findConfirmRow(ids[0]!, declared, rows)
|
|
717
|
+
: undefined;
|
|
673
718
|
return row ? { ...row, ...count } : count;
|
|
674
719
|
};
|
|
675
720
|
|
|
676
721
|
/** Asks the declared confirmation of a bulk action, running it inside. */
|
|
677
|
-
const askDeclaredBulkConfirm = (
|
|
722
|
+
const askDeclaredBulkConfirm = async (
|
|
678
723
|
declared: ActionConfirm,
|
|
679
724
|
ids: string[],
|
|
680
725
|
fallback: Partial<ConfirmOptions>,
|
|
681
726
|
run: ConfirmedRun,
|
|
727
|
+
rows?: Data[],
|
|
682
728
|
): Promise<boolean> =>
|
|
683
729
|
confirmAction(declared, {
|
|
684
730
|
urlParams: {
|
|
685
731
|
id: ids[0],
|
|
686
732
|
[config.rowIdKey ?? DEFAULT_ROW_ID_KEY]: ids[0],
|
|
687
733
|
},
|
|
688
|
-
row: confirmRowFields(ids),
|
|
734
|
+
row: await confirmRowFields(ids, declared, rows),
|
|
689
735
|
fallback,
|
|
690
736
|
run,
|
|
691
737
|
});
|
|
@@ -703,11 +749,14 @@ export const useTableRowActions = <T extends Data>(
|
|
|
703
749
|
actionConfig: boolean | RowActionConfig | undefined,
|
|
704
750
|
action: ConfirmedBulkAction,
|
|
705
751
|
bulkConfig: BulkActionConfig,
|
|
752
|
+
rows?: Data[],
|
|
706
753
|
): Promise<boolean> => {
|
|
707
754
|
const fallback = bulkActionConfirm(action, ids.length, t);
|
|
708
755
|
const run = bulkActionRun(ids, actionConfig, bulkConfig);
|
|
709
756
|
const declared = declaredBulkConfirm(actionConfig, ids);
|
|
710
|
-
if (declared)
|
|
757
|
+
if (declared) {
|
|
758
|
+
return askDeclaredBulkConfirm(declared, ids, fallback, run, rows);
|
|
759
|
+
}
|
|
711
760
|
return confirm({ ...fallback, onConfirm: run });
|
|
712
761
|
};
|
|
713
762
|
|
|
@@ -746,7 +795,13 @@ export const useTableRowActions = <T extends Data>(
|
|
|
746
795
|
): Promise<boolean> => {
|
|
747
796
|
if (!normalizeActionConfig(deleteConfig).isEnabled) return false;
|
|
748
797
|
const action = options.permanently ? "deletePermanently" : "delete";
|
|
749
|
-
return confirmBulkAction(
|
|
798
|
+
return confirmBulkAction(
|
|
799
|
+
ids,
|
|
800
|
+
deleteConfig,
|
|
801
|
+
action,
|
|
802
|
+
DELETE_CONFIG,
|
|
803
|
+
options.rows,
|
|
804
|
+
);
|
|
750
805
|
};
|
|
751
806
|
|
|
752
807
|
const archiveRows = async (
|