@antelopejs/dms 0.6.2 → 0.7.1
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 +30 -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/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 +2 -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/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/useFieldErrors.ts +3 -2
- package/frontend-vue/layers/dms-core/app/types/menu.ts +15 -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/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 +4 -0
- 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/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/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/NavCardGridBlock.vue +12 -1
- 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/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/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-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
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import {
|
|
3
|
+
computed,
|
|
4
|
+
createApp,
|
|
5
|
+
defineComponent,
|
|
6
|
+
h,
|
|
7
|
+
nextTick,
|
|
8
|
+
reactive,
|
|
9
|
+
ref,
|
|
10
|
+
type App,
|
|
11
|
+
type Ref,
|
|
12
|
+
} from "vue";
|
|
13
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
14
|
+
import DashboardHeader from "../layers/dms-layout/app/build/components/layout/DashboardHeader.vue";
|
|
15
|
+
import {
|
|
16
|
+
BUILDER_ACTION_ID,
|
|
17
|
+
type HeaderAction,
|
|
18
|
+
registerHeaderAction,
|
|
19
|
+
useHeaderActions,
|
|
20
|
+
} from "../layers/dms-layout/app/composables/useHeaderActions";
|
|
21
|
+
import { useSidePanel } from "../layers/dms-layout/app/composables/useSidePanel";
|
|
22
|
+
|
|
23
|
+
vi.mock(
|
|
24
|
+
"../layers/dms-layout/app/build/components/notification/NotificationPopover.vue",
|
|
25
|
+
() => ({ default: () => null }),
|
|
26
|
+
);
|
|
27
|
+
vi.mock(
|
|
28
|
+
"../layers/dms-layout/app/build/components/layout/QuickActionsPopover.vue",
|
|
29
|
+
() => ({ default: () => null }),
|
|
30
|
+
);
|
|
31
|
+
vi.mock("#dms-core/app/build/composables/page/usePageRecordLabel", () => ({
|
|
32
|
+
usePageRecordLabel: () => ({ label: ref(null) }),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
const ACTIVE_COLOR = "primary";
|
|
36
|
+
const IDLE_COLOR = "neutral";
|
|
37
|
+
const PANEL_ID = "demo:panel";
|
|
38
|
+
|
|
39
|
+
let sharedState: Map<string, Ref<unknown>>;
|
|
40
|
+
let app: App | undefined;
|
|
41
|
+
|
|
42
|
+
interface CookieOptions {
|
|
43
|
+
default?: () => unknown;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function useDmsState<T>(key: string, init?: () => T): Ref<T> {
|
|
47
|
+
if (!sharedState.has(key)) sharedState.set(key, ref(init?.()));
|
|
48
|
+
return sharedState.get(key) as Ref<T>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function useDmsCookie<T>(name: string, options: CookieOptions = {}): Ref<T> {
|
|
52
|
+
return useDmsState(`cookie:${name}`, () => options.default?.() ?? null);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const ButtonStub = defineComponent({
|
|
56
|
+
inheritAttrs: false,
|
|
57
|
+
props: { color: String, onClick: Function },
|
|
58
|
+
setup:
|
|
59
|
+
(props, { attrs }) =>
|
|
60
|
+
() =>
|
|
61
|
+
h("button", {
|
|
62
|
+
"aria-label": attrs["aria-label"],
|
|
63
|
+
"aria-pressed": attrs["aria-pressed"],
|
|
64
|
+
"data-color": props.color,
|
|
65
|
+
onClick: () => props.onClick?.(),
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const SlotsStub = defineComponent({
|
|
70
|
+
setup:
|
|
71
|
+
(_, { slots }) =>
|
|
72
|
+
() =>
|
|
73
|
+
h("div", [slots.leading?.(), slots.right?.(), slots.default?.()]),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
function installRuntime(): void {
|
|
77
|
+
const runtime: Record<string, unknown> = {
|
|
78
|
+
computed,
|
|
79
|
+
BUILDER_ACTION_ID,
|
|
80
|
+
buildBreadcrumbTarget: () => null,
|
|
81
|
+
buildFavoritePage: () => null,
|
|
82
|
+
useDmsAppConfig: () => ({ ui: { icons: {} } }),
|
|
83
|
+
useDmsCookie,
|
|
84
|
+
useDmsRoute: () => reactive({ path: "/", query: {} }),
|
|
85
|
+
useDmsState,
|
|
86
|
+
useFavoritePages: () => ({ isFavorite: () => false }),
|
|
87
|
+
useHeaderActions,
|
|
88
|
+
useHomepage: () => "/",
|
|
89
|
+
useI18n: () => ({ t: (key: string) => key }),
|
|
90
|
+
useSiteLayout: () => ({ findMatchingRoute: () => null }),
|
|
91
|
+
useTranslation: () => ({
|
|
92
|
+
processI18n: (value: string) => value.replace(/^\$/, "t:"),
|
|
93
|
+
}),
|
|
94
|
+
};
|
|
95
|
+
Object.entries(runtime).forEach(([name, value]) =>
|
|
96
|
+
vi.stubGlobal(name, value),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function mountHeader(): HTMLElement {
|
|
101
|
+
const host = document.createElement("div");
|
|
102
|
+
document.body.append(host);
|
|
103
|
+
app = createApp(DashboardHeader);
|
|
104
|
+
app.component("UButton", ButtonStub);
|
|
105
|
+
["UDashboardNavbar", "UTooltip", "UBreadcrumb", "UDropdownMenu"].forEach(
|
|
106
|
+
(name) => app?.component(name, SlotsStub),
|
|
107
|
+
);
|
|
108
|
+
app.mount(host);
|
|
109
|
+
return host;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function button(host: HTMLElement, label: string): HTMLButtonElement | null {
|
|
113
|
+
return host.querySelector(`button[aria-label="${label}"]`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function action(id: string, extra: Partial<HeaderAction> = {}): HeaderAction {
|
|
117
|
+
return { id, icon: "i-ph-star", label: id, ...extra };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
beforeEach(() => {
|
|
121
|
+
sharedState = new Map();
|
|
122
|
+
installRuntime();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
afterEach(() => {
|
|
126
|
+
app?.unmount();
|
|
127
|
+
app = undefined;
|
|
128
|
+
document.body.innerHTML = "";
|
|
129
|
+
vi.unstubAllGlobals();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("header action registry", () => {
|
|
133
|
+
it("keeps an action linked to a side panel without any callable", () => {
|
|
134
|
+
registerHeaderAction(action("panel", { sidePanelId: PANEL_ID }));
|
|
135
|
+
registerHeaderAction(action("stripped"));
|
|
136
|
+
const { actions } = useHeaderActions();
|
|
137
|
+
expect(actions.value.map((entry) => entry.id)).toEqual(["panel"]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe("header action buttons", () => {
|
|
142
|
+
it("renders the active state of every action, not only the builder's", async () => {
|
|
143
|
+
const isOn = ref(false);
|
|
144
|
+
registerHeaderAction(
|
|
145
|
+
action("toggle", { onSelect: vi.fn(), isActive: () => isOn.value }),
|
|
146
|
+
);
|
|
147
|
+
registerHeaderAction(action("plain", { onSelect: vi.fn() }));
|
|
148
|
+
const host = mountHeader();
|
|
149
|
+
const toggle = button(host, "toggle");
|
|
150
|
+
expect(toggle?.dataset.color).toBe(IDLE_COLOR);
|
|
151
|
+
expect(toggle?.getAttribute("aria-pressed")).toBe("false");
|
|
152
|
+
isOn.value = true;
|
|
153
|
+
await nextTick();
|
|
154
|
+
expect(toggle?.dataset.color).toBe(ACTIVE_COLOR);
|
|
155
|
+
expect(toggle?.getAttribute("aria-pressed")).toBe("true");
|
|
156
|
+
expect(button(host, "plain")?.hasAttribute("aria-pressed")).toBe(false);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("toggles a linked side panel and derives its state from it", async () => {
|
|
160
|
+
registerHeaderAction(
|
|
161
|
+
action("panel", { label: "$panel.toggle", sidePanelId: PANEL_ID }),
|
|
162
|
+
);
|
|
163
|
+
const host = mountHeader();
|
|
164
|
+
const toggle = button(host, "t:panel.toggle");
|
|
165
|
+
const { isOpen } = useSidePanel(PANEL_ID);
|
|
166
|
+
toggle?.click();
|
|
167
|
+
await nextTick();
|
|
168
|
+
expect(isOpen.value).toBe(true);
|
|
169
|
+
expect(toggle?.dataset.color).toBe(ACTIVE_COLOR);
|
|
170
|
+
toggle?.click();
|
|
171
|
+
await nextTick();
|
|
172
|
+
expect(isOpen.value).toBe(false);
|
|
173
|
+
expect(toggle?.dataset.color).toBe(IDLE_COLOR);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("keeps the builder action in its slot, running its own callables", async () => {
|
|
177
|
+
const onSelect = vi.fn();
|
|
178
|
+
registerHeaderAction(
|
|
179
|
+
action(BUILDER_ACTION_ID, {
|
|
180
|
+
label: "Edit",
|
|
181
|
+
onSelect,
|
|
182
|
+
isActive: () => true,
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
const host = mountHeader();
|
|
186
|
+
const builder = button(host, "Edit");
|
|
187
|
+
builder?.click();
|
|
188
|
+
expect(onSelect).toHaveBeenCalledOnce();
|
|
189
|
+
expect(builder?.dataset.color).toBe(ACTIVE_COLOR);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import { createI18n } from "vue-i18n";
|
|
4
|
+
import { Color } from "../layers/dms-core/app/types/color";
|
|
5
|
+
import { HttpMethod } from "../layers/dms-core/app/types/http";
|
|
6
|
+
import { normalizeActionConfig } from "../layers/dms-core/app/utils/row-action-rule-evaluator";
|
|
7
|
+
import { interpolateUrl } from "../layers/dms-core/app/utils/url-interpolation";
|
|
8
|
+
import { useTranslation } from "../layers/dms-core/app/composables/translation/useTranslation";
|
|
9
|
+
import { useEventedAction } from "../layers/dms-core/app/composables/useEventedAction";
|
|
10
|
+
import core from "../layers/dms-core/i18n/locales/core-en-GB.json";
|
|
11
|
+
import ui from "../layers/dms-ui/i18n/locales/ui-en-GB.json";
|
|
12
|
+
import layout from "../layers/dms-layout/i18n/locales/layout-en-GB.json";
|
|
13
|
+
|
|
14
|
+
vi.mock("../layers/dms-ui/app/components/form/Form.vue", () => ({
|
|
15
|
+
default: { name: "DmsForm" },
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
type Messages = Record<string, unknown>;
|
|
19
|
+
const merge = (target: Messages, source: Messages): Messages => {
|
|
20
|
+
for (const [key, value] of Object.entries(source)) {
|
|
21
|
+
const current = target[key];
|
|
22
|
+
target[key] =
|
|
23
|
+
current && typeof current === "object" && typeof value === "object"
|
|
24
|
+
? merge({ ...(current as Messages) }, value as Messages)
|
|
25
|
+
: value;
|
|
26
|
+
}
|
|
27
|
+
return target;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const i18n = createI18n({
|
|
31
|
+
legacy: false,
|
|
32
|
+
locale: "en",
|
|
33
|
+
missingWarn: false,
|
|
34
|
+
fallbackWarn: false,
|
|
35
|
+
messages: { en: merge(merge(merge({}, core), ui), layout) as never },
|
|
36
|
+
});
|
|
37
|
+
const t = i18n.global.t as (...args: unknown[]) => string;
|
|
38
|
+
|
|
39
|
+
const INVITE = { _id: "invite-1", email: "zz-invitee@example.com" };
|
|
40
|
+
const INVITES_PAGE = "/settings/workspace/invites";
|
|
41
|
+
|
|
42
|
+
const modal = { close: vi.fn() };
|
|
43
|
+
const openModal = vi.fn(() => modal);
|
|
44
|
+
const navigateDms = vi.fn();
|
|
45
|
+
const refresh = vi.fn();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The row actions of the invitations table, configured as the server
|
|
49
|
+
* serializes it: the edit form opens in a medium modal under the
|
|
50
|
+
* "Edit invitation" texts, and no form page URL is handed down.
|
|
51
|
+
*/
|
|
52
|
+
async function invitesRowActions() {
|
|
53
|
+
const { useTableRowActions } = await import(
|
|
54
|
+
"../layers/dms-ui/app/build/composables/table-view/useTableViewRowActions"
|
|
55
|
+
);
|
|
56
|
+
return useTableRowActions({
|
|
57
|
+
api: vi.fn() as never,
|
|
58
|
+
location: "/api/tables/admin-invites",
|
|
59
|
+
componentId: "table",
|
|
60
|
+
pageId: "settings.workspace.invites",
|
|
61
|
+
labelKey: "email",
|
|
62
|
+
formContainer: {
|
|
63
|
+
type: "modal",
|
|
64
|
+
size: "md",
|
|
65
|
+
pages: {
|
|
66
|
+
edit: {
|
|
67
|
+
displayName: "$page.settings.invites.form.edit_title",
|
|
68
|
+
description: "$page.settings.invites.form.edit_description",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
} as never,
|
|
72
|
+
formComponents: {
|
|
73
|
+
edit: {
|
|
74
|
+
componentName: "DmsForm",
|
|
75
|
+
options: {
|
|
76
|
+
fields: [],
|
|
77
|
+
fetchUrl: "/api/tables/admin-invites/get?id={{params.id}}",
|
|
78
|
+
submitUrl: "/api/tables/admin-invites/edit?id={{params.id}}",
|
|
79
|
+
},
|
|
80
|
+
} as never,
|
|
81
|
+
},
|
|
82
|
+
refreshCallback: refresh,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
const globals: Record<string, unknown> = {
|
|
88
|
+
ref,
|
|
89
|
+
Color,
|
|
90
|
+
HttpMethod,
|
|
91
|
+
normalizeActionConfig,
|
|
92
|
+
interpolateUrl,
|
|
93
|
+
useTranslation,
|
|
94
|
+
useEventedAction,
|
|
95
|
+
useI18n: () => ({ t, locale: ref("en") }),
|
|
96
|
+
useToast: () => ({ add: vi.fn() }),
|
|
97
|
+
useConfirm: () => ({ confirm: vi.fn() }),
|
|
98
|
+
useAuthFetch: () => ({ $authFetch: vi.fn() }),
|
|
99
|
+
useModal: () => ({ open: openModal }),
|
|
100
|
+
useDrawer: () => ({ open: vi.fn() }),
|
|
101
|
+
useDmsRoute: () => ({ query: {}, path: INVITES_PAGE }),
|
|
102
|
+
useExportJob: () => ({ runJob: vi.fn() }),
|
|
103
|
+
useComponentEvent: () => ({ sendComponentEvent: vi.fn() }),
|
|
104
|
+
navigateDms,
|
|
105
|
+
resolveDmsComponent: vi.fn(),
|
|
106
|
+
};
|
|
107
|
+
for (const [name, value] of Object.entries(globals)) {
|
|
108
|
+
vi.stubGlobal(name, value);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
afterEach(() => {
|
|
113
|
+
vi.unstubAllGlobals();
|
|
114
|
+
vi.clearAllMocks();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe("Invitations table: Edit invitation", () => {
|
|
118
|
+
it("opens the form in a modal over the list, not on a page", async () => {
|
|
119
|
+
const { editRow } = await invitesRowActions();
|
|
120
|
+
await editRow(INVITE);
|
|
121
|
+
|
|
122
|
+
expect(navigateDms).not.toHaveBeenCalled();
|
|
123
|
+
expect(openModal).toHaveBeenCalledTimes(1);
|
|
124
|
+
const [opened] = openModal.mock.calls[0] as unknown as [
|
|
125
|
+
{
|
|
126
|
+
title: string;
|
|
127
|
+
description: string;
|
|
128
|
+
size: string;
|
|
129
|
+
componentOptions: Record<string, unknown>;
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
expect(opened.title).toBe("Edit invitation · zz-invitee@example.com");
|
|
133
|
+
expect(opened.description).toBe(
|
|
134
|
+
"The name, roles and language the invitee gets on accepting.",
|
|
135
|
+
);
|
|
136
|
+
expect(opened.size).toBe("md");
|
|
137
|
+
expect(opened.componentOptions.fetchUrl).toBe(
|
|
138
|
+
"/api/tables/admin-invites/get?id=invite-1",
|
|
139
|
+
);
|
|
140
|
+
expect(opened.componentOptions.submitUrl).toBe(
|
|
141
|
+
"/api/tables/admin-invites/edit?id=invite-1",
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("closes the modal and refreshes the list once saved", async () => {
|
|
146
|
+
const { editRow } = await invitesRowActions();
|
|
147
|
+
await editRow(INVITE);
|
|
148
|
+
|
|
149
|
+
const [opened] = openModal.mock.calls[0] as unknown as [
|
|
150
|
+
{ componentOptions: { onSuccessCallback: () => void } },
|
|
151
|
+
];
|
|
152
|
+
opened.componentOptions.onSuccessCallback();
|
|
153
|
+
|
|
154
|
+
expect(modal.close).toHaveBeenCalledTimes(1);
|
|
155
|
+
expect(refresh).toHaveBeenCalledTimes(1);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -225,3 +225,29 @@ it("waits for the form's values before showing the pills", async () => {
|
|
|
225
225
|
await mountPicker({ loading: true });
|
|
226
226
|
expect(host.querySelectorAll("button[data-value]")).toHaveLength(0);
|
|
227
227
|
});
|
|
228
|
+
|
|
229
|
+
it("warns while a picked role amounts to owner-level access, not for an owner", async () => {
|
|
230
|
+
authFetch.mockResolvedValue({
|
|
231
|
+
...ROLE_OPTIONS,
|
|
232
|
+
roles: ROLE_OPTIONS.roles.map((role) =>
|
|
233
|
+
role._id === "admin"
|
|
234
|
+
? { ...role, warnings: ["$page.settings.roles.warning.members"] }
|
|
235
|
+
: role,
|
|
236
|
+
),
|
|
237
|
+
});
|
|
238
|
+
const warning = () =>
|
|
239
|
+
host.querySelector("[data-role-owner-level]")?.textContent?.trim();
|
|
240
|
+
await mountPicker({ ownerField: "isTenantOwner" });
|
|
241
|
+
|
|
242
|
+
await toggle("Finance");
|
|
243
|
+
expect(warning()).toBeUndefined();
|
|
244
|
+
|
|
245
|
+
await toggle("Admin");
|
|
246
|
+
expect(warning()).toBe(
|
|
247
|
+
"page.settings.members.invite.roles_owner_level Admin",
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
formState.value = { isTenantOwner: true };
|
|
251
|
+
await flush();
|
|
252
|
+
expect(warning()).toBeUndefined();
|
|
253
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { convertSiteLayoutTreeToTreeItems } from "../layers/dms-ui/app/build/types/tree";
|
|
3
|
+
|
|
4
|
+
// A page the viewer may open but whose every block is hidden from them is
|
|
5
|
+
// served out of the menu (`hasAccess: false`, name kept): an Invitations-only
|
|
6
|
+
// role got a Members entry that opened on "nothing to show for you". The
|
|
7
|
+
// pages nested under it keep their own entries, and opening it leads to the
|
|
8
|
+
// first of them.
|
|
9
|
+
|
|
10
|
+
type TreeNode = NonNullable<
|
|
11
|
+
Parameters<typeof convertSiteLayoutTreeToTreeItems>[0]
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
interface NodeFixture {
|
|
15
|
+
id: string;
|
|
16
|
+
fullId: string;
|
|
17
|
+
hasAccess?: boolean;
|
|
18
|
+
layoutUrl?: string;
|
|
19
|
+
children?: NodeFixture[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function node({ children = [], ...fixture }: NodeFixture): TreeNode {
|
|
23
|
+
return {
|
|
24
|
+
displayName: fixture.id,
|
|
25
|
+
fullSlug: `/${fixture.fullId.replaceAll(".", "/")}`,
|
|
26
|
+
...fixture,
|
|
27
|
+
children: Object.fromEntries(
|
|
28
|
+
children.map((child) => [child.id, node(child)]),
|
|
29
|
+
),
|
|
30
|
+
childrenOrders: children.map((child) => child.id),
|
|
31
|
+
} as unknown as TreeNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const page = (
|
|
35
|
+
fullId: string,
|
|
36
|
+
hasAccess = true,
|
|
37
|
+
children: NodeFixture[] = [],
|
|
38
|
+
) => ({
|
|
39
|
+
id: fullId.split(".").pop()!,
|
|
40
|
+
fullId,
|
|
41
|
+
hasAccess,
|
|
42
|
+
layoutUrl: `/${fullId}/pagelayout`,
|
|
43
|
+
children,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
function tree(members: NodeFixture, extra: NodeFixture[] = []): TreeNode {
|
|
47
|
+
return node({
|
|
48
|
+
id: "",
|
|
49
|
+
fullId: "",
|
|
50
|
+
children: [
|
|
51
|
+
{
|
|
52
|
+
id: "workspace",
|
|
53
|
+
fullId: "workspace",
|
|
54
|
+
hasAccess: true,
|
|
55
|
+
children: [members, page("workspace.roles"), ...extra],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function sidebarIds(root: TreeNode): string[] {
|
|
62
|
+
const ids = (items: Array<{ fullId?: unknown; children?: unknown }>) =>
|
|
63
|
+
items.flatMap((item): string[] => [
|
|
64
|
+
String(item.fullId),
|
|
65
|
+
...ids((item.children as typeof items | undefined) ?? []),
|
|
66
|
+
]);
|
|
67
|
+
return ids(convertSiteLayoutTreeToTreeItems(root).flat());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe("the sidebar", () => {
|
|
71
|
+
it("lists the reachable pages nested under a page left out of it", () => {
|
|
72
|
+
const root = tree(
|
|
73
|
+
page("workspace.members", false, [page("workspace.members.invites")]),
|
|
74
|
+
);
|
|
75
|
+
expect(sidebarIds(root)).toEqual([
|
|
76
|
+
"workspace",
|
|
77
|
+
"workspace.members.invites",
|
|
78
|
+
"workspace.roles",
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("still drops a group left out of it, with what it holds", () => {
|
|
83
|
+
const root = tree(page("workspace.members"), [
|
|
84
|
+
{
|
|
85
|
+
id: "billing",
|
|
86
|
+
fullId: "workspace.billing",
|
|
87
|
+
hasAccess: false,
|
|
88
|
+
children: [page("workspace.billing.invoices")],
|
|
89
|
+
},
|
|
90
|
+
]);
|
|
91
|
+
expect(sidebarIds(root)).not.toContain("workspace.billing.invoices");
|
|
92
|
+
});
|
|
93
|
+
});
|