@antelopejs/dms 0.9.8 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +171 -0
- package/README.md +1 -1
- package/data/module-store/catalog.json +2 -2
- package/dist/attachments/table-view.js +2 -2
- package/dist/attachments/table-view.js.map +1 -1
- package/dist/automation/actions.d.ts +2 -0
- package/dist/automation/actions.js +116 -71
- package/dist/automation/actions.js.map +1 -1
- package/dist/automation/i18n.d.ts +4 -0
- package/dist/automation/i18n.js +19 -0
- package/dist/automation/i18n.js.map +1 -0
- package/dist/automation/send-notification.d.ts +21 -0
- package/dist/automation/send-notification.js +163 -0
- package/dist/automation/send-notification.js.map +1 -0
- package/dist/automation/triggers.js +19 -25
- package/dist/automation/triggers.js.map +1 -1
- package/dist/client-origin-cors.d.ts +1 -0
- package/dist/client-origin-cors.js +19 -0
- package/dist/client-origin-cors.js.map +1 -0
- package/dist/config.d.ts +3 -2
- package/dist/config.js +5 -7
- package/dist/config.js.map +1 -1
- package/dist/frontend-module.d.ts +4 -0
- package/dist/frontend-module.js +37 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/implementations/dms/client-ip.js +1 -1
- package/dist/implementations/dms/client-ip.js.map +1 -1
- package/dist/implementations/dms/dev-reload.d.ts +5 -0
- package/dist/implementations/dms/dev-reload.js +23 -3
- package/dist/implementations/dms/dev-reload.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -4
- package/dist/implementations/dms/frontend-modules.js +38 -94
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +12 -2
- package/dist/implementations/dms/frontend-ready.js +34 -4
- package/dist/implementations/dms/frontend-ready.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +2 -1
- package/dist/implementations/dms/layout-banners.js +9 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/manifest.d.ts +7 -2
- package/dist/implementations/dms/manifest.js +12 -7
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +4 -3
- package/dist/implementations/dms/page.js +49 -18
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permissions-resolver.d.ts +2 -2
- package/dist/implementations/dms/permissions-resolver.js +2 -2
- package/dist/implementations/dms/permissions-resolver.js.map +1 -1
- package/dist/implementations/dms/realtime.js +1 -0
- package/dist/implementations/dms/realtime.js.map +1 -1
- package/dist/implementations/dms-base/bulk-selection.d.ts +1 -1
- package/dist/implementations/dms-base/bulk-selection.js +23 -1
- package/dist/implementations/dms-base/bulk-selection.js.map +1 -1
- package/dist/implementations/dms-base/filter-tokens.js +5 -3
- package/dist/implementations/dms-base/filter-tokens.js.map +1 -1
- package/dist/implementations/dms-base/search-route.d.ts +1 -0
- package/dist/implementations/dms-base/search-route.js +35 -13
- package/dist/implementations/dms-base/search-route.js.map +1 -1
- package/dist/implementations/dms-base/table-view.js +11 -6
- package/dist/implementations/dms-base/table-view.js.map +1 -1
- package/dist/implementations/dms-notifications/index.d.ts +2 -2
- package/dist/implementations/dms-notifications/index.js +5 -5
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/index.js +32 -55
- package/dist/index.js.map +1 -1
- package/dist/pages/modules/index.d.ts +1 -0
- package/dist/pages/modules/index.js +1 -0
- package/dist/pages/modules/index.js.map +1 -1
- package/dist/pages/modules/modules-store.d.ts +9 -0
- package/dist/pages/modules/modules-store.js +30 -0
- package/dist/pages/modules/modules-store.js.map +1 -0
- package/dist/pages/settings/users/account-credentials.js +2 -2
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/account-data-store.js +25 -8
- package/dist/pages/settings/users/account-data-store.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.js +9 -3
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -1
- package/dist/pages/settings/users/member-management.js +13 -14
- package/dist/pages/settings/users/member-management.js.map +1 -1
- package/dist/pages/settings/users/profile.d.ts +1 -4
- package/dist/pages/settings/users/profile.js +0 -35
- package/dist/pages/settings/users/profile.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +26 -18
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +0 -1
- package/dist/pages/settings/users/role-editor.js +1 -2
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +1 -2
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +2 -2
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/realtime/broker.d.ts +6 -0
- package/dist/realtime/broker.js +8 -1
- package/dist/realtime/broker.js.map +1 -1
- package/dist/realtime/presence.d.ts +8 -3
- package/dist/realtime/presence.js +8 -4
- package/dist/realtime/presence.js.map +1 -1
- package/dist/realtime/sessions.d.ts +11 -1
- package/dist/realtime/sessions.js +21 -3
- package/dist/realtime/sessions.js.map +1 -1
- package/dist/realtime/table-view.d.ts +2 -2
- package/dist/realtime/table-view.js +4 -3
- package/dist/realtime/table-view.js.map +1 -1
- package/dist/routes/auth/client-ip.d.ts +1 -0
- package/dist/routes/auth/client-ip.js +18 -0
- package/dist/routes/auth/client-ip.js.map +1 -1
- package/dist/routes/auth/oauth/config.d.ts +2 -1
- package/dist/routes/auth/oauth/config.js +5 -1
- package/dist/routes/auth/oauth/config.js.map +1 -1
- package/dist/routes/auth/session-handoff.d.ts +0 -1
- package/dist/routes/auth/session-handoff.js +0 -2
- package/dist/routes/auth/session-handoff.js.map +1 -1
- package/dist/routes/auth.js +3 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/realtime.d.ts +13 -1
- package/dist/routes/realtime.js +114 -29
- package/dist/routes/realtime.js.map +1 -1
- package/dist/startup-config.d.ts +2 -0
- package/dist/startup-config.js +62 -0
- package/dist/startup-config.js.map +1 -0
- package/dist/store/interfaces.d.ts +3 -2
- package/dist/store/interfaces.js +16 -6
- package/dist/store/interfaces.js.map +1 -1
- package/dist/store/listing.js +25 -15
- package/dist/store/listing.js.map +1 -1
- package/dist/store/operations.js +5 -2
- package/dist/store/operations.js.map +1 -1
- package/dist/store/requirements.js +3 -2
- package/dist/store/requirements.js.map +1 -1
- package/dist/store/runtime.d.ts +10 -1
- package/dist/store/runtime.js +33 -6
- package/dist/store/runtime.js.map +1 -1
- package/dist/store/types.d.ts +10 -0
- package/dist/utils/ensure-default-tenant.d.ts +2 -1
- package/dist/utils/ensure-default-tenant.js +13 -1
- package/dist/utils/ensure-default-tenant.js.map +1 -1
- package/dist/utils/export-jobs.js +2 -1
- package/dist/utils/export-jobs.js.map +1 -1
- package/dist/validation/auth.schema.d.ts +2 -2
- package/dist/validation/member-invite.schema.d.ts +2 -10
- package/dist/validation/member-invite.schema.js +2 -15
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +24 -5
- package/frontend-vue/dms.server.ts +17 -0
- package/frontend-vue/layers/dms-auth/server/accounts.ts +3 -4
- package/frontend-vue/layers/dms-core/app/build/composables/renderNow.ts +33 -0
- package/frontend-vue/layers/dms-core/app/build/composables/user/tablePreferences.ts +5 -1
- package/frontend-vue/layers/dms-core/app/build/utils/crossTab.ts +199 -0
- package/frontend-vue/layers/dms-core/app/build/utils/sharedRealtimeConnection.ts +410 -0
- package/frontend-vue/layers/dms-core/app/composables/auth/useApiData.ts +77 -12
- package/frontend-vue/layers/dms-core/app/composables/data-types/useDataType.ts +26 -0
- package/frontend-vue/layers/dms-core/app/composables/live/livePauseSource.ts +29 -0
- package/frontend-vue/layers/dms-core/app/composables/period/compareResolvers.ts +150 -9
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriod.ts +6 -4
- package/frontend-vue/layers/dms-core/app/composables/period/usePeriodScope.ts +27 -1
- package/frontend-vue/layers/dms-core/app/composables/realtime/useUserRealtime.ts +256 -119
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +21 -8
- package/frontend-vue/layers/dms-core/app/composables/translation/useTranslation.ts +25 -5
- package/frontend-vue/layers/dms-core/app/composables/useApiError.ts +3 -5
- package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +61 -26
- package/frontend-vue/layers/dms-core/app/plugins/dev-error-log.ts +16 -0
- package/frontend-vue/layers/dms-core/app/types/user.ts +6 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +7 -2
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +134 -35
- package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +18 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +136 -2
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +136 -2
- package/frontend-vue/layers/dms-core/shared/types/app-config.ts +0 -2
- package/frontend-vue/layers/dms-layout/app/app.config.ts +0 -1
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +11 -1
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/Geist-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Italic-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/assets/fonts/GeistMono-Variable.woff2 +0 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +3 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +41 -21
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardPageBody.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +4 -19
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +11 -107
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +18 -7
- package/frontend-vue/layers/dms-layout/app/build/components/layout/PageHeaderActionsOutlet.vue +4 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/RowSidePanel.vue +43 -82
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidebarUserMenu.vue +44 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/UserIdentity.vue +11 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleCatalogTile.vue +132 -35
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleManageMenu.vue +59 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleSourceLabel.vue +25 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreBanners.vue +73 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreOperation.vue +116 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +8 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +85 -207
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +10 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTileSkeleton.vue +68 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxDisplay.vue +24 -8
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationInboxItem.vue +8 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/region/RegionTimeZoneInput.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +19 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/useRoleEditor.ts +2 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +31 -70
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +11 -1
- package/frontend-vue/layers/dms-layout/app/build/utils/dev-reload-stream.ts +81 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +2 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +232 -36
- package/frontend-vue/layers/dms-layout/app/build/utils/modules-catalog.ts +122 -14
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +32 -3
- package/frontend-vue/layers/dms-layout/app/composables/layout/useServedHeaderActions.ts +49 -11
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleHistory.ts +3 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +59 -4
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStoreActions.ts +194 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageComponentPreload.ts +23 -3
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageLayout.ts +4 -2
- package/frontend-vue/layers/dms-layout/app/composables/page/usePageRecordDeletion.ts +162 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useSiteLayout.ts +6 -1
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-layouts/SettingsLayout.vue +6 -2
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules-store.vue +291 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +87 -474
- package/frontend-vue/layers/dms-layout/app/middleware/module-routing.global.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +13 -22
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-navigation.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-personal-pages.client.ts +22 -52
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-quick-actions.client.ts +7 -7
- package/frontend-vue/layers/dms-layout/app/plugins/command-palette-session.client.ts +11 -10
- package/frontend-vue/layers/dms-layout/app/plugins/dms-dev-reload.client.ts +14 -9
- package/frontend-vue/layers/dms-layout/app/theme/actions.ts +5 -4
- package/frontend-vue/layers/dms-layout/app/theme/form-controls.ts +9 -4
- package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +22 -6
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +9 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +15 -1
- package/frontend-vue/layers/dms-layout/app/utils/account-menu.ts +11 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +57 -0
- package/frontend-vue/layers/dms-layout/app/utils/pageQuery.ts +26 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +45 -18
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +44 -17
- package/frontend-vue/layers/dms-ui/app/build/components/containers/TargetComponentTree.vue +31 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/constants.ts +25 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +244 -15
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +42 -25
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowHeader.vue +153 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/RowNotFound.vue +44 -0
- package/frontend-vue/layers/dms-ui/app/build/components/containers/row/drawerRowHeader.ts +35 -0
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormEntries.vue +44 -9
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormErrorSummary.vue +11 -4
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +38 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldNotes.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSectionNav.vue +3 -1
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormSections.vue +106 -27
- package/frontend-vue/layers/dms-ui/app/build/components/table/Actions.vue +12 -4
- package/frontend-vue/layers/dms-ui/app/build/components/table/Empty.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table/FiltersRow.vue +48 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Pagination.vue +55 -54
- package/frontend-vue/layers/dms-ui/app/build/components/table/RowSelection.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Table.vue +396 -288
- package/frontend-vue/layers/dms-ui/app/build/components/table/Tabs.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table/Views.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardAvatar.vue +59 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardGridSkeleton.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardRowActions.vue +38 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/CardsDisplay.vue +148 -104
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/LiveHoldBanner.vue +17 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/bulkSelection.ts +43 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowComponentOptions.ts +76 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/rowNavigation.ts +172 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +270 -46
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/actionError.ts +6 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/closingLayers.ts +186 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/context.ts +14 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/drawerSize.ts +229 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/containers/useResizableSize.ts +175 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +18 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/numberSuffix.ts +44 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +123 -27
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerFieldTypes.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationFilter.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationRows.ts +92 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/relationValue.ts +39 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +6 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/form/createFormFields.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldSaved.ts +40 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/fieldValueRule.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryContext.ts +5 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +42 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formLayout.ts +106 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +11 -5
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formSections.ts +32 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formValidation.ts +36 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/form/readonlyValue.ts +19 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/registerFormFunctions.ts +27 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/repeaterTable.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/serverFieldErrors.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/toasterClearance.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/useInstantForm.ts +12 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/currentPageLive.ts +41 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/livePoller.ts +10 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/live/pageReadClock.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/live/shortcuts.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/live/usePageLiveHost.ts +17 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/live/useUpdatedLabel.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/pageToolbarContext.ts +75 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/page-toolbar/toolbarControlHeight.ts +29 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodComparison.ts +52 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodDisplay.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/periodShortLabels.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/period/usePeriodDraft.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRelationFilterLabels.ts +97 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useRowScrollAnchor.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +9 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTableColumns.ts +1 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/archivedCount.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/filterEditorValue.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/formatFilterValue.ts +33 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table/utils/scrollEdges.ts +31 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useCardFields.ts +33 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useMobileDisplay.ts +48 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useScrolledPastTop.ts +41 -18
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableFooter.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLinkedVisit.ts +78 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableLiveHold.ts +135 -22
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +56 -25
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +90 -35
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViews.ts +86 -10
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/bulkActions.ts +14 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/card.ts +127 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/compareValues.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/expandedRows.ts +28 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/groupedRows.ts +114 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/linkedArrival.ts +308 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/locateRow.ts +106 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pageArrival.ts +34 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/pinnedRows.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/quickFilters.ts +41 -33
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/recordLink.ts +24 -8
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableCounts.ts +113 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/tableQuery.ts +27 -4
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/views.ts +22 -6
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/writeError.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/addressSuggestions.ts +49 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/codeHighlight.ts +67 -29
- package/frontend-vue/layers/dms-ui/app/build/utils/eyebrow.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/fieldOptionsI18n.ts +51 -11
- package/frontend-vue/layers/dms-ui/app/build/utils/htmlGrammar.ts +79 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/inputWidth.ts +53 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/numberAdjustment.ts +6 -3
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/utils/scrollWithin.ts +99 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/shellParser.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/build/utils/streamHighlight.ts +90 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +36 -14
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/RecursiveComponent.vue +9 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/LiveToggleBlock.vue +80 -32
- package/frontend-vue/layers/dms-ui/app/components/blocks/PageToolbarBlock.vue +137 -0
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +16 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +24 -5
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +41 -23
- package/frontend-vue/layers/dms-ui/app/components/code-snippet/CodeSnippet.vue +23 -12
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/container-footer/ContainerFooter.vue +34 -0
- package/frontend-vue/layers/dms-ui/app/components/field-row/FieldRow.vue +25 -2
- package/frontend-vue/layers/dms-ui/app/components/flow-canvas/FlowCanvas.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +119 -36
- package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +53 -22
- package/frontend-vue/layers/dms-ui/app/components/form/components/DatePicker.vue +20 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +13 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Image.vue +8 -3
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +53 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +29 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputNumber.vue +45 -8
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputPercentage.vue +28 -5
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +5 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputText.vue +19 -2
- package/frontend-vue/layers/dms-ui/app/components/form/components/InputTime.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +226 -65
- package/frontend-vue/layers/dms-ui/app/components/form/components/Repeater.vue +80 -30
- package/frontend-vue/layers/dms-ui/app/components/form/components/RepeaterTable.vue +210 -0
- package/frontend-vue/layers/dms-ui/app/components/form/components/Select.vue +4 -2
- package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +11 -2
- package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +79 -70
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +117 -21
- package/frontend-vue/layers/dms-ui/app/components/meter/Meter.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/period/PeriodSelector.vue +113 -34
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +14 -2
- package/frontend-vue/layers/dms-ui/app/components/section-header/Eyebrow.vue +6 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +13 -0
- package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +52 -3
- package/frontend-vue/layers/dms-ui/app/components/tab/Tab.vue +2 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +74 -25
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanBoard.vue +48 -44
- package/frontend-vue/layers/dms-ui/app/components/table-view/KanbanDisplay.vue +4 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +426 -97
- package/frontend-vue/layers/dms-ui/app/components/top-list/TopListCard.vue +33 -5
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexCategoryLabels.ts +68 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/apexDatetimeBuckets.ts +306 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/formatValue.ts +4 -3
- package/frontend-vue/layers/dms-ui/app/composables/chart/heatmapColors.ts +93 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/localizeSeries.ts +62 -0
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +116 -8
- package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.types.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/composables/containers/types.ts +84 -1
- package/frontend-vue/layers/dms-ui/app/composables/containers/useDrawer.ts +69 -8
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field-saved.ts +11 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/field.ts +16 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/types/functions.ts +1 -0
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +189 -28
- package/frontend-vue/layers/dms-ui/app/composables/live/usePageLive.ts +29 -12
- package/frontend-vue/layers/dms-ui/app/composables/page-toolbar/usePageToolbarSize.ts +30 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/kanban.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +22 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +4 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/display.ts +24 -1
- package/frontend-vue/layers/dms-ui/app/plugins/closing-layers.client.ts +10 -0
- package/frontend-vue/layers/dms-ui/app/plugins/live-pause-source.ts +15 -0
- package/frontend-vue/layers/dms-ui/app/plugins/register.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/types/input-number.ts +3 -2
- package/frontend-vue/layers/dms-ui/app/types/page-toolbar.ts +7 -0
- package/frontend-vue/layers/dms-ui/app/types/row-action.ts +0 -2
- package/frontend-vue/layers/dms-ui/app/types/row-navigation.ts +17 -0
- package/frontend-vue/layers/dms-ui/app/types/table/query.ts +2 -1
- package/frontend-vue/layers/dms-ui/app/utils/blockRefresh.ts +3 -1
- package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +94 -3
- package/frontend-vue/layers/dms-ui/app/utils/componentTree.ts +24 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +20 -5
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +20 -5
- package/frontend-vue/package.json +6 -2
- package/package.json +11 -10
- package/skills/dms/SKILL.md +1 -1
- package/skills/dms-auth/SKILL.md +5 -3
- package/skills/dms-best-practices/REFERENCE.md +2 -0
- package/skills/dms-best-practices/SKILL.md +4 -0
- package/skills/dms-module/SKILL.md +3 -2
- package/skills/dms-pages/REFERENCE.md +129 -16
- package/skills/dms-pages/SKILL.md +1 -1
- package/skills/dms-project/DEV-SERVERS.md +23 -1
- package/skills/dms-project/REFERENCE.md +1 -1
- package/skills/dms-project/SKILL.md +4 -1
- package/skills/dms-project/scripts/dms-dev.sh +205 -17
- package/dist/hooks/tenant-instances.d.ts +0 -1
- package/dist/hooks/tenant-instances.js +0 -13
- package/dist/hooks/tenant-instances.js.map +0 -1
- package/dist/routes/startup-gate.d.ts +0 -7
- package/dist/routes/startup-gate.js +0 -39
- package/dist/routes/startup-gate.js.map +0 -1
- package/frontend-vue/layers/dms-core/app/composables/period/periodRenderNow.ts +0 -42
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type
|
|
2
|
+
import { getCurrentInstance, type Component } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
formBusInjectionKey,
|
|
5
|
+
formErrorsInjectionKey,
|
|
6
|
+
formFieldInjectionKey,
|
|
7
|
+
formInputsInjectionKey,
|
|
8
|
+
formLoadingInjectionKey,
|
|
9
|
+
formOptionsInjectionKey,
|
|
10
|
+
formStateInjectionKey,
|
|
11
|
+
inputIdInjectionKey,
|
|
12
|
+
} from "@nuxt/ui/runtime/composables/useFormField.js";
|
|
3
13
|
import { DialogDescription, DialogTitle, VisuallyHidden } from "reka-ui";
|
|
14
|
+
import { useWindowSize } from "@vueuse/core";
|
|
4
15
|
import type {
|
|
5
16
|
ContainerColor,
|
|
6
17
|
DrawerDirection,
|
|
7
18
|
} from "../../../../composables/containers/types";
|
|
19
|
+
import type { ModalSize } from "../../../../types/modal";
|
|
20
|
+
import {
|
|
21
|
+
drawerSizeStorage,
|
|
22
|
+
isSideDrawer,
|
|
23
|
+
resolveDrawerSizeBounds,
|
|
24
|
+
useDrawerSizePreferences,
|
|
25
|
+
} from "../../../composables/containers/drawerSize";
|
|
26
|
+
import {
|
|
27
|
+
type ResizeSide,
|
|
28
|
+
useResizableSize,
|
|
29
|
+
} from "../../../composables/containers/useResizableSize";
|
|
8
30
|
import DmsIconWell from "../../../../components/icon-well/IconWell.vue";
|
|
9
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
CLOSING_OVERLAY_CLASS,
|
|
33
|
+
CONTAINER_SKELETON_CLASS,
|
|
34
|
+
CONTAINER_SKELETON_FIELDS,
|
|
35
|
+
} from "../constants";
|
|
10
36
|
import { DMS_CONTAINER_KEY } from "../../../composables/containers/context";
|
|
11
37
|
|
|
12
38
|
interface DynamicDrawerProps {
|
|
@@ -20,8 +46,20 @@ interface DynamicDrawerProps {
|
|
|
20
46
|
headerComponent?: Component;
|
|
21
47
|
headerComponentOptions?: Record<string, unknown>;
|
|
22
48
|
direction?: DrawerDirection;
|
|
49
|
+
/**
|
|
50
|
+
* Width a side drawer opens at, from `lg`: a modal's width at that size;
|
|
51
|
+
* 600px without one. Below `lg`, only `full` fills a phone's screen.
|
|
52
|
+
*/
|
|
53
|
+
size?: ModalSize;
|
|
54
|
+
/** The key the size the user gives the drawer is remembered under. */
|
|
55
|
+
sizeKey?: string;
|
|
23
56
|
icon?: string;
|
|
24
57
|
color?: ContainerColor;
|
|
58
|
+
/**
|
|
59
|
+
* What the component that opened the drawer provides (`useDrawer` passes
|
|
60
|
+
* it): the drawer and its body inject it as if rendered in its tree.
|
|
61
|
+
*/
|
|
62
|
+
callerProvides?: object;
|
|
25
63
|
}
|
|
26
64
|
|
|
27
65
|
interface DynamicDrawerEmits {
|
|
@@ -34,29 +72,181 @@ const props = withDefaults(defineProps<DynamicDrawerProps>(), {
|
|
|
34
72
|
headerComponent: undefined,
|
|
35
73
|
headerComponentOptions: undefined,
|
|
36
74
|
direction: "bottom",
|
|
75
|
+
size: undefined,
|
|
76
|
+
sizeKey: undefined,
|
|
37
77
|
icon: undefined,
|
|
38
78
|
color: "primary",
|
|
79
|
+
callerProvides: undefined,
|
|
39
80
|
});
|
|
40
81
|
const emit = defineEmits<DynamicDrawerEmits>();
|
|
41
82
|
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
|
|
83
|
+
// Mounted by the overlay provider, the drawer would only see the app's
|
|
84
|
+
// provides: its own start from the caller's instead, before it provides
|
|
85
|
+
// anything (Vue's `provide` then writes into them). What the drawer provides
|
|
86
|
+
// itself (its container, the form surface) still wins over the caller's.
|
|
87
|
+
const NUXT_UI_FORM_KEYS = [
|
|
88
|
+
formOptionsInjectionKey,
|
|
89
|
+
formBusInjectionKey,
|
|
90
|
+
formStateInjectionKey,
|
|
91
|
+
formFieldInjectionKey,
|
|
92
|
+
inputIdInjectionKey,
|
|
93
|
+
formInputsInjectionKey,
|
|
94
|
+
formLoadingInjectionKey,
|
|
95
|
+
formErrorsInjectionKey,
|
|
96
|
+
];
|
|
97
|
+
const drawerInstance = getCurrentInstance() as { provides: object } | null;
|
|
98
|
+
if (drawerInstance && props.callerProvides) {
|
|
99
|
+
drawerInstance.provides = Object.create(props.callerProvides);
|
|
100
|
+
// A drawer is a surface of its own: a field in its body does not join a
|
|
101
|
+
// Nuxt UI form or form field around the component that opened it.
|
|
102
|
+
for (const key of NUXT_UI_FORM_KEYS) provide(key as symbol, undefined);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Below `lg` a side drawer is a sheet as wide as a side panel (see
|
|
106
|
+
// `useAppSidePanels`), or a modal's width at its size, never wider than the
|
|
107
|
+
// window less the drawer's gutter (Nuxt UI's `max-w-[calc(100%-2rem)]`): on
|
|
108
|
+
// a phone every side drawer leaves the same strip of backdrop, sized or not,
|
|
109
|
+
// and only `full` fills the screen. From
|
|
110
|
+
// `lg` it takes the width the user resizes it to (600px at first), kept per
|
|
111
|
+
// drawer. Its own padding is the gutter: the containers drop theirs.
|
|
46
112
|
const SIDE_DRAWER_CONTENT = "w-[440px]";
|
|
113
|
+
const SIDE_DRAWER_SIZE_CONTENT: Record<ModalSize, string> = {
|
|
114
|
+
sm: "w-sm",
|
|
115
|
+
md: "w-md",
|
|
116
|
+
lg: "w-lg",
|
|
117
|
+
xl: "w-xl",
|
|
118
|
+
"2xl": "w-2xl",
|
|
119
|
+
"3xl": "w-3xl",
|
|
120
|
+
"4xl": "w-4xl",
|
|
121
|
+
"5xl": "w-5xl",
|
|
122
|
+
full: "w-full max-w-full rounded-none",
|
|
123
|
+
};
|
|
124
|
+
const SIZE_VARIABLE = "--dms-drawer-size";
|
|
125
|
+
const SIDE_DRAWER_DESKTOP_CONTENT = "lg:w-(--dms-drawer-size)";
|
|
126
|
+
const EDGE_DRAWER_DESKTOP_CONTENT = "lg:h-(--dms-drawer-size)";
|
|
47
127
|
const SIDE_CONTAINER_CLASS = "px-0 sm:px-0 lg:px-0";
|
|
48
128
|
const EDGE_CONTAINER_CLASS = "max-sm:px-0";
|
|
49
129
|
|
|
50
|
-
|
|
130
|
+
// The handle sits on the drawer's inner edge, over its border.
|
|
131
|
+
const HANDLE_CLASSES: Record<ResizeSide, string> = {
|
|
132
|
+
right: "inset-y-0 left-0 w-2 -translate-x-1/2 cursor-ew-resize",
|
|
133
|
+
left: "inset-y-0 right-0 w-2 translate-x-1/2 cursor-ew-resize",
|
|
134
|
+
bottom: "inset-x-0 top-0 h-2 -translate-y-1/2 cursor-ns-resize",
|
|
135
|
+
top: "inset-x-0 bottom-0 h-2 translate-y-1/2 cursor-ns-resize",
|
|
136
|
+
};
|
|
137
|
+
const SIDE_HANDLE_LINE = "inset-y-0 start-1/2 w-0.5 -translate-x-1/2";
|
|
138
|
+
const EDGE_HANDLE_LINE = "inset-x-0 top-1/2 h-0.5 -translate-y-1/2";
|
|
139
|
+
|
|
140
|
+
const isSide = computed(() => isSideDrawer(props.direction));
|
|
51
141
|
const containerClass = computed(() =>
|
|
52
142
|
isSide.value ? SIDE_CONTAINER_CLASS : EDGE_CONTAINER_CLASS,
|
|
53
143
|
);
|
|
144
|
+
|
|
145
|
+
const viewport = useWindowSize();
|
|
146
|
+
const {
|
|
147
|
+
size: resizedSize,
|
|
148
|
+
bounds: sizeBounds,
|
|
149
|
+
isDragging,
|
|
150
|
+
startDrag,
|
|
151
|
+
drag,
|
|
152
|
+
endDrag,
|
|
153
|
+
resizeFromKey,
|
|
154
|
+
reset: resetSize,
|
|
155
|
+
} = useResizableSize({
|
|
156
|
+
side: props.direction,
|
|
157
|
+
bounds: () =>
|
|
158
|
+
resolveDrawerSizeBounds(
|
|
159
|
+
props.direction,
|
|
160
|
+
{ width: viewport.width.value, height: viewport.height.value },
|
|
161
|
+
props.size,
|
|
162
|
+
),
|
|
163
|
+
storage: drawerSizeStorage(
|
|
164
|
+
useDrawerSizePreferences(),
|
|
165
|
+
props.sizeKey,
|
|
166
|
+
props.direction,
|
|
167
|
+
),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const sideContentClass = computed(() => {
|
|
171
|
+
const narrow = props.size
|
|
172
|
+
? SIDE_DRAWER_SIZE_CONTENT[props.size]
|
|
173
|
+
: SIDE_DRAWER_CONTENT;
|
|
174
|
+
return `${narrow} ${SIDE_DRAWER_DESKTOP_CONTENT}`;
|
|
175
|
+
});
|
|
176
|
+
// A top or bottom drawer keeps its natural height until resized.
|
|
177
|
+
const contentClass = computed(() => {
|
|
178
|
+
if (isSide.value) return sideContentClass.value;
|
|
179
|
+
return resizedSize.value === undefined
|
|
180
|
+
? undefined
|
|
181
|
+
: EDGE_DRAWER_DESKTOP_CONTENT;
|
|
182
|
+
});
|
|
183
|
+
// Reka keeps the page's `pointer-events: none` on the body until the
|
|
184
|
+
// panel has slid out (half a second): released as soon as the close starts,
|
|
185
|
+
// a click on the page lands while the drawer animates away.
|
|
186
|
+
const contentProps = computed(() => ({
|
|
187
|
+
disableOutsidePointerEvents: isOpen.value,
|
|
188
|
+
...(resizedSize.value !== undefined && {
|
|
189
|
+
style: { [SIZE_VARIABLE]: `${resizedSize.value}px` },
|
|
190
|
+
}),
|
|
191
|
+
}));
|
|
192
|
+
const handleClass = computed(() => HANDLE_CLASSES[props.direction]);
|
|
193
|
+
const handleLineClass = computed(() =>
|
|
194
|
+
isSide.value ? SIDE_HANDLE_LINE : EDGE_HANDLE_LINE,
|
|
195
|
+
);
|
|
196
|
+
const handleOrientation = computed(() =>
|
|
197
|
+
isSide.value ? "vertical" : "horizontal",
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
function renderedSize(handle: Element): number | undefined {
|
|
201
|
+
const content = handle.closest("[data-slot='content']");
|
|
202
|
+
if (!content) return undefined;
|
|
203
|
+
const rect = content.getBoundingClientRect();
|
|
204
|
+
return isSide.value ? rect.width : rect.height;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// The pointerdown is left to bubble: reka's outside-click detection listens
|
|
208
|
+
// on the document and, if it never saw this press inside the drawer, would
|
|
209
|
+
// take the next click on the backdrop for one inside and ignore it. The
|
|
210
|
+
// drawer's own drag cannot start from it: vaul drags only a dismissible
|
|
211
|
+
// drawer, and this one is not.
|
|
212
|
+
function startHandleDrag(event: PointerEvent): void {
|
|
213
|
+
const handle = event.currentTarget as HTMLElement;
|
|
214
|
+
handle.setPointerCapture?.(event.pointerId);
|
|
215
|
+
const rendered = renderedSize(handle) || resizedSize.value;
|
|
216
|
+
if (rendered) startDrag(event, rendered);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function resizeHandleFromKey(event: KeyboardEvent): void {
|
|
220
|
+
resizeFromKey(event, renderedSize(event.currentTarget as HTMLElement));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// From lg the resize handle takes the inner edge: the drawer's own grip,
|
|
224
|
+
// drawn in its middle, would sit next to it. Below lg a top or bottom
|
|
225
|
+
// drawer keeps it. A side drawer never draws one: it is not dragged away
|
|
226
|
+
// (`dismissible` is off), and the grip took 22px of a phone's gutter.
|
|
227
|
+
// Important: vaul's unlayered `[data-vaul-handle]` rule outranks a utility.
|
|
228
|
+
const DESKTOP_HIDDEN_GRIP = "lg:hidden!";
|
|
229
|
+
|
|
230
|
+
// The body scrolls, not the whole drawer: the header (title, row steps,
|
|
231
|
+
// close) stays in view. The body reaches over the container's side padding
|
|
232
|
+
// so its scrollbar sits on the drawer's edge, and carries the bottom padding
|
|
233
|
+
// a form's sticky footer reaches over to sit flush with it (see Form.vue).
|
|
234
|
+
// The body is a flex column: a body component whose root grows (`flex-1`)
|
|
235
|
+
// fills the drawer's height while its content is short, so a
|
|
236
|
+
// `<DmsContainerFooter>` at its end sits at the bottom, and it scrolls past
|
|
237
|
+
// it while long.
|
|
238
|
+
const DRAWER_CONTAINER_CLASS =
|
|
239
|
+
"[--dms-form-foot-pb:1rem] min-h-0 overflow-y-hidden pb-0";
|
|
240
|
+
const DRAWER_BODY_CLASS =
|
|
241
|
+
"flex min-h-0 flex-col overflow-y-auto -mx-4 px-4 pb-4";
|
|
242
|
+
|
|
54
243
|
const drawerUi = computed(() => ({
|
|
55
|
-
...(
|
|
244
|
+
...(contentClass.value && { content: contentClass.value }),
|
|
245
|
+
overlay: CLOSING_OVERLAY_CLASS,
|
|
246
|
+
handle: DESKTOP_HIDDEN_GRIP,
|
|
56
247
|
header: "border-b border-default flex shrink-0 items-center gap-4 pb-4",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
container: "[--dms-form-foot-pb:1rem]",
|
|
248
|
+
container: DRAWER_CONTAINER_CLASS,
|
|
249
|
+
body: DRAWER_BODY_CLASS,
|
|
60
250
|
}));
|
|
61
251
|
|
|
62
252
|
// Let a DmsForm rendered in the body drop its DmsCard (the drawer is the surface).
|
|
@@ -126,10 +316,41 @@ const { t } = useI18n();
|
|
|
126
316
|
:description="description"
|
|
127
317
|
:title="title"
|
|
128
318
|
:dismissible="false"
|
|
319
|
+
:handle="!isSide"
|
|
129
320
|
:ui="drawerUi"
|
|
321
|
+
:content="contentProps"
|
|
130
322
|
@close:prevent="tryClose"
|
|
131
323
|
>
|
|
132
324
|
<template #header>
|
|
325
|
+
<!-- Positioned against the drawer's content, which is fixed. From lg,
|
|
326
|
+
a drag or the arrow keys resize the drawer, a double-click gives it
|
|
327
|
+
its default size back. -->
|
|
328
|
+
<div
|
|
329
|
+
role="separator"
|
|
330
|
+
tabindex="0"
|
|
331
|
+
data-dms-drawer-handle
|
|
332
|
+
:aria-orientation="handleOrientation"
|
|
333
|
+
:aria-label="t('dms.drawer.resize')"
|
|
334
|
+
:aria-valuenow="resizedSize"
|
|
335
|
+
:aria-valuemin="sizeBounds.minSize"
|
|
336
|
+
:aria-valuemax="sizeBounds.maxSize"
|
|
337
|
+
:data-dragging="isDragging || undefined"
|
|
338
|
+
class="group/handle absolute z-10 hidden touch-none outline-none select-none lg:block"
|
|
339
|
+
:class="handleClass"
|
|
340
|
+
@pointerdown="startHandleDrag"
|
|
341
|
+
@pointermove="drag"
|
|
342
|
+
@pointerup="endDrag"
|
|
343
|
+
@pointercancel="endDrag"
|
|
344
|
+
@lostpointercapture="endDrag"
|
|
345
|
+
@keydown="resizeHandleFromKey"
|
|
346
|
+
@dblclick="resetSize"
|
|
347
|
+
>
|
|
348
|
+
<span
|
|
349
|
+
aria-hidden="true"
|
|
350
|
+
class="group-hover/handle:bg-primary group-focus-visible/handle:bg-primary absolute transition-colors motion-reduce:transition-none"
|
|
351
|
+
:class="[handleLineClass, { 'bg-primary': isDragging }]"
|
|
352
|
+
/>
|
|
353
|
+
</div>
|
|
133
354
|
<!-- Same container as the body so the title aligns with the form. On
|
|
134
355
|
phones the drawer's own padding is the 16px gutter: the container
|
|
135
356
|
drops its own. -->
|
|
@@ -139,8 +360,11 @@ const { t } = useI18n();
|
|
|
139
360
|
>
|
|
140
361
|
<DmsIconWell v-if="icon" :icon="icon" :tone="color" />
|
|
141
362
|
<div v-if="headerComponent" class="min-w-0 flex-1">
|
|
363
|
+
<!-- The header component draws the visible heading (the row
|
|
364
|
+
header's names the row): the dialog's own title only labels it,
|
|
365
|
+
without a second heading of the same text. -->
|
|
142
366
|
<VisuallyHidden>
|
|
143
|
-
<DialogTitle>{{ title }}</DialogTitle>
|
|
367
|
+
<DialogTitle as="span">{{ title }}</DialogTitle>
|
|
144
368
|
<DialogDescription>{{ description }}</DialogDescription>
|
|
145
369
|
</VisuallyHidden>
|
|
146
370
|
<Suspense>
|
|
@@ -170,14 +394,19 @@ const { t } = useI18n();
|
|
|
170
394
|
variant="ghost"
|
|
171
395
|
size="sm"
|
|
172
396
|
square
|
|
173
|
-
aria-label="
|
|
397
|
+
:aria-label="t('dms.a11y.close')"
|
|
174
398
|
:disabled="isContentLoading"
|
|
175
399
|
@click="tryClose"
|
|
176
400
|
/>
|
|
177
401
|
</UContainer>
|
|
178
402
|
</template>
|
|
179
403
|
<template #body>
|
|
180
|
-
|
|
404
|
+
<!-- A size container: what the body lays out by width (a form's
|
|
405
|
+
columns, a list's) follows the drawer as it is resized. -->
|
|
406
|
+
<UContainer
|
|
407
|
+
class="@container flex flex-1 flex-col"
|
|
408
|
+
:class="containerClass"
|
|
409
|
+
>
|
|
181
410
|
<Suspense @pending="onContentPending" @resolve="onContentResolve">
|
|
182
411
|
<component
|
|
183
412
|
:is="component"
|
|
@@ -187,7 +416,7 @@ const { t } = useI18n();
|
|
|
187
416
|
@success="handleSuccess"
|
|
188
417
|
/>
|
|
189
418
|
<template #fallback>
|
|
190
|
-
<div class="
|
|
419
|
+
<div :class="CONTAINER_SKELETON_CLASS" aria-busy="true">
|
|
191
420
|
<div
|
|
192
421
|
v-for="field in CONTAINER_SKELETON_FIELDS"
|
|
193
422
|
:key="field"
|
|
@@ -4,7 +4,11 @@ import { DialogDescription, DialogTitle, VisuallyHidden } from "reka-ui";
|
|
|
4
4
|
import type { ModalSize } from "../../../../types/modal";
|
|
5
5
|
import type { ContainerColor } from "../../../../composables/containers/types";
|
|
6
6
|
import DmsIconWell from "../../../../components/icon-well/IconWell.vue";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
CLOSING_OVERLAY_CLASS,
|
|
9
|
+
CONTAINER_SKELETON_CLASS,
|
|
10
|
+
CONTAINER_SKELETON_FIELDS,
|
|
11
|
+
} from "../constants";
|
|
8
12
|
import { DMS_CONTAINER_KEY } from "../../../composables/containers/context";
|
|
9
13
|
|
|
10
14
|
interface DynamicModalProps {
|
|
@@ -78,6 +82,7 @@ const resolvedSize = computed(() => {
|
|
|
78
82
|
// A divided head: the body below is a form, not a continuation of the title.
|
|
79
83
|
const modalUi = computed(() => ({
|
|
80
84
|
content: SIZE_CONTENT[resolvedSize.value],
|
|
85
|
+
overlay: CLOSING_OVERLAY_CLASS,
|
|
81
86
|
header: "border-b border-default pb-4 shrink-0",
|
|
82
87
|
// The body's bottom and side padding: a form's sticky footer sits flush
|
|
83
88
|
// with the modal's edges (see Form.vue).
|
|
@@ -87,6 +92,11 @@ const modalUi = computed(() => ({
|
|
|
87
92
|
const { executeGuards, clearGuards } = useLeaveGuard();
|
|
88
93
|
|
|
89
94
|
const isOpen = defineModel<boolean>("open", { default: true });
|
|
95
|
+
// Reka keeps the page's `pointer-events: none` on the body until the modal
|
|
96
|
+
// has scaled out: released as soon as the close starts, a click lands.
|
|
97
|
+
const contentProps = computed(() => ({
|
|
98
|
+
disableOutsidePointerEvents: isOpen.value,
|
|
99
|
+
}));
|
|
90
100
|
const isContentLoading = ref(true);
|
|
91
101
|
let closePromise: Promise<void> | null = null;
|
|
92
102
|
|
|
@@ -148,6 +158,7 @@ const { t } = useI18n();
|
|
|
148
158
|
:title="title"
|
|
149
159
|
:dismissible="false"
|
|
150
160
|
:ui="modalUi"
|
|
161
|
+
:content="contentProps"
|
|
151
162
|
@close:prevent="tryClose"
|
|
152
163
|
>
|
|
153
164
|
<template #header>
|
|
@@ -185,37 +196,43 @@ const { t } = useI18n();
|
|
|
185
196
|
variant="ghost"
|
|
186
197
|
size="sm"
|
|
187
198
|
square
|
|
188
|
-
aria-label="
|
|
199
|
+
:aria-label="t('dms.a11y.close')"
|
|
189
200
|
:disabled="isContentLoading"
|
|
190
201
|
@click="tryClose"
|
|
191
202
|
/>
|
|
192
203
|
</div>
|
|
193
204
|
</template>
|
|
194
205
|
<template #body>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
206
|
+
<!-- A size container: the body lays out by the modal's width. -->
|
|
207
|
+
<div class="@container">
|
|
208
|
+
<Suspense @pending="onContentPending" @resolve="onContentResolve">
|
|
209
|
+
<component
|
|
210
|
+
:is="component"
|
|
211
|
+
:key="componentKey"
|
|
212
|
+
v-bind="componentOptions"
|
|
213
|
+
:container-id="containerId"
|
|
214
|
+
@success="handleSuccess"
|
|
215
|
+
/>
|
|
216
|
+
<template #fallback>
|
|
217
|
+
<div :class="CONTAINER_SKELETON_CLASS" aria-busy="true">
|
|
218
|
+
<div
|
|
219
|
+
v-for="field in CONTAINER_SKELETON_FIELDS"
|
|
220
|
+
:key="field"
|
|
221
|
+
class="flex flex-col gap-2"
|
|
222
|
+
>
|
|
223
|
+
<USkeleton
|
|
224
|
+
:aria-label="t('dms.a11y.loading')"
|
|
225
|
+
class="h-3 w-24"
|
|
226
|
+
/>
|
|
227
|
+
<USkeleton
|
|
228
|
+
:aria-label="t('dms.a11y.loading')"
|
|
229
|
+
class="h-8 w-full"
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
215
232
|
</div>
|
|
216
|
-
</
|
|
217
|
-
</
|
|
218
|
-
</
|
|
233
|
+
</template>
|
|
234
|
+
</Suspense>
|
|
235
|
+
</div>
|
|
219
236
|
</template>
|
|
220
237
|
</UModal>
|
|
221
238
|
</template>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The header the DMS draws over a row opened in a side panel or a drawer:
|
|
4
|
+
* the title (naming the row when the target words it), the row's position
|
|
5
|
+
* among the rows the table shows, and previous / next (J and K too). The
|
|
6
|
+
* container adds its close button in the default slot. A long title wraps
|
|
7
|
+
* onto two lines before it is cut (a ticket subject, a site name on a phone).
|
|
8
|
+
*/
|
|
9
|
+
import { computed } from "vue";
|
|
10
|
+
import type { Component } from "vue";
|
|
11
|
+
import type { RowNavigation } from "../../../../types/row-navigation";
|
|
12
|
+
|
|
13
|
+
interface RowHeaderProps {
|
|
14
|
+
heading?: string;
|
|
15
|
+
/** i18n key (`$`-prefixed) of the position, receiving `{ index, total }`. */
|
|
16
|
+
positionLabel?: string;
|
|
17
|
+
navigation?: RowNavigation;
|
|
18
|
+
/** Prefix of the `data-*` attributes tests and styles find the parts by. */
|
|
19
|
+
part: string;
|
|
20
|
+
headingClass?: string;
|
|
21
|
+
/** Wraps the title only after this separator (`<wbr>` after each one). */
|
|
22
|
+
headingBreakAfter?: string;
|
|
23
|
+
/** Text after the position, on its line, cut at its end. */
|
|
24
|
+
subtitle?: string;
|
|
25
|
+
subtitleClass?: string;
|
|
26
|
+
/** Drawn under the position line (pills, hints). */
|
|
27
|
+
component?: Component;
|
|
28
|
+
componentOptions?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<RowHeaderProps>(), {
|
|
32
|
+
heading: undefined,
|
|
33
|
+
positionLabel: undefined,
|
|
34
|
+
navigation: undefined,
|
|
35
|
+
headingClass: "text-[15px] leading-[1.3] font-[650] tracking-[-0.015em]",
|
|
36
|
+
headingBreakAfter: undefined,
|
|
37
|
+
subtitle: undefined,
|
|
38
|
+
subtitleClass: undefined,
|
|
39
|
+
component: undefined,
|
|
40
|
+
componentOptions: undefined,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const DEFAULT_POSITION_KEY = "side_panel.position";
|
|
44
|
+
|
|
45
|
+
const { t, locale } = useI18n();
|
|
46
|
+
const { processI18n } = useTranslation();
|
|
47
|
+
|
|
48
|
+
// "26 120", not "26120": the figures take the locale's grouping.
|
|
49
|
+
const numberFormat = computed(() => new Intl.NumberFormat(locale.value));
|
|
50
|
+
|
|
51
|
+
const position = computed(() => {
|
|
52
|
+
if (!props.navigation) return undefined;
|
|
53
|
+
const params = {
|
|
54
|
+
index: numberFormat.value.format(props.navigation.index + 1),
|
|
55
|
+
total: numberFormat.value.format(props.navigation.total),
|
|
56
|
+
};
|
|
57
|
+
return props.positionLabel
|
|
58
|
+
? processI18n(props.positionLabel, params)
|
|
59
|
+
: t(DEFAULT_POSITION_KEY, params);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Each segment but the last keeps the separator that follows it.
|
|
63
|
+
const headingSegments = computed(() => {
|
|
64
|
+
const separator = props.headingBreakAfter;
|
|
65
|
+
if (!props.heading || !separator) return undefined;
|
|
66
|
+
const parts = props.heading.split(separator);
|
|
67
|
+
return parts.map((part, index) =>
|
|
68
|
+
index < parts.length - 1 ? `${part}${separator}` : part,
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const partAttribute = (name: string) => ({
|
|
73
|
+
[`data-${props.part}-${name}`]: "",
|
|
74
|
+
});
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<div class="flex min-w-0 flex-1 items-start gap-2">
|
|
79
|
+
<div
|
|
80
|
+
class="min-w-0 flex-1"
|
|
81
|
+
:class="component ? 'space-y-1.5' : 'self-center'"
|
|
82
|
+
>
|
|
83
|
+
<div>
|
|
84
|
+
<h2
|
|
85
|
+
class="text-highlighted line-clamp-2 [overflow-wrap:anywhere]"
|
|
86
|
+
:class="headingClass"
|
|
87
|
+
:title="heading"
|
|
88
|
+
>
|
|
89
|
+
<template v-if="headingSegments">
|
|
90
|
+
<template v-for="(segment, index) in headingSegments" :key="index">
|
|
91
|
+
<span>{{ segment }}</span>
|
|
92
|
+
<wbr />
|
|
93
|
+
</template>
|
|
94
|
+
</template>
|
|
95
|
+
<template v-else>{{ heading }}</template>
|
|
96
|
+
</h2>
|
|
97
|
+
<p
|
|
98
|
+
v-if="position || subtitle"
|
|
99
|
+
class="text-muted mt-0.5 text-[12.5px]"
|
|
100
|
+
:class="
|
|
101
|
+
subtitle ? 'flex min-w-0 items-baseline gap-x-1.5' : 'tabular-nums'
|
|
102
|
+
"
|
|
103
|
+
>
|
|
104
|
+
<span
|
|
105
|
+
v-if="position"
|
|
106
|
+
v-bind="partAttribute('position')"
|
|
107
|
+
:class="subtitle && 'shrink-0 tabular-nums'"
|
|
108
|
+
>
|
|
109
|
+
{{ position }}
|
|
110
|
+
</span>
|
|
111
|
+
<span v-if="position && subtitle" aria-hidden="true">·</span>
|
|
112
|
+
<span
|
|
113
|
+
v-if="subtitle"
|
|
114
|
+
v-bind="partAttribute('subtitle')"
|
|
115
|
+
class="min-w-0 truncate"
|
|
116
|
+
:class="subtitleClass"
|
|
117
|
+
:title="subtitle"
|
|
118
|
+
>
|
|
119
|
+
{{ subtitle }}
|
|
120
|
+
</span>
|
|
121
|
+
</p>
|
|
122
|
+
</div>
|
|
123
|
+
<component :is="component" v-if="component" v-bind="componentOptions" />
|
|
124
|
+
</div>
|
|
125
|
+
<div class="flex shrink-0 items-center gap-0.5">
|
|
126
|
+
<template v-if="navigation">
|
|
127
|
+
<UButton
|
|
128
|
+
v-bind="partAttribute('prev')"
|
|
129
|
+
icon="i-ph-caret-up"
|
|
130
|
+
color="neutral"
|
|
131
|
+
variant="ghost"
|
|
132
|
+
size="sm"
|
|
133
|
+
square
|
|
134
|
+
:aria-label="t('side_panel.previous')"
|
|
135
|
+
:disabled="!navigation.hasPrev"
|
|
136
|
+
@click="navigation.prev()"
|
|
137
|
+
/>
|
|
138
|
+
<UButton
|
|
139
|
+
v-bind="partAttribute('next')"
|
|
140
|
+
icon="i-ph-caret-down"
|
|
141
|
+
color="neutral"
|
|
142
|
+
variant="ghost"
|
|
143
|
+
size="sm"
|
|
144
|
+
square
|
|
145
|
+
:aria-label="t('side_panel.next')"
|
|
146
|
+
:disabled="!navigation.hasNext"
|
|
147
|
+
@click="navigation.next()"
|
|
148
|
+
/>
|
|
149
|
+
</template>
|
|
150
|
+
<slot />
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</template>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* What a side panel or a drawer opened on a row shows in place of its
|
|
4
|
+
* component when the row its link names is gone (a 404): the state, and a
|
|
5
|
+
* close button.
|
|
6
|
+
*/
|
|
7
|
+
import { computed } from "vue";
|
|
8
|
+
import DmsEmptyState from "../../../../components/empty-state/EmptyState.vue";
|
|
9
|
+
|
|
10
|
+
interface RowNotFoundProps {
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface RowNotFoundEmits {
|
|
16
|
+
(e: "close"): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
defineProps<RowNotFoundProps>();
|
|
20
|
+
const emit = defineEmits<RowNotFoundEmits>();
|
|
21
|
+
|
|
22
|
+
const { t } = useI18n();
|
|
23
|
+
|
|
24
|
+
const actions = computed(() => [
|
|
25
|
+
{
|
|
26
|
+
label: t("side_panel.close"),
|
|
27
|
+
icon: "i-ph-x",
|
|
28
|
+
color: "neutral" as const,
|
|
29
|
+
variant: "outline" as const,
|
|
30
|
+
onClick: () => emit("close"),
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<DmsEmptyState
|
|
37
|
+
data-dms-row-not-found
|
|
38
|
+
variant="no-result"
|
|
39
|
+
:title="title"
|
|
40
|
+
:description="description"
|
|
41
|
+
:actions="actions"
|
|
42
|
+
class="py-10"
|
|
43
|
+
/>
|
|
44
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { markRaw } from "vue";
|
|
2
|
+
import type { DrawerRowHeader } from "../../../../composables/containers/types";
|
|
3
|
+
|
|
4
|
+
// The drawer's header title, as `DynamicDrawer` draws its own.
|
|
5
|
+
const DRAWER_ROW_HEADING_CLASS =
|
|
6
|
+
"text-[17px] leading-[1.3] font-[650] tracking-[-0.02em]";
|
|
7
|
+
// The `data-dms-row-drawer-*` hooks tests and styles find the parts by.
|
|
8
|
+
const DRAWER_ROW_HEADER_PART = "dms-row-drawer";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The props of `RowHeader` over a drawer: a row action's drawer and one a
|
|
12
|
+
* module opens with `useDrawer({ rowHeader })` draw the same header.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function drawerRowHeaderProps(
|
|
17
|
+
header: DrawerRowHeader,
|
|
18
|
+
title: string,
|
|
19
|
+
): Record<string, unknown> {
|
|
20
|
+
return {
|
|
21
|
+
part: DRAWER_ROW_HEADER_PART,
|
|
22
|
+
heading: header.title ?? title,
|
|
23
|
+
positionLabel: header.positionLabel,
|
|
24
|
+
navigation: header.navigation,
|
|
25
|
+
headingClass: header.titleClass
|
|
26
|
+
? `${DRAWER_ROW_HEADING_CLASS} ${header.titleClass}`
|
|
27
|
+
: DRAWER_ROW_HEADING_CLASS,
|
|
28
|
+
headingBreakAfter: header.titleBreakAfter,
|
|
29
|
+
subtitle: header.subtitle,
|
|
30
|
+
subtitleClass: header.subtitleClass,
|
|
31
|
+
// Kept out of the overlay's reactive props, as the body component is.
|
|
32
|
+
component: header.component && markRaw(header.component),
|
|
33
|
+
componentOptions: header.componentOptions,
|
|
34
|
+
};
|
|
35
|
+
}
|