@antelopejs/dms 0.4.5 → 0.4.7
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 +47 -0
- package/dist/hooks/invite-extensions.js +2 -2
- package/dist/hooks/invite-extensions.js.map +1 -1
- package/dist/implementations/dms/layout-banners.d.ts +18 -0
- package/dist/implementations/dms/layout-banners.js +60 -0
- package/dist/implementations/dms/layout-banners.js.map +1 -0
- package/dist/implementations/dms/page.d.ts +2 -0
- package/dist/implementations/dms/page.js +82 -27
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/implementations/dms/quick-actions.d.ts +5 -0
- package/dist/implementations/dms/quick-actions.js.map +1 -1
- package/dist/implementations/dms/resolver-timeout.d.ts +1 -0
- package/dist/implementations/dms/resolver-timeout.js +13 -0
- package/dist/implementations/dms/resolver-timeout.js.map +1 -0
- package/dist/implementations/dms/saas-mode.d.ts +8 -0
- package/dist/implementations/dms/saas-mode.js +20 -0
- package/dist/implementations/dms/saas-mode.js.map +1 -0
- package/dist/implementations/dms-auth/index.d.ts +2 -1
- package/dist/implementations/dms-auth/index.js +19 -8
- package/dist/implementations/dms-auth/index.js.map +1 -1
- package/dist/implementations/dms-html-render/service-jwt.js +2 -1
- package/dist/implementations/dms-html-render/service-jwt.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/pages/settings/users/index.d.ts +1 -0
- package/dist/pages/settings/users/index.js +1 -0
- package/dist/pages/settings/users/index.js.map +1 -1
- package/dist/pages/settings/users/invite-extension-routes.d.ts +4 -0
- package/dist/pages/settings/users/invite-extension-routes.js +57 -0
- package/dist/pages/settings/users/invite-extension-routes.js.map +1 -0
- package/dist/pages/settings/users/invites.d.ts +2 -1
- package/dist/pages/settings/users/invites.js +17 -5
- package/dist/pages/settings/users/invites.js.map +1 -1
- package/dist/pages/settings/users/members.d.ts +4 -1
- package/dist/pages/settings/users/members.js +10 -6
- package/dist/pages/settings/users/members.js.map +1 -1
- package/dist/pages/settings/users/notifications.js +1 -1
- package/dist/pages/settings/users/notifications.js.map +1 -1
- package/dist/pages/settings/users/quick-actions.d.ts +1 -0
- package/dist/pages/settings/users/quick-actions.js +22 -0
- package/dist/pages/settings/users/quick-actions.js.map +1 -0
- package/dist/routes/auth/signup.d.ts +2 -0
- package/dist/routes/auth/signup.js +7 -2
- package/dist/routes/auth/signup.js.map +1 -1
- package/dist/test/integration/invite-extension-edit.test.d.ts +1 -0
- package/dist/test/integration/invite-extension-edit.test.js +122 -0
- package/dist/test/integration/invite-extension-edit.test.js.map +1 -0
- package/dist/test/integration/saas-mode-ownership.test.d.ts +1 -0
- package/dist/test/integration/saas-mode-ownership.test.js +81 -0
- package/dist/test/integration/saas-mode-ownership.test.js.map +1 -0
- package/dist/test/integration/tenant-lifecycle.test.js +38 -0
- package/dist/test/integration/tenant-lifecycle.test.js.map +1 -1
- package/dist/test/unit/implementations/dms/layout-banners.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/layout-banners.test.js +217 -0
- package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -0
- package/dist/test/unit/implementations/dms/quick-actions-button.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms/quick-actions-button.test.js +220 -0
- package/dist/test/unit/implementations/dms/quick-actions-button.test.js.map +1 -0
- package/dist/test/unit/implementations/dms-html-render/generate-html.test.js +1 -1
- package/dist/test/unit/implementations/dms-html-render/generate-html.test.js.map +1 -1
- package/dist/test/unit/implementations/dms-html-render/service-jwt.test.d.ts +1 -0
- package/dist/test/unit/implementations/dms-html-render/service-jwt.test.js +37 -0
- package/dist/test/unit/implementations/dms-html-render/service-jwt.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/invite-extension.test.js +138 -12
- package/dist/test/unit/interfaces/dms/invite-extension.test.js.map +1 -1
- package/dist/test/unit/interfaces/dms/password-policy.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/password-policy.test.js +43 -0
- package/dist/test/unit/interfaces/dms/password-policy.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/saas-mode.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/saas-mode.test.js +42 -0
- package/dist/test/unit/interfaces/dms/saas-mode.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms/tenant-invite-email.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms/tenant-invite-email.test.js +53 -0
- package/dist/test/unit/interfaces/dms/tenant-invite-email.test.js.map +1 -0
- package/dist/test/unit/interfaces/dms-base/table-view-form-slots.test.d.ts +1 -0
- package/dist/test/unit/interfaces/dms-base/table-view-form-slots.test.js +80 -0
- package/dist/test/unit/interfaces/dms-base/table-view-form-slots.test.js.map +1 -0
- package/dist/test/unit/pages/settings/invite-member-quick-action.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/invite-member-quick-action.test.js +104 -0
- package/dist/test/unit/pages/settings/invite-member-quick-action.test.js.map +1 -0
- package/dist/test/unit/pages/settings/notifications-access-gate.test.d.ts +1 -0
- package/dist/test/unit/pages/settings/notifications-access-gate.test.js +78 -0
- package/dist/test/unit/pages/settings/notifications-access-gate.test.js.map +1 -0
- package/dist/test/unit/signup-account-guard.test.js +20 -2
- package/dist/test/unit/signup-account-guard.test.js.map +1 -1
- package/dist/test/unit/utils/admin-invite-email.test.d.ts +1 -0
- package/dist/test/unit/utils/admin-invite-email.test.js +69 -0
- package/dist/test/unit/utils/admin-invite-email.test.js.map +1 -0
- package/dist/utils/admin-invite-email.d.ts +14 -0
- package/dist/utils/admin-invite-email.js +51 -0
- package/dist/utils/admin-invite-email.js.map +1 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/validation/auth.schema.d.ts +3 -3
- package/dist/validation/auth.schema.js +1 -1
- package/dist/validation/auth.schema.js.map +1 -1
- package/dist/validation/password.d.ts +0 -1
- package/dist/validation/password.js +6 -3
- package/dist/validation/password.js.map +1 -1
- package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +37 -8
- package/frontend-vue/layers/dms-auth/i18n/locales/auth-en-GB.json +3 -1
- package/frontend-vue/layers/dms-auth/i18n/locales/auth-fr-FR.json +3 -1
- package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +4 -0
- package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +4 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +50 -0
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +16 -13
- package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidebar.vue +2 -2
- package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +11 -5
- package/frontend-vue/layers/dms-layout/app/build/components/notification/widgetRequest.ts +20 -0
- package/frontend-vue/layers/dms-layout/app/composables/layout/useLayoutBanners.ts +59 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useQuickActions.ts +15 -2
- package/frontend-vue/layers/dms-layout/app/custom-layouts/DefaultLayout.vue +2 -0
- package/frontend-vue/layers/dms-layout/app/emails/EmailAdminInvite.vue +54 -9
- package/frontend-vue/layers/dms-layout/app/error.vue +17 -2
- package/frontend-vue/layers/dms-layout/app/types/page.ts +22 -0
- package/frontend-vue/layers/dms-layout/app/utils/breadcrumb.ts +48 -0
- package/frontend-vue/layers/dms-layout/app/utils/favorites.ts +94 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +21 -2
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +21 -2
- package/frontend-vue/layers/dms-onboarding/app/composables/onboarding/index.ts +1 -1
- package/frontend-vue/layers/dms-onboarding/app/composables/onboarding/{useOnboardingMiddleware.ts → useOnboarding.ts} +0 -12
- package/frontend-vue/layers/dms-onboarding/app/custom-pages/onboarding.vue +4 -1
- package/frontend-vue/layers/dms-onboarding/app/middleware/onboarding.global.ts +21 -4
- package/frontend-vue/layers/dms-ui/app/build/components/containers/drawer/DynamicDrawer.vue +13 -3
- package/frontend-vue/layers/dms-ui/app/build/components/containers/modal/DynamicModal.vue +13 -3
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewConfig.ts +2 -7
- package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/columnVisibility.ts +13 -0
- package/frontend-vue/layers/dms-ui/app/components/PasswordStrength.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/activity/ActivityItem.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/banner/Banner.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/card/NavCard.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/Chart.vue +6 -16
- package/frontend-vue/layers/dms-ui/app/components/chart/ChartCard.vue +2 -2
- package/frontend-vue/layers/dms-ui/app/components/chart/internal/TrendBadge.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/copy/CopyButton.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/kpi/KpiCard.vue +3 -3
- package/frontend-vue/layers/dms-ui/app/components/master-detail/MasterDetail.vue +5 -1
- package/frontend-vue/layers/dms-ui/app/components/segmented/Segmented.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/status/StatusSummary.vue +1 -1
- package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +35 -11
- package/frontend-vue/layers/dms-ui/app/components/tree/Tree.vue +10 -9
- package/frontend-vue/layers/dms-ui/app/composables/chart/donutRecords.ts +26 -0
- package/frontend-vue/layers/dms-ui/app/composables/tab/types/props.ts +4 -2
- package/frontend-vue/layers/dms-ui/app/composables/tab/useTab.ts +3 -3
- package/frontend-vue/layers/dms-ui/app/composables/table-view/shortcuts/index.ts +17 -4
- package/frontend-vue/layers/dms-ui/app/composables/table-view/shortcuts/tableViewEscape.ts +22 -0
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/column.ts +1 -1
- package/frontend-vue/layers/dms-ui/app/composables/table-view/types/custom-button.ts +2 -0
- package/frontend-vue/layers/dms-ui/app/composables/tree/shortcuts/index.ts +19 -4
- package/frontend-vue/layers/dms-ui/app/composables/tree/shortcuts/treeEscape.ts +21 -0
- package/frontend-vue/layers/dms-ui/app/types/quick-actions.ts +38 -3
- package/frontend-vue/layers/dms-ui/app/utils/overlayFocus.ts +16 -0
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +4 -2
- package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +4 -2
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/pnpm-lock.yaml +5 -5
- package/frontend-vue/tests/admin-invite-email.test.ts +86 -0
- package/frontend-vue/tests/breadcrumb-target.test.ts +50 -0
- package/frontend-vue/tests/chart-nested-donut.test.ts +97 -0
- package/frontend-vue/tests/error-page-message.test.ts +83 -0
- package/frontend-vue/tests/favorite-page.test.ts +104 -0
- package/frontend-vue/tests/icon-aria-hidden.test.ts +29 -0
- package/frontend-vue/tests/layout-banners.test.ts +224 -0
- package/frontend-vue/tests/notification-popover-errors.test.ts +147 -0
- package/frontend-vue/tests/onboarding-middleware.test.ts +103 -0
- package/frontend-vue/tests/password-strength-meter.test.ts +33 -0
- package/frontend-vue/tests/quick-action-intent.test.ts +74 -0
- package/frontend-vue/tests/quick-actions.test.ts +23 -0
- package/frontend-vue/tests/signup-invitation-link.test.ts +126 -0
- package/frontend-vue/tests/skeleton-paragraph.test.ts +30 -0
- package/frontend-vue/tests/tab-without-component-id.test.ts +51 -0
- package/frontend-vue/tests/table-column-visibility.test.ts +20 -0
- package/frontend-vue/tests/table-view-escape-shortcut.test.ts +141 -0
- package/frontend-vue/tests/tree-escape-shortcut.test.ts +138 -0
- 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,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveAdminInviteLanguage = resolveAdminInviteLanguage;
|
|
4
|
+
exports.buildAdminInviteSubject = buildAdminInviteSubject;
|
|
5
|
+
exports.buildAdminInviteSignupLink = buildAdminInviteSignupLink;
|
|
6
|
+
const DEFAULT_LANGUAGE = "en";
|
|
7
|
+
const LANGUAGE_CODE_LENGTH = 2;
|
|
8
|
+
const SUBJECT_COPY = {
|
|
9
|
+
en: {
|
|
10
|
+
generic: "You're Invited to Join",
|
|
11
|
+
join: (target) => `You're invited to join ${target}`,
|
|
12
|
+
joinFromInviter: (inviter, target) => `${inviter} invited you to join ${target}`,
|
|
13
|
+
workspaceOnPlatform: (workspace, platform) => `${workspace} on ${platform}`,
|
|
14
|
+
},
|
|
15
|
+
fr: {
|
|
16
|
+
generic: "Vous êtes invité à nous rejoindre",
|
|
17
|
+
join: (target) => `Vous êtes invité à rejoindre ${target}`,
|
|
18
|
+
joinFromInviter: (inviter, target) => `${inviter} vous invite à rejoindre ${target}`,
|
|
19
|
+
workspaceOnPlatform: (workspace, platform) => `${workspace} sur ${platform}`,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
function resolveAdminInviteLanguage(language) {
|
|
23
|
+
const code = language?.slice(0, LANGUAGE_CODE_LENGTH).toLowerCase();
|
|
24
|
+
return code && Object.hasOwn(SUBJECT_COPY, code) ? code : DEFAULT_LANGUAGE;
|
|
25
|
+
}
|
|
26
|
+
function joinTarget(copy, names) {
|
|
27
|
+
const { workspaceName, platformName } = names;
|
|
28
|
+
if (workspaceName && platformName) {
|
|
29
|
+
return copy.workspaceOnPlatform(workspaceName, platformName);
|
|
30
|
+
}
|
|
31
|
+
return workspaceName || platformName;
|
|
32
|
+
}
|
|
33
|
+
function buildAdminInviteSubject(names, language) {
|
|
34
|
+
const copy = SUBJECT_COPY[resolveAdminInviteLanguage(language)];
|
|
35
|
+
const target = joinTarget(copy, names);
|
|
36
|
+
if (!target) {
|
|
37
|
+
return copy.generic;
|
|
38
|
+
}
|
|
39
|
+
return names.inviterName
|
|
40
|
+
? copy.joinFromInviter(names.inviterName, target)
|
|
41
|
+
: copy.join(target);
|
|
42
|
+
}
|
|
43
|
+
function buildAdminInviteSignupLink(clientBaseUrl, { email, token, inviteeName, language }) {
|
|
44
|
+
const query = new URLSearchParams({ token, email });
|
|
45
|
+
if (inviteeName)
|
|
46
|
+
query.set("name", inviteeName);
|
|
47
|
+
if (language)
|
|
48
|
+
query.set("lang", language);
|
|
49
|
+
return `${clientBaseUrl}/auth/signup?${query.toString()}`;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=admin-invite-email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-invite-email.js","sourceRoot":"","sources":["../../src/utils/admin-invite-email.ts"],"names":[],"mappings":";;AAyCA,gEAGC;AAiBD,0DAYC;AAcD,gEAQC;AA/FD,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAkB/B,MAAM,YAAY,GAA2C;IAC3D,EAAE,EAAE;QACF,OAAO,EAAE,wBAAwB;QACjC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,0BAA0B,MAAM,EAAE;QACpD,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACnC,GAAG,OAAO,wBAAwB,MAAM,EAAE;QAC5C,mBAAmB,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,SAAS,OAAO,QAAQ,EAAE;KAC5E;IACD,EAAE,EAAE;QACF,OAAO,EAAE,mCAAmC;QAC5C,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,gCAAgC,MAAM,EAAE;QAC1D,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACnC,GAAG,OAAO,4BAA4B,MAAM,EAAE;QAChD,mBAAmB,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAC3C,GAAG,SAAS,QAAQ,QAAQ,EAAE;KACjC;CACF,CAAC;AAMF,SAAgB,0BAA0B,CAAC,QAAiB;IAC1D,MAAM,IAAI,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,WAAW,EAAE,CAAC;IACpE,OAAO,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC7E,CAAC;AAED,SAAS,UAAU,CACjB,IAA4B,EAC5B,KAA4B;IAE5B,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IAC9C,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,aAAa,IAAI,YAAY,CAAC;AACvC,CAAC;AAMD,SAAgB,uBAAuB,CACrC,KAA4B,EAC5B,QAAiB;IAEjB,MAAM,IAAI,GAAG,YAAY,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACD,OAAO,KAAK,CAAC,WAAW;QACtB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC;AAcD,SAAgB,0BAA0B,CACxC,aAAqB,EACrB,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAA2B;IAEhE,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,IAAI,WAAW;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,QAAQ;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,GAAG,aAAa,gBAAgB,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5D,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -4,6 +4,5 @@ export * from "./export-jobs-run";
|
|
|
4
4
|
export * from "./run-in-batches";
|
|
5
5
|
export * from "./tenant-export-archive";
|
|
6
6
|
export * from "@antelopejs/interface-dms/utils/row-instance";
|
|
7
|
-
export * from "@antelopejs/interface-dms/utils/saas-mode";
|
|
8
7
|
export * from "@antelopejs/interface-dms/utils/time";
|
|
9
8
|
export * from "@antelopejs/interface-dms/utils/value-parser";
|
package/dist/utils/index.js
CHANGED
|
@@ -20,7 +20,6 @@ __exportStar(require("./export-jobs-run"), exports);
|
|
|
20
20
|
__exportStar(require("./run-in-batches"), exports);
|
|
21
21
|
__exportStar(require("./tenant-export-archive"), exports);
|
|
22
22
|
__exportStar(require("@antelopejs/interface-dms/utils/row-instance"), exports);
|
|
23
|
-
__exportStar(require("@antelopejs/interface-dms/utils/saas-mode"), exports);
|
|
24
23
|
__exportStar(require("@antelopejs/interface-dms/utils/time"), exports);
|
|
25
24
|
__exportStar(require("@antelopejs/interface-dms/utils/value-parser"), exports);
|
|
26
25
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,gDAA8B;AAC9B,oDAAkC;AAClC,mDAAiC;AACjC,0DAAwC;AACxC,+EAA6D;AAC7D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,gDAA8B;AAC9B,oDAAkC;AAClC,mDAAiC;AACjC,0DAAwC;AACxC,+EAA6D;AAC7D,uEAAqD;AACrD,+EAA6D"}
|
|
@@ -4,20 +4,20 @@ export declare const authSchema: {
|
|
|
4
4
|
name: z.ZodString;
|
|
5
5
|
email: z.ZodString;
|
|
6
6
|
password: z.ZodString;
|
|
7
|
-
lang: z.ZodString
|
|
7
|
+
lang: z.ZodOptional<z.ZodString>;
|
|
8
8
|
token: z.ZodString;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
10
|
token: string;
|
|
11
11
|
name: string;
|
|
12
12
|
password: string;
|
|
13
13
|
email: string;
|
|
14
|
-
lang
|
|
14
|
+
lang?: string | undefined;
|
|
15
15
|
}, {
|
|
16
16
|
token: string;
|
|
17
17
|
name: string;
|
|
18
18
|
password: string;
|
|
19
19
|
email: string;
|
|
20
|
-
lang
|
|
20
|
+
lang?: string | undefined;
|
|
21
21
|
}>;
|
|
22
22
|
login: z.ZodObject<{
|
|
23
23
|
email: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.schema.js","sourceRoot":"","sources":["../../src/validation/auth.schema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEzB,yCAA4C;AAE5C,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAC7C,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEvB,QAAA,UAAU,GAAG;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACzB,QAAQ,EAAE,yBAAc;QACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"auth.schema.js","sourceRoot":"","sources":["../../src/validation/auth.schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,8 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.passwordSchema =
|
|
36
|
+
exports.passwordSchema = void 0;
|
|
37
37
|
const z = __importStar(require("zod"));
|
|
38
|
-
|
|
39
|
-
exports.passwordSchema = z
|
|
38
|
+
const password_1 = require("@antelopejs/interface-dms/auth/password");
|
|
39
|
+
exports.passwordSchema = z
|
|
40
|
+
.string()
|
|
41
|
+
.min(password_1.PASSWORD_MIN_LENGTH)
|
|
42
|
+
.regex(password_1.PASSWORD_PATTERN);
|
|
40
43
|
//# sourceMappingURL=password.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/validation/password.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/validation/password.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,sEAGiD;AAEpC,QAAA,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,GAAG,CAAC,8BAAmB,CAAC;KACxB,KAAK,CAAC,2BAAgB,CAAC,CAAC"}
|
|
@@ -4,7 +4,7 @@ import type { FormSubmitEvent } from "@nuxt/ui";
|
|
|
4
4
|
|
|
5
5
|
const MIN_VALID_PASSWORD_SCORE = 4;
|
|
6
6
|
|
|
7
|
-
const { locale } = useI18n();
|
|
7
|
+
const { locale, locales, setLocale } = useI18n();
|
|
8
8
|
const config = useDmsRuntimeConfig();
|
|
9
9
|
const homepage = useHomepage();
|
|
10
10
|
|
|
@@ -12,13 +12,20 @@ const route = useDmsRoute();
|
|
|
12
12
|
const queryToken = computed(() => route.query.token as string);
|
|
13
13
|
const queryEmail = computed(() => route.query.email as string);
|
|
14
14
|
const queryName = computed(() => route.query.name as string | undefined);
|
|
15
|
+
// Only an invitation email links here, so a link without its token was cut
|
|
16
|
+
// short on the way: say so, rather than answering with a server error.
|
|
17
|
+
const hasInvitationToken = computed(
|
|
18
|
+
() => typeof queryToken.value === "string" && queryToken.value !== "",
|
|
19
|
+
);
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// The invitation link carries the language the invitee was invited in: the
|
|
22
|
+
// page opens in it, and the footer switcher still lets them pick another one
|
|
23
|
+
// before the account is created with whichever is current.
|
|
24
|
+
const invitationLanguage = locales.value.find(
|
|
25
|
+
(available) => available.code === route.query.lang,
|
|
26
|
+
);
|
|
27
|
+
if (invitationLanguage && invitationLanguage.code !== locale.value) {
|
|
28
|
+
void setLocale(invitationLanguage.code);
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
const isLoading = ref(false);
|
|
@@ -66,7 +73,29 @@ async function onSubmit(payload: FormSubmitEvent<Schema>) {
|
|
|
66
73
|
</script>
|
|
67
74
|
|
|
68
75
|
<template>
|
|
69
|
-
<div class="mx-auto max-w-
|
|
76
|
+
<div v-if="!hasInvitationToken" class="mx-auto max-w-md">
|
|
77
|
+
<DmsCard
|
|
78
|
+
variant="elevated"
|
|
79
|
+
:padded="false"
|
|
80
|
+
class="p-6 sm:p-12"
|
|
81
|
+
data-testid="signup-invalid-invitation"
|
|
82
|
+
>
|
|
83
|
+
<UIcon
|
|
84
|
+
name="i-ph-link-break"
|
|
85
|
+
class="text-warning mb-4 size-10"
|
|
86
|
+
:aria-hidden="true"
|
|
87
|
+
/>
|
|
88
|
+
<h1 class="pb-5 text-2xl font-bold">
|
|
89
|
+
{{ $t("page.signup.invalid_invitation_title") }}
|
|
90
|
+
</h1>
|
|
91
|
+
<p class="text-muted pb-7 text-sm font-normal">
|
|
92
|
+
{{ $t("page.signup.invalid_invitation_description") }}
|
|
93
|
+
</p>
|
|
94
|
+
<UButton :label="$t('button.login')" to="/auth" block />
|
|
95
|
+
</DmsCard>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div v-else class="mx-auto max-w-xl">
|
|
70
99
|
<DmsCard variant="elevated" :padded="false" class="p-6 sm:p-12">
|
|
71
100
|
<h1 class="pb-11 text-xl font-bold sm:text-2xl">
|
|
72
101
|
{{ $t("page.signup.create_account_title") }}
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"signup": {
|
|
17
17
|
"create_account_title": "Create your account",
|
|
18
|
-
"error_title": "Account creation error"
|
|
18
|
+
"error_title": "Account creation error",
|
|
19
|
+
"invalid_invitation_title": "This invitation link is invalid or incomplete",
|
|
20
|
+
"invalid_invitation_description": "Open the link from your invitation email again, or ask the workspace owner to send you a new invitation. Already have an account? Log in."
|
|
19
21
|
},
|
|
20
22
|
"2fa": {
|
|
21
23
|
"title": "Two-factor verification",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"signup": {
|
|
17
17
|
"create_account_title": "Créer votre compte",
|
|
18
|
-
"error_title": "Erreur de création de compte"
|
|
18
|
+
"error_title": "Erreur de création de compte",
|
|
19
|
+
"invalid_invitation_title": "Ce lien d'invitation est invalide ou incomplet",
|
|
20
|
+
"invalid_invitation_description": "Rouvrez le lien de votre e-mail d'invitation, ou demandez au propriétaire de l'espace de travail de vous envoyer une nouvelle invitation. Vous avez déjà un compte ? Connectez-vous."
|
|
19
21
|
},
|
|
20
22
|
"2fa": {
|
|
21
23
|
"title": "Vérification à deux facteurs",
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"title": "Restoring your session...",
|
|
45
45
|
"description": "Your session has expired. Refreshing your access and reloading the page."
|
|
46
46
|
},
|
|
47
|
+
"network": {
|
|
48
|
+
"title": "Connection lost",
|
|
49
|
+
"description": "The server could not be reached. Check your connection and try again."
|
|
50
|
+
},
|
|
47
51
|
"switch_account_failed": "Failed to switch account",
|
|
48
52
|
"email_already_used": "This email address is already used.",
|
|
49
53
|
"user_not_found": "No user found with this email address.",
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"title": "Restauration de votre session...",
|
|
45
45
|
"description": "Votre session a expiré. Renouvellement de l'accès et rechargement de la page."
|
|
46
46
|
},
|
|
47
|
+
"network": {
|
|
48
|
+
"title": "Connexion perdue",
|
|
49
|
+
"description": "Le serveur est injoignable. Vérifiez votre connexion et réessayez."
|
|
50
|
+
},
|
|
47
51
|
"switch_account_failed": "Échec du changement de compte",
|
|
48
52
|
"email_already_requested": "Cette adresse e-mail a déjà été demandée. Veuillez attendre avant de réessayer.",
|
|
49
53
|
"email_already_used": "Cette adresse e-mail est déjà utilisée.",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Stacks the global layout banners under the dashboard header, on every page
|
|
4
|
+
* of the dashboard layout. Each banner carries its own live-region role, so a
|
|
5
|
+
* banner appearing after a navigation is announced as well.
|
|
6
|
+
*/
|
|
7
|
+
const { banners, dismiss } = useLayoutBanners();
|
|
8
|
+
const { processI18n } = useTranslation();
|
|
9
|
+
|
|
10
|
+
const entries = computed(() =>
|
|
11
|
+
banners.value.map((banner) => ({
|
|
12
|
+
banner,
|
|
13
|
+
presentation: resolveLayoutBannerPresentation(banner),
|
|
14
|
+
})),
|
|
15
|
+
);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<div
|
|
20
|
+
v-if="entries.length"
|
|
21
|
+
data-dms-layout-banners
|
|
22
|
+
class="border-default flex flex-col border-b"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
v-for="{ banner, presentation } in entries"
|
|
26
|
+
:key="banner.key"
|
|
27
|
+
:role="presentation.role"
|
|
28
|
+
:data-dms-layout-banner="banner.key"
|
|
29
|
+
>
|
|
30
|
+
<UAlert
|
|
31
|
+
variant="subtle"
|
|
32
|
+
orientation="horizontal"
|
|
33
|
+
:color="presentation.color"
|
|
34
|
+
:icon="presentation.icon"
|
|
35
|
+
:close="banner.dismissible"
|
|
36
|
+
class="rounded-none px-4 py-2.5 sm:px-6"
|
|
37
|
+
@update:open="dismiss(banner.key)"
|
|
38
|
+
>
|
|
39
|
+
<template #description>
|
|
40
|
+
<component
|
|
41
|
+
:is="banner.component"
|
|
42
|
+
v-if="banner.component"
|
|
43
|
+
v-bind="banner.props"
|
|
44
|
+
/>
|
|
45
|
+
<template v-else>{{ processI18n(banner.text ?? "") }}</template>
|
|
46
|
+
</template>
|
|
47
|
+
</UAlert>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</template>
|
|
@@ -58,22 +58,21 @@ const { processI18n } = useTranslation();
|
|
|
58
58
|
const favoritePages = useFavoritePages();
|
|
59
59
|
|
|
60
60
|
const currentPageInfo = computed((): FavoritePage | null => {
|
|
61
|
-
const
|
|
62
|
-
const matchedRoute = siteLayout.findMatchingRoute(currentPath);
|
|
61
|
+
const matchedRoute = siteLayout.findMatchingRoute(route.path);
|
|
63
62
|
|
|
64
63
|
if (!matchedRoute) {
|
|
65
64
|
return null;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
return {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
matchedRoute.metadata.displayName ||
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
};
|
|
67
|
+
return buildFavoritePage({
|
|
68
|
+
path: route.path,
|
|
69
|
+
metadata: {
|
|
70
|
+
...matchedRoute.metadata,
|
|
71
|
+
displayName: matchedRoute.metadata.displayName || route.name?.toString(),
|
|
72
|
+
},
|
|
73
|
+
query: route.query,
|
|
74
|
+
translate: processI18n,
|
|
75
|
+
});
|
|
77
76
|
});
|
|
78
77
|
|
|
79
78
|
const isCurrentPageFavorite = computed(() => {
|
|
@@ -112,11 +111,15 @@ const breadcrumb = computed((): BreadcrumbItem[] => {
|
|
|
112
111
|
return null;
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
const
|
|
114
|
+
const target = buildBreadcrumbTarget(
|
|
115
|
+
to,
|
|
116
|
+
matchingRoute.metadata,
|
|
117
|
+
route.query,
|
|
118
|
+
);
|
|
116
119
|
|
|
117
120
|
return {
|
|
118
121
|
label: processI18n(matchingRoute.metadata?.displayName || path),
|
|
119
|
-
...(
|
|
122
|
+
...(target ? { to: target } : {}),
|
|
120
123
|
};
|
|
121
124
|
})
|
|
122
125
|
.filter((item) => item !== null),
|
|
@@ -42,8 +42,8 @@ if (!siteLayout.siteLayout.value) {
|
|
|
42
42
|
|
|
43
43
|
const favoritePages = useFavoritePages();
|
|
44
44
|
|
|
45
|
-
favoritePages.cleanupInvalidFavorites(
|
|
46
|
-
(path
|
|
45
|
+
favoritePages.cleanupInvalidFavorites((path) =>
|
|
46
|
+
isFavoritePathValid(path, siteLayout.findMatchingRoute),
|
|
47
47
|
);
|
|
48
48
|
|
|
49
49
|
const isOwner = useIsOwner();
|
package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { formatRelativeTime } from "#dms-core/app/utils/formatter";
|
|
3
3
|
import NotificationCard from "./NotificationCard.vue";
|
|
4
|
+
import { settleWidgetRequest } from "./widgetRequest";
|
|
4
5
|
|
|
5
6
|
const MAX_DISPLAYED_COUNT = 99;
|
|
6
7
|
|
|
@@ -25,9 +26,14 @@ const { isLoadingMore, setupObserver, disconnectObserver } = useInfiniteScroll(
|
|
|
25
26
|
hasMore,
|
|
26
27
|
);
|
|
27
28
|
|
|
29
|
+
const refreshUnreadCount = () =>
|
|
30
|
+
settleWidgetRequest(fetchUnreadCount, () => {
|
|
31
|
+
unreadCount.value = 0;
|
|
32
|
+
});
|
|
33
|
+
|
|
28
34
|
const handleNotificationEvent = async () => {
|
|
29
35
|
if (!isOpen.value) {
|
|
30
|
-
await
|
|
36
|
+
await refreshUnreadCount();
|
|
31
37
|
}
|
|
32
38
|
};
|
|
33
39
|
|
|
@@ -37,14 +43,14 @@ const handleFormSubmitSuccess = async (event: Event) => {
|
|
|
37
43
|
|
|
38
44
|
if (submitUrl && submitUrl.includes("/api/notification/")) {
|
|
39
45
|
if (!isOpen.value) {
|
|
40
|
-
await
|
|
46
|
+
await refreshUnreadCount();
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
};
|
|
44
50
|
|
|
45
51
|
const markNotificationsAsRead = async () => {
|
|
46
52
|
if (hasBeenOpened.value) {
|
|
47
|
-
await markAllAsRead
|
|
53
|
+
await settleWidgetRequest(markAllAsRead);
|
|
48
54
|
hasBeenOpened.value = false;
|
|
49
55
|
}
|
|
50
56
|
};
|
|
@@ -57,7 +63,7 @@ const handleBeforeUnload = () => {
|
|
|
57
63
|
|
|
58
64
|
onMounted(async () => {
|
|
59
65
|
if (!loggedIn.value) return;
|
|
60
|
-
await
|
|
66
|
+
await refreshUnreadCount();
|
|
61
67
|
|
|
62
68
|
window.addEventListener(
|
|
63
69
|
NotificationEvents.NOTIFICATION_RECEIVED,
|
|
@@ -87,7 +93,7 @@ onUnmounted(() => {
|
|
|
87
93
|
watch(isOpen, async (isNowOpen) => {
|
|
88
94
|
if (isNowOpen) {
|
|
89
95
|
hasBeenOpened.value = true;
|
|
90
|
-
await fetchNotifications(true);
|
|
96
|
+
await settleWidgetRequest(() => fetchNotifications(true));
|
|
91
97
|
await nextTick();
|
|
92
98
|
setupObserver();
|
|
93
99
|
} else {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const WIDGET_REQUEST_FAILED_MESSAGE = "[dms] Header widget request failed";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runs a request a layout widget issues on its own (on mount, on a realtime
|
|
5
|
+
* event, on open). A failure -- a tenant access gate answering 403, a network
|
|
6
|
+
* error -- is logged and degrades the widget through `onFailure` instead of
|
|
7
|
+
* reaching the app error handler, which would replace the whole page with an
|
|
8
|
+
* error screen.
|
|
9
|
+
*/
|
|
10
|
+
export async function settleWidgetRequest(
|
|
11
|
+
request: () => Promise<unknown>,
|
|
12
|
+
onFailure?: () => void,
|
|
13
|
+
): Promise<void> {
|
|
14
|
+
try {
|
|
15
|
+
await request();
|
|
16
|
+
} catch (error) {
|
|
17
|
+
onFailure?.();
|
|
18
|
+
console.warn(WIDGET_REQUEST_FAILED_MESSAGE, error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const DISMISSED_BANNERS_COOKIE = "dms-dismissed-banners";
|
|
2
|
+
|
|
3
|
+
type LayoutBannerRole = "status" | "alert";
|
|
4
|
+
|
|
5
|
+
interface LayoutBannerPresentation {
|
|
6
|
+
role: LayoutBannerRole;
|
|
7
|
+
color: LayoutBannerVariant;
|
|
8
|
+
icon: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// An error interrupts the screen reader; info and warning wait their turn.
|
|
12
|
+
const PRESENTATIONS: Record<LayoutBannerVariant, LayoutBannerPresentation> = {
|
|
13
|
+
info: { role: "status", color: "info", icon: "i-ph-info-light" },
|
|
14
|
+
warning: { role: "status", color: "warning", icon: "i-ph-warning-light" },
|
|
15
|
+
error: { role: "alert", color: "error", icon: "i-ph-warning-octagon-light" },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Role, color and icon a banner renders with. An unknown variant — from a
|
|
20
|
+
* newer backend, or an untyped registration — renders as `info` rather than
|
|
21
|
+
* as an unstyled strip.
|
|
22
|
+
*/
|
|
23
|
+
export const resolveLayoutBannerPresentation = (
|
|
24
|
+
banner: LayoutBanner,
|
|
25
|
+
): LayoutBannerPresentation => {
|
|
26
|
+
const presentation = PRESENTATIONS[banner.variant] ?? PRESENTATIONS.info;
|
|
27
|
+
return { ...presentation, icon: banner.icon ?? presentation.icon };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The global banners rendered under the dashboard header, as resolved by the
|
|
32
|
+
* server for this request (see `RegisterLayoutBanner` in
|
|
33
|
+
* `@antelopejs/interface-dms/layout-banners`), minus the ones the user
|
|
34
|
+
* dismissed.
|
|
35
|
+
*
|
|
36
|
+
* Dismissals are kept in a session cookie rather than in local storage so the
|
|
37
|
+
* server-rendered page already leaves a dismissed banner out, instead of
|
|
38
|
+
* painting it and removing it on hydration.
|
|
39
|
+
*/
|
|
40
|
+
export const useLayoutBanners = () => {
|
|
41
|
+
const { siteLayout } = useSiteLayout();
|
|
42
|
+
const dismissed = useDmsCookie<string[]>(DISMISSED_BANNERS_COOKIE, {
|
|
43
|
+
default: () => [],
|
|
44
|
+
sameSite: "lax",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const banners = computed<LayoutBanner[]>(() =>
|
|
48
|
+
(siteLayout.value?.banners ?? []).filter(
|
|
49
|
+
(banner) => !banner.dismissible || !dismissed.value.includes(banner.key),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
function dismiss(key: string): void {
|
|
54
|
+
if (dismissed.value.includes(key)) return;
|
|
55
|
+
dismissed.value = [...dismissed.value, key];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { banners, dismiss };
|
|
59
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
QUICK_ACTION_ADD,
|
|
3
|
+
QUICK_ACTION_BUTTON,
|
|
4
|
+
QUICK_ACTION_BUTTON_KEY,
|
|
3
5
|
QUICK_ACTION_COMPONENT_KEY,
|
|
4
6
|
QUICK_ACTION_QUERY_KEY,
|
|
5
7
|
} from "#dms-ui/app/types/quick-actions";
|
|
@@ -32,6 +34,17 @@ const targetHandlers: Record<
|
|
|
32
34
|
},
|
|
33
35
|
});
|
|
34
36
|
},
|
|
37
|
+
button: (target) => {
|
|
38
|
+
if (target.type !== "button") return;
|
|
39
|
+
return navigateDms({
|
|
40
|
+
path: target.to,
|
|
41
|
+
query: {
|
|
42
|
+
[QUICK_ACTION_QUERY_KEY]: QUICK_ACTION_BUTTON,
|
|
43
|
+
[QUICK_ACTION_COMPONENT_KEY]: target.component,
|
|
44
|
+
[QUICK_ACTION_BUTTON_KEY]: target.button,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
},
|
|
35
48
|
event: (target) => {
|
|
36
49
|
if (target.type !== "event") return;
|
|
37
50
|
if (typeof window === "undefined") return;
|
|
@@ -43,8 +56,8 @@ const targetHandlers: Record<
|
|
|
43
56
|
|
|
44
57
|
/**
|
|
45
58
|
* Runs the client-side behavior a quick action declares through its
|
|
46
|
-
* discriminated `target`: `navigate` and `
|
|
47
|
-
* page, `event` dispatches a window `CustomEvent` in place for whoever
|
|
59
|
+
* discriminated `target`: `navigate`, `openForm` and `button` route to the
|
|
60
|
+
* action's page, `event` dispatches a window `CustomEvent` in place for whoever
|
|
48
61
|
* listens.
|
|
49
62
|
*/
|
|
50
63
|
export function dispatchQuickActionTarget(target: QuickActionTarget): unknown {
|
|
@@ -3,6 +3,7 @@ import Container from "../build/components/layout/Container.vue";
|
|
|
3
3
|
import PageHeader from "../build/components/layout/PageHeader.vue";
|
|
4
4
|
import DashboardSidebar from "../build/components/layout/DashboardSidebar.vue";
|
|
5
5
|
import DashboardHeader from "../build/components/layout/DashboardHeader.vue";
|
|
6
|
+
import DashboardBanners from "../build/components/layout/DashboardBanners.vue";
|
|
6
7
|
|
|
7
8
|
interface Props {
|
|
8
9
|
fullWidth?: boolean;
|
|
@@ -28,6 +29,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
28
29
|
<UDashboardPanel>
|
|
29
30
|
<template #header>
|
|
30
31
|
<DashboardHeader />
|
|
32
|
+
<DashboardBanners />
|
|
31
33
|
</template>
|
|
32
34
|
|
|
33
35
|
<template #body>
|