@masterteam/delegations 0.0.46 → 0.0.47
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.
|
@@ -401,11 +401,11 @@ class StartSessionDialog {
|
|
|
401
401
|
this.ref.close(false);
|
|
402
402
|
}
|
|
403
403
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StartSessionDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
404
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: StartSessionDialog, isStandalone: true, selector: "mt-start-session-dialog", inputs: { delegation: { classPropertyName: "delegation", publicName: "delegation", isSignal: true, isRequired: true, transformFunction: null }, intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\n <div class=\"flex flex-col gap-4 p-2\">\n <div class=\"flex items-start gap-3\">\n <div class=\"flex flex-col min-w-0\">\n <mt-entity-preview\n [data]=\"userEntity(delegation().delegator)\"\n ></mt-entity-preview>\n </div>\n </div>\n\n <p class=\"text-sm text-surface-600 leading-relaxed\">\n {{ t(bodyKey()) }}\n </p>\n\n <div class=\"flex justify-end gap-2 pt-2 border-t border-surface-200\">\n <mt-button\n variant=\"outlined\"\n color=\"secondary\"\n [label]=\"t('delegations.common.cancel')\"\n [disabled]=\"isBusy()\"\n (click)=\"cancel()\"\n ></mt-button>\n <mt-button\n color=\"primary\"\n icon=\"user.users-check\"\n [label]=\"t(confirmLabelKey())\"\n [loading]=\"isBusy()\"\n (click)=\"confirm()\"\n ></mt-button>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
404
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: StartSessionDialog, isStandalone: true, selector: "mt-start-session-dialog", inputs: { delegation: { classPropertyName: "delegation", publicName: "delegation", isSignal: true, isRequired: true, transformFunction: null }, intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div class=\"flex flex-col gap-4 p-2\">\r\n <div class=\"flex items-start gap-3\">\r\n <div class=\"flex flex-col min-w-0\">\r\n <mt-entity-preview\r\n [data]=\"userEntity(delegation().delegator)\"\r\n ></mt-entity-preview>\r\n </div>\r\n </div>\r\n\r\n <p class=\"text-sm text-surface-600 leading-relaxed\">\r\n {{ t(bodyKey()) }}\r\n </p>\r\n\r\n <div class=\"flex justify-end gap-2 pt-2 border-t border-surface-200\">\r\n <mt-button\r\n variant=\"outlined\"\r\n color=\"secondary\"\r\n [label]=\"t('delegations.common.cancel')\"\r\n [disabled]=\"isBusy()\"\r\n (click)=\"cancel()\"\r\n ></mt-button>\r\n <mt-button\r\n color=\"primary\"\r\n icon=\"user.users-check\"\r\n [label]=\"t(confirmLabelKey())\"\r\n [loading]=\"isBusy()\"\r\n (click)=\"confirm()\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
405
405
|
}
|
|
406
406
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StartSessionDialog, decorators: [{
|
|
407
407
|
type: Component,
|
|
408
|
-
args: [{ selector: 'mt-start-session-dialog', imports: [CommonModule, Button, EntityPreview, TranslocoDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n <div class=\"flex flex-col gap-4 p-2\">\n <div class=\"flex items-start gap-3\">\n <div class=\"flex flex-col min-w-0\">\n <mt-entity-preview\n [data]=\"userEntity(delegation().delegator)\"\n ></mt-entity-preview>\n </div>\n </div>\n\n <p class=\"text-sm text-surface-600 leading-relaxed\">\n {{ t(bodyKey()) }}\n </p>\n\n <div class=\"flex justify-end gap-2 pt-2 border-t border-surface-200\">\n <mt-button\n variant=\"outlined\"\n color=\"secondary\"\n [label]=\"t('delegations.common.cancel')\"\n [disabled]=\"isBusy()\"\n (click)=\"cancel()\"\n ></mt-button>\n <mt-button\n color=\"primary\"\n icon=\"user.users-check\"\n [label]=\"t(confirmLabelKey())\"\n [loading]=\"isBusy()\"\n (click)=\"confirm()\"\n ></mt-button>\n </div>\n </div>\n</ng-container>\n" }]
|
|
408
|
+
args: [{ selector: 'mt-start-session-dialog', imports: [CommonModule, Button, EntityPreview, TranslocoDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n <div class=\"flex flex-col gap-4 p-2\">\r\n <div class=\"flex items-start gap-3\">\r\n <div class=\"flex flex-col min-w-0\">\r\n <mt-entity-preview\r\n [data]=\"userEntity(delegation().delegator)\"\r\n ></mt-entity-preview>\r\n </div>\r\n </div>\r\n\r\n <p class=\"text-sm text-surface-600 leading-relaxed\">\r\n {{ t(bodyKey()) }}\r\n </p>\r\n\r\n <div class=\"flex justify-end gap-2 pt-2 border-t border-surface-200\">\r\n <mt-button\r\n variant=\"outlined\"\r\n color=\"secondary\"\r\n [label]=\"t('delegations.common.cancel')\"\r\n [disabled]=\"isBusy()\"\r\n (click)=\"cancel()\"\r\n ></mt-button>\r\n <mt-button\r\n color=\"primary\"\r\n icon=\"user.users-check\"\r\n [label]=\"t(confirmLabelKey())\"\r\n [loading]=\"isBusy()\"\r\n (click)=\"confirm()\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n" }]
|
|
409
409
|
}], propDecorators: { delegation: [{ type: i0.Input, args: [{ isSignal: true, alias: "delegation", required: true }] }], intent: [{ type: i0.Input, args: [{ isSignal: true, alias: "intent", required: false }] }] } });
|
|
410
410
|
|
|
411
411
|
/**
|
|
@@ -466,20 +466,20 @@ class DelegationStatusChip {
|
|
|
466
466
|
status = input.required(...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
467
467
|
visual = computed(() => STATUS_VISUAL[this.status()] ?? STATUS_VISUAL.Scheduled, ...(ngDevMode ? [{ debugName: "visual" }] : /* istanbul ignore next */ []));
|
|
468
468
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationStatusChip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
469
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: DelegationStatusChip, isStandalone: true, selector: "mt-delegation-status-chip", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
470
|
-
<ng-container *transloco="let t">
|
|
471
|
-
@let v = visual();
|
|
472
|
-
<mt-chip [label]="t(v.i18nKey)" [styleClass]="v.styleClass"></mt-chip>
|
|
473
|
-
</ng-container>
|
|
469
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: DelegationStatusChip, isStandalone: true, selector: "mt-delegation-status-chip", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
470
|
+
<ng-container *transloco="let t">
|
|
471
|
+
@let v = visual();
|
|
472
|
+
<mt-chip [label]="t(v.i18nKey)" [styleClass]="v.styleClass"></mt-chip>
|
|
473
|
+
</ng-container>
|
|
474
474
|
`, isInline: true, styles: [":host{display:inline-flex}:host ::ng-deep .mt-status-chip{font-weight:500;font-size:.75rem;border-radius:9999px;padding-inline:.625rem;padding-block:.125rem}:host ::ng-deep .mt-status-chip--active{background-color:#dcfce7;color:#166534}:host ::ng-deep .mt-status-chip--scheduled{background-color:#dbeafe;color:#1e40af}:host ::ng-deep .mt-status-chip--pending{background-color:#fef9c3;color:#854d0e}:host ::ng-deep .mt-status-chip--expired{background-color:#f3f4f6;color:#4b5563}:host ::ng-deep .mt-status-chip--rejected{background-color:#fee2e2;color:#991b1b}:host ::ng-deep .mt-status-chip--cancelled{background-color:#e5e7eb;color:#374151}:host-context(.dark) ::ng-deep .mt-status-chip--active{background-color:#22c55e33;color:#86efac}:host-context(.dark) ::ng-deep .mt-status-chip--scheduled{background-color:#3b82f633;color:#93c5fd}:host-context(.dark) ::ng-deep .mt-status-chip--pending{background-color:#eab30833;color:#fde047}:host-context(.dark) ::ng-deep .mt-status-chip--expired{background-color:#94a3b833;color:#cbd5e1}:host-context(.dark) ::ng-deep .mt-status-chip--rejected{background-color:#ef444433;color:#fca5a5}:host-context(.dark) ::ng-deep .mt-status-chip--cancelled{background-color:#94a3b826;color:#cbd5e1}\n"], dependencies: [{ kind: "component", type: Chip, selector: "mt-chip", inputs: ["label", "icon", "image", "removable", "removeIcon", "styleClass", "size"], outputs: ["onRemove", "onImageError"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
475
475
|
}
|
|
476
476
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationStatusChip, decorators: [{
|
|
477
477
|
type: Component,
|
|
478
|
-
args: [{ selector: 'mt-delegation-status-chip', standalone: true, imports: [Chip, TranslocoDirective], template: `
|
|
479
|
-
<ng-container *transloco="let t">
|
|
480
|
-
@let v = visual();
|
|
481
|
-
<mt-chip [label]="t(v.i18nKey)" [styleClass]="v.styleClass"></mt-chip>
|
|
482
|
-
</ng-container>
|
|
478
|
+
args: [{ selector: 'mt-delegation-status-chip', standalone: true, imports: [Chip, TranslocoDirective], template: `
|
|
479
|
+
<ng-container *transloco="let t">
|
|
480
|
+
@let v = visual();
|
|
481
|
+
<mt-chip [label]="t(v.i18nKey)" [styleClass]="v.styleClass"></mt-chip>
|
|
482
|
+
</ng-container>
|
|
483
483
|
`, styles: [":host{display:inline-flex}:host ::ng-deep .mt-status-chip{font-weight:500;font-size:.75rem;border-radius:9999px;padding-inline:.625rem;padding-block:.125rem}:host ::ng-deep .mt-status-chip--active{background-color:#dcfce7;color:#166534}:host ::ng-deep .mt-status-chip--scheduled{background-color:#dbeafe;color:#1e40af}:host ::ng-deep .mt-status-chip--pending{background-color:#fef9c3;color:#854d0e}:host ::ng-deep .mt-status-chip--expired{background-color:#f3f4f6;color:#4b5563}:host ::ng-deep .mt-status-chip--rejected{background-color:#fee2e2;color:#991b1b}:host ::ng-deep .mt-status-chip--cancelled{background-color:#e5e7eb;color:#374151}:host-context(.dark) ::ng-deep .mt-status-chip--active{background-color:#22c55e33;color:#86efac}:host-context(.dark) ::ng-deep .mt-status-chip--scheduled{background-color:#3b82f633;color:#93c5fd}:host-context(.dark) ::ng-deep .mt-status-chip--pending{background-color:#eab30833;color:#fde047}:host-context(.dark) ::ng-deep .mt-status-chip--expired{background-color:#94a3b833;color:#cbd5e1}:host-context(.dark) ::ng-deep .mt-status-chip--rejected{background-color:#ef444433;color:#fca5a5}:host-context(.dark) ::ng-deep .mt-status-chip--cancelled{background-color:#94a3b826;color:#cbd5e1}\n"] }]
|
|
484
484
|
}], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: true }] }] } });
|
|
485
485
|
|
|
@@ -554,7 +554,7 @@ class DelegationMenuPanel {
|
|
|
554
554
|
});
|
|
555
555
|
}
|
|
556
556
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationMenuPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
557
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationMenuPanel, isStandalone: true, selector: "mt-delegation-menu-panel", inputs: { managePath: { classPropertyName: "managePath", publicName: "managePath", isSignal: true, isRequired: false, transformFunction: null }, showManageLink: { classPropertyName: "showManageLink", publicName: "showManageLink", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequested: "closeRequested" }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\n @if (mode() !== \"hidden\") {\n <div class=\"flex w-full flex-col\">\n @if (mode() === \"active\" && active(); as session) {\n <!-- Active session -->\n <div class=\"flex items-center gap-3 border-b border-surface px-4 py-3\">\n <mt-avatar\n [label]=\"initials(onBehalfOf())\"\n shape=\"circle\"\n styleClass=\"!size-9 !text-sm !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <span\n class=\"text-[0.625rem] font-medium uppercase text-surface-500\"\n >\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\n </span>\n <span class=\"truncate text-sm font-semibold text-surface-900\">\n {{ onBehalfOf()?.displayName }}\n </span>\n <span class=\"truncate text-xs text-surface-500\">\n {{\n t(\"delegations.session.executedBy\", {\n actualUserName: executedBy()?.displayName,\n })\n }}\n </span>\n </div>\n <mt-delegation-status-chip\n status=\"Active\"\n ></mt-delegation-status-chip>\n </div>\n\n <div class=\"flex flex-col p-1.5\">\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-surface-700 hover:bg-surface-100\"\n (click)=\"endSession($event)\"\n >\n <mt-icon icon=\"arrow.arrow-left\" styleClass=\"text-base\"></mt-icon>\n <span>{{ t(\"delegations.action.endSession\") }}</span>\n </button>\n </div>\n\n @if (candidates().length > 1) {\n <div class=\"border-t border-surface p-1.5\">\n <div\n class=\"px-2 pb-1 text-[0.625rem] font-medium uppercase text-surface-400\"\n >\n {{ t(\"delegations.session.switchToAnother\") }}\n </div>\n @for (cand of candidates(); track $index) {\n @if (cand.delegationId !== session.delegation.delegationId) {\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\n [attr.aria-label]=\"\n t('delegations.action.switchSession') +\n ': ' +\n cand.delegator.displayName\n \"\n (click)=\"switchTo(cand, $event)\"\n >\n <mt-avatar\n [label]=\"initials(cand.delegator)\"\n shape=\"circle\"\n styleClass=\"!size-8 !text-xs !bg-surface-100 !text-surface-600\"\n ></mt-avatar>\n <span\n class=\"min-w-0 flex-1 truncate text-sm font-medium text-surface-800\"\n >\n {{ cand.delegator.displayName }}\n </span>\n <mt-icon\n icon=\"arrow.switch-horizontal-01\"\n styleClass=\"text-base text-surface-400\"\n ></mt-icon>\n </button>\n }\n }\n </div>\n }\n } @else if (mode() === \"candidates\") {\n <!-- Candidates available -->\n <div class=\"border-b border-surface px-4 py-3\">\n <div class=\"text-sm font-semibold text-surface-900\">\n {{ t(\"delegations.session.youCanActAs\") }}\n </div>\n <div class=\"mt-0.5 text-xs text-surface-500\">\n {{ t(\"delegations.session.chooseDelegatorHint\") }}\n </div>\n </div>\n <div class=\"flex max-h-72 flex-col overflow-y-auto p-1.5\">\n @for (cand of candidates(); track $index) {\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\n [attr.aria-label]=\"\n t('delegations.action.startSession') +\n ': ' +\n cand.delegator.displayName\n \"\n (click)=\"start(cand, $event)\"\n >\n <mt-avatar\n [label]=\"initials(cand.delegator)\"\n shape=\"circle\"\n styleClass=\"!size-8 !text-xs !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"truncate text-sm font-medium text-surface-800\">\n {{ cand.delegator.displayName }}\n </span>\n @if (cand.delegator.email) {\n <span class=\"truncate text-xs text-surface-500\">\n {{ cand.delegator.email }}\n </span>\n }\n </span>\n <mt-icon\n icon=\"arrow.arrow-right\"\n styleClass=\"text-base text-surface-400\"\n ></mt-icon>\n </button>\n }\n </div>\n }\n\n @if (showManageLink()) {\n <div class=\"border-t border-surface p-1.5\">\n <a\n [routerLink]=\"managePath()\"\n (click)=\"onManage()\"\n class=\"flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm text-surface-700 hover:bg-surface-100\"\n >\n <mt-icon\n icon=\"general.settings-02\"\n styleClass=\"text-base\"\n ></mt-icon>\n <span>{{ t(\"delegations.session.manage\") }}</span>\n </a>\n </div>\n }\n </div>\n }\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationStatusChip, selector: "mt-delegation-status-chip", inputs: ["status"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
557
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationMenuPanel, isStandalone: true, selector: "mt-delegation-menu-panel", inputs: { managePath: { classPropertyName: "managePath", publicName: "managePath", isSignal: true, isRequired: false, transformFunction: null }, showManageLink: { classPropertyName: "showManageLink", publicName: "showManageLink", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequested: "closeRequested" }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n @if (mode() !== \"hidden\") {\r\n <div class=\"flex w-full flex-col\">\r\n @if (mode() === \"active\" && active(); as session) {\r\n <!-- Active session -->\r\n <div class=\"flex items-center gap-3 border-b border-surface px-4 py-3\">\r\n <mt-avatar\r\n [label]=\"initials(onBehalfOf())\"\r\n shape=\"circle\"\r\n styleClass=\"!size-9 !text-sm !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <div class=\"flex min-w-0 flex-1 flex-col\">\r\n <span\r\n class=\"text-[0.625rem] font-medium uppercase text-surface-500\"\r\n >\r\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\r\n </span>\r\n <span class=\"truncate text-sm font-semibold text-surface-900\">\r\n {{ onBehalfOf()?.displayName }}\r\n </span>\r\n <span class=\"truncate text-xs text-surface-500\">\r\n {{\r\n t(\"delegations.session.executedBy\", {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n }}\r\n </span>\r\n </div>\r\n <mt-delegation-status-chip\r\n status=\"Active\"\r\n ></mt-delegation-status-chip>\r\n </div>\r\n\r\n <div class=\"flex flex-col p-1.5\">\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-surface-700 hover:bg-surface-100\"\r\n (click)=\"endSession($event)\"\r\n >\r\n <mt-icon icon=\"arrow.arrow-left\" styleClass=\"text-base\"></mt-icon>\r\n <span>{{ t(\"delegations.action.endSession\") }}</span>\r\n </button>\r\n </div>\r\n\r\n @if (candidates().length > 1) {\r\n <div class=\"border-t border-surface p-1.5\">\r\n <div\r\n class=\"px-2 pb-1 text-[0.625rem] font-medium uppercase text-surface-400\"\r\n >\r\n {{ t(\"delegations.session.switchToAnother\") }}\r\n </div>\r\n @for (cand of candidates(); track $index) {\r\n @if (cand.delegationId !== session.delegation.delegationId) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\r\n [attr.aria-label]=\"\r\n t('delegations.action.switchSession') +\r\n ': ' +\r\n cand.delegator.displayName\r\n \"\r\n (click)=\"switchTo(cand, $event)\"\r\n >\r\n <mt-avatar\r\n [label]=\"initials(cand.delegator)\"\r\n shape=\"circle\"\r\n styleClass=\"!size-8 !text-xs !bg-surface-100 !text-surface-600\"\r\n ></mt-avatar>\r\n <span\r\n class=\"min-w-0 flex-1 truncate text-sm font-medium text-surface-800\"\r\n >\r\n {{ cand.delegator.displayName }}\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.switch-horizontal-01\"\r\n styleClass=\"text-base text-surface-400\"\r\n ></mt-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n } @else if (mode() === \"candidates\") {\r\n <!-- Candidates available -->\r\n <div class=\"border-b border-surface px-4 py-3\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ t(\"delegations.session.youCanActAs\") }}\r\n </div>\r\n <div class=\"mt-0.5 text-xs text-surface-500\">\r\n {{ t(\"delegations.session.chooseDelegatorHint\") }}\r\n </div>\r\n </div>\r\n <div class=\"flex max-h-72 flex-col overflow-y-auto p-1.5\">\r\n @for (cand of candidates(); track $index) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\r\n [attr.aria-label]=\"\r\n t('delegations.action.startSession') +\r\n ': ' +\r\n cand.delegator.displayName\r\n \"\r\n (click)=\"start(cand, $event)\"\r\n >\r\n <mt-avatar\r\n [label]=\"initials(cand.delegator)\"\r\n shape=\"circle\"\r\n styleClass=\"!size-8 !text-xs !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <span class=\"flex min-w-0 flex-1 flex-col\">\r\n <span class=\"truncate text-sm font-medium text-surface-800\">\r\n {{ cand.delegator.displayName }}\r\n </span>\r\n @if (cand.delegator.email) {\r\n <span class=\"truncate text-xs text-surface-500\">\r\n {{ cand.delegator.email }}\r\n </span>\r\n }\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.arrow-right\"\r\n styleClass=\"text-base text-surface-400\"\r\n ></mt-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (showManageLink()) {\r\n <div class=\"border-t border-surface p-1.5\">\r\n <a\r\n [routerLink]=\"managePath()\"\r\n (click)=\"onManage()\"\r\n class=\"flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm text-surface-700 hover:bg-surface-100\"\r\n >\r\n <mt-icon\r\n icon=\"general.settings-02\"\r\n styleClass=\"text-base\"\r\n ></mt-icon>\r\n <span>{{ t(\"delegations.session.manage\") }}</span>\r\n </a>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationStatusChip, selector: "mt-delegation-status-chip", inputs: ["status"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
558
558
|
}
|
|
559
559
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationMenuPanel, decorators: [{
|
|
560
560
|
type: Component,
|
|
@@ -565,7 +565,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
565
565
|
RouterLink,
|
|
566
566
|
TranslocoDirective,
|
|
567
567
|
DelegationStatusChip,
|
|
568
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n @if (mode() !== \"hidden\") {\n <div class=\"flex w-full flex-col\">\n @if (mode() === \"active\" && active(); as session) {\n <!-- Active session -->\n <div class=\"flex items-center gap-3 border-b border-surface px-4 py-3\">\n <mt-avatar\n [label]=\"initials(onBehalfOf())\"\n shape=\"circle\"\n styleClass=\"!size-9 !text-sm !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <span\n class=\"text-[0.625rem] font-medium uppercase text-surface-500\"\n >\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\n </span>\n <span class=\"truncate text-sm font-semibold text-surface-900\">\n {{ onBehalfOf()?.displayName }}\n </span>\n <span class=\"truncate text-xs text-surface-500\">\n {{\n t(\"delegations.session.executedBy\", {\n actualUserName: executedBy()?.displayName,\n })\n }}\n </span>\n </div>\n <mt-delegation-status-chip\n status=\"Active\"\n ></mt-delegation-status-chip>\n </div>\n\n <div class=\"flex flex-col p-1.5\">\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-surface-700 hover:bg-surface-100\"\n (click)=\"endSession($event)\"\n >\n <mt-icon icon=\"arrow.arrow-left\" styleClass=\"text-base\"></mt-icon>\n <span>{{ t(\"delegations.action.endSession\") }}</span>\n </button>\n </div>\n\n @if (candidates().length > 1) {\n <div class=\"border-t border-surface p-1.5\">\n <div\n class=\"px-2 pb-1 text-[0.625rem] font-medium uppercase text-surface-400\"\n >\n {{ t(\"delegations.session.switchToAnother\") }}\n </div>\n @for (cand of candidates(); track $index) {\n @if (cand.delegationId !== session.delegation.delegationId) {\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\n [attr.aria-label]=\"\n t('delegations.action.switchSession') +\n ': ' +\n cand.delegator.displayName\n \"\n (click)=\"switchTo(cand, $event)\"\n >\n <mt-avatar\n [label]=\"initials(cand.delegator)\"\n shape=\"circle\"\n styleClass=\"!size-8 !text-xs !bg-surface-100 !text-surface-600\"\n ></mt-avatar>\n <span\n class=\"min-w-0 flex-1 truncate text-sm font-medium text-surface-800\"\n >\n {{ cand.delegator.displayName }}\n </span>\n <mt-icon\n icon=\"arrow.switch-horizontal-01\"\n styleClass=\"text-base text-surface-400\"\n ></mt-icon>\n </button>\n }\n }\n </div>\n }\n } @else if (mode() === \"candidates\") {\n <!-- Candidates available -->\n <div class=\"border-b border-surface px-4 py-3\">\n <div class=\"text-sm font-semibold text-surface-900\">\n {{ t(\"delegations.session.youCanActAs\") }}\n </div>\n <div class=\"mt-0.5 text-xs text-surface-500\">\n {{ t(\"delegations.session.chooseDelegatorHint\") }}\n </div>\n </div>\n <div class=\"flex max-h-72 flex-col overflow-y-auto p-1.5\">\n @for (cand of candidates(); track $index) {\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\n [attr.aria-label]=\"\n t('delegations.action.startSession') +\n ': ' +\n cand.delegator.displayName\n \"\n (click)=\"start(cand, $event)\"\n >\n <mt-avatar\n [label]=\"initials(cand.delegator)\"\n shape=\"circle\"\n styleClass=\"!size-8 !text-xs !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"truncate text-sm font-medium text-surface-800\">\n {{ cand.delegator.displayName }}\n </span>\n @if (cand.delegator.email) {\n <span class=\"truncate text-xs text-surface-500\">\n {{ cand.delegator.email }}\n </span>\n }\n </span>\n <mt-icon\n icon=\"arrow.arrow-right\"\n styleClass=\"text-base text-surface-400\"\n ></mt-icon>\n </button>\n }\n </div>\n }\n\n @if (showManageLink()) {\n <div class=\"border-t border-surface p-1.5\">\n <a\n [routerLink]=\"managePath()\"\n (click)=\"onManage()\"\n class=\"flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm text-surface-700 hover:bg-surface-100\"\n >\n <mt-icon\n icon=\"general.settings-02\"\n styleClass=\"text-base\"\n ></mt-icon>\n <span>{{ t(\"delegations.session.manage\") }}</span>\n </a>\n </div>\n }\n </div>\n }\n</ng-container>\n" }]
|
|
568
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n @if (mode() !== \"hidden\") {\r\n <div class=\"flex w-full flex-col\">\r\n @if (mode() === \"active\" && active(); as session) {\r\n <!-- Active session -->\r\n <div class=\"flex items-center gap-3 border-b border-surface px-4 py-3\">\r\n <mt-avatar\r\n [label]=\"initials(onBehalfOf())\"\r\n shape=\"circle\"\r\n styleClass=\"!size-9 !text-sm !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <div class=\"flex min-w-0 flex-1 flex-col\">\r\n <span\r\n class=\"text-[0.625rem] font-medium uppercase text-surface-500\"\r\n >\r\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\r\n </span>\r\n <span class=\"truncate text-sm font-semibold text-surface-900\">\r\n {{ onBehalfOf()?.displayName }}\r\n </span>\r\n <span class=\"truncate text-xs text-surface-500\">\r\n {{\r\n t(\"delegations.session.executedBy\", {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n }}\r\n </span>\r\n </div>\r\n <mt-delegation-status-chip\r\n status=\"Active\"\r\n ></mt-delegation-status-chip>\r\n </div>\r\n\r\n <div class=\"flex flex-col p-1.5\">\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-surface-700 hover:bg-surface-100\"\r\n (click)=\"endSession($event)\"\r\n >\r\n <mt-icon icon=\"arrow.arrow-left\" styleClass=\"text-base\"></mt-icon>\r\n <span>{{ t(\"delegations.action.endSession\") }}</span>\r\n </button>\r\n </div>\r\n\r\n @if (candidates().length > 1) {\r\n <div class=\"border-t border-surface p-1.5\">\r\n <div\r\n class=\"px-2 pb-1 text-[0.625rem] font-medium uppercase text-surface-400\"\r\n >\r\n {{ t(\"delegations.session.switchToAnother\") }}\r\n </div>\r\n @for (cand of candidates(); track $index) {\r\n @if (cand.delegationId !== session.delegation.delegationId) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\r\n [attr.aria-label]=\"\r\n t('delegations.action.switchSession') +\r\n ': ' +\r\n cand.delegator.displayName\r\n \"\r\n (click)=\"switchTo(cand, $event)\"\r\n >\r\n <mt-avatar\r\n [label]=\"initials(cand.delegator)\"\r\n shape=\"circle\"\r\n styleClass=\"!size-8 !text-xs !bg-surface-100 !text-surface-600\"\r\n ></mt-avatar>\r\n <span\r\n class=\"min-w-0 flex-1 truncate text-sm font-medium text-surface-800\"\r\n >\r\n {{ cand.delegator.displayName }}\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.switch-horizontal-01\"\r\n styleClass=\"text-base text-surface-400\"\r\n ></mt-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n } @else if (mode() === \"candidates\") {\r\n <!-- Candidates available -->\r\n <div class=\"border-b border-surface px-4 py-3\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ t(\"delegations.session.youCanActAs\") }}\r\n </div>\r\n <div class=\"mt-0.5 text-xs text-surface-500\">\r\n {{ t(\"delegations.session.chooseDelegatorHint\") }}\r\n </div>\r\n </div>\r\n <div class=\"flex max-h-72 flex-col overflow-y-auto p-1.5\">\r\n @for (cand of candidates(); track $index) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-start hover:bg-surface-100\"\r\n [attr.aria-label]=\"\r\n t('delegations.action.startSession') +\r\n ': ' +\r\n cand.delegator.displayName\r\n \"\r\n (click)=\"start(cand, $event)\"\r\n >\r\n <mt-avatar\r\n [label]=\"initials(cand.delegator)\"\r\n shape=\"circle\"\r\n styleClass=\"!size-8 !text-xs !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <span class=\"flex min-w-0 flex-1 flex-col\">\r\n <span class=\"truncate text-sm font-medium text-surface-800\">\r\n {{ cand.delegator.displayName }}\r\n </span>\r\n @if (cand.delegator.email) {\r\n <span class=\"truncate text-xs text-surface-500\">\r\n {{ cand.delegator.email }}\r\n </span>\r\n }\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.arrow-right\"\r\n styleClass=\"text-base text-surface-400\"\r\n ></mt-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (showManageLink()) {\r\n <div class=\"border-t border-surface p-1.5\">\r\n <a\r\n [routerLink]=\"managePath()\"\r\n (click)=\"onManage()\"\r\n class=\"flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm text-surface-700 hover:bg-surface-100\"\r\n >\r\n <mt-icon\r\n icon=\"general.settings-02\"\r\n styleClass=\"text-base\"\r\n ></mt-icon>\r\n <span>{{ t(\"delegations.session.manage\") }}</span>\r\n </a>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</ng-container>\r\n" }]
|
|
569
569
|
}], propDecorators: { managePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "managePath", required: false }] }], showManageLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "showManageLink", required: false }] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
|
|
570
570
|
|
|
571
571
|
/**
|
|
@@ -677,7 +677,7 @@ class TopbarDelegationMenu {
|
|
|
677
677
|
});
|
|
678
678
|
}
|
|
679
679
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TopbarDelegationMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
680
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TopbarDelegationMenu, isStandalone: true, selector: "mt-topbar-delegation-menu", inputs: { managePath: { classPropertyName: "managePath", publicName: "managePath", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, showManageLink: { classPropertyName: "showManageLink", publicName: "showManageLink", isSignal: true, isRequired: false, transformFunction: null }, promptOnCandidates: { classPropertyName: "promptOnCandidates", publicName: "promptOnCandidates", isSignal: true, isRequired: false, transformFunction: null }, headless: { classPropertyName: "headless", publicName: "headless", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t\">\n <!-- Headless = controller only (no topbar UI); the menu is surfaced in the\n host user dropdown via <mt-delegation-menu-panel>. -->\n @if (!headless() && mode() !== \"hidden\") {\n @if (mode() === \"active\") {\n <span class=\"sr-only\" role=\"status\" aria-live=\"polite\">\n {{\n t(\"delegations.session.banner\", {\n delegatorName: onBehalfOf()?.displayName,\n })\n }}.\n {{\n t(\"delegations.session.executedBy\", {\n actualUserName: executedBy()?.displayName,\n })\n }}\n </span>\n }\n\n <div class=\"mt-delegation-trigger flex items-center\">\n @if (mode() === \"active\") {\n <!-- Active: show the delegator like a user identity, with a switcher caret -->\n <button\n type=\"button\"\n class=\"mt-delegation-trigger__button mt-delegation-trigger__button--active flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full p-1 pe-2 text-current\"\n [attr.aria-label]=\"\n t('delegations.session.banner', {\n delegatorName: onBehalfOf()?.displayName,\n }) +\n '. ' +\n t('delegations.session.executedBy', {\n actualUserName: executedBy()?.displayName,\n })\n \"\n (click)=\"togglePopover($event)\"\n >\n <span class=\"relative shrink-0\">\n <mt-avatar\n [label]=\"initials(onBehalfOf())\"\n shape=\"circle\"\n styleClass=\"!size-7 !text-[0.7rem] !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <span\n class=\"absolute -bottom-0.5 -end-0.5 flex size-3.5 items-center justify-center rounded-full bg-emerald-500 ring-2 ring-white\"\n aria-hidden=\"true\"\n >\n <mt-icon\n icon=\"user.users-check\"\n styleClass=\"text-[0.55rem] text-white\"\n ></mt-icon>\n </span>\n </span>\n @if (!compact()) {\n <span\n class=\"mt-delegation-trigger__label hidden min-w-0 flex-col text-start leading-tight md:flex\"\n >\n <span class=\"text-[0.625rem] font-medium uppercase opacity-60\">\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\n </span>\n <span class=\"truncate text-sm font-semibold\">\n {{ onBehalfOf()?.displayName }}\n </span>\n </span>\n }\n <mt-icon\n icon=\"arrow.chevron-down\"\n styleClass=\"text-sm opacity-70\"\n ></mt-icon>\n </button>\n } @else {\n <!-- Candidates: plain icon button matching the other topbar icons -->\n <button\n type=\"button\"\n class=\"mt-delegation-trigger__icon relative flex size-9 cursor-pointer items-center justify-center rounded-full text-current\"\n [attr.aria-label]=\"t('delegations.session.availableTitle')\"\n (click)=\"togglePopover($event)\"\n >\n <mt-icon icon=\"user.users-plus\" styleClass=\"text-xl\"></mt-icon>\n @if (candidates().length > 0) {\n <span\n class=\"absolute -top-0.5 -end-0.5 inline-flex min-w-[1.05rem] items-center justify-center rounded-full bg-primary px-1 text-[0.625rem] font-bold leading-4 text-white ring-2 ring-white\"\n >\n {{ candidates().length }}\n </span>\n }\n </button>\n }\n </div>\n\n <p-popover #popover [pt]=\"{ content: { class: 'p-0!' } }\">\n <div class=\"w-72 max-w-[88vw]\">\n <mt-delegation-menu-panel\n [managePath]=\"managePath()\"\n [showManageLink]=\"showManageLink()\"\n (closeRequested)=\"closePopover()\"\n ></mt-delegation-menu-panel>\n </div>\n </p-popover>\n }\n</ng-container>\n", styles: [":host{display:inline-flex;align-items:center;min-width:0;max-width:100%}.mt-delegation-trigger{min-width:0;max-width:100%}.mt-delegation-trigger__button,.mt-delegation-trigger__icon{transition:background-color .15s ease-out;border:1px solid transparent}.mt-delegation-trigger__button:hover,.mt-delegation-trigger__icon:hover{background-color:var(--p-surface-100, rgba(0, 0, 0, .05))}.mt-delegation-trigger__button--active{background-color:var(--p-surface-100, rgba(0, 0, 0, .05));border-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__button--active:hover{background-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__label{max-width:min(12rem,20vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:1280px){.mt-delegation-trigger__label{max-width:8rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationMenuPanel, selector: "mt-delegation-menu-panel", inputs: ["managePath", "showManageLink"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
680
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TopbarDelegationMenu, isStandalone: true, selector: "mt-topbar-delegation-menu", inputs: { managePath: { classPropertyName: "managePath", publicName: "managePath", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, showManageLink: { classPropertyName: "showManageLink", publicName: "showManageLink", isSignal: true, isRequired: false, transformFunction: null }, promptOnCandidates: { classPropertyName: "promptOnCandidates", publicName: "promptOnCandidates", isSignal: true, isRequired: false, transformFunction: null }, headless: { classPropertyName: "headless", publicName: "headless", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <!-- Headless = controller only (no topbar UI); the menu is surfaced in the\r\n host user dropdown via <mt-delegation-menu-panel>. -->\r\n @if (!headless() && mode() !== \"hidden\") {\r\n @if (mode() === \"active\") {\r\n <span class=\"sr-only\" role=\"status\" aria-live=\"polite\">\r\n {{\r\n t(\"delegations.session.banner\", {\r\n delegatorName: onBehalfOf()?.displayName,\r\n })\r\n }}.\r\n {{\r\n t(\"delegations.session.executedBy\", {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n }}\r\n </span>\r\n }\r\n\r\n <div class=\"mt-delegation-trigger flex items-center\">\r\n @if (mode() === \"active\") {\r\n <!-- Active: show the delegator like a user identity, with a switcher caret -->\r\n <button\r\n type=\"button\"\r\n class=\"mt-delegation-trigger__button mt-delegation-trigger__button--active flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full p-1 pe-2 text-current\"\r\n [attr.aria-label]=\"\r\n t('delegations.session.banner', {\r\n delegatorName: onBehalfOf()?.displayName,\r\n }) +\r\n '. ' +\r\n t('delegations.session.executedBy', {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n \"\r\n (click)=\"togglePopover($event)\"\r\n >\r\n <span class=\"relative shrink-0\">\r\n <mt-avatar\r\n [label]=\"initials(onBehalfOf())\"\r\n shape=\"circle\"\r\n styleClass=\"!size-7 !text-[0.7rem] !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <span\r\n class=\"absolute -bottom-0.5 -end-0.5 flex size-3.5 items-center justify-center rounded-full bg-emerald-500 ring-2 ring-white\"\r\n aria-hidden=\"true\"\r\n >\r\n <mt-icon\r\n icon=\"user.users-check\"\r\n styleClass=\"text-[0.55rem] text-white\"\r\n ></mt-icon>\r\n </span>\r\n </span>\r\n @if (!compact()) {\r\n <span\r\n class=\"mt-delegation-trigger__label hidden min-w-0 flex-col text-start leading-tight md:flex\"\r\n >\r\n <span class=\"text-[0.625rem] font-medium uppercase opacity-60\">\r\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\r\n </span>\r\n <span class=\"truncate text-sm font-semibold\">\r\n {{ onBehalfOf()?.displayName }}\r\n </span>\r\n </span>\r\n }\r\n <mt-icon\r\n icon=\"arrow.chevron-down\"\r\n styleClass=\"text-sm opacity-70\"\r\n ></mt-icon>\r\n </button>\r\n } @else {\r\n <!-- Candidates: plain icon button matching the other topbar icons -->\r\n <button\r\n type=\"button\"\r\n class=\"mt-delegation-trigger__icon relative flex size-9 cursor-pointer items-center justify-center rounded-full text-current\"\r\n [attr.aria-label]=\"t('delegations.session.availableTitle')\"\r\n (click)=\"togglePopover($event)\"\r\n >\r\n <mt-icon icon=\"user.users-plus\" styleClass=\"text-xl\"></mt-icon>\r\n @if (candidates().length > 0) {\r\n <span\r\n class=\"absolute -top-0.5 -end-0.5 inline-flex min-w-[1.05rem] items-center justify-center rounded-full bg-primary px-1 text-[0.625rem] font-bold leading-4 text-white ring-2 ring-white\"\r\n >\r\n {{ candidates().length }}\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <p-popover #popover [pt]=\"{ content: { class: 'p-0!' } }\">\r\n <div class=\"w-72 max-w-[88vw]\">\r\n <mt-delegation-menu-panel\r\n [managePath]=\"managePath()\"\r\n [showManageLink]=\"showManageLink()\"\r\n (closeRequested)=\"closePopover()\"\r\n ></mt-delegation-menu-panel>\r\n </div>\r\n </p-popover>\r\n }\r\n</ng-container>\r\n", styles: [":host{display:inline-flex;align-items:center;min-width:0;max-width:100%}.mt-delegation-trigger{min-width:0;max-width:100%}.mt-delegation-trigger__button,.mt-delegation-trigger__icon{transition:background-color .15s ease-out;border:1px solid transparent}.mt-delegation-trigger__button:hover,.mt-delegation-trigger__icon:hover{background-color:var(--p-surface-100, rgba(0, 0, 0, .05))}.mt-delegation-trigger__button--active{background-color:var(--p-surface-100, rgba(0, 0, 0, .05));border-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__button--active:hover{background-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__label{max-width:min(12rem,20vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:1280px){.mt-delegation-trigger__label{max-width:8rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationMenuPanel, selector: "mt-delegation-menu-panel", inputs: ["managePath", "showManageLink"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
681
681
|
}
|
|
682
682
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TopbarDelegationMenu, decorators: [{
|
|
683
683
|
type: Component,
|
|
@@ -688,7 +688,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
688
688
|
Popover,
|
|
689
689
|
TranslocoDirective,
|
|
690
690
|
DelegationMenuPanel,
|
|
691
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n <!-- Headless = controller only (no topbar UI); the menu is surfaced in the\n host user dropdown via <mt-delegation-menu-panel>. -->\n @if (!headless() && mode() !== \"hidden\") {\n @if (mode() === \"active\") {\n <span class=\"sr-only\" role=\"status\" aria-live=\"polite\">\n {{\n t(\"delegations.session.banner\", {\n delegatorName: onBehalfOf()?.displayName,\n })\n }}.\n {{\n t(\"delegations.session.executedBy\", {\n actualUserName: executedBy()?.displayName,\n })\n }}\n </span>\n }\n\n <div class=\"mt-delegation-trigger flex items-center\">\n @if (mode() === \"active\") {\n <!-- Active: show the delegator like a user identity, with a switcher caret -->\n <button\n type=\"button\"\n class=\"mt-delegation-trigger__button mt-delegation-trigger__button--active flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full p-1 pe-2 text-current\"\n [attr.aria-label]=\"\n t('delegations.session.banner', {\n delegatorName: onBehalfOf()?.displayName,\n }) +\n '. ' +\n t('delegations.session.executedBy', {\n actualUserName: executedBy()?.displayName,\n })\n \"\n (click)=\"togglePopover($event)\"\n >\n <span class=\"relative shrink-0\">\n <mt-avatar\n [label]=\"initials(onBehalfOf())\"\n shape=\"circle\"\n styleClass=\"!size-7 !text-[0.7rem] !bg-primary-100 !text-primary-700\"\n ></mt-avatar>\n <span\n class=\"absolute -bottom-0.5 -end-0.5 flex size-3.5 items-center justify-center rounded-full bg-emerald-500 ring-2 ring-white\"\n aria-hidden=\"true\"\n >\n <mt-icon\n icon=\"user.users-check\"\n styleClass=\"text-[0.55rem] text-white\"\n ></mt-icon>\n </span>\n </span>\n @if (!compact()) {\n <span\n class=\"mt-delegation-trigger__label hidden min-w-0 flex-col text-start leading-tight md:flex\"\n >\n <span class=\"text-[0.625rem] font-medium uppercase opacity-60\">\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\n </span>\n <span class=\"truncate text-sm font-semibold\">\n {{ onBehalfOf()?.displayName }}\n </span>\n </span>\n }\n <mt-icon\n icon=\"arrow.chevron-down\"\n styleClass=\"text-sm opacity-70\"\n ></mt-icon>\n </button>\n } @else {\n <!-- Candidates: plain icon button matching the other topbar icons -->\n <button\n type=\"button\"\n class=\"mt-delegation-trigger__icon relative flex size-9 cursor-pointer items-center justify-center rounded-full text-current\"\n [attr.aria-label]=\"t('delegations.session.availableTitle')\"\n (click)=\"togglePopover($event)\"\n >\n <mt-icon icon=\"user.users-plus\" styleClass=\"text-xl\"></mt-icon>\n @if (candidates().length > 0) {\n <span\n class=\"absolute -top-0.5 -end-0.5 inline-flex min-w-[1.05rem] items-center justify-center rounded-full bg-primary px-1 text-[0.625rem] font-bold leading-4 text-white ring-2 ring-white\"\n >\n {{ candidates().length }}\n </span>\n }\n </button>\n }\n </div>\n\n <p-popover #popover [pt]=\"{ content: { class: 'p-0!' } }\">\n <div class=\"w-72 max-w-[88vw]\">\n <mt-delegation-menu-panel\n [managePath]=\"managePath()\"\n [showManageLink]=\"showManageLink()\"\n (closeRequested)=\"closePopover()\"\n ></mt-delegation-menu-panel>\n </div>\n </p-popover>\n }\n</ng-container>\n", styles: [":host{display:inline-flex;align-items:center;min-width:0;max-width:100%}.mt-delegation-trigger{min-width:0;max-width:100%}.mt-delegation-trigger__button,.mt-delegation-trigger__icon{transition:background-color .15s ease-out;border:1px solid transparent}.mt-delegation-trigger__button:hover,.mt-delegation-trigger__icon:hover{background-color:var(--p-surface-100, rgba(0, 0, 0, .05))}.mt-delegation-trigger__button--active{background-color:var(--p-surface-100, rgba(0, 0, 0, .05));border-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__button--active:hover{background-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__label{max-width:min(12rem,20vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:1280px){.mt-delegation-trigger__label{max-width:8rem}}\n"] }]
|
|
691
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n <!-- Headless = controller only (no topbar UI); the menu is surfaced in the\r\n host user dropdown via <mt-delegation-menu-panel>. -->\r\n @if (!headless() && mode() !== \"hidden\") {\r\n @if (mode() === \"active\") {\r\n <span class=\"sr-only\" role=\"status\" aria-live=\"polite\">\r\n {{\r\n t(\"delegations.session.banner\", {\r\n delegatorName: onBehalfOf()?.displayName,\r\n })\r\n }}.\r\n {{\r\n t(\"delegations.session.executedBy\", {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n }}\r\n </span>\r\n }\r\n\r\n <div class=\"mt-delegation-trigger flex items-center\">\r\n @if (mode() === \"active\") {\r\n <!-- Active: show the delegator like a user identity, with a switcher caret -->\r\n <button\r\n type=\"button\"\r\n class=\"mt-delegation-trigger__button mt-delegation-trigger__button--active flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full p-1 pe-2 text-current\"\r\n [attr.aria-label]=\"\r\n t('delegations.session.banner', {\r\n delegatorName: onBehalfOf()?.displayName,\r\n }) +\r\n '. ' +\r\n t('delegations.session.executedBy', {\r\n actualUserName: executedBy()?.displayName,\r\n })\r\n \"\r\n (click)=\"togglePopover($event)\"\r\n >\r\n <span class=\"relative shrink-0\">\r\n <mt-avatar\r\n [label]=\"initials(onBehalfOf())\"\r\n shape=\"circle\"\r\n styleClass=\"!size-7 !text-[0.7rem] !bg-primary-100 !text-primary-700\"\r\n ></mt-avatar>\r\n <span\r\n class=\"absolute -bottom-0.5 -end-0.5 flex size-3.5 items-center justify-center rounded-full bg-emerald-500 ring-2 ring-white\"\r\n aria-hidden=\"true\"\r\n >\r\n <mt-icon\r\n icon=\"user.users-check\"\r\n styleClass=\"text-[0.55rem] text-white\"\r\n ></mt-icon>\r\n </span>\r\n </span>\r\n @if (!compact()) {\r\n <span\r\n class=\"mt-delegation-trigger__label hidden min-w-0 flex-col text-start leading-tight md:flex\"\r\n >\r\n <span class=\"text-[0.625rem] font-medium uppercase opacity-60\">\r\n {{ t(\"delegations.session.actingOnBehalfOf\") }}\r\n </span>\r\n <span class=\"truncate text-sm font-semibold\">\r\n {{ onBehalfOf()?.displayName }}\r\n </span>\r\n </span>\r\n }\r\n <mt-icon\r\n icon=\"arrow.chevron-down\"\r\n styleClass=\"text-sm opacity-70\"\r\n ></mt-icon>\r\n </button>\r\n } @else {\r\n <!-- Candidates: plain icon button matching the other topbar icons -->\r\n <button\r\n type=\"button\"\r\n class=\"mt-delegation-trigger__icon relative flex size-9 cursor-pointer items-center justify-center rounded-full text-current\"\r\n [attr.aria-label]=\"t('delegations.session.availableTitle')\"\r\n (click)=\"togglePopover($event)\"\r\n >\r\n <mt-icon icon=\"user.users-plus\" styleClass=\"text-xl\"></mt-icon>\r\n @if (candidates().length > 0) {\r\n <span\r\n class=\"absolute -top-0.5 -end-0.5 inline-flex min-w-[1.05rem] items-center justify-center rounded-full bg-primary px-1 text-[0.625rem] font-bold leading-4 text-white ring-2 ring-white\"\r\n >\r\n {{ candidates().length }}\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <p-popover #popover [pt]=\"{ content: { class: 'p-0!' } }\">\r\n <div class=\"w-72 max-w-[88vw]\">\r\n <mt-delegation-menu-panel\r\n [managePath]=\"managePath()\"\r\n [showManageLink]=\"showManageLink()\"\r\n (closeRequested)=\"closePopover()\"\r\n ></mt-delegation-menu-panel>\r\n </div>\r\n </p-popover>\r\n }\r\n</ng-container>\r\n", styles: [":host{display:inline-flex;align-items:center;min-width:0;max-width:100%}.mt-delegation-trigger{min-width:0;max-width:100%}.mt-delegation-trigger__button,.mt-delegation-trigger__icon{transition:background-color .15s ease-out;border:1px solid transparent}.mt-delegation-trigger__button:hover,.mt-delegation-trigger__icon:hover{background-color:var(--p-surface-100, rgba(0, 0, 0, .05))}.mt-delegation-trigger__button--active{background-color:var(--p-surface-100, rgba(0, 0, 0, .05));border-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__button--active:hover{background-color:var(--p-surface-200, rgba(0, 0, 0, .08))}.mt-delegation-trigger__label{max-width:min(12rem,20vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:1280px){.mt-delegation-trigger__label{max-width:8rem}}\n"] }]
|
|
692
692
|
}], ctorParameters: () => [], propDecorators: { managePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "managePath", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], showManageLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "showManageLink", required: false }] }], promptOnCandidates: [{ type: i0.Input, args: [{ isSignal: true, alias: "promptOnCandidates", required: false }] }], headless: [{ type: i0.Input, args: [{ isSignal: true, alias: "headless", required: false }] }], popover: [{ type: i0.ViewChild, args: ['popover', { isSignal: true }] }] } });
|
|
693
693
|
|
|
694
694
|
// ---------------------------------------------------------------------------
|
|
@@ -1433,11 +1433,11 @@ class Delegations {
|
|
|
1433
1433
|
});
|
|
1434
1434
|
}
|
|
1435
1435
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Delegations, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1436
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: Delegations, isStandalone: true, selector: "mt-delegations", ngImport: i0, template: "<ng-container *transloco=\"let t\">\n <mt-page\n [title]=\"t('delegations.title')\"\n [avatarIcon]=\"'custom.hierarchy-structure'\"\n [tabs]=\"tabs()\"\n [activeTab]=\"activeTab()\"\n [contentClass]=\"'max-[1025px]:p-4 max-[640px]:p-3'\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-indigo-50)',\n '--p-avatar-color': 'var(--p-indigo-700)',\n }\"\n (tabChange)=\"onTabChange($event)\"\n (backButtonClick)=\"goBack()\"\n backButton\n >\n <router-outlet />\n </mt-page>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1436
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: Delegations, isStandalone: true, selector: "mt-delegations", ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <mt-page\r\n [title]=\"t('delegations.title')\"\r\n [avatarIcon]=\"'custom.hierarchy-structure'\"\r\n [tabs]=\"tabs()\"\r\n [activeTab]=\"activeTab()\"\r\n [contentClass]=\"'max-[1025px]:p-4 max-[640px]:p-3'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-indigo-50)',\r\n '--p-avatar-color': 'var(--p-indigo-700)',\r\n }\"\r\n (tabChange)=\"onTabChange($event)\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <router-outlet />\r\n </mt-page>\r\n</ng-container>\r\n", styles: [""], dependencies: [{ kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1437
1437
|
}
|
|
1438
1438
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Delegations, decorators: [{
|
|
1439
1439
|
type: Component,
|
|
1440
|
-
args: [{ selector: 'mt-delegations', imports: [Page, RouterOutlet, TranslocoDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n <mt-page\n [title]=\"t('delegations.title')\"\n [avatarIcon]=\"'custom.hierarchy-structure'\"\n [tabs]=\"tabs()\"\n [activeTab]=\"activeTab()\"\n [contentClass]=\"'max-[1025px]:p-4 max-[640px]:p-3'\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-indigo-50)',\n '--p-avatar-color': 'var(--p-indigo-700)',\n }\"\n (tabChange)=\"onTabChange($event)\"\n (backButtonClick)=\"goBack()\"\n backButton\n >\n <router-outlet />\n </mt-page>\n</ng-container>\n" }]
|
|
1440
|
+
args: [{ selector: 'mt-delegations', imports: [Page, RouterOutlet, TranslocoDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n <mt-page\r\n [title]=\"t('delegations.title')\"\r\n [avatarIcon]=\"'custom.hierarchy-structure'\"\r\n [tabs]=\"tabs()\"\r\n [activeTab]=\"activeTab()\"\r\n [contentClass]=\"'max-[1025px]:p-4 max-[640px]:p-3'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-indigo-50)',\r\n '--p-avatar-color': 'var(--p-indigo-700)',\r\n }\"\r\n (tabChange)=\"onTabChange($event)\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <router-outlet />\r\n </mt-page>\r\n</ng-container>\r\n" }]
|
|
1441
1441
|
}], ctorParameters: () => [] });
|
|
1442
1442
|
|
|
1443
1443
|
function isRecord$1(value) {
|
|
@@ -2408,7 +2408,7 @@ class ScopePicker {
|
|
|
2408
2408
|
return this.activeLang() ?? this.transloco.getActiveLang();
|
|
2409
2409
|
}
|
|
2410
2410
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ScopePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2411
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ScopePicker, isStandalone: true, selector: "mt-scope-picker", inputs: { scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null }, delegatorUserId: { classPropertyName: "delegatorUserId", publicName: "delegatorUserId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scope: "scopeChange" }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\n <!-- Reusable tri-state checkbox box -->\n <ng-template #checkbox let-state=\"state\">\n <span\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors\"\n [class.border-primary-500]=\"state !== 'unchecked'\"\n [class.bg-primary-500]=\"state !== 'unchecked'\"\n [class.text-white]=\"state !== 'unchecked'\"\n [class.border-surface-300]=\"state === 'unchecked'\"\n [class.bg-surface-0]=\"state === 'unchecked'\"\n >\n @if (state === \"checked\") {\n <svg\n viewBox=\"0 0 16 16\"\n class=\"size-3\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n } @else if (state === \"indeterminate\") {\n <span class=\"h-[2px] w-2.5 rounded-full bg-white\"></span>\n }\n </span>\n </ng-template>\n\n <div class=\"flex flex-col gap-3\">\n @if (isLoadingOptions()) {\n <mt-card [paddingless]=\"true\">\n <div class=\"flex flex-col gap-3 p-4\">\n <p-skeleton height=\"2.5rem\"></p-skeleton>\n @for (item of [0, 1, 2, 3, 4, 5]; track $index) {\n <p-skeleton height=\"2rem\"></p-skeleton>\n }\n </div>\n </mt-card>\n } @else {\n @if (errorOptions(); as errorMessage) {\n <div\n class=\"rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\n >\n {{ errorMessage }}\n </div>\n }\n\n @if (!hasOptions() && !errorOptions()) {\n <mt-card [paddingless]=\"true\">\n <div\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 px-6 py-8 text-center\"\n >\n <div\n class=\"flex size-16 items-center justify-center rounded-3xl bg-surface-50 text-primary\"\n >\n <svg\n viewBox=\"0 0 64 64\"\n class=\"size-9\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"10\"\n y=\"12\"\n width=\"44\"\n height=\"38\"\n rx=\"12\"\n class=\"fill-primary/10 stroke-primary/35\"\n stroke-width=\"2\"\n />\n <path\n d=\"M21 27H43\"\n class=\"stroke-primary\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M21 35H37\"\n class=\"stroke-primary/70\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n <div class=\"space-y-1\">\n <p class=\"text-base font-medium text-surface-900\">\n {{ t(\"delegations.scope.permissionsTitle\") }}\n </p>\n <p class=\"text-sm text-surface-500\">\n {{ t(\"delegations.scope.noGrantableOptions\") }}\n </p>\n </div>\n </div>\n </mt-card>\n }\n\n @if (hasOptions()) {\n <mt-card [paddingless]=\"true\" class=\"overflow-hidden\">\n <!-- Inner view switch: Permissions / Pages & accessibility -->\n @if (hasAccessibility()) {\n <div class=\"border-b border-surface px-3 pt-2.5 pb-0\">\n <mt-tabs\n mode=\"underline\"\n [(active)]=\"activeScopeTab\"\n [options]=\"[\n {\n value: 'permissions',\n label: t('delegations.scope.permissionsTab'),\n badge: selectedCount() || null,\n },\n {\n value: 'accessibility',\n label: t('delegations.scope.accessibilityTitle'),\n badge: selectedAccessibilityCount() || null,\n },\n ]\"\n fluid\n ></mt-tabs>\n </div>\n }\n\n @if (activeScopeTab() === \"permissions\" || !hasAccessibility()) {\n <!-- Toolbar: table-style search + clear -->\n <div\n class=\"flex items-center gap-2 border-b border-surface px-3 py-2\"\n >\n <div class=\"min-w-0 flex-1\">\n <mt-text-field\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"searchTerm.set($event)\"\n icon=\"general.search-lg\"\n [placeholder]=\"t('delegations.scope.searchPlaceholder')\"\n ></mt-text-field>\n </div>\n @if (selectedCount() > 0) {\n <span class=\"shrink-0 text-xs font-medium text-surface-500\">\n {{ selectedCount() }} {{ t(\"delegations.scope.selected\") }}\n </span>\n <mt-button\n variant=\"text\"\n size=\"small\"\n [label]=\"t('delegations.scope.clear')\"\n [disabled]=\"readonly()\"\n (click)=\"clearSelection()\"\n ></mt-button>\n }\n </div>\n\n <!-- Select-all header -->\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-2 border-b border-surface px-3 py-2 text-start hover:bg-surface-50\"\n role=\"checkbox\"\n [attr.aria-checked]=\"\n selectAllState() === 'indeterminate'\n ? 'mixed'\n : selectAllState() === 'checked'\n \"\n [disabled]=\"readonly()\"\n (click)=\"toggleAll()\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n checkbox;\n context: { state: selectAllState() }\n \"\n ></ng-container>\n <span\n class=\"text-xs font-semibold uppercase tracking-wide text-surface-500\"\n >\n {{ t(\"delegations.scope.selectAll\") }}\n </span>\n </button>\n\n <!-- Virtualized permission tree -->\n @if (visibleNodes().length > 0) {\n <cdk-virtual-scroll-viewport\n itemSize=\"40\"\n class=\"block h-[20rem]\"\n >\n <div\n *cdkVirtualFor=\"\n let item of visibleNodes();\n trackBy: trackVisible\n \"\n class=\"group flex h-10 items-center gap-2 pe-2 transition-colors hover:bg-surface-50\"\n [style.padding-inline-start.rem]=\"0.5 + item.depth * 1.25\"\n >\n @if (hasChildren(item.node)) {\n <button\n type=\"button\"\n class=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-surface-400 hover:bg-surface-100 hover:text-surface-600\"\n [attr.aria-expanded]=\"isExpanded(item.node)\"\n [attr.aria-label]=\"nodeLabel(item.node)\"\n (click)=\"\n toggleExpand(item.node); $event.stopPropagation()\n \"\n >\n <mt-icon\n [icon]=\"\n isExpanded(item.node)\n ? 'arrow.chevron-down'\n : 'arrow.chevron-right'\n \"\n styleClass=\"text-base\"\n ></mt-icon>\n </button>\n } @else {\n <span class=\"size-6 shrink-0\"></span>\n }\n\n <button\n type=\"button\"\n role=\"checkbox\"\n [attr.aria-checked]=\"\n nodeState(item.node) === 'indeterminate'\n ? 'mixed'\n : nodeState(item.node) === 'checked'\n \"\n [attr.aria-label]=\"nodeLabel(item.node)\"\n class=\"shrink-0\"\n [class.cursor-pointer]=\"!readonly()\"\n [disabled]=\"readonly()\"\n (click)=\"toggle(item.node); $event.stopPropagation()\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n checkbox;\n context: { state: nodeState(item.node) }\n \"\n ></ng-container>\n </button>\n\n <button\n type=\"button\"\n class=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-start\"\n (click)=\"onRowClick(item.node)\"\n >\n <span\n class=\"truncate text-sm\"\n [class.font-semibold]=\"item.node.kind === 'template'\"\n [class.text-surface-900]=\"item.node.kind === 'template'\"\n [class.font-medium]=\"\n item.node.kind === 'level' ||\n item.node.kind === 'module'\n \"\n [class.text-surface-800]=\"\n item.node.kind === 'level' ||\n item.node.kind === 'module'\n \"\n [class.text-surface-600]=\"item.node.kind === 'operation'\"\n >\n {{ nodeLabel(item.node) }}\n </span>\n @if (\n item.node.kind === \"operation\" && item.node.isHighRisk\n ) {\n <span\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\n >\n {{ t(\"delegations.scope.highRisk\") }}\n </span>\n }\n </button>\n </div>\n </cdk-virtual-scroll-viewport>\n } @else {\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\n {{ t(\"components.table.no-data-found\") }}\n </p>\n }\n } @else {\n <!-- App accessibility -->\n <div class=\"flex flex-col gap-3 p-4\">\n <p class=\"text-xs text-surface-500\">\n {{ t(\"delegations.scope.accessibilityHint\") }}\n </p>\n <div class=\"flex flex-wrap gap-2\">\n @for (\n item of appAccessibilities();\n track item.accessibilityKey\n ) {\n @let selected =\n isAccessibilitySelected(item.accessibilityKey);\n <button\n type=\"button\"\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors\"\n [class.border-primary-400]=\"selected\"\n [class.bg-primary-50]=\"selected\"\n [class.text-primary-700]=\"selected\"\n [class.border-surface-200]=\"!selected\"\n [class.text-surface-600]=\"!selected\"\n [class.hover:border-primary-300]=\"!readonly()\"\n [disabled]=\"readonly()\"\n [attr.aria-pressed]=\"selected\"\n (click)=\"toggleAccessibility(item.accessibilityKey)\"\n >\n <span\n class=\"inline-flex size-1.5 rounded-full\"\n [class.bg-primary-500]=\"selected\"\n [class.bg-surface-300]=\"!selected\"\n ></span>\n {{ accessibilityLabel(item) }}\n </button>\n }\n </div>\n </div>\n }\n </mt-card>\n }\n\n <!-- Compact live scope preview -->\n <div\n class=\"flex flex-col gap-1.5 rounded-lg border border-surface bg-surface-50 px-3 py-2\"\n >\n <div class=\"flex items-center gap-2 text-xs\">\n <span class=\"shrink-0 font-semibold text-surface-700\">\n {{ t(\"delegations.scope.previewTitle\") }}:\n </span>\n @if (isPreviewing()) {\n <p-skeleton width=\"8rem\" height=\"0.7rem\"></p-skeleton>\n } @else if (preview(); as p) {\n @if (p.isValid) {\n <span class=\"min-w-0 flex-1 truncate text-surface-900\">\n {{\n getPreviewSummary(p.summary) ||\n t(\"delegations.column.scopeSummary\")\n }}\n </span>\n } @else {\n <span class=\"font-medium text-red-700\">\n {{ t(\"delegations.scope.previewInvalid\") }}\n </span>\n }\n } @else {\n <span class=\"text-surface-500\">\n {{ t(\"delegations.scope.noSelection\") }}\n </span>\n }\n </div>\n @if (preview(); as p) {\n @if (p.warnings.length > 0) {\n <ul\n class=\"list-inside list-disc space-y-0.5 text-xs text-amber-700\"\n >\n @for (w of p.warnings; track $index) {\n <li>{{ w.message }}</li>\n }\n </ul>\n }\n @if (p.deniedItems.length > 0) {\n <ul class=\"list-inside list-disc space-y-0.5 text-xs text-red-700\">\n @for (d of p.deniedItems; track $index) {\n <li>\n {{ formatDeniedTarget(d.targetKey) }} /\n {{ formatDeniedOperation(d.operationKey) }} -\n {{ d.reasonCode }}\n </li>\n }\n </ul>\n }\n }\n </div>\n }\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i4.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2411
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ScopePicker, isStandalone: true, selector: "mt-scope-picker", inputs: { scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null }, delegatorUserId: { classPropertyName: "delegatorUserId", publicName: "delegatorUserId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scope: "scopeChange" }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <!-- Reusable tri-state checkbox box -->\r\n <ng-template #checkbox let-state=\"state\">\r\n <span\r\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors\"\r\n [class.border-primary-500]=\"state !== 'unchecked'\"\r\n [class.bg-primary-500]=\"state !== 'unchecked'\"\r\n [class.text-white]=\"state !== 'unchecked'\"\r\n [class.border-surface-300]=\"state === 'unchecked'\"\r\n [class.bg-surface-0]=\"state === 'unchecked'\"\r\n >\r\n @if (state === \"checked\") {\r\n <svg\r\n viewBox=\"0 0 16 16\"\r\n class=\"size-3\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <path\r\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n } @else if (state === \"indeterminate\") {\r\n <span class=\"h-[2px] w-2.5 rounded-full bg-white\"></span>\r\n }\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-3\">\r\n @if (isLoadingOptions()) {\r\n <mt-card [paddingless]=\"true\">\r\n <div class=\"flex flex-col gap-3 p-4\">\r\n <p-skeleton height=\"2.5rem\"></p-skeleton>\r\n @for (item of [0, 1, 2, 3, 4, 5]; track $index) {\r\n <p-skeleton height=\"2rem\"></p-skeleton>\r\n }\r\n </div>\r\n </mt-card>\r\n } @else {\r\n @if (errorOptions(); as errorMessage) {\r\n <div\r\n class=\"rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n\r\n @if (!hasOptions() && !errorOptions()) {\r\n <mt-card [paddingless]=\"true\">\r\n <div\r\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 px-6 py-8 text-center\"\r\n >\r\n <div\r\n class=\"flex size-16 items-center justify-center rounded-3xl bg-surface-50 text-primary\"\r\n >\r\n <svg\r\n viewBox=\"0 0 64 64\"\r\n class=\"size-9\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <rect\r\n x=\"10\"\r\n y=\"12\"\r\n width=\"44\"\r\n height=\"38\"\r\n rx=\"12\"\r\n class=\"fill-primary/10 stroke-primary/35\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M21 27H43\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M21 35H37\"\r\n class=\"stroke-primary/70\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <div class=\"space-y-1\">\r\n <p class=\"text-base font-medium text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </p>\r\n <p class=\"text-sm text-surface-500\">\r\n {{ t(\"delegations.scope.noGrantableOptions\") }}\r\n </p>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n @if (hasOptions()) {\r\n <mt-card [paddingless]=\"true\" class=\"overflow-hidden\">\r\n <!-- Inner view switch: Permissions / Pages & accessibility -->\r\n @if (hasAccessibility()) {\r\n <div class=\"border-b border-surface px-3 pt-2.5 pb-0\">\r\n <mt-tabs\r\n mode=\"underline\"\r\n [(active)]=\"activeScopeTab\"\r\n [options]=\"[\r\n {\r\n value: 'permissions',\r\n label: t('delegations.scope.permissionsTab'),\r\n badge: selectedCount() || null,\r\n },\r\n {\r\n value: 'accessibility',\r\n label: t('delegations.scope.accessibilityTitle'),\r\n badge: selectedAccessibilityCount() || null,\r\n },\r\n ]\"\r\n fluid\r\n ></mt-tabs>\r\n </div>\r\n }\r\n\r\n @if (activeScopeTab() === \"permissions\" || !hasAccessibility()) {\r\n <!-- Toolbar: table-style search + clear -->\r\n <div\r\n class=\"flex items-center gap-2 border-b border-surface px-3 py-2\"\r\n >\r\n <div class=\"min-w-0 flex-1\">\r\n <mt-text-field\r\n [ngModel]=\"searchTerm()\"\r\n (ngModelChange)=\"searchTerm.set($event)\"\r\n icon=\"general.search-lg\"\r\n [placeholder]=\"t('delegations.scope.searchPlaceholder')\"\r\n ></mt-text-field>\r\n </div>\r\n @if (selectedCount() > 0) {\r\n <span class=\"shrink-0 text-xs font-medium text-surface-500\">\r\n {{ selectedCount() }} {{ t(\"delegations.scope.selected\") }}\r\n </span>\r\n <mt-button\r\n variant=\"text\"\r\n size=\"small\"\r\n [label]=\"t('delegations.scope.clear')\"\r\n [disabled]=\"readonly()\"\r\n (click)=\"clearSelection()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <!-- Select-all header -->\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-2 border-b border-surface px-3 py-2 text-start hover:bg-surface-50\"\r\n role=\"checkbox\"\r\n [attr.aria-checked]=\"\r\n selectAllState() === 'indeterminate'\r\n ? 'mixed'\r\n : selectAllState() === 'checked'\r\n \"\r\n [disabled]=\"readonly()\"\r\n (click)=\"toggleAll()\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n checkbox;\r\n context: { state: selectAllState() }\r\n \"\r\n ></ng-container>\r\n <span\r\n class=\"text-xs font-semibold uppercase tracking-wide text-surface-500\"\r\n >\r\n {{ t(\"delegations.scope.selectAll\") }}\r\n </span>\r\n </button>\r\n\r\n <!-- Virtualized permission tree -->\r\n @if (visibleNodes().length > 0) {\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"40\"\r\n class=\"block h-[20rem]\"\r\n >\r\n <div\r\n *cdkVirtualFor=\"\r\n let item of visibleNodes();\r\n trackBy: trackVisible\r\n \"\r\n class=\"group flex h-10 items-center gap-2 pe-2 transition-colors hover:bg-surface-50\"\r\n [style.padding-inline-start.rem]=\"0.5 + item.depth * 1.25\"\r\n >\r\n @if (hasChildren(item.node)) {\r\n <button\r\n type=\"button\"\r\n class=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-surface-400 hover:bg-surface-100 hover:text-surface-600\"\r\n [attr.aria-expanded]=\"isExpanded(item.node)\"\r\n [attr.aria-label]=\"nodeLabel(item.node)\"\r\n (click)=\"\r\n toggleExpand(item.node); $event.stopPropagation()\r\n \"\r\n >\r\n <mt-icon\r\n [icon]=\"\r\n isExpanded(item.node)\r\n ? 'arrow.chevron-down'\r\n : 'arrow.chevron-right'\r\n \"\r\n styleClass=\"text-base\"\r\n ></mt-icon>\r\n </button>\r\n } @else {\r\n <span class=\"size-6 shrink-0\"></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n role=\"checkbox\"\r\n [attr.aria-checked]=\"\r\n nodeState(item.node) === 'indeterminate'\r\n ? 'mixed'\r\n : nodeState(item.node) === 'checked'\r\n \"\r\n [attr.aria-label]=\"nodeLabel(item.node)\"\r\n class=\"shrink-0\"\r\n [class.cursor-pointer]=\"!readonly()\"\r\n [disabled]=\"readonly()\"\r\n (click)=\"toggle(item.node); $event.stopPropagation()\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n checkbox;\r\n context: { state: nodeState(item.node) }\r\n \"\r\n ></ng-container>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-start\"\r\n (click)=\"onRowClick(item.node)\"\r\n >\r\n <span\r\n class=\"truncate text-sm\"\r\n [class.font-semibold]=\"item.node.kind === 'template'\"\r\n [class.text-surface-900]=\"item.node.kind === 'template'\"\r\n [class.font-medium]=\"\r\n item.node.kind === 'level' ||\r\n item.node.kind === 'module'\r\n \"\r\n [class.text-surface-800]=\"\r\n item.node.kind === 'level' ||\r\n item.node.kind === 'module'\r\n \"\r\n [class.text-surface-600]=\"item.node.kind === 'operation'\"\r\n >\r\n {{ nodeLabel(item.node) }}\r\n </span>\r\n @if (\r\n item.node.kind === \"operation\" && item.node.isHighRisk\r\n ) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\r\n >\r\n {{ t(\"delegations.scope.highRisk\") }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\r\n {{ t(\"components.table.no-data-found\") }}\r\n </p>\r\n }\r\n } @else {\r\n <!-- App accessibility -->\r\n <div class=\"flex flex-col gap-3 p-4\">\r\n <p class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.scope.accessibilityHint\") }}\r\n </p>\r\n <div class=\"flex flex-wrap gap-2\">\r\n @for (\r\n item of appAccessibilities();\r\n track item.accessibilityKey\r\n ) {\r\n @let selected =\r\n isAccessibilitySelected(item.accessibilityKey);\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors\"\r\n [class.border-primary-400]=\"selected\"\r\n [class.bg-primary-50]=\"selected\"\r\n [class.text-primary-700]=\"selected\"\r\n [class.border-surface-200]=\"!selected\"\r\n [class.text-surface-600]=\"!selected\"\r\n [class.hover:border-primary-300]=\"!readonly()\"\r\n [disabled]=\"readonly()\"\r\n [attr.aria-pressed]=\"selected\"\r\n (click)=\"toggleAccessibility(item.accessibilityKey)\"\r\n >\r\n <span\r\n class=\"inline-flex size-1.5 rounded-full\"\r\n [class.bg-primary-500]=\"selected\"\r\n [class.bg-surface-300]=\"!selected\"\r\n ></span>\r\n {{ accessibilityLabel(item) }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Compact live scope preview -->\r\n <div\r\n class=\"flex flex-col gap-1.5 rounded-lg border border-surface bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"flex items-center gap-2 text-xs\">\r\n <span class=\"shrink-0 font-semibold text-surface-700\">\r\n {{ t(\"delegations.scope.previewTitle\") }}:\r\n </span>\r\n @if (isPreviewing()) {\r\n <p-skeleton width=\"8rem\" height=\"0.7rem\"></p-skeleton>\r\n } @else if (preview(); as p) {\r\n @if (p.isValid) {\r\n <span class=\"min-w-0 flex-1 truncate text-surface-900\">\r\n {{\r\n getPreviewSummary(p.summary) ||\r\n t(\"delegations.column.scopeSummary\")\r\n }}\r\n </span>\r\n } @else {\r\n <span class=\"font-medium text-red-700\">\r\n {{ t(\"delegations.scope.previewInvalid\") }}\r\n </span>\r\n }\r\n } @else {\r\n <span class=\"text-surface-500\">\r\n {{ t(\"delegations.scope.noSelection\") }}\r\n </span>\r\n }\r\n </div>\r\n @if (preview(); as p) {\r\n @if (p.warnings.length > 0) {\r\n <ul\r\n class=\"list-inside list-disc space-y-0.5 text-xs text-amber-700\"\r\n >\r\n @for (w of p.warnings; track $index) {\r\n <li>{{ w.message }}</li>\r\n }\r\n </ul>\r\n }\r\n @if (p.deniedItems.length > 0) {\r\n <ul class=\"list-inside list-disc space-y-0.5 text-xs text-red-700\">\r\n @for (d of p.deniedItems; track $index) {\r\n <li>\r\n {{ formatDeniedTarget(d.targetKey) }} /\r\n {{ formatDeniedOperation(d.operationKey) }} -\r\n {{ d.reasonCode }}\r\n </li>\r\n }\r\n </ul>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i4.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2412
2412
|
}
|
|
2413
2413
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ScopePicker, decorators: [{
|
|
2414
2414
|
type: Component,
|
|
@@ -2423,7 +2423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
2423
2423
|
TextField,
|
|
2424
2424
|
SkeletonModule,
|
|
2425
2425
|
TranslocoDirective,
|
|
2426
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n <!-- Reusable tri-state checkbox box -->\n <ng-template #checkbox let-state=\"state\">\n <span\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors\"\n [class.border-primary-500]=\"state !== 'unchecked'\"\n [class.bg-primary-500]=\"state !== 'unchecked'\"\n [class.text-white]=\"state !== 'unchecked'\"\n [class.border-surface-300]=\"state === 'unchecked'\"\n [class.bg-surface-0]=\"state === 'unchecked'\"\n >\n @if (state === \"checked\") {\n <svg\n viewBox=\"0 0 16 16\"\n class=\"size-3\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n } @else if (state === \"indeterminate\") {\n <span class=\"h-[2px] w-2.5 rounded-full bg-white\"></span>\n }\n </span>\n </ng-template>\n\n <div class=\"flex flex-col gap-3\">\n @if (isLoadingOptions()) {\n <mt-card [paddingless]=\"true\">\n <div class=\"flex flex-col gap-3 p-4\">\n <p-skeleton height=\"2.5rem\"></p-skeleton>\n @for (item of [0, 1, 2, 3, 4, 5]; track $index) {\n <p-skeleton height=\"2rem\"></p-skeleton>\n }\n </div>\n </mt-card>\n } @else {\n @if (errorOptions(); as errorMessage) {\n <div\n class=\"rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\n >\n {{ errorMessage }}\n </div>\n }\n\n @if (!hasOptions() && !errorOptions()) {\n <mt-card [paddingless]=\"true\">\n <div\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 px-6 py-8 text-center\"\n >\n <div\n class=\"flex size-16 items-center justify-center rounded-3xl bg-surface-50 text-primary\"\n >\n <svg\n viewBox=\"0 0 64 64\"\n class=\"size-9\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"10\"\n y=\"12\"\n width=\"44\"\n height=\"38\"\n rx=\"12\"\n class=\"fill-primary/10 stroke-primary/35\"\n stroke-width=\"2\"\n />\n <path\n d=\"M21 27H43\"\n class=\"stroke-primary\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M21 35H37\"\n class=\"stroke-primary/70\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n <div class=\"space-y-1\">\n <p class=\"text-base font-medium text-surface-900\">\n {{ t(\"delegations.scope.permissionsTitle\") }}\n </p>\n <p class=\"text-sm text-surface-500\">\n {{ t(\"delegations.scope.noGrantableOptions\") }}\n </p>\n </div>\n </div>\n </mt-card>\n }\n\n @if (hasOptions()) {\n <mt-card [paddingless]=\"true\" class=\"overflow-hidden\">\n <!-- Inner view switch: Permissions / Pages & accessibility -->\n @if (hasAccessibility()) {\n <div class=\"border-b border-surface px-3 pt-2.5 pb-0\">\n <mt-tabs\n mode=\"underline\"\n [(active)]=\"activeScopeTab\"\n [options]=\"[\n {\n value: 'permissions',\n label: t('delegations.scope.permissionsTab'),\n badge: selectedCount() || null,\n },\n {\n value: 'accessibility',\n label: t('delegations.scope.accessibilityTitle'),\n badge: selectedAccessibilityCount() || null,\n },\n ]\"\n fluid\n ></mt-tabs>\n </div>\n }\n\n @if (activeScopeTab() === \"permissions\" || !hasAccessibility()) {\n <!-- Toolbar: table-style search + clear -->\n <div\n class=\"flex items-center gap-2 border-b border-surface px-3 py-2\"\n >\n <div class=\"min-w-0 flex-1\">\n <mt-text-field\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"searchTerm.set($event)\"\n icon=\"general.search-lg\"\n [placeholder]=\"t('delegations.scope.searchPlaceholder')\"\n ></mt-text-field>\n </div>\n @if (selectedCount() > 0) {\n <span class=\"shrink-0 text-xs font-medium text-surface-500\">\n {{ selectedCount() }} {{ t(\"delegations.scope.selected\") }}\n </span>\n <mt-button\n variant=\"text\"\n size=\"small\"\n [label]=\"t('delegations.scope.clear')\"\n [disabled]=\"readonly()\"\n (click)=\"clearSelection()\"\n ></mt-button>\n }\n </div>\n\n <!-- Select-all header -->\n <button\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center gap-2 border-b border-surface px-3 py-2 text-start hover:bg-surface-50\"\n role=\"checkbox\"\n [attr.aria-checked]=\"\n selectAllState() === 'indeterminate'\n ? 'mixed'\n : selectAllState() === 'checked'\n \"\n [disabled]=\"readonly()\"\n (click)=\"toggleAll()\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n checkbox;\n context: { state: selectAllState() }\n \"\n ></ng-container>\n <span\n class=\"text-xs font-semibold uppercase tracking-wide text-surface-500\"\n >\n {{ t(\"delegations.scope.selectAll\") }}\n </span>\n </button>\n\n <!-- Virtualized permission tree -->\n @if (visibleNodes().length > 0) {\n <cdk-virtual-scroll-viewport\n itemSize=\"40\"\n class=\"block h-[20rem]\"\n >\n <div\n *cdkVirtualFor=\"\n let item of visibleNodes();\n trackBy: trackVisible\n \"\n class=\"group flex h-10 items-center gap-2 pe-2 transition-colors hover:bg-surface-50\"\n [style.padding-inline-start.rem]=\"0.5 + item.depth * 1.25\"\n >\n @if (hasChildren(item.node)) {\n <button\n type=\"button\"\n class=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-surface-400 hover:bg-surface-100 hover:text-surface-600\"\n [attr.aria-expanded]=\"isExpanded(item.node)\"\n [attr.aria-label]=\"nodeLabel(item.node)\"\n (click)=\"\n toggleExpand(item.node); $event.stopPropagation()\n \"\n >\n <mt-icon\n [icon]=\"\n isExpanded(item.node)\n ? 'arrow.chevron-down'\n : 'arrow.chevron-right'\n \"\n styleClass=\"text-base\"\n ></mt-icon>\n </button>\n } @else {\n <span class=\"size-6 shrink-0\"></span>\n }\n\n <button\n type=\"button\"\n role=\"checkbox\"\n [attr.aria-checked]=\"\n nodeState(item.node) === 'indeterminate'\n ? 'mixed'\n : nodeState(item.node) === 'checked'\n \"\n [attr.aria-label]=\"nodeLabel(item.node)\"\n class=\"shrink-0\"\n [class.cursor-pointer]=\"!readonly()\"\n [disabled]=\"readonly()\"\n (click)=\"toggle(item.node); $event.stopPropagation()\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n checkbox;\n context: { state: nodeState(item.node) }\n \"\n ></ng-container>\n </button>\n\n <button\n type=\"button\"\n class=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-start\"\n (click)=\"onRowClick(item.node)\"\n >\n <span\n class=\"truncate text-sm\"\n [class.font-semibold]=\"item.node.kind === 'template'\"\n [class.text-surface-900]=\"item.node.kind === 'template'\"\n [class.font-medium]=\"\n item.node.kind === 'level' ||\n item.node.kind === 'module'\n \"\n [class.text-surface-800]=\"\n item.node.kind === 'level' ||\n item.node.kind === 'module'\n \"\n [class.text-surface-600]=\"item.node.kind === 'operation'\"\n >\n {{ nodeLabel(item.node) }}\n </span>\n @if (\n item.node.kind === \"operation\" && item.node.isHighRisk\n ) {\n <span\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\n >\n {{ t(\"delegations.scope.highRisk\") }}\n </span>\n }\n </button>\n </div>\n </cdk-virtual-scroll-viewport>\n } @else {\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\n {{ t(\"components.table.no-data-found\") }}\n </p>\n }\n } @else {\n <!-- App accessibility -->\n <div class=\"flex flex-col gap-3 p-4\">\n <p class=\"text-xs text-surface-500\">\n {{ t(\"delegations.scope.accessibilityHint\") }}\n </p>\n <div class=\"flex flex-wrap gap-2\">\n @for (\n item of appAccessibilities();\n track item.accessibilityKey\n ) {\n @let selected =\n isAccessibilitySelected(item.accessibilityKey);\n <button\n type=\"button\"\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors\"\n [class.border-primary-400]=\"selected\"\n [class.bg-primary-50]=\"selected\"\n [class.text-primary-700]=\"selected\"\n [class.border-surface-200]=\"!selected\"\n [class.text-surface-600]=\"!selected\"\n [class.hover:border-primary-300]=\"!readonly()\"\n [disabled]=\"readonly()\"\n [attr.aria-pressed]=\"selected\"\n (click)=\"toggleAccessibility(item.accessibilityKey)\"\n >\n <span\n class=\"inline-flex size-1.5 rounded-full\"\n [class.bg-primary-500]=\"selected\"\n [class.bg-surface-300]=\"!selected\"\n ></span>\n {{ accessibilityLabel(item) }}\n </button>\n }\n </div>\n </div>\n }\n </mt-card>\n }\n\n <!-- Compact live scope preview -->\n <div\n class=\"flex flex-col gap-1.5 rounded-lg border border-surface bg-surface-50 px-3 py-2\"\n >\n <div class=\"flex items-center gap-2 text-xs\">\n <span class=\"shrink-0 font-semibold text-surface-700\">\n {{ t(\"delegations.scope.previewTitle\") }}:\n </span>\n @if (isPreviewing()) {\n <p-skeleton width=\"8rem\" height=\"0.7rem\"></p-skeleton>\n } @else if (preview(); as p) {\n @if (p.isValid) {\n <span class=\"min-w-0 flex-1 truncate text-surface-900\">\n {{\n getPreviewSummary(p.summary) ||\n t(\"delegations.column.scopeSummary\")\n }}\n </span>\n } @else {\n <span class=\"font-medium text-red-700\">\n {{ t(\"delegations.scope.previewInvalid\") }}\n </span>\n }\n } @else {\n <span class=\"text-surface-500\">\n {{ t(\"delegations.scope.noSelection\") }}\n </span>\n }\n </div>\n @if (preview(); as p) {\n @if (p.warnings.length > 0) {\n <ul\n class=\"list-inside list-disc space-y-0.5 text-xs text-amber-700\"\n >\n @for (w of p.warnings; track $index) {\n <li>{{ w.message }}</li>\n }\n </ul>\n }\n @if (p.deniedItems.length > 0) {\n <ul class=\"list-inside list-disc space-y-0.5 text-xs text-red-700\">\n @for (d of p.deniedItems; track $index) {\n <li>\n {{ formatDeniedTarget(d.targetKey) }} /\n {{ formatDeniedOperation(d.operationKey) }} -\n {{ d.reasonCode }}\n </li>\n }\n </ul>\n }\n }\n </div>\n }\n </div>\n</ng-container>\n" }]
|
|
2426
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n <!-- Reusable tri-state checkbox box -->\r\n <ng-template #checkbox let-state=\"state\">\r\n <span\r\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors\"\r\n [class.border-primary-500]=\"state !== 'unchecked'\"\r\n [class.bg-primary-500]=\"state !== 'unchecked'\"\r\n [class.text-white]=\"state !== 'unchecked'\"\r\n [class.border-surface-300]=\"state === 'unchecked'\"\r\n [class.bg-surface-0]=\"state === 'unchecked'\"\r\n >\r\n @if (state === \"checked\") {\r\n <svg\r\n viewBox=\"0 0 16 16\"\r\n class=\"size-3\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <path\r\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n } @else if (state === \"indeterminate\") {\r\n <span class=\"h-[2px] w-2.5 rounded-full bg-white\"></span>\r\n }\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-3\">\r\n @if (isLoadingOptions()) {\r\n <mt-card [paddingless]=\"true\">\r\n <div class=\"flex flex-col gap-3 p-4\">\r\n <p-skeleton height=\"2.5rem\"></p-skeleton>\r\n @for (item of [0, 1, 2, 3, 4, 5]; track $index) {\r\n <p-skeleton height=\"2rem\"></p-skeleton>\r\n }\r\n </div>\r\n </mt-card>\r\n } @else {\r\n @if (errorOptions(); as errorMessage) {\r\n <div\r\n class=\"rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n\r\n @if (!hasOptions() && !errorOptions()) {\r\n <mt-card [paddingless]=\"true\">\r\n <div\r\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 px-6 py-8 text-center\"\r\n >\r\n <div\r\n class=\"flex size-16 items-center justify-center rounded-3xl bg-surface-50 text-primary\"\r\n >\r\n <svg\r\n viewBox=\"0 0 64 64\"\r\n class=\"size-9\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <rect\r\n x=\"10\"\r\n y=\"12\"\r\n width=\"44\"\r\n height=\"38\"\r\n rx=\"12\"\r\n class=\"fill-primary/10 stroke-primary/35\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M21 27H43\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M21 35H37\"\r\n class=\"stroke-primary/70\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <div class=\"space-y-1\">\r\n <p class=\"text-base font-medium text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </p>\r\n <p class=\"text-sm text-surface-500\">\r\n {{ t(\"delegations.scope.noGrantableOptions\") }}\r\n </p>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n @if (hasOptions()) {\r\n <mt-card [paddingless]=\"true\" class=\"overflow-hidden\">\r\n <!-- Inner view switch: Permissions / Pages & accessibility -->\r\n @if (hasAccessibility()) {\r\n <div class=\"border-b border-surface px-3 pt-2.5 pb-0\">\r\n <mt-tabs\r\n mode=\"underline\"\r\n [(active)]=\"activeScopeTab\"\r\n [options]=\"[\r\n {\r\n value: 'permissions',\r\n label: t('delegations.scope.permissionsTab'),\r\n badge: selectedCount() || null,\r\n },\r\n {\r\n value: 'accessibility',\r\n label: t('delegations.scope.accessibilityTitle'),\r\n badge: selectedAccessibilityCount() || null,\r\n },\r\n ]\"\r\n fluid\r\n ></mt-tabs>\r\n </div>\r\n }\r\n\r\n @if (activeScopeTab() === \"permissions\" || !hasAccessibility()) {\r\n <!-- Toolbar: table-style search + clear -->\r\n <div\r\n class=\"flex items-center gap-2 border-b border-surface px-3 py-2\"\r\n >\r\n <div class=\"min-w-0 flex-1\">\r\n <mt-text-field\r\n [ngModel]=\"searchTerm()\"\r\n (ngModelChange)=\"searchTerm.set($event)\"\r\n icon=\"general.search-lg\"\r\n [placeholder]=\"t('delegations.scope.searchPlaceholder')\"\r\n ></mt-text-field>\r\n </div>\r\n @if (selectedCount() > 0) {\r\n <span class=\"shrink-0 text-xs font-medium text-surface-500\">\r\n {{ selectedCount() }} {{ t(\"delegations.scope.selected\") }}\r\n </span>\r\n <mt-button\r\n variant=\"text\"\r\n size=\"small\"\r\n [label]=\"t('delegations.scope.clear')\"\r\n [disabled]=\"readonly()\"\r\n (click)=\"clearSelection()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <!-- Select-all header -->\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-center gap-2 border-b border-surface px-3 py-2 text-start hover:bg-surface-50\"\r\n role=\"checkbox\"\r\n [attr.aria-checked]=\"\r\n selectAllState() === 'indeterminate'\r\n ? 'mixed'\r\n : selectAllState() === 'checked'\r\n \"\r\n [disabled]=\"readonly()\"\r\n (click)=\"toggleAll()\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n checkbox;\r\n context: { state: selectAllState() }\r\n \"\r\n ></ng-container>\r\n <span\r\n class=\"text-xs font-semibold uppercase tracking-wide text-surface-500\"\r\n >\r\n {{ t(\"delegations.scope.selectAll\") }}\r\n </span>\r\n </button>\r\n\r\n <!-- Virtualized permission tree -->\r\n @if (visibleNodes().length > 0) {\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"40\"\r\n class=\"block h-[20rem]\"\r\n >\r\n <div\r\n *cdkVirtualFor=\"\r\n let item of visibleNodes();\r\n trackBy: trackVisible\r\n \"\r\n class=\"group flex h-10 items-center gap-2 pe-2 transition-colors hover:bg-surface-50\"\r\n [style.padding-inline-start.rem]=\"0.5 + item.depth * 1.25\"\r\n >\r\n @if (hasChildren(item.node)) {\r\n <button\r\n type=\"button\"\r\n class=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-surface-400 hover:bg-surface-100 hover:text-surface-600\"\r\n [attr.aria-expanded]=\"isExpanded(item.node)\"\r\n [attr.aria-label]=\"nodeLabel(item.node)\"\r\n (click)=\"\r\n toggleExpand(item.node); $event.stopPropagation()\r\n \"\r\n >\r\n <mt-icon\r\n [icon]=\"\r\n isExpanded(item.node)\r\n ? 'arrow.chevron-down'\r\n : 'arrow.chevron-right'\r\n \"\r\n styleClass=\"text-base\"\r\n ></mt-icon>\r\n </button>\r\n } @else {\r\n <span class=\"size-6 shrink-0\"></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n role=\"checkbox\"\r\n [attr.aria-checked]=\"\r\n nodeState(item.node) === 'indeterminate'\r\n ? 'mixed'\r\n : nodeState(item.node) === 'checked'\r\n \"\r\n [attr.aria-label]=\"nodeLabel(item.node)\"\r\n class=\"shrink-0\"\r\n [class.cursor-pointer]=\"!readonly()\"\r\n [disabled]=\"readonly()\"\r\n (click)=\"toggle(item.node); $event.stopPropagation()\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n checkbox;\r\n context: { state: nodeState(item.node) }\r\n \"\r\n ></ng-container>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-start\"\r\n (click)=\"onRowClick(item.node)\"\r\n >\r\n <span\r\n class=\"truncate text-sm\"\r\n [class.font-semibold]=\"item.node.kind === 'template'\"\r\n [class.text-surface-900]=\"item.node.kind === 'template'\"\r\n [class.font-medium]=\"\r\n item.node.kind === 'level' ||\r\n item.node.kind === 'module'\r\n \"\r\n [class.text-surface-800]=\"\r\n item.node.kind === 'level' ||\r\n item.node.kind === 'module'\r\n \"\r\n [class.text-surface-600]=\"item.node.kind === 'operation'\"\r\n >\r\n {{ nodeLabel(item.node) }}\r\n </span>\r\n @if (\r\n item.node.kind === \"operation\" && item.node.isHighRisk\r\n ) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\r\n >\r\n {{ t(\"delegations.scope.highRisk\") }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\r\n {{ t(\"components.table.no-data-found\") }}\r\n </p>\r\n }\r\n } @else {\r\n <!-- App accessibility -->\r\n <div class=\"flex flex-col gap-3 p-4\">\r\n <p class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.scope.accessibilityHint\") }}\r\n </p>\r\n <div class=\"flex flex-wrap gap-2\">\r\n @for (\r\n item of appAccessibilities();\r\n track item.accessibilityKey\r\n ) {\r\n @let selected =\r\n isAccessibilitySelected(item.accessibilityKey);\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors\"\r\n [class.border-primary-400]=\"selected\"\r\n [class.bg-primary-50]=\"selected\"\r\n [class.text-primary-700]=\"selected\"\r\n [class.border-surface-200]=\"!selected\"\r\n [class.text-surface-600]=\"!selected\"\r\n [class.hover:border-primary-300]=\"!readonly()\"\r\n [disabled]=\"readonly()\"\r\n [attr.aria-pressed]=\"selected\"\r\n (click)=\"toggleAccessibility(item.accessibilityKey)\"\r\n >\r\n <span\r\n class=\"inline-flex size-1.5 rounded-full\"\r\n [class.bg-primary-500]=\"selected\"\r\n [class.bg-surface-300]=\"!selected\"\r\n ></span>\r\n {{ accessibilityLabel(item) }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Compact live scope preview -->\r\n <div\r\n class=\"flex flex-col gap-1.5 rounded-lg border border-surface bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"flex items-center gap-2 text-xs\">\r\n <span class=\"shrink-0 font-semibold text-surface-700\">\r\n {{ t(\"delegations.scope.previewTitle\") }}:\r\n </span>\r\n @if (isPreviewing()) {\r\n <p-skeleton width=\"8rem\" height=\"0.7rem\"></p-skeleton>\r\n } @else if (preview(); as p) {\r\n @if (p.isValid) {\r\n <span class=\"min-w-0 flex-1 truncate text-surface-900\">\r\n {{\r\n getPreviewSummary(p.summary) ||\r\n t(\"delegations.column.scopeSummary\")\r\n }}\r\n </span>\r\n } @else {\r\n <span class=\"font-medium text-red-700\">\r\n {{ t(\"delegations.scope.previewInvalid\") }}\r\n </span>\r\n }\r\n } @else {\r\n <span class=\"text-surface-500\">\r\n {{ t(\"delegations.scope.noSelection\") }}\r\n </span>\r\n }\r\n </div>\r\n @if (preview(); as p) {\r\n @if (p.warnings.length > 0) {\r\n <ul\r\n class=\"list-inside list-disc space-y-0.5 text-xs text-amber-700\"\r\n >\r\n @for (w of p.warnings; track $index) {\r\n <li>{{ w.message }}</li>\r\n }\r\n </ul>\r\n }\r\n @if (p.deniedItems.length > 0) {\r\n <ul class=\"list-inside list-disc space-y-0.5 text-xs text-red-700\">\r\n @for (d of p.deniedItems; track $index) {\r\n <li>\r\n {{ formatDeniedTarget(d.targetKey) }} /\r\n {{ formatDeniedOperation(d.operationKey) }} -\r\n {{ d.reasonCode }}\r\n </li>\r\n }\r\n </ul>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
|
|
2427
2427
|
}], ctorParameters: () => [], propDecorators: { scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }, { type: i0.Output, args: ["scopeChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], adminMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "adminMode", required: false }] }], delegatorUserId: [{ type: i0.Input, args: [{ isSignal: true, alias: "delegatorUserId", required: false }] }] } });
|
|
2428
2428
|
|
|
2429
2429
|
const EMPTY_SCOPE = { grants: [], metadata: {} };
|
|
@@ -2824,7 +2824,7 @@ class DelegationForm {
|
|
|
2824
2824
|
};
|
|
2825
2825
|
}
|
|
2826
2826
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2827
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationForm, isStandalone: true, selector: "mt-delegation-form", inputs: { delegationForEdit: { classPropertyName: "delegationForEdit", publicName: "delegationForEdit", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div\r\n [class]=\"\r\n 'flex h-full min-h-0 min-w-0 flex-col overflow-hidden ' +\r\n modal.contentClass\r\n \"\r\n >\r\n <div\r\n class=\"grid min-h-0 flex-1 gap-4 overflow-y-auto p-4 max-[640px]:p-3 lg:grid-cols-2 lg:items-start\"\r\n >\r\n <section\r\n class=\"flex flex-col gap-4 rounded-3xl border border-surface-200 bg-surface-0 p-4 shadow-xs lg:sticky lg:top-0\"\r\n >\r\n <mt-dynamic-form\r\n [formConfig]=\"formConfig()\"\r\n [formControl]=\"delegationFormControl\"\r\n />\r\n </section>\r\n\r\n <section class=\"flex min-h-0 flex-col gap-3\">\r\n <div class=\"flex flex-col gap-1\">\r\n <h3 class=\"text-xl font-semibold text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </h3>\r\n <p class=\"text-sm text-surface-500\">\r\n {{\r\n adminMode() && !showScopePicker()\r\n ? t(\"delegations.form.selectDelegatorFirst\")\r\n : t(\"delegations.scope.permissionsSubtitle\")\r\n }}\r\n </p>\r\n </div>\r\n\r\n @if (showScopePicker()) {\r\n <mt-scope-picker\r\n [(scope)]=\"scope\"\r\n [readonly]=\"readonly()\"\r\n [adminMode]=\"adminMode()\"\r\n [delegatorUserId]=\"selectedDelegatorId()\"\r\n ></mt-scope-picker>\r\n } @else {\r\n <div\r\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 rounded-3xl border border-dashed border-surface-300 bg-surface-50 px-6 py-8 text-center\"\r\n >\r\n <div\r\n class=\"flex size-18 items-center justify-center rounded-3xl bg-surface-0 text-primary shadow-sm\"\r\n >\r\n <svg\r\n viewBox=\"0 0 64 64\"\r\n class=\"size-10\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <rect\r\n x=\"10\"\r\n y=\"12\"\r\n width=\"44\"\r\n height=\"40\"\r\n rx=\"12\"\r\n class=\"fill-primary/10 stroke-primary/35\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M22 28H42\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M22 36H34\"\r\n class=\"stroke-primary/70\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <circle\r\n cx=\"45\"\r\n cy=\"20\"\r\n r=\"7\"\r\n class=\"fill-surface-0 stroke-primary\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M45 17V23\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M42 20H48\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <div class=\"space-y-1\">\r\n <p class=\"text-base font-medium text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </p>\r\n <p class=\"text-sm text-surface-500\">\r\n {{ t(\"delegations.form.selectDelegatorFirst\") }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n </section>\r\n </div>\r\n </div>\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('delegations.common.cancel')\"\r\n variant=\"outlined\"\r\n (click)=\"ref.close()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n />\r\n @if (!readonly()) {\r\n <mt-button\r\n [label]=\"\r\n delegationForEdit()\r\n ? t('delegations.common.update')\r\n : t('delegations.common.create')\r\n \"\r\n [loading]=\"isSaving()\"\r\n [disabled]=\"!delegationFormControl.valid || !canSubmit()\"\r\n (click)=\"onSubmit()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n />\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ScopePicker, selector: "mt-scope-picker", inputs: ["scope", "readonly", "adminMode", "delegatorUserId"], outputs: ["scopeChange"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2827
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationForm, isStandalone: true, selector: "mt-delegation-form", inputs: { delegationForEdit: { classPropertyName: "delegationForEdit", publicName: "delegationForEdit", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div\r\n [class]=\"\r\n 'flex h-full min-h-0 min-w-0 flex-col overflow-hidden ' +\r\n modal.contentClass\r\n \"\r\n >\r\n <div\r\n class=\"grid min-h-0 flex-1 gap-4 overflow-y-auto p-4 max-[640px]:p-3 lg:grid-cols-2 lg:items-start\"\r\n >\r\n <section\r\n class=\"flex flex-col gap-4 rounded-3xl border border-surface-200 bg-surface-0 p-4 shadow-xs lg:sticky lg:top-0\"\r\n >\r\n <mt-dynamic-form\r\n [formConfig]=\"formConfig()\"\r\n [formControl]=\"delegationFormControl\"\r\n />\r\n </section>\r\n\r\n <section class=\"flex min-h-0 flex-col gap-3\">\r\n <div class=\"flex flex-col gap-1\">\r\n <h3 class=\"text-xl font-semibold text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </h3>\r\n <p class=\"text-sm text-surface-500\">\r\n {{\r\n adminMode() && !showScopePicker()\r\n ? t(\"delegations.form.selectDelegatorFirst\")\r\n : t(\"delegations.scope.permissionsSubtitle\")\r\n }}\r\n </p>\r\n </div>\r\n\r\n @if (showScopePicker()) {\r\n <mt-scope-picker\r\n [(scope)]=\"scope\"\r\n [readonly]=\"readonly()\"\r\n [adminMode]=\"adminMode()\"\r\n [delegatorUserId]=\"selectedDelegatorId()\"\r\n ></mt-scope-picker>\r\n } @else {\r\n <div\r\n class=\"flex min-h-72 flex-col items-center justify-center gap-4 rounded-3xl border border-dashed border-surface-300 bg-surface-50 px-6 py-8 text-center\"\r\n >\r\n <div\r\n class=\"flex size-18 items-center justify-center rounded-3xl bg-surface-0 text-primary shadow-sm\"\r\n >\r\n <svg\r\n viewBox=\"0 0 64 64\"\r\n class=\"size-10\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-hidden=\"true\"\r\n >\r\n <rect\r\n x=\"10\"\r\n y=\"12\"\r\n width=\"44\"\r\n height=\"40\"\r\n rx=\"12\"\r\n class=\"fill-primary/10 stroke-primary/35\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M22 28H42\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M22 36H34\"\r\n class=\"stroke-primary/70\"\r\n stroke-width=\"3\"\r\n stroke-linecap=\"round\"\r\n />\r\n <circle\r\n cx=\"45\"\r\n cy=\"20\"\r\n r=\"7\"\r\n class=\"fill-surface-0 stroke-primary\"\r\n stroke-width=\"2\"\r\n />\r\n <path\r\n d=\"M45 17V23\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M42 20H48\"\r\n class=\"stroke-primary\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <div class=\"space-y-1\">\r\n <p class=\"text-base font-medium text-surface-900\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </p>\r\n <p class=\"text-sm text-surface-500\">\r\n {{ t(\"delegations.form.selectDelegatorFirst\") }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n </section>\r\n </div>\r\n </div>\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('delegations.common.cancel')\"\r\n variant=\"outlined\"\r\n (click)=\"ref.close()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n />\r\n @if (!readonly()) {\r\n <mt-button\r\n [label]=\"\r\n delegationForEdit()\r\n ? t('delegations.common.update')\r\n : t('delegations.common.create')\r\n \"\r\n [loading]=\"isSaving()\"\r\n [disabled]=\"!delegationFormControl.valid || !canSubmit()\"\r\n (click)=\"onSubmit()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n />\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ScopePicker, selector: "mt-scope-picker", inputs: ["scope", "readonly", "adminMode", "delegatorUserId"], outputs: ["scopeChange"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2828
2828
|
}
|
|
2829
2829
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationForm, decorators: [{
|
|
2830
2830
|
type: Component,
|
|
@@ -2989,7 +2989,7 @@ class DelegationDetailDrawer {
|
|
|
2989
2989
|
return 'children' in node && node.children.length > 0;
|
|
2990
2990
|
}
|
|
2991
2991
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationDetailDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2992
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationDetailDrawer, isStandalone: true, selector: "mt-delegation-detail-drawer", inputs: { delegationId: { classPropertyName: "delegationId", publicName: "delegationId", isSignal: true, isRequired: true, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\n <div class=\"flex flex-col h-full\">\n <!-- Tabs -->\n <div class=\"border-b border-surface-200 px-4 pt-2\">\n <mt-tabs\n mode=\"underline\"\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n fluid\n ></mt-tabs>\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto p-4\">\n @if (isLoading() && !detail()) {\n <p-skeleton height=\"2rem\" class=\"mb-3\"></p-skeleton>\n <p-skeleton height=\"6rem\" class=\"mb-3\"></p-skeleton>\n <p-skeleton height=\"6rem\"></p-skeleton>\n } @else if (detail(); as d) {\n @if (activeTab() === \"overview\") {\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"flex items-center gap-3 min-w-0\">\n <mt-entity-preview\n [data]=\"\n userEntity(\n d.row.delegator,\n t('delegations.column.delegatorName')\n )\n \"\n ></mt-entity-preview>\n </div>\n <mt-delegation-status-chip\n [status]=\"d.status.effectiveStatus\"\n ></mt-delegation-status-chip>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"flex flex-col\">\n <mt-entity-preview\n [data]=\"\n userEntity(\n d.row.delegatedUser,\n t('delegations.column.delegatedTo')\n )\n \"\n ></mt-entity-preview>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.approval\") }}\n </span>\n <span class=\"text-sm text-surface-900\">{{\n approvalLabel()\n }}</span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.startDate\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n {{ d.row.startsAtUtc | date: \"medium\" }}\n </span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.endDate\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n {{ d.row.endsAtUtc | date: \"medium\" }}\n </span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.form.timeZone\") }}\n </span>\n <span class=\"text-sm text-surface-900\">{{\n d.row.timeZoneId\n }}</span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.days\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n @if (d.row.dayRuleMode === \"FullRange\") {\n {{ t(\"delegations.form.fullRange\") }}\n } @else {\n {{ formatSpecificDays(d.row.specificDays) }}\n }\n </span>\n </div>\n </div>\n\n @if (d.row.cancellation?.cancellationReason) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3 text-sm text-surface-800\"\n >\n <div class=\"font-medium\">\n {{ t(\"delegations.form.cancellationReason\") }}\n </div>\n <div>{{ d.row.cancellation.cancellationReason }}</div>\n </div>\n }\n </div>\n } @else {\n <!-- Scope tab -->\n <div\n class=\"flex flex-col overflow-hidden rounded-lg border border-surface\"\n >\n <div\n class=\"flex items-center justify-between gap-2 border-b border-surface bg-surface-50 px-3 py-2\"\n >\n <span class=\"text-xs font-semibold uppercase text-surface-500\">\n {{ t(\"delegations.scope.permissionsTitle\") }}\n </span>\n @if (selectedOperationCount() > 0) {\n <span class=\"text-xs font-medium text-surface-500\">\n {{ selectedOperationCount() }}\n {{ t(\"delegations.scope.selected\") }}\n </span>\n }\n </div>\n\n @if (scopeVisibleNodes().length > 0) {\n <div class=\"flex max-h-[34rem] flex-col overflow-y-auto\">\n @for (\n node of scopeVisibleNodes();\n track trackScopeNode($index, node)\n ) {\n <div\n class=\"group flex min-h-10 items-center gap-2 pe-3 transition-colors hover:bg-surface-50\"\n [style.padding-inline-start.rem]=\"0.75 + node.depth * 1.25\"\n >\n @if (hasChildren(node)) {\n <span\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md text-surface-400\"\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 20 20\"\n class=\"size-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 7L10 12L15 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n } @else {\n <span class=\"size-6 shrink-0\"></span>\n }\n\n <span\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border border-primary-500 bg-primary-500 text-white\"\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 16 16\"\n class=\"size-3\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n\n <span\n class=\"min-w-0 flex-1 truncate text-sm\"\n [class.font-semibold]=\"node.kind === 'template'\"\n [class.text-surface-900]=\"node.kind === 'template'\"\n [class.font-medium]=\"\n node.kind === 'level' || node.kind === 'module'\n \"\n [class.text-surface-800]=\"\n node.kind === 'level' || node.kind === 'module'\n \"\n [class.text-surface-600]=\"node.kind === 'operation'\"\n >\n {{ node.label }}\n </span>\n\n @if (node.kind === \"operation\" && node.isHighRisk) {\n <span\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\n >\n {{ t(\"delegations.scope.highRisk\") }}\n </span>\n }\n\n @if (!node.isAvailable) {\n <span\n class=\"shrink-0 rounded-full bg-surface-100 px-2 py-0.5 text-[0.625rem] font-medium text-surface-500\"\n >\n {{ t(\"delegations.scope.unavailable\") }}\n </span>\n }\n </div>\n }\n </div>\n } @else {\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\n {{ t(\"delegations.scope.noSelection\") }}\n </p>\n }\n </div>\n }\n }\n </div>\n\n <!-- Footer -->\n <div\n class=\"border-t border-surface-200 px-4 py-3 flex items-center justify-end\"\n >\n <mt-button\n [label]=\"t('delegations.common.cancel')\"\n variant=\"outlined\"\n (click)=\"ref.close()\"\n ></mt-button>\n </div>\n </div>\n</ng-container>\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i4.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationStatusChip, selector: "mt-delegation-status-chip", inputs: ["status"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2992
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DelegationDetailDrawer, isStandalone: true, selector: "mt-delegation-detail-drawer", inputs: { delegationId: { classPropertyName: "delegationId", publicName: "delegationId", isSignal: true, isRequired: true, transformFunction: null }, adminMode: { classPropertyName: "adminMode", publicName: "adminMode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div class=\"flex flex-col h-full\">\r\n <!-- Tabs -->\r\n <div class=\"border-b border-surface-200 px-4 pt-2\">\r\n <mt-tabs\r\n mode=\"underline\"\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n fluid\r\n ></mt-tabs>\r\n </div>\r\n\r\n <!-- Body -->\r\n <div class=\"flex-1 overflow-y-auto p-4\">\r\n @if (isLoading() && !detail()) {\r\n <p-skeleton height=\"2rem\" class=\"mb-3\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" class=\"mb-3\"></p-skeleton>\r\n <p-skeleton height=\"6rem\"></p-skeleton>\r\n } @else if (detail(); as d) {\r\n @if (activeTab() === \"overview\") {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"flex items-center justify-between gap-3\">\r\n <div class=\"flex items-center gap-3 min-w-0\">\r\n <mt-entity-preview\r\n [data]=\"\r\n userEntity(\r\n d.row.delegator,\r\n t('delegations.column.delegatorName')\r\n )\r\n \"\r\n ></mt-entity-preview>\r\n </div>\r\n <mt-delegation-status-chip\r\n [status]=\"d.status.effectiveStatus\"\r\n ></mt-delegation-status-chip>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-2 gap-4\">\r\n <div class=\"flex flex-col\">\r\n <mt-entity-preview\r\n [data]=\"\r\n userEntity(\r\n d.row.delegatedUser,\r\n t('delegations.column.delegatedTo')\r\n )\r\n \"\r\n ></mt-entity-preview>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.approval\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">{{\r\n approvalLabel()\r\n }}</span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.startDate\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n {{ d.row.startsAtUtc | date: \"medium\" }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.endDate\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n {{ d.row.endsAtUtc | date: \"medium\" }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.form.timeZone\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">{{\r\n d.row.timeZoneId\r\n }}</span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.days\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n @if (d.row.dayRuleMode === \"FullRange\") {\r\n {{ t(\"delegations.form.fullRange\") }}\r\n } @else {\r\n {{ formatSpecificDays(d.row.specificDays) }}\r\n }\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (d.row.cancellation?.cancellationReason) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3 text-sm text-surface-800\"\r\n >\r\n <div class=\"font-medium\">\r\n {{ t(\"delegations.form.cancellationReason\") }}\r\n </div>\r\n <div>{{ d.row.cancellation.cancellationReason }}</div>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Scope tab -->\r\n <div\r\n class=\"flex flex-col overflow-hidden rounded-lg border border-surface\"\r\n >\r\n <div\r\n class=\"flex items-center justify-between gap-2 border-b border-surface bg-surface-50 px-3 py-2\"\r\n >\r\n <span class=\"text-xs font-semibold uppercase text-surface-500\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </span>\r\n @if (selectedOperationCount() > 0) {\r\n <span class=\"text-xs font-medium text-surface-500\">\r\n {{ selectedOperationCount() }}\r\n {{ t(\"delegations.scope.selected\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (scopeVisibleNodes().length > 0) {\r\n <div class=\"flex max-h-[34rem] flex-col overflow-y-auto\">\r\n @for (\r\n node of scopeVisibleNodes();\r\n track trackScopeNode($index, node)\r\n ) {\r\n <div\r\n class=\"group flex min-h-10 items-center gap-2 pe-3 transition-colors hover:bg-surface-50\"\r\n [style.padding-inline-start.rem]=\"0.75 + node.depth * 1.25\"\r\n >\r\n @if (hasChildren(node)) {\r\n <span\r\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md text-surface-400\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg\r\n viewBox=\"0 0 20 20\"\r\n class=\"size-4\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M5 7L10 12L15 7\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.8\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </span>\r\n } @else {\r\n <span class=\"size-6 shrink-0\"></span>\r\n }\r\n\r\n <span\r\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border border-primary-500 bg-primary-500 text-white\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg\r\n viewBox=\"0 0 16 16\"\r\n class=\"size-3\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </span>\r\n\r\n <span\r\n class=\"min-w-0 flex-1 truncate text-sm\"\r\n [class.font-semibold]=\"node.kind === 'template'\"\r\n [class.text-surface-900]=\"node.kind === 'template'\"\r\n [class.font-medium]=\"\r\n node.kind === 'level' || node.kind === 'module'\r\n \"\r\n [class.text-surface-800]=\"\r\n node.kind === 'level' || node.kind === 'module'\r\n \"\r\n [class.text-surface-600]=\"node.kind === 'operation'\"\r\n >\r\n {{ node.label }}\r\n </span>\r\n\r\n @if (node.kind === \"operation\" && node.isHighRisk) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\r\n >\r\n {{ t(\"delegations.scope.highRisk\") }}\r\n </span>\r\n }\r\n\r\n @if (!node.isAvailable) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-100 px-2 py-0.5 text-[0.625rem] font-medium text-surface-500\"\r\n >\r\n {{ t(\"delegations.scope.unavailable\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\r\n {{ t(\"delegations.scope.noSelection\") }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div\r\n class=\"border-t border-surface-200 px-4 py-3 flex items-center justify-end\"\r\n >\r\n <mt-button\r\n [label]=\"t('delegations.common.cancel')\"\r\n variant=\"outlined\"\r\n (click)=\"ref.close()\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i4.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DelegationStatusChip, selector: "mt-delegation-status-chip", inputs: ["status"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2993
2993
|
}
|
|
2994
2994
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DelegationDetailDrawer, decorators: [{
|
|
2995
2995
|
type: Component,
|
|
@@ -3001,7 +3001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
3001
3001
|
Tabs,
|
|
3002
3002
|
TranslocoDirective,
|
|
3003
3003
|
DelegationStatusChip,
|
|
3004
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\n <div class=\"flex flex-col h-full\">\n <!-- Tabs -->\n <div class=\"border-b border-surface-200 px-4 pt-2\">\n <mt-tabs\n mode=\"underline\"\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n fluid\n ></mt-tabs>\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto p-4\">\n @if (isLoading() && !detail()) {\n <p-skeleton height=\"2rem\" class=\"mb-3\"></p-skeleton>\n <p-skeleton height=\"6rem\" class=\"mb-3\"></p-skeleton>\n <p-skeleton height=\"6rem\"></p-skeleton>\n } @else if (detail(); as d) {\n @if (activeTab() === \"overview\") {\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"flex items-center gap-3 min-w-0\">\n <mt-entity-preview\n [data]=\"\n userEntity(\n d.row.delegator,\n t('delegations.column.delegatorName')\n )\n \"\n ></mt-entity-preview>\n </div>\n <mt-delegation-status-chip\n [status]=\"d.status.effectiveStatus\"\n ></mt-delegation-status-chip>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"flex flex-col\">\n <mt-entity-preview\n [data]=\"\n userEntity(\n d.row.delegatedUser,\n t('delegations.column.delegatedTo')\n )\n \"\n ></mt-entity-preview>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.approval\") }}\n </span>\n <span class=\"text-sm text-surface-900\">{{\n approvalLabel()\n }}</span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.startDate\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n {{ d.row.startsAtUtc | date: \"medium\" }}\n </span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.endDate\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n {{ d.row.endsAtUtc | date: \"medium\" }}\n </span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.form.timeZone\") }}\n </span>\n <span class=\"text-sm text-surface-900\">{{\n d.row.timeZoneId\n }}</span>\n </div>\n <div class=\"flex flex-col\">\n <span class=\"text-xs text-surface-500\">\n {{ t(\"delegations.column.days\") }}\n </span>\n <span class=\"text-sm text-surface-900\">\n @if (d.row.dayRuleMode === \"FullRange\") {\n {{ t(\"delegations.form.fullRange\") }}\n } @else {\n {{ formatSpecificDays(d.row.specificDays) }}\n }\n </span>\n </div>\n </div>\n\n @if (d.row.cancellation?.cancellationReason) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3 text-sm text-surface-800\"\n >\n <div class=\"font-medium\">\n {{ t(\"delegations.form.cancellationReason\") }}\n </div>\n <div>{{ d.row.cancellation.cancellationReason }}</div>\n </div>\n }\n </div>\n } @else {\n <!-- Scope tab -->\n <div\n class=\"flex flex-col overflow-hidden rounded-lg border border-surface\"\n >\n <div\n class=\"flex items-center justify-between gap-2 border-b border-surface bg-surface-50 px-3 py-2\"\n >\n <span class=\"text-xs font-semibold uppercase text-surface-500\">\n {{ t(\"delegations.scope.permissionsTitle\") }}\n </span>\n @if (selectedOperationCount() > 0) {\n <span class=\"text-xs font-medium text-surface-500\">\n {{ selectedOperationCount() }}\n {{ t(\"delegations.scope.selected\") }}\n </span>\n }\n </div>\n\n @if (scopeVisibleNodes().length > 0) {\n <div class=\"flex max-h-[34rem] flex-col overflow-y-auto\">\n @for (\n node of scopeVisibleNodes();\n track trackScopeNode($index, node)\n ) {\n <div\n class=\"group flex min-h-10 items-center gap-2 pe-3 transition-colors hover:bg-surface-50\"\n [style.padding-inline-start.rem]=\"0.75 + node.depth * 1.25\"\n >\n @if (hasChildren(node)) {\n <span\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md text-surface-400\"\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 20 20\"\n class=\"size-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 7L10 12L15 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n } @else {\n <span class=\"size-6 shrink-0\"></span>\n }\n\n <span\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border border-primary-500 bg-primary-500 text-white\"\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 16 16\"\n class=\"size-3\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n\n <span\n class=\"min-w-0 flex-1 truncate text-sm\"\n [class.font-semibold]=\"node.kind === 'template'\"\n [class.text-surface-900]=\"node.kind === 'template'\"\n [class.font-medium]=\"\n node.kind === 'level' || node.kind === 'module'\n \"\n [class.text-surface-800]=\"\n node.kind === 'level' || node.kind === 'module'\n \"\n [class.text-surface-600]=\"node.kind === 'operation'\"\n >\n {{ node.label }}\n </span>\n\n @if (node.kind === \"operation\" && node.isHighRisk) {\n <span\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\n >\n {{ t(\"delegations.scope.highRisk\") }}\n </span>\n }\n\n @if (!node.isAvailable) {\n <span\n class=\"shrink-0 rounded-full bg-surface-100 px-2 py-0.5 text-[0.625rem] font-medium text-surface-500\"\n >\n {{ t(\"delegations.scope.unavailable\") }}\n </span>\n }\n </div>\n }\n </div>\n } @else {\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\n {{ t(\"delegations.scope.noSelection\") }}\n </p>\n }\n </div>\n }\n }\n </div>\n\n <!-- Footer -->\n <div\n class=\"border-t border-surface-200 px-4 py-3 flex items-center justify-end\"\n >\n <mt-button\n [label]=\"t('delegations.common.cancel')\"\n variant=\"outlined\"\n (click)=\"ref.close()\"\n ></mt-button>\n </div>\n </div>\n</ng-container>\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
3004
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t\">\r\n <div class=\"flex flex-col h-full\">\r\n <!-- Tabs -->\r\n <div class=\"border-b border-surface-200 px-4 pt-2\">\r\n <mt-tabs\r\n mode=\"underline\"\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n fluid\r\n ></mt-tabs>\r\n </div>\r\n\r\n <!-- Body -->\r\n <div class=\"flex-1 overflow-y-auto p-4\">\r\n @if (isLoading() && !detail()) {\r\n <p-skeleton height=\"2rem\" class=\"mb-3\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" class=\"mb-3\"></p-skeleton>\r\n <p-skeleton height=\"6rem\"></p-skeleton>\r\n } @else if (detail(); as d) {\r\n @if (activeTab() === \"overview\") {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"flex items-center justify-between gap-3\">\r\n <div class=\"flex items-center gap-3 min-w-0\">\r\n <mt-entity-preview\r\n [data]=\"\r\n userEntity(\r\n d.row.delegator,\r\n t('delegations.column.delegatorName')\r\n )\r\n \"\r\n ></mt-entity-preview>\r\n </div>\r\n <mt-delegation-status-chip\r\n [status]=\"d.status.effectiveStatus\"\r\n ></mt-delegation-status-chip>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-2 gap-4\">\r\n <div class=\"flex flex-col\">\r\n <mt-entity-preview\r\n [data]=\"\r\n userEntity(\r\n d.row.delegatedUser,\r\n t('delegations.column.delegatedTo')\r\n )\r\n \"\r\n ></mt-entity-preview>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.approval\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">{{\r\n approvalLabel()\r\n }}</span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.startDate\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n {{ d.row.startsAtUtc | date: \"medium\" }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.endDate\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n {{ d.row.endsAtUtc | date: \"medium\" }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.form.timeZone\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">{{\r\n d.row.timeZoneId\r\n }}</span>\r\n </div>\r\n <div class=\"flex flex-col\">\r\n <span class=\"text-xs text-surface-500\">\r\n {{ t(\"delegations.column.days\") }}\r\n </span>\r\n <span class=\"text-sm text-surface-900\">\r\n @if (d.row.dayRuleMode === \"FullRange\") {\r\n {{ t(\"delegations.form.fullRange\") }}\r\n } @else {\r\n {{ formatSpecificDays(d.row.specificDays) }}\r\n }\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (d.row.cancellation?.cancellationReason) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3 text-sm text-surface-800\"\r\n >\r\n <div class=\"font-medium\">\r\n {{ t(\"delegations.form.cancellationReason\") }}\r\n </div>\r\n <div>{{ d.row.cancellation.cancellationReason }}</div>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Scope tab -->\r\n <div\r\n class=\"flex flex-col overflow-hidden rounded-lg border border-surface\"\r\n >\r\n <div\r\n class=\"flex items-center justify-between gap-2 border-b border-surface bg-surface-50 px-3 py-2\"\r\n >\r\n <span class=\"text-xs font-semibold uppercase text-surface-500\">\r\n {{ t(\"delegations.scope.permissionsTitle\") }}\r\n </span>\r\n @if (selectedOperationCount() > 0) {\r\n <span class=\"text-xs font-medium text-surface-500\">\r\n {{ selectedOperationCount() }}\r\n {{ t(\"delegations.scope.selected\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (scopeVisibleNodes().length > 0) {\r\n <div class=\"flex max-h-[34rem] flex-col overflow-y-auto\">\r\n @for (\r\n node of scopeVisibleNodes();\r\n track trackScopeNode($index, node)\r\n ) {\r\n <div\r\n class=\"group flex min-h-10 items-center gap-2 pe-3 transition-colors hover:bg-surface-50\"\r\n [style.padding-inline-start.rem]=\"0.75 + node.depth * 1.25\"\r\n >\r\n @if (hasChildren(node)) {\r\n <span\r\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md text-surface-400\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg\r\n viewBox=\"0 0 20 20\"\r\n class=\"size-4\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M5 7L10 12L15 7\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.8\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </span>\r\n } @else {\r\n <span class=\"size-6 shrink-0\"></span>\r\n }\r\n\r\n <span\r\n class=\"flex size-[18px] shrink-0 items-center justify-center rounded-[5px] border border-primary-500 bg-primary-500 text-white\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg\r\n viewBox=\"0 0 16 16\"\r\n class=\"size-3\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </span>\r\n\r\n <span\r\n class=\"min-w-0 flex-1 truncate text-sm\"\r\n [class.font-semibold]=\"node.kind === 'template'\"\r\n [class.text-surface-900]=\"node.kind === 'template'\"\r\n [class.font-medium]=\"\r\n node.kind === 'level' || node.kind === 'module'\r\n \"\r\n [class.text-surface-800]=\"\r\n node.kind === 'level' || node.kind === 'module'\r\n \"\r\n [class.text-surface-600]=\"node.kind === 'operation'\"\r\n >\r\n {{ node.label }}\r\n </span>\r\n\r\n @if (node.kind === \"operation\" && node.isHighRisk) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[0.625rem] font-medium text-amber-700\"\r\n >\r\n {{ t(\"delegations.scope.highRisk\") }}\r\n </span>\r\n }\r\n\r\n @if (!node.isAvailable) {\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-100 px-2 py-0.5 text-[0.625rem] font-medium text-surface-500\"\r\n >\r\n {{ t(\"delegations.scope.unavailable\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <p class=\"px-3 py-8 text-center text-sm text-surface-500\">\r\n {{ t(\"delegations.scope.noSelection\") }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div\r\n class=\"border-t border-surface-200 px-4 py-3 flex items-center justify-end\"\r\n >\r\n <mt-button\r\n [label]=\"t('delegations.common.cancel')\"\r\n variant=\"outlined\"\r\n (click)=\"ref.close()\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
3005
3005
|
}], propDecorators: { delegationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "delegationId", required: true }] }], adminMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "adminMode", required: false }] }] } });
|
|
3006
3006
|
|
|
3007
3007
|
function defaultTrueBooleanAttribute(value) {
|