@antelopejs/dms 0.6.1 → 0.7.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 +39 -0
- package/dist/db/models/notification-feed-filter.d.ts +0 -1
- package/dist/db/models/notification-feed-filter.js +0 -4
- package/dist/db/models/notification-feed-filter.js.map +1 -1
- package/dist/db/models/signInAttempts.model.d.ts +18 -0
- package/dist/db/models/signInAttempts.model.js +83 -12
- package/dist/db/models/signInAttempts.model.js.map +1 -1
- package/dist/db/models/userEmailChanges.model.d.ts +8 -1
- package/dist/db/models/userEmailChanges.model.js +27 -2
- package/dist/db/models/userEmailChanges.model.js.map +1 -1
- package/dist/db/models/userNotificationPreferences.model.d.ts +0 -2
- package/dist/db/models/userNotificationPreferences.model.js +0 -13
- package/dist/db/models/userNotificationPreferences.model.js.map +1 -1
- package/dist/db/models/userNotifications.model.d.ts +5 -2
- package/dist/db/models/userNotifications.model.js +19 -2
- package/dist/db/models/userNotifications.model.js.map +1 -1
- package/dist/db/tables/signInAttempts.table.d.ts +2 -1
- package/dist/db/tables/signInAttempts.table.js +4 -0
- package/dist/db/tables/signInAttempts.table.js.map +1 -1
- package/dist/db/tables/userEmailChanges.table.d.ts +2 -1
- package/dist/db/tables/userEmailChanges.table.js +6 -1
- package/dist/db/tables/userEmailChanges.table.js.map +1 -1
- package/dist/db/tables/userNotificationPreferences.table.d.ts +0 -1
- package/dist/db/tables/userNotificationPreferences.table.js +0 -4
- package/dist/db/tables/userNotificationPreferences.table.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +4 -1
- package/dist/implementations/dms/layout-banners.js +33 -18
- package/dist/implementations/dms/layout-banners.js.map +1 -1
- package/dist/implementations/dms/nav-badges.d.ts +6 -4
- package/dist/implementations/dms/nav-badges.js +6 -5
- package/dist/implementations/dms/nav-badges.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +1 -0
- package/dist/implementations/dms/page.js +46 -8
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/permission-preview.d.ts +1 -1
- package/dist/implementations/dms/permission-preview.js +9 -4
- package/dist/implementations/dms/permission-preview.js.map +1 -1
- package/dist/implementations/dms-auth/index.d.ts +3 -2
- package/dist/implementations/dms-auth/index.js +39 -35
- package/dist/implementations/dms-auth/index.js.map +1 -1
- package/dist/implementations/dms-auth/token-session.d.ts +3 -0
- package/dist/implementations/dms-auth/token-session.js +22 -0
- package/dist/implementations/dms-auth/token-session.js.map +1 -0
- package/dist/implementations/dms-notifications/index.d.ts +0 -1
- package/dist/implementations/dms-notifications/index.js +0 -7
- package/dist/implementations/dms-notifications/index.js.map +1 -1
- package/dist/pages/settings/settings-index.js +3 -2
- package/dist/pages/settings/settings-index.js.map +1 -1
- package/dist/pages/settings/users/account-activity-feed.d.ts +1 -1
- package/dist/pages/settings/users/account-activity-feed.js +1 -1
- package/dist/pages/settings/users/account-activity-feed.js.map +1 -1
- package/dist/pages/settings/users/account-activity.d.ts +1 -1
- package/dist/pages/settings/users/account-activity.js +1 -1
- package/dist/pages/settings/users/account-activity.js.map +1 -1
- package/dist/pages/settings/users/account-credentials.d.ts +3 -0
- package/dist/pages/settings/users/account-credentials.js +2 -0
- package/dist/pages/settings/users/account-credentials.js.map +1 -1
- package/dist/pages/settings/users/current-password.d.ts +1 -1
- package/dist/pages/settings/users/current-password.js +23 -2
- package/dist/pages/settings/users/current-password.js.map +1 -1
- package/dist/pages/settings/users/email-change.d.ts +1 -1
- package/dist/pages/settings/users/email-change.js +33 -26
- package/dist/pages/settings/users/email-change.js.map +1 -1
- package/dist/pages/settings/users/invite-resend.js +0 -1
- package/dist/pages/settings/users/invite-resend.js.map +1 -1
- package/dist/pages/settings/users/invites.d.ts +1 -2
- package/dist/pages/settings/users/invites.js +21 -19
- package/dist/pages/settings/users/invites.js.map +1 -1
- package/dist/pages/settings/users/member-invite-batch.js +0 -1
- package/dist/pages/settings/users/member-invite-batch.js.map +1 -1
- package/dist/pages/settings/users/member-invite-form.js +10 -22
- package/dist/pages/settings/users/member-invite-form.js.map +1 -1
- package/dist/pages/settings/users/member-role-options.d.ts +6 -4
- package/dist/pages/settings/users/member-role-options.js +15 -4
- package/dist/pages/settings/users/member-role-options.js.map +1 -1
- package/dist/pages/settings/users/members.d.ts +2 -3
- package/dist/pages/settings/users/members.js +7 -12
- package/dist/pages/settings/users/members.js.map +1 -1
- package/dist/pages/settings/users/notifications.d.ts +1 -8
- package/dist/pages/settings/users/notifications.js +6 -38
- package/dist/pages/settings/users/notifications.js.map +1 -1
- package/dist/pages/settings/users/permission-tree-nodes.d.ts +1 -1
- package/dist/pages/settings/users/permission-tree-nodes.js +23 -9
- package/dist/pages/settings/users/permission-tree-nodes.js.map +1 -1
- package/dist/pages/settings/users/permission-warnings.d.ts +7 -0
- package/dist/pages/settings/users/permission-warnings.js +42 -0
- package/dist/pages/settings/users/permission-warnings.js.map +1 -0
- package/dist/pages/settings/users/profile-helpers.d.ts +1 -3
- package/dist/pages/settings/users/profile-helpers.js +0 -16
- package/dist/pages/settings/users/profile-helpers.js.map +1 -1
- package/dist/pages/settings/users/role-editor-store.js +6 -3
- package/dist/pages/settings/users/role-editor-store.js.map +1 -1
- package/dist/pages/settings/users/role-editor.d.ts +2 -1
- package/dist/pages/settings/users/role-editor.js +8 -4
- package/dist/pages/settings/users/role-editor.js.map +1 -1
- package/dist/pages/settings/users/role-preview.js +2 -1
- package/dist/pages/settings/users/role-preview.js.map +1 -1
- package/dist/pages/settings/users/roles.js +5 -1
- package/dist/pages/settings/users/roles.js.map +1 -1
- package/dist/pages/settings/users/security-attention.d.ts +4 -0
- package/dist/pages/settings/users/security-attention.js +23 -7
- package/dist/pages/settings/users/security-attention.js.map +1 -1
- package/dist/pages/settings/users/security.d.ts +2 -1
- package/dist/pages/settings/users/security.js +13 -2
- package/dist/pages/settings/users/security.js.map +1 -1
- package/dist/pages/settings/users/two-factor-operations.d.ts +2 -1
- package/dist/pages/settings/users/two-factor-operations.js +28 -29
- package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
- package/dist/routes/auth/forgot-password.js +3 -0
- package/dist/routes/auth/forgot-password.js.map +1 -1
- package/dist/routes/auth/index.d.ts +1 -0
- package/dist/routes/auth/index.js +1 -0
- package/dist/routes/auth/index.js.map +1 -1
- package/dist/routes/auth/invite.js +28 -4
- package/dist/routes/auth/invite.js.map +1 -1
- package/dist/routes/auth/login-throttle.d.ts +2 -0
- package/dist/routes/auth/login-throttle.js +5 -4
- package/dist/routes/auth/login-throttle.js.map +1 -1
- package/dist/routes/auth/request-2fa-email.js +6 -18
- package/dist/routes/auth/request-2fa-email.js.map +1 -1
- package/dist/routes/auth/reset-code.d.ts +3 -0
- package/dist/routes/auth/reset-code.js +37 -0
- package/dist/routes/auth/reset-code.js.map +1 -0
- package/dist/routes/auth/reset-password.d.ts +2 -2
- package/dist/routes/auth/reset-password.js +5 -10
- package/dist/routes/auth/reset-password.js.map +1 -1
- package/dist/routes/auth/signup.js +10 -32
- package/dist/routes/auth/signup.js.map +1 -1
- package/dist/routes/auth/two-factor-throttle.d.ts +5 -0
- package/dist/routes/auth/two-factor-throttle.js +81 -0
- package/dist/routes/auth/two-factor-throttle.js.map +1 -0
- package/dist/routes/auth/validate-forgot-password-token.js +2 -8
- package/dist/routes/auth/validate-forgot-password-token.js.map +1 -1
- package/dist/routes/auth/validate-invite-token.d.ts +1 -0
- package/dist/routes/auth/validate-invite-token.js +11 -0
- package/dist/routes/auth/validate-invite-token.js.map +1 -0
- package/dist/routes/auth/verify-2fa.js +10 -13
- package/dist/routes/auth/verify-2fa.js.map +1 -1
- package/dist/routes/auth.d.ts +1 -0
- package/dist/routes/auth.js +11 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/test/helpers/auth.d.ts +0 -1
- package/dist/test/helpers/auth.js +0 -1
- package/dist/test/helpers/auth.js.map +1 -1
- package/dist/test/helpers/emails.d.ts +10 -0
- package/dist/test/helpers/emails.js +36 -0
- package/dist/test/helpers/emails.js.map +1 -0
- package/dist/test/helpers/fixtures.d.ts +0 -1
- package/dist/test/helpers/fixtures.js +1 -2
- package/dist/test/helpers/fixtures.js.map +1 -1
- package/dist/test/helpers/page-access.d.ts +1 -0
- package/dist/test/helpers/page-access.js +6 -1
- package/dist/test/helpers/page-access.js.map +1 -1
- package/dist/test/integration/auth/current-password.test.d.ts +1 -0
- package/dist/test/integration/auth/current-password.test.js +65 -0
- package/dist/test/integration/auth/current-password.test.js.map +1 -0
- package/dist/test/integration/auth/password-reset.test.d.ts +1 -0
- package/dist/test/integration/auth/password-reset.test.js +126 -0
- package/dist/test/integration/auth/password-reset.test.js.map +1 -0
- package/dist/test/integration/auth/session-revocation.test.d.ts +1 -0
- package/dist/test/integration/auth/session-revocation.test.js +45 -0
- package/dist/test/integration/auth/session-revocation.test.js.map +1 -0
- package/dist/test/integration/auth/two-factor-codes.test.d.ts +1 -0
- package/dist/test/integration/auth/two-factor-codes.test.js +335 -0
- package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -0
- package/dist/test/integration/auth/two-factor-password.test.js +5 -1
- package/dist/test/integration/auth/two-factor-password.test.js.map +1 -1
- package/dist/test/integration/auth/two-factor-token.test.d.ts +1 -0
- package/dist/test/integration/auth/two-factor-token.test.js +92 -0
- package/dist/test/integration/auth/two-factor-token.test.js.map +1 -0
- package/dist/test/integration/email-change.test.js +36 -0
- package/dist/test/integration/email-change.test.js.map +1 -1
- package/dist/test/integration/invite-extension-edit.test.js +0 -1
- package/dist/test/integration/invite-extension-edit.test.js.map +1 -1
- package/dist/test/integration/invite-link-status.test.d.ts +1 -0
- package/dist/test/integration/invite-link-status.test.js +110 -0
- package/dist/test/integration/invite-link-status.test.js.map +1 -0
- package/dist/test/integration/invite-resolution.test.js +0 -3
- package/dist/test/integration/invite-resolution.test.js.map +1 -1
- package/dist/test/integration/member-settings-access.test.js +17 -0
- package/dist/test/integration/member-settings-access.test.js.map +1 -1
- package/dist/test/integration/notification-unread-badge.test.d.ts +1 -0
- package/dist/test/integration/notification-unread-badge.test.js +92 -0
- package/dist/test/integration/notification-unread-badge.test.js.map +1 -0
- package/dist/test/integration/permission-warnings.test.d.ts +1 -0
- package/dist/test/integration/permission-warnings.test.js +71 -0
- package/dist/test/integration/permission-warnings.test.js.map +1 -0
- package/dist/test/integration/removed-member-notifications.test.d.ts +1 -0
- package/dist/test/integration/removed-member-notifications.test.js +80 -0
- package/dist/test/integration/removed-member-notifications.test.js.map +1 -0
- package/dist/test/integration/role-permission-ancestors.test.d.ts +1 -0
- package/dist/test/integration/role-permission-ancestors.test.js +146 -0
- package/dist/test/integration/role-permission-ancestors.test.js.map +1 -0
- package/dist/test/integration/tenant-lifecycle.test.js +0 -4
- package/dist/test/integration/tenant-lifecycle.test.js.map +1 -1
- package/dist/test/unit/auth-session-revocation.test.d.ts +1 -0
- package/dist/test/unit/auth-session-revocation.test.js +105 -0
- package/dist/test/unit/auth-session-revocation.test.js.map +1 -0
- package/dist/test/unit/db/email-normalization.test.js +0 -1
- package/dist/test/unit/db/email-normalization.test.js.map +1 -1
- package/dist/test/unit/db/notification-feed-filter.test.js +0 -16
- package/dist/test/unit/db/notification-feed-filter.test.js.map +1 -1
- package/dist/test/unit/db/notification-inbox.test.js +63 -13
- package/dist/test/unit/db/notification-inbox.test.js.map +1 -1
- package/dist/test/unit/db/notification-preferences.test.js +0 -17
- package/dist/test/unit/db/notification-preferences.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/empty-menu-group.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/empty-menu-group.test.js +133 -0
- package/dist/test/unit/implementations/dms/empty-menu-group.test.js.map +1 -0
- package/dist/test/unit/implementations/dms/layout-banners.test.js +78 -1
- package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js +149 -0
- package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js.map +1 -0
- package/dist/test/unit/implementations/dms/nav-badges.test.js +55 -4
- package/dist/test/unit/implementations/dms/nav-badges.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/page-all-components-hidden.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js +118 -0
- package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js.map +1 -0
- package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js +16 -0
- package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/permission-preview-cost.test.js +5 -3
- package/dist/test/unit/implementations/dms/permission-preview-cost.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/permission-preview-menu.test.js +29 -3
- package/dist/test/unit/implementations/dms/permission-preview-menu.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/quick-actions-button.test.js +4 -2
- package/dist/test/unit/implementations/dms/quick-actions-button.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/user-permissions-gate.test.js +2 -1
- package/dist/test/unit/implementations/dms/user-permissions-gate.test.js.map +1 -1
- package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js +2 -1
- package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/component-children-permissions.test.js +7 -2
- package/dist/test/unit/interfaces/dms/component-children-permissions.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/form-watch-permissions.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js +133 -0
- package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js +149 -0
- package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/invite-extension.test.js +13 -0
- package/dist/test/unit/interfaces/dms/invite-extension.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/member-access.test.js +27 -1
- package/dist/test/unit/interfaces/dms/member-access.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/nav-badge-tones.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js +31 -0
- package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/page-extension.test.js +4 -1
- package/dist/test/unit/interfaces/dms/page-extension.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/permission-requirements.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/permission-requirements.test.js +144 -0
- package/dist/test/unit/interfaces/dms/permission-requirements.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms-base/column-display.test.js +70 -0
- package/dist/test/unit/interfaces/dms-base/column-display.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/display-blocks-catalog.test.js +38 -0
- package/dist/test/unit/interfaces/dms-base/display-blocks-catalog.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js +6 -2
- package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js +1 -1
- package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js +2 -1
- package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js +2 -1
- package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js +2 -1
- package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js.map +1 -1
- package/dist/test/unit/pages/settings/account-activity-feed.test.js +2 -2
- package/dist/test/unit/pages/settings/account-activity-feed.test.js.map +1 -1
- package/dist/test/unit/pages/settings/account-activity.test.js +11 -2
- package/dist/test/unit/pages/settings/account-activity.test.js.map +1 -1
- package/dist/test/unit/pages/settings/invite-email-delivery.test.js +0 -1
- package/dist/test/unit/pages/settings/invite-email-delivery.test.js.map +1 -1
- package/dist/test/unit/pages/settings/invite-email-validation-option.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/invite-email-validation-option.test.js +33 -0
- package/dist/test/unit/pages/settings/invite-email-validation-option.test.js.map +1 -0
- package/dist/test/unit/pages/settings/member-lists-page-size.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/member-lists-page-size.test.js +22 -0
- package/dist/test/unit/pages/settings/member-lists-page-size.test.js.map +1 -0
- package/dist/test/unit/pages/settings/member-table-widths.test.js +2 -2
- package/dist/test/unit/pages/settings/member-table-widths.test.js.map +1 -1
- package/dist/test/unit/pages/settings/members-page.test.js +7 -10
- package/dist/test/unit/pages/settings/members-page.test.js.map +1 -1
- package/dist/test/unit/pages/settings/notifications-access-gate.test.js +3 -10
- package/dist/test/unit/pages/settings/notifications-access-gate.test.js.map +1 -1
- package/dist/test/unit/pages/settings/permission-tree-nodes.test.js +57 -0
- package/dist/test/unit/pages/settings/permission-tree-nodes.test.js.map +1 -1
- package/dist/test/unit/pages/settings/permission-warnings.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/permission-warnings.test.js +49 -0
- package/dist/test/unit/pages/settings/permission-warnings.test.js.map +1 -0
- package/dist/test/unit/pages/settings/role-editor.test.js +16 -0
- package/dist/test/unit/pages/settings/role-editor.test.js.map +1 -1
- package/dist/test/unit/pages/settings/role-preview.test.js +7 -0
- package/dist/test/unit/pages/settings/role-preview.test.js.map +1 -1
- package/dist/test/unit/pages/settings/security-attention.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/security-attention.test.js +74 -0
- package/dist/test/unit/pages/settings/security-attention.test.js.map +1 -0
- package/dist/test/unit/sanitize-user.test.d.ts +1 -0
- package/dist/test/unit/sanitize-user.test.js +21 -0
- package/dist/test/unit/sanitize-user.test.js.map +1 -0
- package/dist/test/unit/signup-email-validation.test.d.ts +1 -0
- package/dist/test/unit/signup-email-validation.test.js +79 -0
- package/dist/test/unit/signup-email-validation.test.js.map +1 -0
- package/dist/test/unit/validation/member-invite.schema.test.js +14 -52
- package/dist/test/unit/validation/member-invite.schema.test.js.map +1 -1
- package/dist/utils/account-notifications.d.ts +5 -0
- package/dist/utils/account-notifications.js +8 -0
- package/dist/utils/account-notifications.js.map +1 -1
- package/dist/utils/notification-emitter.d.ts +1 -1
- package/dist/utils/notification-emitter.js +1 -1
- package/dist/utils/notification-emitter.js.map +1 -1
- package/dist/utils/notification-tones.d.ts +2 -1
- package/dist/utils/notification-tones.js +5 -1
- package/dist/utils/notification-tones.js.map +1 -1
- package/dist/utils/one-time-code.d.ts +3 -0
- package/dist/utils/one-time-code.js +21 -0
- package/dist/utils/one-time-code.js.map +1 -0
- package/dist/utils/sign-in-monitor.d.ts +1 -0
- package/dist/utils/sign-in-monitor.js +3 -2
- package/dist/utils/sign-in-monitor.js.map +1 -1
- package/dist/utils/two-factor-codes.d.ts +10 -0
- package/dist/utils/two-factor-codes.js +76 -0
- package/dist/utils/two-factor-codes.js.map +1 -0
- package/dist/validation/auth.schema.d.ts +17 -0
- package/dist/validation/auth.schema.js +17 -6
- package/dist/validation/auth.schema.js.map +1 -1
- package/dist/validation/issue-message.d.ts +1 -0
- package/dist/validation/issue-message.js +9 -0
- package/dist/validation/issue-message.js.map +1 -0
- package/dist/validation/member-invite.schema.d.ts +1 -25
- package/dist/validation/member-invite.schema.js +2 -23
- package/dist/validation/member-invite.schema.js.map +1 -1
- package/frontend-vue/dms.frontend.ts +2 -0
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/forgot-validation.vue +3 -0
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +105 -5
- package/frontend-vue/layers/dms-auth/i18n/locales/auth-en-GB.json +20 -4
- package/frontend-vue/layers/dms-auth/i18n/locales/auth-fr-FR.json +20 -4
- package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +25 -0
- package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +3 -2
- package/frontend-vue/layers/dms-core/app/types/composed-text.ts +64 -0
- package/frontend-vue/layers/dms-core/app/types/menu.ts +15 -0
- package/frontend-vue/layers/dms-core/app/utils/composedText.ts +227 -0
- package/frontend-vue/layers/dms-core/app/utils/formatter.ts +49 -0
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +4 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +4 -1
- package/frontend-vue/layers/dms-layout/app/assets/css/main.css +20 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/CommandPaletteAssistantAnswer.vue +75 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +17 -3
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardFrame.vue +22 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +24 -10
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidePanel.vue +139 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +4 -2
- package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +90 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/SidePanelHost.vue +17 -0
- package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +25 -43
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/members/MemberRolePicker.vue +24 -2
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationMatrixCategory.vue +70 -25
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationPreferencesForm.vue +25 -10
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/notificationDisplay.ts +41 -5
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfilePreferencesSummary.vue +2 -1
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfileSecuritySummary.vue +20 -4
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RoleEditor.vue +21 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionArea.vue +16 -2
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionBranch.vue +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionLeaf.vue +13 -1
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionTree.vue +9 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionWarning.vue +46 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +108 -29
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-types.ts +2 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityDialogFrame.vue +6 -6
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityEmail.vue +7 -1
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecuritySessions.vue +5 -4
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityStatus.vue +4 -3
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityTwoFactor.vue +54 -18
- package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/shell/SettingsNav.vue +13 -8
- package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/assistantGroups.ts +143 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/useCommandPaletteAssistantMode.ts +249 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/general/useGithubStarPrompt.ts +178 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/sidePanelState.ts +191 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useHeaderActionControls.ts +51 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +113 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/navigation/useCategoryNavCards.ts +17 -10
- package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +45 -0
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfilePreferences.ts +8 -1
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityOverview.ts +50 -3
- package/frontend-vue/layers/dms-layout/app/build/composables/settings/useSettingsNavigation.ts +3 -0
- package/frontend-vue/layers/dms-layout/app/build/utils/categoryPages.ts +1 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +5 -0
- package/frontend-vue/layers/dms-layout/app/components/layout/DashboardSearch.vue +109 -7
- package/frontend-vue/layers/dms-layout/app/components/navigation/NavigationMenu.vue +19 -9
- package/frontend-vue/layers/dms-layout/app/composables/notification/useNotifications.ts +22 -40
- package/frontend-vue/layers/dms-layout/app/composables/useAppSidePanels.ts +96 -0
- package/frontend-vue/layers/dms-layout/app/composables/useCommandPaletteAssistant.ts +129 -0
- package/frontend-vue/layers/dms-layout/app/composables/useHeaderActions.ts +33 -11
- package/frontend-vue/layers/dms-layout/app/composables/useSidePanel.ts +41 -0
- package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +15 -0
- package/frontend-vue/layers/dms-layout/app/plugins/notification-stream.client.ts +1 -7
- package/frontend-vue/layers/dms-layout/app/plugins/side-panel-host.ts +13 -0
- package/frontend-vue/layers/dms-layout/app/types/page.ts +11 -1
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +43 -13
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +43 -13
- package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +45 -0
- package/frontend-vue/layers/dms-ui/app/build/components/modal/ModalEscHint.vue +28 -0
- package/frontend-vue/layers/dms-ui/app/build/components/table-view/IdentityCell.vue +36 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/cellHelpers.ts +57 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +19 -5
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +22 -2
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +118 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +5 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/form/floatingSaveBars.ts +38 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +66 -0
- package/frontend-vue/layers/dms-ui/app/build/composables/navigation/useNavBadges.ts +50 -9
- package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +7 -1
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/chrome.ts +2 -2
- package/frontend-vue/layers/dms-ui/app/build/types/tree.ts +14 -10
- package/frontend-vue/layers/dms-ui/app/build/utils/navBadge.ts +12 -0
- package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +4 -35
- package/frontend-vue/layers/dms-ui/app/build/utils/tone.ts +22 -0
- package/frontend-vue/layers/dms-ui/app/components/activity-feed/ActivityFeed.vue +117 -82
- package/frontend-vue/layers/dms-ui/app/components/blocks/BannerBlock.vue +8 -5
- package/frontend-vue/layers/dms-ui/app/components/blocks/KeyValueListBlock.vue +38 -18
- package/frontend-vue/layers/dms-ui/app/components/blocks/NavCardGridBlock.vue +12 -1
- package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +26 -23
- package/frontend-vue/layers/dms-ui/app/components/card/NavCard.vue +16 -1
- package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +7 -8
- package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +28 -6
- package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +4 -0
- package/frontend-vue/layers/dms-ui/app/components/status-pill/StatusPill.vue +7 -2
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +7 -2
- package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +48 -34
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +13 -3
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -14
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -14
- package/frontend-vue/package.json +2 -2
- package/frontend-vue/pnpm-lock.yaml +5 -5
- package/frontend-vue/tests/activity-feed-fill-height.test.ts +107 -0
- package/frontend-vue/tests/category-nav-cards.test.ts +21 -13
- package/frontend-vue/tests/command-palette-assistant.test.ts +344 -0
- package/frontend-vue/tests/composed-text-blocks.test.ts +205 -0
- package/frontend-vue/tests/composed-text.test.ts +265 -0
- package/frontend-vue/tests/fixtures/dashboard-search-stub.ts +91 -0
- package/frontend-vue/tests/forgot-validation-resend.test.ts +234 -0
- package/frontend-vue/tests/form-display-options.test.ts +64 -0
- package/frontend-vue/tests/form-load-error.test.ts +160 -0
- package/frontend-vue/tests/form-saved-before-success.test.ts +110 -0
- package/frontend-vue/tests/github-star-prompt.test.ts +328 -0
- package/frontend-vue/tests/header-actions.test.ts +191 -0
- package/frontend-vue/tests/invites-edit-modal.test.ts +157 -0
- package/frontend-vue/tests/layout-banners.test.ts +56 -0
- package/frontend-vue/tests/member-role-picker.test.ts +26 -0
- package/frontend-vue/tests/menu-hidden-page.test.ts +93 -0
- package/frontend-vue/tests/nav-badge-tones.test.ts +274 -0
- package/frontend-vue/tests/nav-card-badge.test.ts +69 -0
- package/frontend-vue/tests/nav-card-grid-empty-category.test.ts +163 -0
- package/frontend-vue/tests/notification-popover-errors.test.ts +71 -37
- package/frontend-vue/tests/notification-preferences-groups.test.ts +268 -0
- package/frontend-vue/tests/notification-tone-contract.test.ts +70 -0
- package/frontend-vue/tests/page-fill-height.test.ts +9 -1
- package/frontend-vue/tests/page-no-visible-blocks.test.ts +202 -0
- package/frontend-vue/tests/profile-preferences-summary.test.ts +26 -2
- package/frontend-vue/tests/profile-security-summary.test.ts +121 -0
- package/frontend-vue/tests/role-permission-tree.test.ts +102 -8
- package/frontend-vue/tests/role-permissions.test.ts +178 -56
- package/frontend-vue/tests/side-panels.test.ts +470 -0
- package/frontend-vue/tests/signup-invitation-link.test.ts +71 -2
- package/frontend-vue/tests/table-actions-column-width.test.ts +51 -1
- package/frontend-vue/tests/table-cell-sublines.test.ts +466 -0
- package/frontend-vue/tests/table-metric-cells.test.ts +4 -0
- package/frontend-vue/tests/table-view-chrome.test.ts +2 -2
- package/frontend-vue/tests/vue-inventory.test.ts +1 -1
- package/package.json +2 -2
- package/skills/dms/REFERENCE.md +1 -1
- package/skills/dms/SKILL.md +7 -0
|
@@ -36,6 +36,11 @@ interface ActivityFeedProps extends Partial<DefaultComponentProps> {
|
|
|
36
36
|
groupByDay?: boolean;
|
|
37
37
|
/** Shows at most this many entries. */
|
|
38
38
|
maxItems?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Fills its grid cell instead of growing with its entries, which scroll
|
|
41
|
+
* under the fixed head: the cards beside it set the row's height.
|
|
42
|
+
*/
|
|
43
|
+
fillHeight?: boolean;
|
|
39
44
|
/**
|
|
40
45
|
* Placeholder rows while `fetchUrl` loads: the length the source usually
|
|
41
46
|
* answers, never more than `maxItems`. Optional. Defaults to `maxItems`,
|
|
@@ -59,6 +64,7 @@ const props = withDefaults(defineProps<ActivityFeedProps>(), {
|
|
|
59
64
|
fetchUrlMethod: undefined,
|
|
60
65
|
groupByDay: true,
|
|
61
66
|
maxItems: undefined,
|
|
67
|
+
fillHeight: false,
|
|
62
68
|
skeletonCount: undefined,
|
|
63
69
|
actions: () => [],
|
|
64
70
|
empty: undefined,
|
|
@@ -137,6 +143,32 @@ const skeletonDays = computed<number[][]>(() => {
|
|
|
137
143
|
}
|
|
138
144
|
return days;
|
|
139
145
|
});
|
|
146
|
+
|
|
147
|
+
// Filling its cell, the body is the scroll area: sized to nothing
|
|
148
|
+
// (`contain: size`), it leaves the row's height to the cards beside it and
|
|
149
|
+
// stretches to it. Once the grid stacks its cells (`--dms-grid-tracks: 1`,
|
|
150
|
+
// see grid/columns.ts) no neighbour sets that height: the list takes its own,
|
|
151
|
+
// capped like a top-list card's (24rem, about six entries under their day
|
|
152
|
+
// separators). Focusable, so the keyboard scrolls it too; its ring is drawn
|
|
153
|
+
// inside, where the card's clipped edge cannot hide it.
|
|
154
|
+
const scrollArea = computed(() =>
|
|
155
|
+
props.fillHeight
|
|
156
|
+
? {
|
|
157
|
+
class:
|
|
158
|
+
"h-full overflow-y-auto overscroll-contain [scrollbar-width:thin] contain-size focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--dms-accent-line) [@container_style(--dms-grid-tracks:1)]:h-auto [@container_style(--dms-grid-tracks:1)]:max-h-[24rem] [@container_style(--dms-grid-tracks:1)]:contain-none",
|
|
159
|
+
role: "region",
|
|
160
|
+
tabindex: 0,
|
|
161
|
+
"aria-label": props.title
|
|
162
|
+
? processI18n(props.title)
|
|
163
|
+
: t("dms.activity_feed.list_label"),
|
|
164
|
+
}
|
|
165
|
+
: {},
|
|
166
|
+
);
|
|
167
|
+
// Inside the scroll area, a day's separator stays on top of its entries.
|
|
168
|
+
const dayHeadClass = computed(
|
|
169
|
+
() => props.fillHeight && "sticky top-0 z-[1] bg-(--dms-surface-card)",
|
|
170
|
+
);
|
|
171
|
+
|
|
140
172
|
const Wrapper = props.card ? resolveComponent("DmsCard") : "div";
|
|
141
173
|
const wrapperProps = computed(() =>
|
|
142
174
|
props.card
|
|
@@ -161,91 +193,94 @@ const wrapperProps = computed(() =>
|
|
|
161
193
|
/>
|
|
162
194
|
</template>
|
|
163
195
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
<div v-
|
|
168
|
-
<div
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
196
|
+
<div v-bind="scrollArea">
|
|
197
|
+
<!-- Rows at the loaded rows' boxes (a 18px title line over a 16px meta
|
|
198
|
+
line beside the 30px well), split by the same hairlines. -->
|
|
199
|
+
<div v-if="isFirstLoad" class="py-1" aria-busy="true">
|
|
200
|
+
<div v-for="(day, dayIndex) in skeletonDays" :key="dayIndex">
|
|
201
|
+
<div
|
|
202
|
+
v-if="props.groupByDay"
|
|
203
|
+
class="flex items-center gap-2.5 px-[18px] pt-3.5 pb-1.5 after:h-px after:flex-1 after:bg-(--ui-border-muted)"
|
|
204
|
+
>
|
|
205
|
+
<USkeleton class="my-[1.5px] h-2.5 w-24" />
|
|
206
|
+
</div>
|
|
207
|
+
<div class="divide-y divide-(--ui-border-muted)">
|
|
208
|
+
<DmsRowSkeleton
|
|
209
|
+
v-for="row in day"
|
|
210
|
+
:key="row"
|
|
211
|
+
class="px-[18px] py-2.5"
|
|
212
|
+
well="size-[30px] rounded-lg"
|
|
213
|
+
:lines="[
|
|
214
|
+
`my-[3px] h-3 ${SKELETON_TITLE_WIDTHS[row % SKELETON_TITLE_WIDTHS.length]}`,
|
|
215
|
+
'my-[3px] h-2.5 w-1/3',
|
|
216
|
+
]"
|
|
217
|
+
lines-class="grid gap-px"
|
|
218
|
+
/>
|
|
219
|
+
</div>
|
|
186
220
|
</div>
|
|
187
221
|
</div>
|
|
188
|
-
</div>
|
|
189
222
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
223
|
+
<DmsEmptyState
|
|
224
|
+
v-else-if="hasError"
|
|
225
|
+
variant="error"
|
|
226
|
+
size="sm"
|
|
227
|
+
:title="t('dms.activity_feed.error_title')"
|
|
228
|
+
:description="t('dms.activity_feed.error_description')"
|
|
229
|
+
:actions="[
|
|
230
|
+
{
|
|
231
|
+
label: t('dms.activity_feed.retry'),
|
|
232
|
+
icon: 'i-ph-arrow-clockwise',
|
|
233
|
+
color: 'neutral',
|
|
234
|
+
variant: 'outline',
|
|
235
|
+
onClick: () => refresh(),
|
|
236
|
+
},
|
|
237
|
+
]"
|
|
238
|
+
/>
|
|
239
|
+
|
|
240
|
+
<DmsEmptyState
|
|
241
|
+
v-else-if="!entries.length"
|
|
242
|
+
icon="i-ph-tray"
|
|
243
|
+
size="sm"
|
|
244
|
+
:title="
|
|
245
|
+
props.empty
|
|
246
|
+
? processI18n(props.empty.title)
|
|
247
|
+
: t('dms.activity_feed.empty_title')
|
|
248
|
+
"
|
|
249
|
+
:description="
|
|
250
|
+
props.empty?.description
|
|
251
|
+
? processI18n(props.empty.description)
|
|
252
|
+
: undefined
|
|
253
|
+
"
|
|
254
|
+
/>
|
|
255
|
+
|
|
256
|
+
<div v-else class="py-1">
|
|
257
|
+
<section v-for="day in days" :key="day.key">
|
|
258
|
+
<!-- v2 .feed__day: "Today · Sep 29" and a hairline to the edge. -->
|
|
259
|
+
<div
|
|
260
|
+
v-if="props.groupByDay && day.name"
|
|
261
|
+
class="flex items-center gap-2.5 px-[18px] pt-3.5 pb-1.5 after:h-px after:flex-1 after:bg-(--ui-border-muted)"
|
|
262
|
+
:class="dayHeadClass"
|
|
263
|
+
>
|
|
264
|
+
<DmsEyebrow as="h3">
|
|
265
|
+
<b class="text-muted font-semibold">{{ day.name }}</b>
|
|
266
|
+
{{ day.date ? ` · ${day.date}` : "" }}
|
|
267
|
+
</DmsEyebrow>
|
|
268
|
+
</div>
|
|
269
|
+
<DmsActivityItem
|
|
270
|
+
v-for="(item, index) in day.items"
|
|
271
|
+
:key="item.id ?? `${day.key}-${index}`"
|
|
272
|
+
:icon="item.icon"
|
|
273
|
+
:icon-color="item.tone ?? 'neutral'"
|
|
274
|
+
:title="textOf(item, item.title)"
|
|
275
|
+
:subtitle="metaOf(item)"
|
|
276
|
+
:trailing="trailingOf(item)"
|
|
277
|
+
:unread="item.unread"
|
|
278
|
+
:mono="props.mono"
|
|
279
|
+
:to="item.to"
|
|
280
|
+
:interactive="!!item.to"
|
|
281
|
+
/>
|
|
282
|
+
</section>
|
|
283
|
+
</div>
|
|
249
284
|
</div>
|
|
250
285
|
</component>
|
|
251
286
|
</template>
|
|
@@ -5,7 +5,9 @@ import DmsBlockActions, {
|
|
|
5
5
|
type BlockAction,
|
|
6
6
|
} from "../../build/components/blocks/BlockActions.vue";
|
|
7
7
|
import { useWatch } from "../../../../dms-core/app/composables/watch/useWatch";
|
|
8
|
+
import { useComposedText } from "../../../../dms-core/app/composables/translation/useComposedText";
|
|
8
9
|
import type { DefaultComponentProps } from "../../../../dms-core/app/types/component";
|
|
10
|
+
import type { BlockText } from "../../../../dms-core/app/types/composed-text";
|
|
9
11
|
|
|
10
12
|
type BannerTone = "info" | "success" | "warning" | "error" | "primary";
|
|
11
13
|
|
|
@@ -14,8 +16,9 @@ type BannerTone = "info" | "success" | "warning" | "error" | "primary";
|
|
|
14
16
|
// Dismissals live in a cookie (like the dashboard banners) so the server
|
|
15
17
|
// render already leaves a dismissed banner out instead of flashing it.
|
|
16
18
|
interface BannerBlockProps extends Partial<DefaultComponentProps> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
/** A string (`$` for an i18n key) or a composed text. */
|
|
20
|
+
title?: BlockText;
|
|
21
|
+
description?: BlockText;
|
|
19
22
|
tone?: BannerTone;
|
|
20
23
|
/** Overrides the tone's icon. */
|
|
21
24
|
icon?: string;
|
|
@@ -56,7 +59,7 @@ const TONE_ICONS: Record<BannerTone, string> = {
|
|
|
56
59
|
|
|
57
60
|
useWatch(props.watchActions || [], props.componentId);
|
|
58
61
|
|
|
59
|
-
const {
|
|
62
|
+
const { processText } = useComposedText();
|
|
60
63
|
const dismissed = useDmsCookie<string[]>(DISMISSED_COOKIE, {
|
|
61
64
|
default: () => [],
|
|
62
65
|
maxAge: DISMISSED_MAX_AGE_S,
|
|
@@ -91,9 +94,9 @@ function dismiss(): void {
|
|
|
91
94
|
<template>
|
|
92
95
|
<DmsBanner
|
|
93
96
|
v-if="isVisible"
|
|
94
|
-
:title="props.title ?
|
|
97
|
+
:title="props.title ? processText(props.title) : undefined"
|
|
95
98
|
:description="
|
|
96
|
-
props.description ?
|
|
99
|
+
props.description ? processText(props.description) : undefined
|
|
97
100
|
"
|
|
98
101
|
:icon="props.icon ?? TONE_ICONS[props.tone]"
|
|
99
102
|
:tone="props.tone"
|
|
@@ -8,13 +8,24 @@ import DmsBlockStatus, {
|
|
|
8
8
|
type BlockEmptyText,
|
|
9
9
|
} from "../../build/components/blocks/BlockStatus.vue";
|
|
10
10
|
import { useBlockItems } from "../../build/composables/blocks/useBlockItems";
|
|
11
|
+
import { useComposedText } from "../../../../dms-core/app/composables/translation/useComposedText";
|
|
11
12
|
import type { DefaultComponentProps } from "../../../../dms-core/app/types/component";
|
|
13
|
+
import type { BlockText } from "../../../../dms-core/app/types/composed-text";
|
|
14
|
+
import { isComposedText } from "../../../../dms-core/app/utils/composedText";
|
|
12
15
|
|
|
13
16
|
// `KeyValueList` block (interface-dms `base/key-value-list`): label / value
|
|
14
17
|
// rows (v2 .c-dl), static or from `fetchUrl` (`{ items }`), in a card by
|
|
15
|
-
// default. Labels, details and text values follow the `$` i18n convention
|
|
18
|
+
// default. Labels, details and text values follow the `$` i18n convention or
|
|
19
|
+
// are composed texts.
|
|
20
|
+
interface KeyValueListBlockItem
|
|
21
|
+
extends Omit<KeyValueItem, "label" | "value" | "detail"> {
|
|
22
|
+
label: BlockText;
|
|
23
|
+
value?: BlockText | number | null;
|
|
24
|
+
detail?: BlockText;
|
|
25
|
+
}
|
|
26
|
+
|
|
16
27
|
interface KeyValueListBlockProps extends DefaultComponentProps {
|
|
17
|
-
items?:
|
|
28
|
+
items?: KeyValueListBlockItem[];
|
|
18
29
|
dense?: boolean;
|
|
19
30
|
columns?: number;
|
|
20
31
|
currency?: string;
|
|
@@ -50,30 +61,39 @@ const props = withDefaults(defineProps<KeyValueListBlockProps>(), {
|
|
|
50
61
|
|
|
51
62
|
const TRANSLATED_TYPES = new Set([undefined, "text", "status", "link"]);
|
|
52
63
|
|
|
53
|
-
const {
|
|
64
|
+
const { processText } = useComposedText();
|
|
54
65
|
|
|
55
|
-
const { items, isPending, hasError, refresh } =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
const { items, isPending, hasError, refresh } =
|
|
67
|
+
useBlockItems<KeyValueListBlockItem>({
|
|
68
|
+
items: () => props.items,
|
|
69
|
+
fetchUrl: props.fetchUrl,
|
|
70
|
+
fetchUrlMethod: props.fetchUrlMethod,
|
|
71
|
+
routeParams: () => props.routeParams,
|
|
72
|
+
watchActions: props.watchActions,
|
|
73
|
+
componentId: props.componentId,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// A composed value already says how each of its parameters is written, so it
|
|
77
|
+
// is composed whatever the row's type; a plain one is translated only where
|
|
78
|
+
// the type draws text.
|
|
79
|
+
function resolveValue(item: KeyValueListBlockItem): KeyValueItem["value"] {
|
|
80
|
+
if (isComposedText(item.value)) return processText(item.value);
|
|
81
|
+
if (typeof item.value === "string" && TRANSLATED_TYPES.has(item.type)) {
|
|
82
|
+
return processText(item.value);
|
|
83
|
+
}
|
|
84
|
+
return item.value as KeyValueItem["value"];
|
|
85
|
+
}
|
|
63
86
|
|
|
64
87
|
const resolvedItems = computed<KeyValueItem[]>(() =>
|
|
65
88
|
items.value.map((item) => ({
|
|
66
89
|
...item,
|
|
67
|
-
label:
|
|
68
|
-
detail: item.detail ?
|
|
69
|
-
value:
|
|
70
|
-
typeof item.value === "string" && TRANSLATED_TYPES.has(item.type)
|
|
71
|
-
? processI18n(item.value)
|
|
72
|
-
: item.value,
|
|
90
|
+
label: processText(item.label),
|
|
91
|
+
detail: item.detail ? processText(item.detail) : undefined,
|
|
92
|
+
value: resolveValue(item),
|
|
73
93
|
})),
|
|
74
94
|
);
|
|
75
95
|
const title = computed(() =>
|
|
76
|
-
props.title ?
|
|
96
|
+
props.title ? processText(props.title) : undefined,
|
|
77
97
|
);
|
|
78
98
|
const isEmpty = computed(
|
|
79
99
|
() => !isPending.value && !hasError.value && resolvedItems.value.length === 0,
|
|
@@ -30,6 +30,9 @@ interface NavCardGridItem {
|
|
|
30
30
|
stateTone?: Tone;
|
|
31
31
|
tag?: string;
|
|
32
32
|
readout?: string[];
|
|
33
|
+
/** The page's navigation badge (a category's cards), in the top corner. */
|
|
34
|
+
badge?: string;
|
|
35
|
+
badgeTone?: Tone;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
interface NavCardGridBlockProps extends DefaultComponentProps {
|
|
@@ -125,10 +128,16 @@ const cards = computed(() =>
|
|
|
125
128
|
// v2 .sx-grid: cards closing on a state line run a tighter rhythm, the whole
|
|
126
129
|
// grid at once so the rows stay aligned.
|
|
127
130
|
const hasStates = computed(() => cards.value.some((card) => !!card.state));
|
|
131
|
+
// A category the viewer opens no page of is left out, title included, as the
|
|
132
|
+
// navigation leaves out an empty group: the settings overview of a member
|
|
133
|
+
// without a role shows no Workspace section. `empty` shows a message instead.
|
|
134
|
+
const isLeftOut = computed(
|
|
135
|
+
() => !!props.categoryId && !props.empty && cards.value.length === 0,
|
|
136
|
+
);
|
|
128
137
|
</script>
|
|
129
138
|
|
|
130
139
|
<template>
|
|
131
|
-
<section>
|
|
140
|
+
<section v-if="!isLeftOut">
|
|
132
141
|
<DmsSectionHeader
|
|
133
142
|
v-if="props.title || props.description"
|
|
134
143
|
class="mb-3"
|
|
@@ -190,6 +199,8 @@ const hasStates = computed(() => cards.value.some((card) => !!card.state));
|
|
|
190
199
|
:state="card.state"
|
|
191
200
|
:state-tone="card.stateTone"
|
|
192
201
|
:tag="card.tag"
|
|
202
|
+
:badge="card.badge"
|
|
203
|
+
:badge-tone="card.badgeTone"
|
|
193
204
|
:readout="card.readout"
|
|
194
205
|
:class="hasStates && 'gap-2.5'"
|
|
195
206
|
/>
|
|
@@ -8,13 +8,23 @@ import DmsBlockStatus, {
|
|
|
8
8
|
type BlockEmptyText,
|
|
9
9
|
} from "../../build/components/blocks/BlockStatus.vue";
|
|
10
10
|
import { useBlockItems } from "../../build/composables/blocks/useBlockItems";
|
|
11
|
+
import { useComposedText } from "../../../../dms-core/app/composables/translation/useComposedText";
|
|
11
12
|
import type { DefaultComponentProps } from "../../../../dms-core/app/types/component";
|
|
13
|
+
import type { BlockText } from "../../../../dms-core/app/types/composed-text";
|
|
12
14
|
|
|
13
15
|
// `StatGroup` block (interface-dms `base/stat-group`): the generic StatGroup
|
|
14
16
|
// fed from the block options or from `fetchUrl` (`{ items }`). Texts follow
|
|
15
|
-
// the `$` i18n-key convention; numeric values are
|
|
17
|
+
// the `$` i18n-key convention or are composed texts; numeric values are
|
|
18
|
+
// formatted for the locale.
|
|
19
|
+
interface StatGroupBlockItem
|
|
20
|
+
extends Omit<StatGroupItem, "eyebrow" | "value" | "detail"> {
|
|
21
|
+
eyebrow: BlockText;
|
|
22
|
+
value: BlockText | number;
|
|
23
|
+
detail?: BlockText;
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
interface StatGroupBlockProps extends DefaultComponentProps {
|
|
17
|
-
items?:
|
|
27
|
+
items?: StatGroupBlockItem[];
|
|
18
28
|
layout?: StatGroupLayout;
|
|
19
29
|
columns?: number;
|
|
20
30
|
/** Accessible name of the group. */
|
|
@@ -43,31 +53,24 @@ const props = withDefaults(defineProps<StatGroupBlockProps>(), {
|
|
|
43
53
|
|
|
44
54
|
const DEFAULT_SKELETON_COUNT = 4;
|
|
45
55
|
|
|
46
|
-
const {
|
|
47
|
-
const { processI18n } = useTranslation();
|
|
56
|
+
const { processText } = useComposedText();
|
|
48
57
|
|
|
49
|
-
const { items, isPending, hasError, refresh } =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
function formatValue(value: StatGroupItem["value"]): string {
|
|
59
|
-
if (typeof value === "number") {
|
|
60
|
-
return new Intl.NumberFormat(locale.value).format(value);
|
|
61
|
-
}
|
|
62
|
-
return processI18n(String(value ?? ""));
|
|
63
|
-
}
|
|
58
|
+
const { items, isPending, hasError, refresh } =
|
|
59
|
+
useBlockItems<StatGroupBlockItem>({
|
|
60
|
+
items: () => props.items,
|
|
61
|
+
fetchUrl: props.fetchUrl,
|
|
62
|
+
fetchUrlMethod: props.fetchUrlMethod,
|
|
63
|
+
routeParams: () => props.routeParams,
|
|
64
|
+
watchActions: props.watchActions,
|
|
65
|
+
componentId: props.componentId,
|
|
66
|
+
});
|
|
64
67
|
|
|
65
68
|
const resolvedItems = computed<StatGroupItem[]>(() =>
|
|
66
69
|
items.value.map((item) => ({
|
|
67
70
|
...item,
|
|
68
|
-
eyebrow:
|
|
69
|
-
value:
|
|
70
|
-
detail: item.detail ?
|
|
71
|
+
eyebrow: processText(item.eyebrow),
|
|
72
|
+
value: processText(item.value),
|
|
73
|
+
detail: item.detail ? processText(item.detail) : undefined,
|
|
71
74
|
})),
|
|
72
75
|
);
|
|
73
76
|
</script>
|
|
@@ -88,6 +91,6 @@ const resolvedItems = computed<StatGroupItem[]>(() =>
|
|
|
88
91
|
:skeleton-count="
|
|
89
92
|
props.skeletonCount ?? props.columns ?? DEFAULT_SKELETON_COUNT
|
|
90
93
|
"
|
|
91
|
-
:label="props.label ?
|
|
94
|
+
:label="props.label ? processText(props.label) : undefined"
|
|
92
95
|
/>
|
|
93
96
|
</template>
|
|
@@ -6,12 +6,14 @@ import DmsStatusPill from "../status-pill/StatusPill.vue";
|
|
|
6
6
|
import DmsAutoLink from "../link/AutoLink.vue";
|
|
7
7
|
import type { Tone } from "../../types/tone";
|
|
8
8
|
import { MONO_TAG_CLASS } from "../../build/utils/monoChip";
|
|
9
|
+
import { navBadgeClass } from "../../build/utils/navBadge";
|
|
9
10
|
|
|
10
11
|
// Navigation tile (v2 .navcard): an icon well + title + description rendered
|
|
11
12
|
// as a clickable card linking elsewhere (settings overview, a module's home),
|
|
12
13
|
// optionally closed by the target's live state (v2 .sx-state, pinned to the
|
|
13
14
|
// bottom so the states of a row line up) or a mono readout (v2
|
|
14
|
-
// .module-tile__viz). A tag follows the title (v2 .sx-mod)
|
|
15
|
+
// .module-tile__viz). A tag follows the title (v2 .sx-mod); the target's
|
|
16
|
+
// navigation badge sits in the top corner, drawn as the settings nav draws it.
|
|
15
17
|
//
|
|
16
18
|
// Built on a bare <DmsAutoLink> rather than <ULink> on purpose: ULink's theme
|
|
17
19
|
// injects its own `rounded-md` which would override the .dms-card radius.
|
|
@@ -34,6 +36,10 @@ interface NavCardProps {
|
|
|
34
36
|
statePending?: boolean;
|
|
35
37
|
/** Small uppercase mono tag after the title (module tag: "SAAS"). */
|
|
36
38
|
tag?: string;
|
|
39
|
+
/** The target's navigation badge ("3"), in the card's top corner. */
|
|
40
|
+
badge?: string;
|
|
41
|
+
/** Tone of the badge; neutral grey when absent. */
|
|
42
|
+
badgeTone?: Tone;
|
|
37
43
|
/** Mono readout lines under the description (module tile). */
|
|
38
44
|
readout?: string[];
|
|
39
45
|
}
|
|
@@ -46,6 +52,8 @@ const props = withDefaults(defineProps<NavCardProps>(), {
|
|
|
46
52
|
state: undefined,
|
|
47
53
|
stateTone: "neutral",
|
|
48
54
|
tag: undefined,
|
|
55
|
+
badge: undefined,
|
|
56
|
+
badgeTone: undefined,
|
|
49
57
|
readout: undefined,
|
|
50
58
|
});
|
|
51
59
|
const attrs = useAttrs();
|
|
@@ -55,6 +63,7 @@ const theme = tv({
|
|
|
55
63
|
root: "dms-card dms-card--interactive group flex flex-col gap-3 p-[18px] text-start",
|
|
56
64
|
title: "text-highlighted min-w-0 truncate text-sm font-[650]",
|
|
57
65
|
tag: `${MONO_TAG_CLASS} bg-elevated shrink-0 text-dimmed`,
|
|
66
|
+
badge: "shrink-0",
|
|
58
67
|
arrow:
|
|
59
68
|
"text-dimmed group-hover:text-primary ms-auto size-4 shrink-0 -translate-x-[3px] opacity-0 transition group-hover:translate-x-0 group-hover:opacity-100",
|
|
60
69
|
description: "text-muted text-[13px] leading-normal",
|
|
@@ -78,6 +87,12 @@ const passthrough = computed(() => {
|
|
|
78
87
|
<h3 :class="ui.title()">{{ props.title }}</h3>
|
|
79
88
|
<span v-if="props.tag" :class="ui.tag()">{{ props.tag }}</span>
|
|
80
89
|
<UIcon name="i-ph-arrow-right" :class="ui.arrow()" :aria-hidden="true" />
|
|
90
|
+
<span
|
|
91
|
+
v-if="props.badge"
|
|
92
|
+
:class="ui.badge({ class: navBadgeClass(props.badgeTone) })"
|
|
93
|
+
>
|
|
94
|
+
{{ props.badge }}
|
|
95
|
+
</span>
|
|
81
96
|
</div>
|
|
82
97
|
|
|
83
98
|
<p v-if="props.description" :class="ui.description()">
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { nextTick, useTemplateRef, watch, type FunctionalComponent } from "vue";
|
|
3
3
|
import { DialogDescription, DialogTitle } from "reka-ui";
|
|
4
4
|
import DmsIconWell from "../icon-well/IconWell.vue";
|
|
5
|
+
import DmsModalEscHint from "../../build/components/modal/ModalEscHint.vue";
|
|
5
6
|
import {
|
|
6
7
|
ConfirmActionError,
|
|
7
8
|
type ConfirmBodyRender,
|
|
@@ -454,16 +455,14 @@ function handleCancel() {
|
|
|
454
455
|
|
|
455
456
|
<template #footer>
|
|
456
457
|
<div class="flex w-full items-center justify-end gap-2">
|
|
457
|
-
<
|
|
458
|
-
class="
|
|
459
|
-
|
|
460
|
-
<UKbd value="Esc" size="sm" />
|
|
461
|
-
{{
|
|
458
|
+
<DmsModalEscHint
|
|
459
|
+
class="max-sm:hidden"
|
|
460
|
+
:label="
|
|
462
461
|
$t(
|
|
463
|
-
isSettled ?
|
|
462
|
+
isSettled ? 'dms.confirm.esc_close_hint' : 'dms.confirm.esc_hint',
|
|
464
463
|
)
|
|
465
|
-
|
|
466
|
-
|
|
464
|
+
"
|
|
465
|
+
/>
|
|
467
466
|
<UButton
|
|
468
467
|
:label="
|
|
469
468
|
isSettled
|
|
@@ -57,6 +57,11 @@ import { useInstantForm } from "../../build/composables/form/useInstantForm";
|
|
|
57
57
|
import { useInstantSaveHeader } from "#dms-layout/app/composables/layout/useInstantSaveHeader";
|
|
58
58
|
import DmsFormEntries from "../../build/components/form/FormEntries.vue";
|
|
59
59
|
import DmsFormErrorSummary from "../../build/components/form/FormErrorSummary.vue";
|
|
60
|
+
import DmsFormLoadError from "../../build/components/form/FormLoadError.vue";
|
|
61
|
+
import {
|
|
62
|
+
type FormRecordLoad,
|
|
63
|
+
trackFormRecordLoad,
|
|
64
|
+
} from "../../build/composables/form/formRecordLoad";
|
|
60
65
|
import DmsFormRequiredLegend from "../../build/components/form/FormRequiredLegend.vue";
|
|
61
66
|
import DmsFormSections from "../../build/components/form/FormSections.vue";
|
|
62
67
|
|
|
@@ -506,7 +511,7 @@ function setFieldLoading(id: string, isLoading: boolean): void {
|
|
|
506
511
|
const isAnyFieldLoading = computed(() => fieldLoadingStates.value.size > 0);
|
|
507
512
|
|
|
508
513
|
function onSubmit(event: Parameters<typeof handleSubmit>[0]) {
|
|
509
|
-
if (!runValidators()) return;
|
|
514
|
+
if (loadFailure.value || !runValidators()) return;
|
|
510
515
|
handleSubmit(event);
|
|
511
516
|
}
|
|
512
517
|
|
|
@@ -522,6 +527,7 @@ allFields.value.forEach((field) => {
|
|
|
522
527
|
) as FormFieldValue;
|
|
523
528
|
});
|
|
524
529
|
|
|
530
|
+
let recordLoad: FormRecordLoad | undefined;
|
|
525
531
|
if (props.fetchUrl) {
|
|
526
532
|
const formLoad = await useDmsAsyncData(
|
|
527
533
|
`form-${props.componentId}-${props.pageId}`,
|
|
@@ -539,15 +545,23 @@ if (props.fetchUrl) {
|
|
|
539
545
|
formLoad.status.value = "idle";
|
|
540
546
|
});
|
|
541
547
|
|
|
542
|
-
|
|
543
|
-
if (payload) {
|
|
548
|
+
recordLoad = trackFormRecordLoad(formLoad, (payload) => {
|
|
544
549
|
if (payload.values && Object.keys(payload.values).length > 0) {
|
|
545
550
|
Object.assign(state.value, payload.values);
|
|
546
551
|
}
|
|
547
552
|
if (payload.initial && payload.initial !== initialValues.value) {
|
|
548
553
|
initialValues.value = { ...initialValues.value, ...payload.initial };
|
|
549
554
|
}
|
|
550
|
-
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const loadFailure = computed(() => recordLoad?.failure.value ?? null);
|
|
559
|
+
const isRetryingLoad = computed(() => recordLoad?.retrying.value ?? false);
|
|
560
|
+
|
|
561
|
+
/** Load the record again after a failure; it is what the form starts from. */
|
|
562
|
+
async function retryRecordLoad(): Promise<void> {
|
|
563
|
+
await recordLoad?.retry();
|
|
564
|
+
if (!recordLoad?.failure.value) markFormClean();
|
|
551
565
|
}
|
|
552
566
|
|
|
553
567
|
// Loaded (or filled with its defaults): this is what the form starts from.
|
|
@@ -868,7 +882,15 @@ onUnmounted(async () => {
|
|
|
868
882
|
</p>
|
|
869
883
|
</header>
|
|
870
884
|
|
|
871
|
-
<div :class="surfaceClasses.body">
|
|
885
|
+
<div v-if="loadFailure" :class="surfaceClasses.body">
|
|
886
|
+
<DmsFormLoadError
|
|
887
|
+
:failure="loadFailure"
|
|
888
|
+
:retrying="isRetryingLoad"
|
|
889
|
+
@retry="retryRecordLoad"
|
|
890
|
+
/>
|
|
891
|
+
</div>
|
|
892
|
+
|
|
893
|
+
<div v-else :class="surfaceClasses.body">
|
|
872
894
|
<UAlert
|
|
873
895
|
v-if="showConcurrentEditBanner"
|
|
874
896
|
color="warning"
|
|
@@ -935,7 +957,7 @@ onUnmounted(async () => {
|
|
|
935
957
|
on a page, the footer band of a card, a drawer or a modal. It holds
|
|
936
958
|
its place while hidden, so its showing up never moves anything. -->
|
|
937
959
|
<DmsSaveBar
|
|
938
|
-
v-if="canSave && !isInstant"
|
|
960
|
+
v-if="canSave && !isInstant && !loadFailure"
|
|
939
961
|
:variant="usesSaveBar ? 'floating' : 'band'"
|
|
940
962
|
:kind="props.kind"
|
|
941
963
|
:dirty="isDirty"
|