@masterteam/system-settings 0.0.16 → 0.0.17

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.
@@ -386,11 +386,11 @@ class EmailDeliveryFacade {
386
386
  }
387
387
  updateConnection(id, request) {
388
388
  this.mutationLoading.set('update');
389
- return this.api.updateConnection(id, request).pipe(switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-updated')), finalize(() => this.mutationLoading.set(null)));
389
+ return this.api.updateConnection(id, request).pipe(this.reloadOnConflict(id), switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-updated')), finalize(() => this.mutationLoading.set(null)));
390
390
  }
391
391
  deleteConnection(id, concurrencyToken) {
392
392
  this.mutationLoading.set('delete');
393
- return this.api.deleteConnection(id, concurrencyToken).pipe(switchMap(() => forkJoin({
393
+ return this.api.deleteConnection(id, concurrencyToken).pipe(this.reloadOnConflict(id), switchMap(() => forkJoin({
394
394
  connections: this.loadConnections(),
395
395
  status: this.loadStatus(),
396
396
  })), tap(() => {
@@ -400,7 +400,7 @@ class EmailDeliveryFacade {
400
400
  }
401
401
  validateConnection(id) {
402
402
  this.mutationLoading.set('validate');
403
- return this.api.validateConnection(id).pipe(switchMap((result) => this.refreshConnection(id).pipe(map(() => result))), tap((result) => result.isValid
403
+ return this.api.validateConnection(id).pipe(this.reloadOnConflict(id), switchMap((result) => this.refreshConnection(id).pipe(map(() => result))), tap((result) => result.isValid
404
404
  ? this.toast.success(this.describeCode(result.code))
405
405
  : this.toast.warn(this.describeCode(result.code))), finalize(() => this.mutationLoading.set(null)));
406
406
  }
@@ -422,11 +422,11 @@ class EmailDeliveryFacade {
422
422
  }
423
423
  bindConnection(id, purpose = 'notifications') {
424
424
  this.mutationLoading.set('bind');
425
- return this.api.bindConnection(purpose, id).pipe(switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-bound')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
425
+ return this.api.bindConnection(purpose, id).pipe(this.reloadOnConflict(id), switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-bound')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
426
426
  }
427
427
  unbindConnection(id, purpose = 'notifications') {
428
428
  this.mutationLoading.set('unbind');
429
- return this.api.unbindConnection(purpose).pipe(switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-unbound')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
429
+ return this.api.unbindConnection(purpose).pipe(this.reloadOnConflict(id), switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('connection-unbound')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
430
430
  }
431
431
  startAuthorization(id, kind) {
432
432
  this.mutationLoading.set(kind);
@@ -437,7 +437,7 @@ class EmailDeliveryFacade {
437
437
  }
438
438
  revokeAuthorization(id) {
439
439
  this.mutationLoading.set('revoke');
440
- return this.api.revokeAuthorization(id).pipe(switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('authorization-revoked')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
440
+ return this.api.revokeAuthorization(id).pipe(this.reloadOnConflict(id), switchMap(() => this.refreshConnection(id)), tap(() => this.showSuccess('authorization-revoked')), map(() => undefined), finalize(() => this.mutationLoading.set(null)));
441
441
  }
442
442
  loadAttempts(reset = true, status = this.attemptStatusFilter()) {
443
443
  this.attemptsLoading.set(true);
@@ -532,25 +532,81 @@ class EmailDeliveryFacade {
532
532
  const action = this.transloco.translate(actionKey);
533
533
  return action === actionKey ? code : `${action} (${code})`;
534
534
  }
535
+ /**
536
+ * The one sentence every failure path shows. It prefers the backend's stable
537
+ * code, falls back to the transport status the contract assigns a required
538
+ * behaviour to (401/403/409/422/428/429/503), and always appends the
539
+ * correlation ID when one is available — that identifier is what support asks
540
+ * for, and it is the only part of a failure this page is allowed to keep.
541
+ */
535
542
  describeError(error) {
536
- const problem = extractProblem(error);
537
- const base = this.describeCode(problem?.code);
538
- return problem?.correlationId
539
- ? `${base} (${this.transloco.translate('email-delivery.correlation-id')}: ${problem.correlationId})`
540
- : base;
543
+ const failure = extractFailure(error);
544
+ const parts = [this.describeFailure(failure)];
545
+ if (failure.retryAfterSeconds !== null) {
546
+ parts.push(this.transloco.translate('email-delivery.retry-after', {
547
+ seconds: failure.retryAfterSeconds,
548
+ }));
549
+ }
550
+ if (failure.correlationId) {
551
+ parts.push(`${this.transloco.translate('email-delivery.correlation-id')}: ${failure.correlationId}`);
552
+ }
553
+ return parts.join(' ');
541
554
  }
542
555
  errorAction(error) {
543
- const problem = extractProblem(error);
544
- if (!problem)
545
- return null;
546
- return (problem.action ||
547
- this.errorCatalog().find((entry) => entry.code === problem.code)
556
+ const failure = extractFailure(error);
557
+ return (failure.action ||
558
+ this.errorCatalog().find((entry) => entry.code === failure.code)
548
559
  ?.frontendAction ||
549
- null);
560
+ statusAction(failure.status));
550
561
  }
551
562
  showError(error) {
552
563
  this.toast.error(this.describeError(error));
553
564
  }
565
+ /**
566
+ * A `409` means the server state moved under this page. The contract requires
567
+ * reloading it rather than re-submitting over it, so every mutation that can
568
+ * conflict routes through here: the latest connection, list and readiness are
569
+ * pulled back before the caller sees the rejection.
570
+ */
571
+ reloadOnConflict(id) {
572
+ return catchError((error) => {
573
+ if (statusOf(error) !== 409)
574
+ return throwError(() => error);
575
+ const reload = id
576
+ ? this.refreshConnection(id).pipe(map(() => undefined))
577
+ : forkJoin({
578
+ connections: this.loadConnections(),
579
+ status: this.loadStatus(),
580
+ }).pipe(map(() => undefined));
581
+ reload.subscribe({ error: () => undefined });
582
+ return throwError(() => error);
583
+ });
584
+ }
585
+ describeFailure(failure) {
586
+ const translated = failure.code ? this.translateCode(failure.code) : null;
587
+ if (translated)
588
+ return translated;
589
+ const statusMessage = this.translateStatus(failure.status);
590
+ if (statusMessage) {
591
+ return failure.code
592
+ ? `${statusMessage} (${failure.code})`
593
+ : statusMessage;
594
+ }
595
+ return this.describeCode(failure.code);
596
+ }
597
+ translateCode(code) {
598
+ const key = `email-delivery.codes.${code}`;
599
+ const translated = this.transloco.translate(key);
600
+ return translated === key ? null : translated;
601
+ }
602
+ translateStatus(status) {
603
+ const key = status === null ? null : HTTP_STATUS_KEYS[status];
604
+ if (!key)
605
+ return null;
606
+ const fullKey = `email-delivery.http.${key}`;
607
+ const translated = this.transloco.translate(fullKey);
608
+ return translated === fullKey ? null : translated;
609
+ }
554
610
  takePendingAuthorizationConnection() {
555
611
  if (typeof sessionStorage === 'undefined')
556
612
  return null;
@@ -595,20 +651,81 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
595
651
  type: Injectable,
596
652
  args: [{ providedIn: 'root' }]
597
653
  }] });
598
- function extractProblem(error) {
599
- if (error instanceof HttpErrorResponse) {
600
- const value = error.error;
601
- return value && typeof value.code === 'string'
602
- ? value
603
- : null;
604
- }
605
- if (typeof error === 'object' &&
606
- error !== null &&
607
- typeof error.code === 'string') {
608
- return error;
654
+ const HTTP_STATUS_KEYS = {
655
+ 401: 'unauthorized',
656
+ 403: 'forbidden',
657
+ 409: 'conflict',
658
+ 422: 'unprocessable',
659
+ 428: 'authorization-required',
660
+ 429: 'too-many-requests',
661
+ 503: 'unavailable',
662
+ };
663
+ const HTTP_STATUS_ACTIONS = {
664
+ 403: 'request_permission',
665
+ 409: 'refresh',
666
+ 422: 'correct_configuration',
667
+ 428: 'authorize',
668
+ 429: 'retry_later',
669
+ 503: 'retry_later',
670
+ };
671
+ function statusAction(status) {
672
+ return status === null ? null : (HTTP_STATUS_ACTIONS[status] ?? null);
673
+ }
674
+ function statusOf(error) {
675
+ return error instanceof HttpErrorResponse ? error.status : null;
676
+ }
677
+ function extractFailure(error) {
678
+ const body = error instanceof HttpErrorResponse ? error.error : error;
679
+ const problem = readProblem(body);
680
+ const headers = error instanceof HttpErrorResponse ? error.headers : null;
681
+ return {
682
+ code: problem?.code ?? null,
683
+ action: problem?.action || null,
684
+ correlationId: problem?.correlationId ||
685
+ headers?.get('x-correlation-id') ||
686
+ headers?.get('correlation-id') ||
687
+ null,
688
+ retryAfterSeconds: problem?.retryAfterSeconds ??
689
+ parseRetryAfter(headers?.get('retry-after') ?? null),
690
+ status: statusOf(error),
691
+ };
692
+ }
693
+ /**
694
+ * Two envelopes reach this page. The email contract answers with the problem
695
+ * shape itself; Gateway rejects a request before it ever gets there and answers
696
+ * with `{ errors: { code, message } }` — that is how `REQ_001` arrives, and
697
+ * reading only the first shape lost it.
698
+ */
699
+ function readProblem(body) {
700
+ if (typeof body !== 'object' || body === null)
701
+ return null;
702
+ const problem = body;
703
+ if (typeof problem.code === 'string')
704
+ return problem;
705
+ const gatewayCode = problem.errors?.code;
706
+ if (typeof gatewayCode === 'string') {
707
+ return { ...problem, code: gatewayCode };
609
708
  }
610
709
  return null;
611
710
  }
711
+ /**
712
+ * `Retry-After` is either a delay in seconds or an HTTP date. Both become a
713
+ * whole number of seconds so the message can say when to try again; anything
714
+ * unparseable or already in the past is simply not offered.
715
+ */
716
+ function parseRetryAfter(value) {
717
+ if (!value)
718
+ return null;
719
+ const seconds = Number(value);
720
+ if (Number.isFinite(seconds)) {
721
+ return seconds > 0 ? Math.ceil(seconds) : null;
722
+ }
723
+ const date = Date.parse(value);
724
+ if (Number.isNaN(date))
725
+ return null;
726
+ const delta = Math.ceil((date - Date.now()) / 1000);
727
+ return delta > 0 ? delta : null;
728
+ }
612
729
  function mergeById(current, incoming, key) {
613
730
  const values = new Map(current.map((item) => [item[key], item]));
614
731
  incoming.forEach((item) => values.set(item[key], item));
@@ -657,7 +774,7 @@ class EmailOperatorReasonDialog {
657
774
  this.exceptionalOverride.getRawValue()));
658
775
  }
659
776
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailOperatorReasonDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
660
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailOperatorReasonDialog, isStandalone: true, selector: "mt-email-operator-reason-dialog", inputs: { itemName: { classPropertyName: "itemName", publicName: "itemName", isSignal: true, isRequired: true, transformFunction: null }, consequence: { classPropertyName: "consequence", publicName: "consequence", isSignal: true, isRequired: true, transformFunction: null }, showExceptionalOverride: { classPropertyName: "showExceptionalOverride", publicName: "showExceptionalOverride", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <form\n [class]=\"'space-y-5 p-4 sm:p-5 ' + modal.contentClass\"\n (ngSubmit)=\"confirm()\"\n >\n <div\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-950\"\n role=\"note\"\n >\n <p class=\"m-0 break-words font-semibold\">{{ itemName() }}</p>\n <p class=\"mb-0 mt-1\">{{ consequence() }}</p>\n </div>\n\n <mt-textarea-field\n [formControl]=\"reason\"\n [label]=\"t('operator-reason')\"\n [hint]=\"t('operator-reason-hint')\"\n [required]=\"true\"\n [maxLength]=\"500\"\n rows=\"4\"\n />\n\n @if (showExceptionalOverride()) {\n <div class=\"flex flex-col gap-1\">\n <mt-toggle-field\n [formControl]=\"exceptionalOverride\"\n [label]=\"t('exceptional-override')\"\n />\n <!-- mt-toggle-field has no hint input, so the consequence of an\n exceptional replay is rendered here instead of silently dropped. -->\n <p class=\"m-0 text-xs text-muted-color\">\n {{ t(\"exceptional-override-hint\") }}\n </p>\n </div>\n }\n </form>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n type=\"button\"\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"cancel()\"\n />\n <mt-button\n type=\"button\"\n severity=\"warn\"\n [label]=\"confirmLabel() || t('confirm-action')\"\n [disabled]=\"!canConfirm()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"confirm()\"\n />\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required", "maxLength"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
777
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailOperatorReasonDialog, isStandalone: true, selector: "mt-email-operator-reason-dialog", inputs: { itemName: { classPropertyName: "itemName", publicName: "itemName", isSignal: true, isRequired: true, transformFunction: null }, consequence: { classPropertyName: "consequence", publicName: "consequence", isSignal: true, isRequired: true, transformFunction: null }, showExceptionalOverride: { classPropertyName: "showExceptionalOverride", publicName: "showExceptionalOverride", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <form\r\n [class]=\"'space-y-5 p-4 sm:p-5 ' + modal.contentClass\"\r\n (ngSubmit)=\"confirm()\"\r\n >\r\n <div\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-950\"\r\n role=\"note\"\r\n >\r\n <p class=\"m-0 break-words font-semibold\">{{ itemName() }}</p>\r\n <p class=\"mb-0 mt-1\">{{ consequence() }}</p>\r\n </div>\r\n\r\n <mt-textarea-field\r\n [formControl]=\"reason\"\r\n [label]=\"t('operator-reason')\"\r\n [hint]=\"t('operator-reason-hint')\"\r\n [required]=\"true\"\r\n [maxLength]=\"500\"\r\n rows=\"4\"\r\n />\r\n\r\n @if (showExceptionalOverride()) {\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-toggle-field\r\n [formControl]=\"exceptionalOverride\"\r\n [label]=\"t('exceptional-override')\"\r\n />\r\n <!-- mt-toggle-field has no hint input, so the consequence of an\r\n exceptional replay is rendered here instead of silently dropped. -->\r\n <p class=\"m-0 text-xs text-muted-color\">\r\n {{ t(\"exceptional-override-hint\") }}\r\n </p>\r\n </div>\r\n }\r\n </form>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('cancel')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n severity=\"warn\"\r\n [label]=\"confirmLabel() || t('confirm-action')\"\r\n [disabled]=\"!canConfirm()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"confirm()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required", "maxLength"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
661
778
  }
662
779
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailOperatorReasonDialog, decorators: [{
663
780
  type: Component,
@@ -667,7 +784,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
667
784
  Button,
668
785
  TextareaField,
669
786
  ToggleField,
670
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <form\n [class]=\"'space-y-5 p-4 sm:p-5 ' + modal.contentClass\"\n (ngSubmit)=\"confirm()\"\n >\n <div\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-950\"\n role=\"note\"\n >\n <p class=\"m-0 break-words font-semibold\">{{ itemName() }}</p>\n <p class=\"mb-0 mt-1\">{{ consequence() }}</p>\n </div>\n\n <mt-textarea-field\n [formControl]=\"reason\"\n [label]=\"t('operator-reason')\"\n [hint]=\"t('operator-reason-hint')\"\n [required]=\"true\"\n [maxLength]=\"500\"\n rows=\"4\"\n />\n\n @if (showExceptionalOverride()) {\n <div class=\"flex flex-col gap-1\">\n <mt-toggle-field\n [formControl]=\"exceptionalOverride\"\n [label]=\"t('exceptional-override')\"\n />\n <!-- mt-toggle-field has no hint input, so the consequence of an\n exceptional replay is rendered here instead of silently dropped. -->\n <p class=\"m-0 text-xs text-muted-color\">\n {{ t(\"exceptional-override-hint\") }}\n </p>\n </div>\n }\n </form>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n type=\"button\"\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"cancel()\"\n />\n <mt-button\n type=\"button\"\n severity=\"warn\"\n [label]=\"confirmLabel() || t('confirm-action')\"\n [disabled]=\"!canConfirm()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"confirm()\"\n />\n </div>\n</ng-container>\n" }]
787
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <form\r\n [class]=\"'space-y-5 p-4 sm:p-5 ' + modal.contentClass\"\r\n (ngSubmit)=\"confirm()\"\r\n >\r\n <div\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-950\"\r\n role=\"note\"\r\n >\r\n <p class=\"m-0 break-words font-semibold\">{{ itemName() }}</p>\r\n <p class=\"mb-0 mt-1\">{{ consequence() }}</p>\r\n </div>\r\n\r\n <mt-textarea-field\r\n [formControl]=\"reason\"\r\n [label]=\"t('operator-reason')\"\r\n [hint]=\"t('operator-reason-hint')\"\r\n [required]=\"true\"\r\n [maxLength]=\"500\"\r\n rows=\"4\"\r\n />\r\n\r\n @if (showExceptionalOverride()) {\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-toggle-field\r\n [formControl]=\"exceptionalOverride\"\r\n [label]=\"t('exceptional-override')\"\r\n />\r\n <!-- mt-toggle-field has no hint input, so the consequence of an\r\n exceptional replay is rendered here instead of silently dropped. -->\r\n <p class=\"m-0 text-xs text-muted-color\">\r\n {{ t(\"exceptional-override-hint\") }}\r\n </p>\r\n </div>\r\n }\r\n </form>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('cancel')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n severity=\"warn\"\r\n [label]=\"confirmLabel() || t('confirm-action')\"\r\n [disabled]=\"!canConfirm()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"confirm()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
671
788
  }], propDecorators: { itemName: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemName", required: true }] }], consequence: [{ type: i0.Input, args: [{ isSignal: true, alias: "consequence", required: true }] }], showExceptionalOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExceptionalOverride", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }] } });
672
789
 
673
790
  class EmailAttemptDetails {
@@ -738,11 +855,11 @@ class EmailAttemptDetails {
738
855
  return this.transloco.translate(`email-delivery.${key}`);
739
856
  }
740
857
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailAttemptDetails, deps: [], target: i0.ɵɵFactoryTarget.Component });
741
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailAttemptDetails, isStandalone: true, selector: "mt-email-attempt-details", inputs: { attempt: { classPropertyName: "attempt", publicName: "attempt", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n @if (attempt(); as item) {\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\n <div class=\"grid w-full gap-5\">\n <div\n class=\"rounded-md border px-4 py-3 text-sm\"\n [class.border-amber-200]=\"item.status === 'OutcomeUnknown'\"\n [class.bg-amber-50]=\"item.status === 'OutcomeUnknown'\"\n [class.border-blue-200]=\"item.status !== 'OutcomeUnknown'\"\n [class.bg-blue-50]=\"item.status !== 'OutcomeUnknown'\"\n role=\"status\"\n >\n @if (item.status === \"OutcomeUnknown\") {\n {{ t(\"outcome-unknown-copy\") }}\n } @else if (item.outcome === \"Accepted\") {\n {{ t(\"accepted-copy\") }}\n } @else {\n {{ facade.describeCode(item.resultCode) }}\n }\n </div>\n\n <!-- Same section shape the connection form uses (mt-client-form section\n mode): header strip on a bordered, flat, rounded-md container. -->\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"delivery-summary\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.operation\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{\n isConnectionTest()\n ? t(\"operation.connection-test\")\n : item.operationKind\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.status\") }}\n </dt>\n <dd class=\"mb-0 mt-2\">\n <mt-email-delivery-status\n kind=\"attempt\"\n [value]=\"item.status\"\n />\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.outcome\") }}\n </dt>\n <dd class=\"mb-0 mt-2\">\n @if (item.outcome) {\n <mt-email-delivery-status\n kind=\"attempt\"\n [value]=\"item.outcome\"\n />\n } @else {\n <span class=\"font-medium text-color\">\u2014</span>\n }\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.provider\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ providerLabel(item.providerKey) }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.created\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n <time [attr.datetime]=\"item.createdAtUtc\">{{\n item.createdAtUtc | date: \"medium\"\n }}</time>\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.count\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{ item.attemptCount }}\n </dd>\n </div>\n </dl>\n </section>\n\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"technical-identifiers\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"recipient-fingerprint\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.recipientFingerprint }}\n </dd>\n <p class=\"mt-2 text-xs text-muted-color\">\n {{ t(\"recipient-fingerprint-hint\") }}\n </p>\n </div>\n @if (item.testRequestId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"test-request-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.testRequestId }}\n </dd>\n </div>\n }\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">{{ t(\"attempt.id\") }}</dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.id }}\n </dd>\n </div>\n @if (item.correlationId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"correlation-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.correlationId }}\n </dd>\n </div>\n }\n @if (item.providerRequestId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"provider-request-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.providerRequestId }}\n </dd>\n </div>\n }\n </dl>\n </section>\n </div>\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('close')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (canReplay()) {\n <mt-button\n severity=\"warn\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('replay-attempt')\"\n [disabled]=\"!facade.managementAvailable()\"\n [loading]=\"facade.mutationLoading() === 'replay-' + item.id\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"replay()\"\n />\n }\n </div>\n }\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
858
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailAttemptDetails, isStandalone: true, selector: "mt-email-attempt-details", inputs: { attempt: { classPropertyName: "attempt", publicName: "attempt", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n @if (attempt(); as item) {\r\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\r\n <div class=\"grid w-full gap-5\">\r\n <div\r\n class=\"rounded-md border px-4 py-3 text-sm\"\r\n [class.border-amber-200]=\"item.status === 'OutcomeUnknown'\"\r\n [class.bg-amber-50]=\"item.status === 'OutcomeUnknown'\"\r\n [class.border-blue-200]=\"item.status !== 'OutcomeUnknown'\"\r\n [class.bg-blue-50]=\"item.status !== 'OutcomeUnknown'\"\r\n role=\"status\"\r\n >\r\n @if (item.status === \"OutcomeUnknown\") {\r\n {{ t(\"outcome-unknown-copy\") }}\r\n } @else if (item.outcome === \"Accepted\") {\r\n {{ t(\"accepted-copy\") }}\r\n } @else {\r\n {{ facade.describeCode(item.resultCode) }}\r\n }\r\n </div>\r\n\r\n <!-- Same section shape the connection form uses (mt-client-form section\r\n mode): header strip on a bordered, flat, rounded-md container. -->\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"delivery-summary\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.operation\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{\r\n isConnectionTest()\r\n ? t(\"operation.connection-test\")\r\n : item.operationKind\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.status\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-2\">\r\n <mt-email-delivery-status\r\n kind=\"attempt\"\r\n [value]=\"item.status\"\r\n />\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.outcome\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-2\">\r\n @if (item.outcome) {\r\n <mt-email-delivery-status\r\n kind=\"attempt\"\r\n [value]=\"item.outcome\"\r\n />\r\n } @else {\r\n <span class=\"font-medium text-color\">\u2014</span>\r\n }\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.provider\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ providerLabel(item.providerKey) }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.created\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n <time [attr.datetime]=\"item.createdAtUtc\">{{\r\n item.createdAtUtc | date: \"medium\"\r\n }}</time>\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.count\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{ item.attemptCount }}\r\n </dd>\r\n </div>\r\n </dl>\r\n </section>\r\n\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"technical-identifiers\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"recipient-fingerprint\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.recipientFingerprint }}\r\n </dd>\r\n <p class=\"mt-2 text-xs text-muted-color\">\r\n {{ t(\"recipient-fingerprint-hint\") }}\r\n </p>\r\n </div>\r\n @if (item.testRequestId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"test-request-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.testRequestId }}\r\n </dd>\r\n </div>\r\n }\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">{{ t(\"attempt.id\") }}</dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.id }}\r\n </dd>\r\n </div>\r\n @if (item.correlationId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"correlation-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.correlationId }}\r\n </dd>\r\n </div>\r\n }\r\n @if (item.providerRequestId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"provider-request-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.providerRequestId }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('close')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (canReplay()) {\r\n <mt-button\r\n severity=\"warn\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('replay-attempt')\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n [loading]=\"facade.mutationLoading() === 'replay-' + item.id\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"replay()\"\r\n />\r\n }\r\n </div>\r\n }\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
742
859
  }
743
860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailAttemptDetails, decorators: [{
744
861
  type: Component,
745
- args: [{ selector: 'mt-email-attempt-details', imports: [DatePipe, TranslocoDirective, Button, EmailDeliveryStatus], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n @if (attempt(); as item) {\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\n <div class=\"grid w-full gap-5\">\n <div\n class=\"rounded-md border px-4 py-3 text-sm\"\n [class.border-amber-200]=\"item.status === 'OutcomeUnknown'\"\n [class.bg-amber-50]=\"item.status === 'OutcomeUnknown'\"\n [class.border-blue-200]=\"item.status !== 'OutcomeUnknown'\"\n [class.bg-blue-50]=\"item.status !== 'OutcomeUnknown'\"\n role=\"status\"\n >\n @if (item.status === \"OutcomeUnknown\") {\n {{ t(\"outcome-unknown-copy\") }}\n } @else if (item.outcome === \"Accepted\") {\n {{ t(\"accepted-copy\") }}\n } @else {\n {{ facade.describeCode(item.resultCode) }}\n }\n </div>\n\n <!-- Same section shape the connection form uses (mt-client-form section\n mode): header strip on a bordered, flat, rounded-md container. -->\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"delivery-summary\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.operation\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{\n isConnectionTest()\n ? t(\"operation.connection-test\")\n : item.operationKind\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.status\") }}\n </dt>\n <dd class=\"mb-0 mt-2\">\n <mt-email-delivery-status\n kind=\"attempt\"\n [value]=\"item.status\"\n />\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.outcome\") }}\n </dt>\n <dd class=\"mb-0 mt-2\">\n @if (item.outcome) {\n <mt-email-delivery-status\n kind=\"attempt\"\n [value]=\"item.outcome\"\n />\n } @else {\n <span class=\"font-medium text-color\">\u2014</span>\n }\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.provider\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ providerLabel(item.providerKey) }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.created\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n <time [attr.datetime]=\"item.createdAtUtc\">{{\n item.createdAtUtc | date: \"medium\"\n }}</time>\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"attempt.count\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{ item.attemptCount }}\n </dd>\n </div>\n </dl>\n </section>\n\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"technical-identifiers\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"recipient-fingerprint\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.recipientFingerprint }}\n </dd>\n <p class=\"mt-2 text-xs text-muted-color\">\n {{ t(\"recipient-fingerprint-hint\") }}\n </p>\n </div>\n @if (item.testRequestId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"test-request-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.testRequestId }}\n </dd>\n </div>\n }\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">{{ t(\"attempt.id\") }}</dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.id }}\n </dd>\n </div>\n @if (item.correlationId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"correlation-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.correlationId }}\n </dd>\n </div>\n }\n @if (item.providerRequestId) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"provider-request-id\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\n {{ item.providerRequestId }}\n </dd>\n </div>\n }\n </dl>\n </section>\n </div>\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('close')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (canReplay()) {\n <mt-button\n severity=\"warn\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('replay-attempt')\"\n [disabled]=\"!facade.managementAvailable()\"\n [loading]=\"facade.mutationLoading() === 'replay-' + item.id\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"replay()\"\n />\n }\n </div>\n }\n</ng-container>\n" }]
862
+ args: [{ selector: 'mt-email-attempt-details', imports: [DatePipe, TranslocoDirective, Button, EmailDeliveryStatus], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n @if (attempt(); as item) {\r\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\r\n <div class=\"grid w-full gap-5\">\r\n <div\r\n class=\"rounded-md border px-4 py-3 text-sm\"\r\n [class.border-amber-200]=\"item.status === 'OutcomeUnknown'\"\r\n [class.bg-amber-50]=\"item.status === 'OutcomeUnknown'\"\r\n [class.border-blue-200]=\"item.status !== 'OutcomeUnknown'\"\r\n [class.bg-blue-50]=\"item.status !== 'OutcomeUnknown'\"\r\n role=\"status\"\r\n >\r\n @if (item.status === \"OutcomeUnknown\") {\r\n {{ t(\"outcome-unknown-copy\") }}\r\n } @else if (item.outcome === \"Accepted\") {\r\n {{ t(\"accepted-copy\") }}\r\n } @else {\r\n {{ facade.describeCode(item.resultCode) }}\r\n }\r\n </div>\r\n\r\n <!-- Same section shape the connection form uses (mt-client-form section\r\n mode): header strip on a bordered, flat, rounded-md container. -->\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"delivery-summary\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.operation\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{\r\n isConnectionTest()\r\n ? t(\"operation.connection-test\")\r\n : item.operationKind\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.status\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-2\">\r\n <mt-email-delivery-status\r\n kind=\"attempt\"\r\n [value]=\"item.status\"\r\n />\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.outcome\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-2\">\r\n @if (item.outcome) {\r\n <mt-email-delivery-status\r\n kind=\"attempt\"\r\n [value]=\"item.outcome\"\r\n />\r\n } @else {\r\n <span class=\"font-medium text-color\">\u2014</span>\r\n }\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.provider\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ providerLabel(item.providerKey) }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.created\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n <time [attr.datetime]=\"item.createdAtUtc\">{{\r\n item.createdAtUtc | date: \"medium\"\r\n }}</time>\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"attempt.count\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{ item.attemptCount }}\r\n </dd>\r\n </div>\r\n </dl>\r\n </section>\r\n\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"technical-identifiers\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"recipient-fingerprint\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.recipientFingerprint }}\r\n </dd>\r\n <p class=\"mt-2 text-xs text-muted-color\">\r\n {{ t(\"recipient-fingerprint-hint\") }}\r\n </p>\r\n </div>\r\n @if (item.testRequestId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"test-request-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.testRequestId }}\r\n </dd>\r\n </div>\r\n }\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">{{ t(\"attempt.id\") }}</dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.id }}\r\n </dd>\r\n </div>\r\n @if (item.correlationId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"correlation-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.correlationId }}\r\n </dd>\r\n </div>\r\n }\r\n @if (item.providerRequestId) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"provider-request-id\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-all font-mono text-sm text-color\">\r\n {{ item.providerRequestId }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('close')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (canReplay()) {\r\n <mt-button\r\n severity=\"warn\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('replay-attempt')\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n [loading]=\"facade.mutationLoading() === 'replay-' + item.id\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"replay()\"\r\n />\r\n }\r\n </div>\r\n }\r\n</ng-container>\r\n" }]
746
863
  }], propDecorators: { attempt: [{ type: i0.Input, args: [{ isSignal: true, alias: "attempt", required: true }] }] } });
747
864
  function isExceptionalReplay(status) {
748
865
  return status === 'Accepted' || status === 'OutcomeUnknown';
@@ -929,11 +1046,11 @@ class EmailDeliveryAttempts {
929
1046
  return this.transloco.translate(`email-delivery.${key}`);
930
1047
  }
931
1048
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryAttempts, deps: [], target: i0.ɵɵFactoryTarget.Component });
932
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryAttempts, isStandalone: true, selector: "mt-email-delivery-attempts", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-4\" aria-label=\"{{ t('activity-title') }}\">\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [filters]=\"tableFilters()\"\n [loading]=\"facade.attemptsLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-attempts-title')\"\n [emptyDescription]=\"t('no-attempts-description')\"\n filterMode=\"column\"\n dataKey=\"id\"\n actionShape=\"popover\"\n [clickableRows]=\"true\"\n storageKey=\"email-delivery-attempts\"\n (filtersChange)=\"onFiltersChange($event)\"\n (rowClick)=\"openDetails($event)\"\n >\n <ng-template #captionEnd>\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('refresh')\"\n [loading]=\"facade.attemptsLoading()\"\n (onClick)=\"refresh()\"\n />\n </ng-template>\n </mt-table>\n\n @if (facade.attemptsNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.attemptsLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1049
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryAttempts, isStandalone: true, selector: "mt-email-delivery-attempts", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-4\" aria-label=\"{{ t('activity-title') }}\">\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [filters]=\"tableFilters()\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-attempts-title')\"\r\n [emptyDescription]=\"t('no-attempts-description')\"\r\n filterMode=\"column\"\r\n dataKey=\"id\"\r\n actionShape=\"popover\"\r\n [clickableRows]=\"true\"\r\n storageKey=\"email-delivery-attempts\"\r\n (filtersChange)=\"onFiltersChange($event)\"\r\n (rowClick)=\"openDetails($event)\"\r\n >\r\n <ng-template #captionEnd>\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('refresh')\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </ng-template>\r\n </mt-table>\r\n\r\n @if (facade.attemptsNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
933
1050
  }
934
1051
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryAttempts, decorators: [{
935
1052
  type: Component,
936
- args: [{ selector: 'mt-email-delivery-attempts', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-4\" aria-label=\"{{ t('activity-title') }}\">\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [filters]=\"tableFilters()\"\n [loading]=\"facade.attemptsLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-attempts-title')\"\n [emptyDescription]=\"t('no-attempts-description')\"\n filterMode=\"column\"\n dataKey=\"id\"\n actionShape=\"popover\"\n [clickableRows]=\"true\"\n storageKey=\"email-delivery-attempts\"\n (filtersChange)=\"onFiltersChange($event)\"\n (rowClick)=\"openDetails($event)\"\n >\n <ng-template #captionEnd>\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('refresh')\"\n [loading]=\"facade.attemptsLoading()\"\n (onClick)=\"refresh()\"\n />\n </ng-template>\n </mt-table>\n\n @if (facade.attemptsNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.attemptsLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n" }]
1053
+ args: [{ selector: 'mt-email-delivery-attempts', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-4\" aria-label=\"{{ t('activity-title') }}\">\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [filters]=\"tableFilters()\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-attempts-title')\"\r\n [emptyDescription]=\"t('no-attempts-description')\"\r\n filterMode=\"column\"\r\n dataKey=\"id\"\r\n actionShape=\"popover\"\r\n [clickableRows]=\"true\"\r\n storageKey=\"email-delivery-attempts\"\r\n (filtersChange)=\"onFiltersChange($event)\"\r\n (rowClick)=\"openDetails($event)\"\r\n >\r\n <ng-template #captionEnd>\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('refresh')\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </ng-template>\r\n </mt-table>\r\n\r\n @if (facade.attemptsNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.attemptsLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n" }]
937
1054
  }] });
938
1055
  /**
939
1056
  * The status column is a single-select, so its stored value is the raw status.
@@ -1116,11 +1233,11 @@ class EmailDeliveryHostEvidence {
1116
1233
  return this.transloco.translate(`email-delivery.${key}`);
1117
1234
  }
1118
1235
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryHostEvidence, deps: [], target: i0.ɵɵFactoryTarget.Component });
1119
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryHostEvidence, isStandalone: true, selector: "mt-email-delivery-host-evidence", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-3\" aria-labelledby=\"host-evidence-heading\">\n <div\n class=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div>\n <h3 id=\"host-evidence-heading\" class=\"font-semibold text-color\">\n {{ t(\"host-evidence-title\") }}\n </h3>\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ t(\"host-evidence-description\") }}\n </p>\n </div>\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('rebuild-evidence-index')\"\n [disabled]=\"!facade.managementAvailable()\"\n [loading]=\"facade.mutationLoading() === 'rebuild-evidence'\"\n (onClick)=\"confirmRebuild()\"\n />\n </div>\n\n @if (facade.hostEvidenceScanBudgetExhausted()) {\n <div\n class=\"rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-950\"\n role=\"status\"\n >\n {{ t(\"scan-budget-exhausted\") }}\n </div>\n }\n\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [loading]=\"facade.hostEvidenceLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-evidence-title')\"\n [emptyDescription]=\"t('no-evidence-description')\"\n filterMode=\"column\"\n actionShape=\"popover\"\n dataKey=\"evidenceRowId\"\n storageKey=\"email-delivery-host-evidence\"\n />\n\n @if (facade.hostEvidenceNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.hostEvidenceLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1236
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryHostEvidence, isStandalone: true, selector: "mt-email-delivery-host-evidence", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-3\" aria-labelledby=\"host-evidence-heading\">\r\n <div\r\n class=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\"\r\n >\r\n <div>\r\n <h3 id=\"host-evidence-heading\" class=\"font-semibold text-color\">\r\n {{ t(\"host-evidence-title\") }}\r\n </h3>\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"host-evidence-description\") }}\r\n </p>\r\n </div>\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('rebuild-evidence-index')\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n [loading]=\"facade.mutationLoading() === 'rebuild-evidence'\"\r\n (onClick)=\"confirmRebuild()\"\r\n />\r\n </div>\r\n\r\n @if (facade.hostEvidenceScanBudgetExhausted()) {\r\n <div\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-950\"\r\n role=\"status\"\r\n >\r\n {{ t(\"scan-budget-exhausted\") }}\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [loading]=\"facade.hostEvidenceLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-evidence-title')\"\r\n [emptyDescription]=\"t('no-evidence-description')\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n dataKey=\"evidenceRowId\"\r\n storageKey=\"email-delivery-host-evidence\"\r\n />\r\n\r\n @if (facade.hostEvidenceNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.hostEvidenceLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1120
1237
  }
1121
1238
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryHostEvidence, decorators: [{
1122
1239
  type: Component,
1123
- args: [{ selector: 'mt-email-delivery-host-evidence', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-3\" aria-labelledby=\"host-evidence-heading\">\n <div\n class=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div>\n <h3 id=\"host-evidence-heading\" class=\"font-semibold text-color\">\n {{ t(\"host-evidence-title\") }}\n </h3>\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ t(\"host-evidence-description\") }}\n </p>\n </div>\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"arrow.refresh-cw-01\"\n [label]=\"t('rebuild-evidence-index')\"\n [disabled]=\"!facade.managementAvailable()\"\n [loading]=\"facade.mutationLoading() === 'rebuild-evidence'\"\n (onClick)=\"confirmRebuild()\"\n />\n </div>\n\n @if (facade.hostEvidenceScanBudgetExhausted()) {\n <div\n class=\"rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-950\"\n role=\"status\"\n >\n {{ t(\"scan-budget-exhausted\") }}\n </div>\n }\n\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [loading]=\"facade.hostEvidenceLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-evidence-title')\"\n [emptyDescription]=\"t('no-evidence-description')\"\n filterMode=\"column\"\n actionShape=\"popover\"\n dataKey=\"evidenceRowId\"\n storageKey=\"email-delivery-host-evidence\"\n />\n\n @if (facade.hostEvidenceNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.hostEvidenceLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n" }]
1240
+ args: [{ selector: 'mt-email-delivery-host-evidence', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-3\" aria-labelledby=\"host-evidence-heading\">\r\n <div\r\n class=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\"\r\n >\r\n <div>\r\n <h3 id=\"host-evidence-heading\" class=\"font-semibold text-color\">\r\n {{ t(\"host-evidence-title\") }}\r\n </h3>\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"host-evidence-description\") }}\r\n </p>\r\n </div>\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [label]=\"t('rebuild-evidence-index')\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n [loading]=\"facade.mutationLoading() === 'rebuild-evidence'\"\r\n (onClick)=\"confirmRebuild()\"\r\n />\r\n </div>\r\n\r\n @if (facade.hostEvidenceScanBudgetExhausted()) {\r\n <div\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-950\"\r\n role=\"status\"\r\n >\r\n {{ t(\"scan-budget-exhausted\") }}\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [loading]=\"facade.hostEvidenceLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-evidence-title')\"\r\n [emptyDescription]=\"t('no-evidence-description')\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n dataKey=\"evidenceRowId\"\r\n storageKey=\"email-delivery-host-evidence\"\r\n />\r\n\r\n @if (facade.hostEvidenceNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.hostEvidenceLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n" }]
1124
1241
  }] });
1125
1242
  function identifierEntity$1(value) {
1126
1243
  return {
@@ -1241,11 +1358,11 @@ class EmailDeliveryQuarantine {
1241
1358
  return this.transloco.translate(`email-delivery.${key}`);
1242
1359
  }
1243
1360
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryQuarantine, deps: [], target: i0.ɵɵFactoryTarget.Component });
1244
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryQuarantine, isStandalone: true, selector: "mt-email-delivery-quarantine", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-3\" aria-labelledby=\"quarantine-heading\">\n <div>\n <h3 id=\"quarantine-heading\" class=\"font-semibold text-color\">\n {{ t(\"quarantine-title\") }}\n </h3>\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ t(\"quarantine-description\") }}\n </p>\n </div>\n\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [loading]=\"facade.quarantineLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-quarantine-title')\"\n [emptyDescription]=\"t('no-quarantine-description')\"\n filterMode=\"column\"\n actionShape=\"popover\"\n dataKey=\"itemId\"\n storageKey=\"email-delivery-quarantine\"\n />\n\n @if (facade.quarantineNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.quarantineLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1361
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryQuarantine, isStandalone: true, selector: "mt-email-delivery-quarantine", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-3\" aria-labelledby=\"quarantine-heading\">\r\n <div>\r\n <h3 id=\"quarantine-heading\" class=\"font-semibold text-color\">\r\n {{ t(\"quarantine-title\") }}\r\n </h3>\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"quarantine-description\") }}\r\n </p>\r\n </div>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [loading]=\"facade.quarantineLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-quarantine-title')\"\r\n [emptyDescription]=\"t('no-quarantine-description')\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n dataKey=\"itemId\"\r\n storageKey=\"email-delivery-quarantine\"\r\n />\r\n\r\n @if (facade.quarantineNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.quarantineLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1245
1362
  }
1246
1363
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryQuarantine, decorators: [{
1247
1364
  type: Component,
1248
- args: [{ selector: 'mt-email-delivery-quarantine', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-3\" aria-labelledby=\"quarantine-heading\">\n <div>\n <h3 id=\"quarantine-heading\" class=\"font-semibold text-color\">\n {{ t(\"quarantine-title\") }}\n </h3>\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ t(\"quarantine-description\") }}\n </p>\n </div>\n\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"actions()\"\n [loading]=\"facade.quarantineLoading()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-quarantine-title')\"\n [emptyDescription]=\"t('no-quarantine-description')\"\n filterMode=\"column\"\n actionShape=\"popover\"\n dataKey=\"itemId\"\n storageKey=\"email-delivery-quarantine\"\n />\n\n @if (facade.quarantineNextCursor()) {\n <div class=\"flex justify-center\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('load-more')\"\n [loading]=\"facade.quarantineLoading()\"\n (onClick)=\"loadMore()\"\n />\n </div>\n }\n </section>\n</ng-container>\n" }]
1365
+ args: [{ selector: 'mt-email-delivery-quarantine', imports: [TranslocoDirective, Button, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-3\" aria-labelledby=\"quarantine-heading\">\r\n <div>\r\n <h3 id=\"quarantine-heading\" class=\"font-semibold text-color\">\r\n {{ t(\"quarantine-title\") }}\r\n </h3>\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"quarantine-description\") }}\r\n </p>\r\n </div>\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"actions()\"\r\n [loading]=\"facade.quarantineLoading()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-quarantine-title')\"\r\n [emptyDescription]=\"t('no-quarantine-description')\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n dataKey=\"itemId\"\r\n storageKey=\"email-delivery-quarantine\"\r\n />\r\n\r\n @if (facade.quarantineNextCursor()) {\r\n <div class=\"flex justify-center\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('load-more')\"\r\n [loading]=\"facade.quarantineLoading()\"\r\n (onClick)=\"loadMore()\"\r\n />\r\n </div>\r\n }\r\n </section>\r\n</ng-container>\r\n" }]
1249
1366
  }] });
1250
1367
  function identifierEntity(value) {
1251
1368
  return {
@@ -1262,7 +1379,7 @@ class EmailDeliveryActivity {
1262
1379
  this.advancedExpanded.set(event.currentTarget.open);
1263
1380
  }
1264
1381
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryActivity, deps: [], target: i0.ɵɵFactoryTarget.Component });
1265
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryActivity, isStandalone: true, selector: "mt-email-delivery-activity", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div class=\"grid gap-5\">\n <mt-email-delivery-attempts class=\"block min-w-0\" />\n\n <!-- Operator recovery tools. Kept collapsed and visually quieter than the\n Activity table above it: they are for incident work, not daily use. -->\n <details\n class=\"group overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n (toggle)=\"onAdvancedToggle($event)\"\n >\n <summary\n class=\"flex cursor-pointer list-none items-center gap-3 p-4 focus-visible:outline-2 focus-visible:outline-offset-2\"\n >\n <span\n class=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md bg-surface-100 text-muted-color\"\n >\n <mt-icon icon=\"general.tool-02\" aria-hidden=\"true\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block font-semibold text-color\">\n {{ t(\"advanced-support\") }}\n </span>\n <span class=\"mt-0.5 block text-sm font-normal text-muted-color\">\n {{ t(\"advanced-support-description\") }}\n </span>\n </span>\n <mt-icon\n icon=\"arrow.chevron-down\"\n aria-hidden=\"true\"\n class=\"shrink-0 text-base text-muted-color transition-transform group-open:rotate-180\"\n />\n </summary>\n @if (advancedExpanded()) {\n <div\n class=\"grid gap-4 border-t border-surface-200 bg-surface-50/60 p-4 sm:p-5\"\n >\n <mt-email-delivery-quarantine class=\"block min-w-0\" />\n <mt-email-delivery-host-evidence class=\"block min-w-0\" />\n </div>\n }\n </details>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: EmailDeliveryAttempts, selector: "mt-email-delivery-attempts" }, { kind: "component", type: EmailDeliveryQuarantine, selector: "mt-email-delivery-quarantine" }, { kind: "component", type: EmailDeliveryHostEvidence, selector: "mt-email-delivery-host-evidence" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1382
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryActivity, isStandalone: true, selector: "mt-email-delivery-activity", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div class=\"grid gap-5\">\r\n <mt-email-delivery-attempts class=\"block min-w-0\" />\r\n\r\n <!-- Operator recovery tools. Kept collapsed and visually quieter than the\r\n Activity table above it: they are for incident work, not daily use. -->\r\n <details\r\n class=\"group overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n (toggle)=\"onAdvancedToggle($event)\"\r\n >\r\n <summary\r\n class=\"flex cursor-pointer list-none items-center gap-3 p-4 focus-visible:outline-2 focus-visible:outline-offset-2\"\r\n >\r\n <span\r\n class=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md bg-surface-100 text-muted-color\"\r\n >\r\n <mt-icon icon=\"general.tool-02\" aria-hidden=\"true\" />\r\n </span>\r\n <span class=\"min-w-0 flex-1\">\r\n <span class=\"block font-semibold text-color\">\r\n {{ t(\"advanced-support\") }}\r\n </span>\r\n <span class=\"mt-0.5 block text-sm font-normal text-muted-color\">\r\n {{ t(\"advanced-support-description\") }}\r\n </span>\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.chevron-down\"\r\n aria-hidden=\"true\"\r\n class=\"shrink-0 text-base text-muted-color transition-transform group-open:rotate-180\"\r\n />\r\n </summary>\r\n @if (advancedExpanded()) {\r\n <div\r\n class=\"grid gap-4 border-t border-surface-200 bg-surface-50/60 p-4 sm:p-5\"\r\n >\r\n <mt-email-delivery-quarantine class=\"block min-w-0\" />\r\n <mt-email-delivery-host-evidence class=\"block min-w-0\" />\r\n </div>\r\n }\r\n </details>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: EmailDeliveryAttempts, selector: "mt-email-delivery-attempts" }, { kind: "component", type: EmailDeliveryQuarantine, selector: "mt-email-delivery-quarantine" }, { kind: "component", type: EmailDeliveryHostEvidence, selector: "mt-email-delivery-host-evidence" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1266
1383
  }
1267
1384
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryActivity, decorators: [{
1268
1385
  type: Component,
@@ -1272,7 +1389,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1272
1389
  EmailDeliveryAttempts,
1273
1390
  EmailDeliveryQuarantine,
1274
1391
  EmailDeliveryHostEvidence,
1275
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div class=\"grid gap-5\">\n <mt-email-delivery-attempts class=\"block min-w-0\" />\n\n <!-- Operator recovery tools. Kept collapsed and visually quieter than the\n Activity table above it: they are for incident work, not daily use. -->\n <details\n class=\"group overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n (toggle)=\"onAdvancedToggle($event)\"\n >\n <summary\n class=\"flex cursor-pointer list-none items-center gap-3 p-4 focus-visible:outline-2 focus-visible:outline-offset-2\"\n >\n <span\n class=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md bg-surface-100 text-muted-color\"\n >\n <mt-icon icon=\"general.tool-02\" aria-hidden=\"true\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block font-semibold text-color\">\n {{ t(\"advanced-support\") }}\n </span>\n <span class=\"mt-0.5 block text-sm font-normal text-muted-color\">\n {{ t(\"advanced-support-description\") }}\n </span>\n </span>\n <mt-icon\n icon=\"arrow.chevron-down\"\n aria-hidden=\"true\"\n class=\"shrink-0 text-base text-muted-color transition-transform group-open:rotate-180\"\n />\n </summary>\n @if (advancedExpanded()) {\n <div\n class=\"grid gap-4 border-t border-surface-200 bg-surface-50/60 p-4 sm:p-5\"\n >\n <mt-email-delivery-quarantine class=\"block min-w-0\" />\n <mt-email-delivery-host-evidence class=\"block min-w-0\" />\n </div>\n }\n </details>\n </div>\n</ng-container>\n" }]
1392
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div class=\"grid gap-5\">\r\n <mt-email-delivery-attempts class=\"block min-w-0\" />\r\n\r\n <!-- Operator recovery tools. Kept collapsed and visually quieter than the\r\n Activity table above it: they are for incident work, not daily use. -->\r\n <details\r\n class=\"group overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n (toggle)=\"onAdvancedToggle($event)\"\r\n >\r\n <summary\r\n class=\"flex cursor-pointer list-none items-center gap-3 p-4 focus-visible:outline-2 focus-visible:outline-offset-2\"\r\n >\r\n <span\r\n class=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md bg-surface-100 text-muted-color\"\r\n >\r\n <mt-icon icon=\"general.tool-02\" aria-hidden=\"true\" />\r\n </span>\r\n <span class=\"min-w-0 flex-1\">\r\n <span class=\"block font-semibold text-color\">\r\n {{ t(\"advanced-support\") }}\r\n </span>\r\n <span class=\"mt-0.5 block text-sm font-normal text-muted-color\">\r\n {{ t(\"advanced-support-description\") }}\r\n </span>\r\n </span>\r\n <mt-icon\r\n icon=\"arrow.chevron-down\"\r\n aria-hidden=\"true\"\r\n class=\"shrink-0 text-base text-muted-color transition-transform group-open:rotate-180\"\r\n />\r\n </summary>\r\n @if (advancedExpanded()) {\r\n <div\r\n class=\"grid gap-4 border-t border-surface-200 bg-surface-50/60 p-4 sm:p-5\"\r\n >\r\n <mt-email-delivery-quarantine class=\"block min-w-0\" />\r\n <mt-email-delivery-host-evidence class=\"block min-w-0\" />\r\n </div>\r\n }\r\n </details>\r\n </div>\r\n</ng-container>\r\n" }]
1276
1393
  }] });
1277
1394
 
1278
1395
  class EmailControlledTestDialog {
@@ -1380,6 +1497,13 @@ class EmailControlledTestDialog {
1380
1497
  return;
1381
1498
  }
1382
1499
  this.facade.showError(error);
1500
+ // The backend rejected this GUID because it already stands for a
1501
+ // different send. Retrieving it would return someone else's test and
1502
+ // reusing it can never succeed, so the dialog mints a fresh one and
1503
+ // waits for the operator to press Send again — it never resends.
1504
+ if (isTestRequestConflict(error)) {
1505
+ this.testRequestId.set(createId());
1506
+ }
1383
1507
  },
1384
1508
  });
1385
1509
  }
@@ -1443,7 +1567,7 @@ class EmailControlledTestDialog {
1443
1567
  return this.transloco.translate(`email-delivery.${key}`);
1444
1568
  }
1445
1569
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailControlledTestDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
1446
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailControlledTestDialog, isStandalone: true, selector: "mt-email-controlled-test-dialog", inputs: { connectionId: { classPropertyName: "connectionId", publicName: "connectionId", isSignal: true, isRequired: true, transformFunction: null }, connectionName: { classPropertyName: "connectionName", publicName: "connectionName", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\n <div\n class=\"mb-4 rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950\"\n role=\"note\"\n >\n <strong>{{ t(\"test.real-email-warning-title\") }}</strong>\n {{ t(\"test.real-email-warning\") }}\n </div>\n\n @if (!result()) {\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\n }\n\n @if (timedOut()) {\n <div\n class=\"mt-4 rounded-md border border-orange-200 bg-orange-50 px-4 py-3\"\n role=\"alert\"\n >\n <p class=\"font-semibold text-orange-950\">\n {{ t(\"test.timeout-title\") }}\n </p>\n <p class=\"mt-1 text-sm text-orange-900\">\n {{ t(\"test.timeout-description\") }}\n </p>\n </div>\n }\n\n @if (result(); as testResult) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-4\"\n aria-live=\"polite\"\n >\n <mt-email-delivery-status kind=\"attempt\" [value]=\"testResult.outcome\" />\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ facade.describeCode(testResult.code) }}\n </p>\n @if (showsAcceptedCaveat(testResult)) {\n <p class=\"mt-3 text-sm font-medium text-amber-800\">\n {{ t(\"accepted-unconfirmed\") }}\n </p>\n }\n @if (testResult.outcome === \"OutcomeUnknown\") {\n <p class=\"mt-3 text-sm font-medium text-red-700\">\n {{ t(\"outcome-unknown-warning\") }}\n </p>\n }\n </div>\n }\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('close')\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (timedOut()) {\n <mt-button\n [label]=\"t('test.retrieve')\"\n icon=\"arrow.refresh-cw-01\"\n [disabled]=\"polling()\"\n [loading]=\"polling() || facade.mutationLoading() === 'retrieve-test'\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"retrieve()\"\n />\n } @else if (!result()) {\n <mt-button\n [label]=\"t('test.send')\"\n icon=\"communication.send-01\"\n [disabled]=\"!canSubmit()\"\n [loading]=\"facade.mutationLoading() === 'test'\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"submit()\"\n />\n }\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues", "serverFieldErrors"], outputs: ["runtimeMessagesChange"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1570
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailControlledTestDialog, isStandalone: true, selector: "mt-email-controlled-test-dialog", inputs: { connectionId: { classPropertyName: "connectionId", publicName: "connectionId", isSignal: true, isRequired: true, transformFunction: null }, connectionName: { classPropertyName: "connectionName", publicName: "connectionName", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\r\n <div\r\n class=\"mb-4 rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950\"\r\n role=\"note\"\r\n >\r\n <strong>{{ t(\"test.real-email-warning-title\") }}</strong>\r\n {{ t(\"test.real-email-warning\") }}\r\n </div>\r\n\r\n <!-- The GUID this dialog will keep for the whole exchange. It is what a\r\n lost response is retrieved with, so the operator can record it before\r\n sending rather than reconstructing it afterwards. -->\r\n <p class=\"mb-4 text-xs text-muted-color\">\r\n {{ t(\"test-request-id\") }}:\r\n <span class=\"break-all font-mono\">{{ testRequestId() }}</span>\r\n </p>\r\n\r\n @if (!result()) {\r\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\r\n }\r\n\r\n @if (timedOut()) {\r\n <div\r\n class=\"mt-4 rounded-md border border-orange-200 bg-orange-50 px-4 py-3\"\r\n role=\"alert\"\r\n >\r\n <p class=\"font-semibold text-orange-950\">\r\n {{ t(\"test.timeout-title\") }}\r\n </p>\r\n <p class=\"mt-1 text-sm text-orange-900\">\r\n {{ t(\"test.timeout-description\") }}\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (result(); as testResult) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-4\"\r\n aria-live=\"polite\"\r\n >\r\n <mt-email-delivery-status kind=\"attempt\" [value]=\"testResult.outcome\" />\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ facade.describeCode(testResult.code) }}\r\n </p>\r\n @if (showsAcceptedCaveat(testResult)) {\r\n <p class=\"mt-3 text-sm font-medium text-amber-800\">\r\n {{ t(\"accepted-unconfirmed\") }}\r\n </p>\r\n }\r\n @if (testResult.outcome === \"OutcomeUnknown\") {\r\n <p class=\"mt-3 text-sm font-medium text-red-700\">\r\n {{ t(\"outcome-unknown-warning\") }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('close')\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (timedOut()) {\r\n <mt-button\r\n [label]=\"t('test.retrieve')\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [disabled]=\"polling()\"\r\n [loading]=\"polling() || facade.mutationLoading() === 'retrieve-test'\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"retrieve()\"\r\n />\r\n } @else if (!result()) {\r\n <mt-button\r\n [label]=\"t('test.send')\"\r\n icon=\"communication.send-01\"\r\n [disabled]=\"!canSubmit()\"\r\n [loading]=\"facade.mutationLoading() === 'test'\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"submit()\"\r\n />\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues", "serverFieldErrors"], outputs: ["runtimeMessagesChange"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1447
1571
  }
1448
1572
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailControlledTestDialog, decorators: [{
1449
1573
  type: Component,
@@ -1453,9 +1577,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1453
1577
  DynamicForm,
1454
1578
  Button,
1455
1579
  EmailDeliveryStatus,
1456
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\n <div\n class=\"mb-4 rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950\"\n role=\"note\"\n >\n <strong>{{ t(\"test.real-email-warning-title\") }}</strong>\n {{ t(\"test.real-email-warning\") }}\n </div>\n\n @if (!result()) {\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\n }\n\n @if (timedOut()) {\n <div\n class=\"mt-4 rounded-md border border-orange-200 bg-orange-50 px-4 py-3\"\n role=\"alert\"\n >\n <p class=\"font-semibold text-orange-950\">\n {{ t(\"test.timeout-title\") }}\n </p>\n <p class=\"mt-1 text-sm text-orange-900\">\n {{ t(\"test.timeout-description\") }}\n </p>\n </div>\n }\n\n @if (result(); as testResult) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-4\"\n aria-live=\"polite\"\n >\n <mt-email-delivery-status kind=\"attempt\" [value]=\"testResult.outcome\" />\n <p class=\"mt-1 text-sm text-muted-color\">\n {{ facade.describeCode(testResult.code) }}\n </p>\n @if (showsAcceptedCaveat(testResult)) {\n <p class=\"mt-3 text-sm font-medium text-amber-800\">\n {{ t(\"accepted-unconfirmed\") }}\n </p>\n }\n @if (testResult.outcome === \"OutcomeUnknown\") {\n <p class=\"mt-3 text-sm font-medium text-red-700\">\n {{ t(\"outcome-unknown-warning\") }}\n </p>\n }\n </div>\n }\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n severity=\"secondary\"\n variant=\"outlined\"\n [label]=\"t('close')\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (timedOut()) {\n <mt-button\n [label]=\"t('test.retrieve')\"\n icon=\"arrow.refresh-cw-01\"\n [disabled]=\"polling()\"\n [loading]=\"polling() || facade.mutationLoading() === 'retrieve-test'\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"retrieve()\"\n />\n } @else if (!result()) {\n <mt-button\n [label]=\"t('test.send')\"\n icon=\"communication.send-01\"\n [disabled]=\"!canSubmit()\"\n [loading]=\"facade.mutationLoading() === 'test'\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"submit()\"\n />\n }\n </div>\n</ng-container>\n" }]
1580
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\r\n <div\r\n class=\"mb-4 rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950\"\r\n role=\"note\"\r\n >\r\n <strong>{{ t(\"test.real-email-warning-title\") }}</strong>\r\n {{ t(\"test.real-email-warning\") }}\r\n </div>\r\n\r\n <!-- The GUID this dialog will keep for the whole exchange. It is what a\r\n lost response is retrieved with, so the operator can record it before\r\n sending rather than reconstructing it afterwards. -->\r\n <p class=\"mb-4 text-xs text-muted-color\">\r\n {{ t(\"test-request-id\") }}:\r\n <span class=\"break-all font-mono\">{{ testRequestId() }}</span>\r\n </p>\r\n\r\n @if (!result()) {\r\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\r\n }\r\n\r\n @if (timedOut()) {\r\n <div\r\n class=\"mt-4 rounded-md border border-orange-200 bg-orange-50 px-4 py-3\"\r\n role=\"alert\"\r\n >\r\n <p class=\"font-semibold text-orange-950\">\r\n {{ t(\"test.timeout-title\") }}\r\n </p>\r\n <p class=\"mt-1 text-sm text-orange-900\">\r\n {{ t(\"test.timeout-description\") }}\r\n </p>\r\n </div>\r\n }\r\n\r\n @if (result(); as testResult) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-4\"\r\n aria-live=\"polite\"\r\n >\r\n <mt-email-delivery-status kind=\"attempt\" [value]=\"testResult.outcome\" />\r\n <p class=\"mt-1 text-sm text-muted-color\">\r\n {{ facade.describeCode(testResult.code) }}\r\n </p>\r\n @if (showsAcceptedCaveat(testResult)) {\r\n <p class=\"mt-3 text-sm font-medium text-amber-800\">\r\n {{ t(\"accepted-unconfirmed\") }}\r\n </p>\r\n }\r\n @if (testResult.outcome === \"OutcomeUnknown\") {\r\n <p class=\"mt-3 text-sm font-medium text-red-700\">\r\n {{ t(\"outcome-unknown-warning\") }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [label]=\"t('close')\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (timedOut()) {\r\n <mt-button\r\n [label]=\"t('test.retrieve')\"\r\n icon=\"arrow.refresh-cw-01\"\r\n [disabled]=\"polling()\"\r\n [loading]=\"polling() || facade.mutationLoading() === 'retrieve-test'\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"retrieve()\"\r\n />\r\n } @else if (!result()) {\r\n <mt-button\r\n [label]=\"t('test.send')\"\r\n icon=\"communication.send-01\"\r\n [disabled]=\"!canSubmit()\"\r\n [loading]=\"facade.mutationLoading() === 'test'\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"submit()\"\r\n />\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
1457
1581
  }], propDecorators: { connectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionId", required: true }] }], connectionName: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionName", required: true }] }] } });
1458
1582
  const ACCEPTED_DELIVERY_UNCONFIRMED_CODE = 'email.accepted_delivery_unconfirmed';
1583
+ const TEST_REQUEST_CONFLICT_CODE = 'email.delivery_test_request_conflict';
1584
+ function isTestRequestConflict(error) {
1585
+ const body = error instanceof HttpErrorResponse ? error.error : error;
1586
+ return (typeof body === 'object' &&
1587
+ body !== null &&
1588
+ body.code === TEST_REQUEST_CONFLICT_CODE);
1589
+ }
1459
1590
  const POLL_DELAYS_MS = [1_000, 2_000, 4_000, 5_000, 5_000, 5_000];
1460
1591
  function isPendingRequestState(value) {
1461
1592
  return !['Completed', 'Failed', 'Cancelled', 'Canceled'].includes(value);
@@ -2014,7 +2145,7 @@ class EmailConnectionEditor {
2014
2145
  return this.transloco.translate(`email-delivery.${key}`);
2015
2146
  }
2016
2147
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailConnectionEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
2017
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailConnectionEditor, isStandalone: true, selector: "mt-email-connection-editor", inputs: { editorConnectionId: { classPropertyName: "editorConnectionId", publicName: "editorConnectionId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div\n [class]=\"\n 'flex min-h-0 flex-col gap-5 overflow-y-auto p-4 sm:p-5 ' +\n modal.contentClass\n \"\n >\n @if (editorLoading()) {\n <div\n class=\"flex flex-col gap-5\"\n role=\"status\"\n [attr.aria-label]=\"t('loading')\"\n >\n @for (section of [1, 2, 3]; track section) {\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\n <p-skeleton\n width=\"10rem\"\n height=\"1.25rem\"\n borderRadius=\"0.375rem\"\n />\n </div>\n <div class=\"grid gap-4 p-4 sm:grid-cols-2\">\n @for (field of [1, 2, 3, 4]; track field) {\n <p-skeleton height=\"3.25rem\" borderRadius=\"0.375rem\" />\n }\n </div>\n </div>\n }\n </div>\n } @else {\n @if (selectedProvider(); as provider) {\n @if (provider.warnings.length > 0) {\n <section\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\n role=\"note\"\n aria-labelledby=\"provider-warnings-heading\"\n >\n <h2\n id=\"provider-warnings-heading\"\n class=\"m-0 text-sm font-semibold text-amber-950\"\n >\n {{ t(\"provider-warnings\") }}\n </h2>\n <ul\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\n >\n @for (warning of provider.warnings; track warning) {\n <li class=\"ps-1\">{{ warning }}</li>\n }\n </ul>\n </section>\n }\n }\n\n @if (isEdit()) {\n <div\n class=\"rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950\"\n role=\"note\"\n >\n {{ t(\"editor.update-invalidates-proof\") }}\n </div>\n }\n\n @for (generation of [formGeneration()]; track generation) {\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\n }\n\n @if (applicableFields().length === 0) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-3 text-sm text-muted-color\"\n >\n {{ t(\"editor.select-provider-mode\") }}\n </div>\n }\n }\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n [disabled]=\"!!facade.mutationLoading()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"cancel()\"\n />\n <mt-button\n [label]=\"t('save')\"\n icon=\"general.save-01\"\n [disabled]=\"!canSave()\"\n [loading]=\"facade.mutationLoading() === (isEdit() ? 'update' : 'create')\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"save()\"\n />\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues", "serverFieldErrors"], outputs: ["runtimeMessagesChange"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2148
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailConnectionEditor, isStandalone: true, selector: "mt-email-connection-editor", inputs: { editorConnectionId: { classPropertyName: "editorConnectionId", publicName: "editorConnectionId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div\r\n [class]=\"\r\n 'flex min-h-0 flex-col gap-5 overflow-y-auto p-4 sm:p-5 ' +\r\n modal.contentClass\r\n \"\r\n >\r\n @if (editorLoading()) {\r\n <div\r\n class=\"flex flex-col gap-5\"\r\n role=\"status\"\r\n [attr.aria-label]=\"t('loading')\"\r\n >\r\n @for (section of [1, 2, 3]; track section) {\r\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\r\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.25rem\"\r\n borderRadius=\"0.375rem\"\r\n />\r\n </div>\r\n <div class=\"grid gap-4 p-4 sm:grid-cols-2\">\r\n @for (field of [1, 2, 3, 4]; track field) {\r\n <p-skeleton height=\"3.25rem\" borderRadius=\"0.375rem\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @if (selectedProvider(); as provider) {\r\n @if (provider.warnings.length > 0) {\r\n <section\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\r\n role=\"note\"\r\n aria-labelledby=\"provider-warnings-heading\"\r\n >\r\n <h2\r\n id=\"provider-warnings-heading\"\r\n class=\"m-0 text-sm font-semibold text-amber-950\"\r\n >\r\n {{ t(\"provider-warnings\") }}\r\n </h2>\r\n <ul\r\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\r\n >\r\n @for (warning of provider.warnings; track warning) {\r\n <li class=\"ps-1\">{{ warning }}</li>\r\n }\r\n </ul>\r\n </section>\r\n }\r\n }\r\n\r\n @if (isEdit()) {\r\n <div\r\n class=\"rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950\"\r\n role=\"note\"\r\n >\r\n {{ t(\"editor.update-invalidates-proof\") }}\r\n </div>\r\n }\r\n\r\n @for (generation of [formGeneration()]; track generation) {\r\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\r\n }\r\n\r\n @if (applicableFields().length === 0) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-3 text-sm text-muted-color\"\r\n >\r\n {{ t(\"editor.select-provider-mode\") }}\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n variant=\"outlined\"\r\n [disabled]=\"!!facade.mutationLoading()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-01\"\r\n [disabled]=\"!canSave()\"\r\n [loading]=\"facade.mutationLoading() === (isEdit() ? 'update' : 'create')\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues", "serverFieldErrors"], outputs: ["runtimeMessagesChange"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2018
2149
  }
2019
2150
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailConnectionEditor, decorators: [{
2020
2151
  type: Component,
@@ -2024,7 +2155,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2024
2155
  SkeletonModule,
2025
2156
  DynamicForm,
2026
2157
  Button,
2027
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <div\n [class]=\"\n 'flex min-h-0 flex-col gap-5 overflow-y-auto p-4 sm:p-5 ' +\n modal.contentClass\n \"\n >\n @if (editorLoading()) {\n <div\n class=\"flex flex-col gap-5\"\n role=\"status\"\n [attr.aria-label]=\"t('loading')\"\n >\n @for (section of [1, 2, 3]; track section) {\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\n <p-skeleton\n width=\"10rem\"\n height=\"1.25rem\"\n borderRadius=\"0.375rem\"\n />\n </div>\n <div class=\"grid gap-4 p-4 sm:grid-cols-2\">\n @for (field of [1, 2, 3, 4]; track field) {\n <p-skeleton height=\"3.25rem\" borderRadius=\"0.375rem\" />\n }\n </div>\n </div>\n }\n </div>\n } @else {\n @if (selectedProvider(); as provider) {\n @if (provider.warnings.length > 0) {\n <section\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\n role=\"note\"\n aria-labelledby=\"provider-warnings-heading\"\n >\n <h2\n id=\"provider-warnings-heading\"\n class=\"m-0 text-sm font-semibold text-amber-950\"\n >\n {{ t(\"provider-warnings\") }}\n </h2>\n <ul\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\n >\n @for (warning of provider.warnings; track warning) {\n <li class=\"ps-1\">{{ warning }}</li>\n }\n </ul>\n </section>\n }\n }\n\n @if (isEdit()) {\n <div\n class=\"rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950\"\n role=\"note\"\n >\n {{ t(\"editor.update-invalidates-proof\") }}\n </div>\n }\n\n @for (generation of [formGeneration()]; track generation) {\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\n }\n\n @if (applicableFields().length === 0) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-3 text-sm text-muted-color\"\n >\n {{ t(\"editor.select-provider-mode\") }}\n </div>\n }\n }\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n [disabled]=\"!!facade.mutationLoading()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"cancel()\"\n />\n <mt-button\n [label]=\"t('save')\"\n icon=\"general.save-01\"\n [disabled]=\"!canSave()\"\n [loading]=\"facade.mutationLoading() === (isEdit() ? 'update' : 'create')\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"save()\"\n />\n </div>\n</ng-container>\n" }]
2158
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <div\r\n [class]=\"\r\n 'flex min-h-0 flex-col gap-5 overflow-y-auto p-4 sm:p-5 ' +\r\n modal.contentClass\r\n \"\r\n >\r\n @if (editorLoading()) {\r\n <div\r\n class=\"flex flex-col gap-5\"\r\n role=\"status\"\r\n [attr.aria-label]=\"t('loading')\"\r\n >\r\n @for (section of [1, 2, 3]; track section) {\r\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\r\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.25rem\"\r\n borderRadius=\"0.375rem\"\r\n />\r\n </div>\r\n <div class=\"grid gap-4 p-4 sm:grid-cols-2\">\r\n @for (field of [1, 2, 3, 4]; track field) {\r\n <p-skeleton height=\"3.25rem\" borderRadius=\"0.375rem\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @if (selectedProvider(); as provider) {\r\n @if (provider.warnings.length > 0) {\r\n <section\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\r\n role=\"note\"\r\n aria-labelledby=\"provider-warnings-heading\"\r\n >\r\n <h2\r\n id=\"provider-warnings-heading\"\r\n class=\"m-0 text-sm font-semibold text-amber-950\"\r\n >\r\n {{ t(\"provider-warnings\") }}\r\n </h2>\r\n <ul\r\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\r\n >\r\n @for (warning of provider.warnings; track warning) {\r\n <li class=\"ps-1\">{{ warning }}</li>\r\n }\r\n </ul>\r\n </section>\r\n }\r\n }\r\n\r\n @if (isEdit()) {\r\n <div\r\n class=\"rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950\"\r\n role=\"note\"\r\n >\r\n {{ t(\"editor.update-invalidates-proof\") }}\r\n </div>\r\n }\r\n\r\n @for (generation of [formGeneration()]; track generation) {\r\n <mt-dynamic-form [formConfig]=\"formConfig()\" [formControl]=\"form\" />\r\n }\r\n\r\n @if (applicableFields().length === 0) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 px-4 py-3 text-sm text-muted-color\"\r\n >\r\n {{ t(\"editor.select-provider-mode\") }}\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n variant=\"outlined\"\r\n [disabled]=\"!!facade.mutationLoading()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-01\"\r\n [disabled]=\"!canSave()\"\r\n [loading]=\"facade.mutationLoading() === (isEdit() ? 'update' : 'create')\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
2028
2159
  }], ctorParameters: () => [], propDecorators: { editorConnectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editorConnectionId", required: false }] }] } });
2029
2160
  // Mirrors the section-mode styling mt-client-form applies to its own sections.
2030
2161
  const SECTION_MODE_LAYOUT = {
@@ -2129,6 +2260,34 @@ class EmailConnectionDetailsPage {
2129
2260
  ? this.facade.providerByKey(details.connection.providerKey)
2130
2261
  : null;
2131
2262
  }, ...(ngDevMode ? [{ debugName: "provider" }] : /* istanbul ignore next */ []));
2263
+ /**
2264
+ * The provider descriptor's own warnings, shown here and not only while
2265
+ * editing: a connection whose mode carries a standing caveat — the QC SMTP
2266
+ * endpoint that runs without TLS or authentication, for instance — must
2267
+ * still say so to whoever opens it later.
2268
+ */
2269
+ providerWarnings = computed(() => this.provider()?.warnings ?? [], ...(ngDevMode ? [{ debugName: "providerWarnings" }] : /* istanbul ignore next */ []));
2270
+ /**
2271
+ * The contract assigns each connection state one next step. Saying it in
2272
+ * words means the chip is not the only place the operator can read what to
2273
+ * do, which is also what keeps the state legible without relying on color.
2274
+ */
2275
+ stateGuidance = computed(() => {
2276
+ this.activeLanguage();
2277
+ const details = this.facade.selectedConnection();
2278
+ if (!details)
2279
+ return '';
2280
+ return this.optionalT(`state-guidance.${toKebabCase$1(details.connection.state)}`);
2281
+ }, ...(ngDevMode ? [{ debugName: "stateGuidance" }] : /* istanbul ignore next */ []));
2282
+ /**
2283
+ * The last validation code, so an invalid connection shows the reason rather
2284
+ * than only a chip that says something went wrong.
2285
+ */
2286
+ lastValidationMessage = computed(() => {
2287
+ this.activeLanguage();
2288
+ const code = this.facade.selectedConnection()?.connection.lastValidationCode;
2289
+ return code ? this.facade.describeCode(code) : '';
2290
+ }, ...(ngDevMode ? [{ debugName: "lastValidationMessage" }] : /* istanbul ignore next */ []));
2132
2291
  authenticationModeLabel = computed(() => {
2133
2292
  const details = this.facade.selectedConnection();
2134
2293
  if (!details)
@@ -2339,6 +2498,12 @@ class EmailConnectionDetailsPage {
2339
2498
  t(key) {
2340
2499
  return this.transloco.translate(`email-delivery.${key}`);
2341
2500
  }
2501
+ /** Empty rather than the raw key when a state has no guidance sentence. */
2502
+ optionalT(key) {
2503
+ const fullKey = `email-delivery.${key}`;
2504
+ const translated = this.transloco.translate(fullKey);
2505
+ return translated === fullKey ? '' : translated;
2506
+ }
2342
2507
  credentialStorageLabel(storageKind) {
2343
2508
  switch (storageKind.replace(/[-_\s]/g, '').toLowerCase()) {
2344
2509
  case 'externalreference':
@@ -2357,7 +2522,7 @@ class EmailConnectionDetailsPage {
2357
2522
  return field?.dataType === 'Choice' ? humanizeIdentifier(value) : value;
2358
2523
  }
2359
2524
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailConnectionDetailsPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
2360
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailConnectionDetailsPage, isStandalone: true, selector: "mt-email-connection-details", inputs: { connectionId: { classPropertyName: "connectionId", publicName: "connectionId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n @if (facade.detailsLoading()) {\n <div\n [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\"\n role=\"status\"\n [attr.aria-label]=\"t('loading')\"\n >\n <div class=\"grid w-full gap-5\">\n <p-skeleton height=\"5rem\" borderRadius=\"0.375rem\" />\n @for (section of [1, 2, 3]; track section) {\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\n <p-skeleton\n width=\"12rem\"\n height=\"1.25rem\"\n borderRadius=\"0.375rem\"\n />\n </div>\n <div class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n @for (tile of [1, 2, 3]; track tile) {\n <p-skeleton height=\"4rem\" borderRadius=\"0.375rem\" />\n }\n </div>\n </div>\n }\n </div>\n </div>\n } @else if (facade.selectedConnection(); as details) {\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\n <div class=\"grid w-full gap-5\">\n <section\n class=\"flex flex-col gap-3 rounded-md border border-surface-200 bg-surface-0 p-4 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div class=\"min-w-0\">\n <h2 class=\"m-0 truncate text-lg font-semibold text-color\">\n {{ details.connection.name }}\n </h2>\n <p class=\"mb-0 mt-1 break-all text-sm text-muted-color\">\n {{ details.connection.senderAddress }}\n </p>\n </div>\n <mt-email-delivery-status\n class=\"shrink-0\"\n kind=\"connection\"\n [value]=\"details.connection.state\"\n />\n </section>\n\n <!-- Same section shape the connection form uses (mt-client-form section\n mode): header strip on a bordered, flat, rounded-md container. -->\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"connection-overview\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.provider\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ provider()?.displayName || details.connection.providerKey }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.authentication-mode\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ authenticationModeLabel() }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"used-for-notifications\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{\n details.bindings.includes(\"notifications\")\n ? t(\"yes\")\n : t(\"no\")\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.last-validation\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{\n details.connection.lastValidatedAtUtc\n ? (details.connection.lastValidatedAtUtc | date: \"medium\")\n : \"\u2014\"\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"authorization-state\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ details.authorizationState || \"\u2014\" }}\n </dd>\n </div>\n @if (details.connection.senderDisplayName) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.sender-display-name\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ details.connection.senderDisplayName }}\n </dd>\n </div>\n }\n </dl>\n </section>\n\n @if (publicConfiguration().length > 0) {\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"provider-settings\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n @for (entry of publicConfiguration(); track entry.key) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">{{ entry.label }}</dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ entry.value }}\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"credential-status\") }}\n </h3>\n <div class=\"grid gap-3 p-4\">\n @for (credential of credentialItems(); track credential.key) {\n <div\n class=\"grid gap-3 rounded-md border border-surface-200 bg-surface-50 p-3 sm:grid-cols-3 sm:items-center\"\n >\n <div class=\"min-w-0\">\n <p class=\"m-0 break-words font-medium text-color\">\n {{ credential.label }}\n </p>\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\n {{ credential.key }}\n </p>\n </div>\n <div class=\"min-w-0\">\n <p class=\"m-0 text-sm font-medium text-color\">\n {{ credential.storageLabel }}\n </p>\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\n @if (credential.lastRotatedAtUtc) {\n {{ t(\"last-rotated\") }} \u00B7\n {{ credential.lastRotatedAtUtc | date: \"medium\" }}\n } @else {\n {{ t(\"last-rotated\") }} \u00B7 \u2014\n }\n </p>\n </div>\n <mt-email-delivery-status\n class=\"shrink-0 sm:justify-self-end\"\n kind=\"support\"\n [value]=\"\n credential.configured ? 'configured' : 'not-configured'\n \"\n />\n </div>\n } @empty {\n <p class=\"m-0 text-sm text-muted-color\">\n {{ t(\"no-credentials\") }}\n </p>\n }\n </div>\n </section>\n </div>\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('close')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (actionMenuItems().length > 0) {\n <mt-button\n [label]=\"t('actions')\"\n icon=\"general.dots-vertical\"\n severity=\"secondary\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"actionMenu.toggle($event)\"\n />\n <mt-menu\n #actionMenu\n [model]=\"actionMenuItems()\"\n appendTo=\"body\"\n [ariaLabel]=\"t('actions')\"\n />\n }\n <mt-button\n [label]=\"t('edit')\"\n icon=\"general.edit-01\"\n [disabled]=\"!facade.managementAvailable()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"edit()\"\n />\n </div>\n } @else {\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\n <mt-empty-state illustration=\"none\" [title]=\"t('connection-not-found')\" />\n </div>\n <div [class]=\"modal.footerClass\">\n <mt-button [label]=\"t('close')\" variant=\"outlined\" (onClick)=\"close()\" />\n </div>\n }\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "component", type: Menu, selector: "mt-menu", inputs: ["model", "popup", "appendTo", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "activeItemId"], outputs: ["activeItemIdChange", "onShow", "onHide", "onBlur", "onFocus", "onItemSelect"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2525
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailConnectionDetailsPage, isStandalone: true, selector: "mt-email-connection-details", inputs: { connectionId: { classPropertyName: "connectionId", publicName: "connectionId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n @if (facade.detailsLoading()) {\r\n <div\r\n [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\"\r\n role=\"status\"\r\n [attr.aria-label]=\"t('loading')\"\r\n >\r\n <div class=\"grid w-full gap-5\">\r\n <p-skeleton height=\"5rem\" borderRadius=\"0.375rem\" />\r\n @for (section of [1, 2, 3]; track section) {\r\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\r\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.25rem\"\r\n borderRadius=\"0.375rem\"\r\n />\r\n </div>\r\n <div class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n @for (tile of [1, 2, 3]; track tile) {\r\n <p-skeleton height=\"4rem\" borderRadius=\"0.375rem\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else if (facade.selectedConnection(); as details) {\r\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\r\n <div class=\"grid w-full gap-5\">\r\n <section\r\n class=\"flex flex-col gap-3 rounded-md border border-surface-200 bg-surface-0 p-4 sm:flex-row sm:items-center sm:justify-between\"\r\n >\r\n <div class=\"min-w-0\">\r\n <h2 class=\"m-0 truncate text-lg font-semibold text-color\">\r\n {{ details.connection.name }}\r\n </h2>\r\n <p class=\"mb-0 mt-1 break-all text-sm text-muted-color\">\r\n {{ details.connection.senderAddress }}\r\n </p>\r\n <!-- The next step in words, so the state is never carried by the\r\n chip's color alone. -->\r\n @if (stateGuidance(); as guidance) {\r\n <p class=\"mb-0 mt-2 text-sm text-color\">{{ guidance }}</p>\r\n }\r\n @if (lastValidationMessage(); as lastResult) {\r\n <p class=\"mb-0 mt-1 text-sm text-muted-color\">\r\n {{ t(\"last-result\") }}: {{ lastResult }}\r\n </p>\r\n }\r\n </div>\r\n <mt-email-delivery-status\r\n class=\"shrink-0 self-start\"\r\n kind=\"connection\"\r\n [value]=\"details.connection.state\"\r\n />\r\n </section>\r\n\r\n <!-- The descriptor's standing caveats for this provider and mode. The\r\n editor shows them while configuring; they belong here too, because\r\n whoever opens an existing connection is the one deciding whether\r\n it may carry production notification email. -->\r\n @if (providerWarnings().length > 0) {\r\n <section\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\r\n role=\"note\"\r\n aria-labelledby=\"connection-provider-warnings-heading\"\r\n >\r\n <h3\r\n id=\"connection-provider-warnings-heading\"\r\n class=\"m-0 text-sm font-semibold text-amber-950\"\r\n >\r\n {{ t(\"provider-warnings\") }}\r\n </h3>\r\n <ul\r\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\r\n >\r\n @for (warning of providerWarnings(); track warning) {\r\n <li class=\"ps-1\">{{ warning }}</li>\r\n }\r\n </ul>\r\n </section>\r\n }\r\n\r\n <!-- Same section shape the connection form uses (mt-client-form section\r\n mode): header strip on a bordered, flat, rounded-md container. -->\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"connection-overview\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.provider\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ provider()?.displayName || details.connection.providerKey }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.authentication-mode\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ authenticationModeLabel() }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"used-for-notifications\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{\r\n details.bindings.includes(\"notifications\")\r\n ? t(\"yes\")\r\n : t(\"no\")\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.last-validation\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{\r\n details.connection.lastValidatedAtUtc\r\n ? (details.connection.lastValidatedAtUtc | date: \"medium\")\r\n : \"\u2014\"\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"authorization-state\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ details.authorizationState || \"\u2014\" }}\r\n </dd>\r\n </div>\r\n @if (details.connection.senderDisplayName) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.sender-display-name\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ details.connection.senderDisplayName }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n\r\n @if (publicConfiguration().length > 0) {\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"provider-settings\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n @for (entry of publicConfiguration(); track entry.key) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">{{ entry.label }}</dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ entry.value }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n }\r\n\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"credential-status\") }}\r\n </h3>\r\n <div class=\"grid gap-3 p-4\">\r\n @for (credential of credentialItems(); track credential.key) {\r\n <div\r\n class=\"grid gap-3 rounded-md border border-surface-200 bg-surface-50 p-3 sm:grid-cols-3 sm:items-center\"\r\n >\r\n <div class=\"min-w-0\">\r\n <p class=\"m-0 break-words font-medium text-color\">\r\n {{ credential.label }}\r\n </p>\r\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\r\n {{ credential.key }}\r\n </p>\r\n </div>\r\n <div class=\"min-w-0\">\r\n <p class=\"m-0 text-sm font-medium text-color\">\r\n {{ credential.storageLabel }}\r\n </p>\r\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\r\n @if (credential.lastRotatedAtUtc) {\r\n {{ t(\"last-rotated\") }} \u00B7\r\n {{ credential.lastRotatedAtUtc | date: \"medium\" }}\r\n } @else {\r\n {{ t(\"last-rotated\") }} \u00B7 \u2014\r\n }\r\n </p>\r\n </div>\r\n <mt-email-delivery-status\r\n class=\"shrink-0 sm:justify-self-end\"\r\n kind=\"support\"\r\n [value]=\"\r\n credential.configured ? 'configured' : 'not-configured'\r\n \"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"m-0 text-sm text-muted-color\">\r\n {{ t(\"no-credentials\") }}\r\n </p>\r\n }\r\n </div>\r\n </section>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('close')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (actionMenuItems().length > 0) {\r\n <mt-button\r\n [label]=\"t('actions')\"\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"actionMenu.toggle($event)\"\r\n />\r\n <mt-menu\r\n #actionMenu\r\n [model]=\"actionMenuItems()\"\r\n appendTo=\"body\"\r\n [ariaLabel]=\"t('actions')\"\r\n />\r\n }\r\n <mt-button\r\n [label]=\"t('edit')\"\r\n icon=\"general.edit-01\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"edit()\"\r\n />\r\n </div>\r\n } @else {\r\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\r\n <mt-empty-state illustration=\"none\" [title]=\"t('connection-not-found')\" />\r\n </div>\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button [label]=\"t('close')\" variant=\"outlined\" (onClick)=\"close()\" />\r\n </div>\r\n }\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "component", type: Menu, selector: "mt-menu", inputs: ["model", "popup", "appendTo", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "activeItemId"], outputs: ["activeItemIdChange", "onShow", "onHide", "onBlur", "onFocus", "onItemSelect"] }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2361
2526
  }
2362
2527
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailConnectionDetailsPage, decorators: [{
2363
2528
  type: Component,
@@ -2369,8 +2534,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2369
2534
  EmptyState,
2370
2535
  Menu,
2371
2536
  EmailDeliveryStatus,
2372
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n @if (facade.detailsLoading()) {\n <div\n [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\"\n role=\"status\"\n [attr.aria-label]=\"t('loading')\"\n >\n <div class=\"grid w-full gap-5\">\n <p-skeleton height=\"5rem\" borderRadius=\"0.375rem\" />\n @for (section of [1, 2, 3]; track section) {\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\n <p-skeleton\n width=\"12rem\"\n height=\"1.25rem\"\n borderRadius=\"0.375rem\"\n />\n </div>\n <div class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n @for (tile of [1, 2, 3]; track tile) {\n <p-skeleton height=\"4rem\" borderRadius=\"0.375rem\" />\n }\n </div>\n </div>\n }\n </div>\n </div>\n } @else if (facade.selectedConnection(); as details) {\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\n <div class=\"grid w-full gap-5\">\n <section\n class=\"flex flex-col gap-3 rounded-md border border-surface-200 bg-surface-0 p-4 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div class=\"min-w-0\">\n <h2 class=\"m-0 truncate text-lg font-semibold text-color\">\n {{ details.connection.name }}\n </h2>\n <p class=\"mb-0 mt-1 break-all text-sm text-muted-color\">\n {{ details.connection.senderAddress }}\n </p>\n </div>\n <mt-email-delivery-status\n class=\"shrink-0\"\n kind=\"connection\"\n [value]=\"details.connection.state\"\n />\n </section>\n\n <!-- Same section shape the connection form uses (mt-client-form section\n mode): header strip on a bordered, flat, rounded-md container. -->\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"connection-overview\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.provider\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ provider()?.displayName || details.connection.providerKey }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.authentication-mode\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ authenticationModeLabel() }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"used-for-notifications\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{\n details.bindings.includes(\"notifications\")\n ? t(\"yes\")\n : t(\"no\")\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.last-validation\") }}\n </dt>\n <dd class=\"mb-0 mt-1 font-medium text-color\">\n {{\n details.connection.lastValidatedAtUtc\n ? (details.connection.lastValidatedAtUtc | date: \"medium\")\n : \"\u2014\"\n }}\n </dd>\n </div>\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"authorization-state\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ details.authorizationState || \"\u2014\" }}\n </dd>\n </div>\n @if (details.connection.senderDisplayName) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">\n {{ t(\"connection.sender-display-name\") }}\n </dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ details.connection.senderDisplayName }}\n </dd>\n </div>\n }\n </dl>\n </section>\n\n @if (publicConfiguration().length > 0) {\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"provider-settings\") }}\n </h3>\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n @for (entry of publicConfiguration(); track entry.key) {\n <div\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\n >\n <dt class=\"text-xs text-muted-color\">{{ entry.label }}</dt>\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\n {{ entry.value }}\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n\n <section\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\n >\n <h3\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\n >\n {{ t(\"credential-status\") }}\n </h3>\n <div class=\"grid gap-3 p-4\">\n @for (credential of credentialItems(); track credential.key) {\n <div\n class=\"grid gap-3 rounded-md border border-surface-200 bg-surface-50 p-3 sm:grid-cols-3 sm:items-center\"\n >\n <div class=\"min-w-0\">\n <p class=\"m-0 break-words font-medium text-color\">\n {{ credential.label }}\n </p>\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\n {{ credential.key }}\n </p>\n </div>\n <div class=\"min-w-0\">\n <p class=\"m-0 text-sm font-medium text-color\">\n {{ credential.storageLabel }}\n </p>\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\n @if (credential.lastRotatedAtUtc) {\n {{ t(\"last-rotated\") }} \u00B7\n {{ credential.lastRotatedAtUtc | date: \"medium\" }}\n } @else {\n {{ t(\"last-rotated\") }} \u00B7 \u2014\n }\n </p>\n </div>\n <mt-email-delivery-status\n class=\"shrink-0 sm:justify-self-end\"\n kind=\"support\"\n [value]=\"\n credential.configured ? 'configured' : 'not-configured'\n \"\n />\n </div>\n } @empty {\n <p class=\"m-0 text-sm text-muted-color\">\n {{ t(\"no-credentials\") }}\n </p>\n }\n </div>\n </section>\n </div>\n </div>\n\n <div [class]=\"modal.footerClass\">\n <mt-button\n [label]=\"t('close')\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"close()\"\n />\n @if (actionMenuItems().length > 0) {\n <mt-button\n [label]=\"t('actions')\"\n icon=\"general.dots-vertical\"\n severity=\"secondary\"\n variant=\"outlined\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"actionMenu.toggle($event)\"\n />\n <mt-menu\n #actionMenu\n [model]=\"actionMenuItems()\"\n appendTo=\"body\"\n [ariaLabel]=\"t('actions')\"\n />\n }\n <mt-button\n [label]=\"t('edit')\"\n icon=\"general.edit-01\"\n [disabled]=\"!facade.managementAvailable()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"edit()\"\n />\n </div>\n } @else {\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\n <mt-empty-state illustration=\"none\" [title]=\"t('connection-not-found')\" />\n </div>\n <div [class]=\"modal.footerClass\">\n <mt-button [label]=\"t('close')\" variant=\"outlined\" (onClick)=\"close()\" />\n </div>\n }\n</ng-container>\n" }]
2537
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n @if (facade.detailsLoading()) {\r\n <div\r\n [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\"\r\n role=\"status\"\r\n [attr.aria-label]=\"t('loading')\"\r\n >\r\n <div class=\"grid w-full gap-5\">\r\n <p-skeleton height=\"5rem\" borderRadius=\"0.375rem\" />\r\n @for (section of [1, 2, 3]; track section) {\r\n <div class=\"overflow-hidden rounded-md border border-surface-200\">\r\n <div class=\"border-b border-surface-200 bg-surface-50 px-4 py-3\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.25rem\"\r\n borderRadius=\"0.375rem\"\r\n />\r\n </div>\r\n <div class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n @for (tile of [1, 2, 3]; track tile) {\r\n <p-skeleton height=\"4rem\" borderRadius=\"0.375rem\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else if (facade.selectedConnection(); as details) {\r\n <div [class]=\"'min-h-0 overflow-y-auto p-4 sm:p-5 ' + modal.contentClass\">\r\n <div class=\"grid w-full gap-5\">\r\n <section\r\n class=\"flex flex-col gap-3 rounded-md border border-surface-200 bg-surface-0 p-4 sm:flex-row sm:items-center sm:justify-between\"\r\n >\r\n <div class=\"min-w-0\">\r\n <h2 class=\"m-0 truncate text-lg font-semibold text-color\">\r\n {{ details.connection.name }}\r\n </h2>\r\n <p class=\"mb-0 mt-1 break-all text-sm text-muted-color\">\r\n {{ details.connection.senderAddress }}\r\n </p>\r\n <!-- The next step in words, so the state is never carried by the\r\n chip's color alone. -->\r\n @if (stateGuidance(); as guidance) {\r\n <p class=\"mb-0 mt-2 text-sm text-color\">{{ guidance }}</p>\r\n }\r\n @if (lastValidationMessage(); as lastResult) {\r\n <p class=\"mb-0 mt-1 text-sm text-muted-color\">\r\n {{ t(\"last-result\") }}: {{ lastResult }}\r\n </p>\r\n }\r\n </div>\r\n <mt-email-delivery-status\r\n class=\"shrink-0 self-start\"\r\n kind=\"connection\"\r\n [value]=\"details.connection.state\"\r\n />\r\n </section>\r\n\r\n <!-- The descriptor's standing caveats for this provider and mode. The\r\n editor shows them while configuring; they belong here too, because\r\n whoever opens an existing connection is the one deciding whether\r\n it may carry production notification email. -->\r\n @if (providerWarnings().length > 0) {\r\n <section\r\n class=\"rounded-md border border-amber-200 bg-amber-50 p-4\"\r\n role=\"note\"\r\n aria-labelledby=\"connection-provider-warnings-heading\"\r\n >\r\n <h3\r\n id=\"connection-provider-warnings-heading\"\r\n class=\"m-0 text-sm font-semibold text-amber-950\"\r\n >\r\n {{ t(\"provider-warnings\") }}\r\n </h3>\r\n <ul\r\n class=\"mb-0 mt-2.5 list-disc space-y-2 ps-5 text-sm leading-relaxed text-amber-900\"\r\n >\r\n @for (warning of providerWarnings(); track warning) {\r\n <li class=\"ps-1\">{{ warning }}</li>\r\n }\r\n </ul>\r\n </section>\r\n }\r\n\r\n <!-- Same section shape the connection form uses (mt-client-form section\r\n mode): header strip on a bordered, flat, rounded-md container. -->\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"connection-overview\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.provider\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ provider()?.displayName || details.connection.providerKey }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.authentication-mode\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ authenticationModeLabel() }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"used-for-notifications\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{\r\n details.bindings.includes(\"notifications\")\r\n ? t(\"yes\")\r\n : t(\"no\")\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.last-validation\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 font-medium text-color\">\r\n {{\r\n details.connection.lastValidatedAtUtc\r\n ? (details.connection.lastValidatedAtUtc | date: \"medium\")\r\n : \"\u2014\"\r\n }}\r\n </dd>\r\n </div>\r\n <div class=\"rounded-md border border-surface-200 bg-surface-50 p-3\">\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"authorization-state\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ details.authorizationState || \"\u2014\" }}\r\n </dd>\r\n </div>\r\n @if (details.connection.senderDisplayName) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">\r\n {{ t(\"connection.sender-display-name\") }}\r\n </dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ details.connection.senderDisplayName }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n\r\n @if (publicConfiguration().length > 0) {\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"provider-settings\") }}\r\n </h3>\r\n <dl class=\"grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3\">\r\n @for (entry of publicConfiguration(); track entry.key) {\r\n <div\r\n class=\"rounded-md border border-surface-200 bg-surface-50 p-3\"\r\n >\r\n <dt class=\"text-xs text-muted-color\">{{ entry.label }}</dt>\r\n <dd class=\"mb-0 mt-1 break-words font-medium text-color\">\r\n {{ entry.value }}\r\n </dd>\r\n </div>\r\n }\r\n </dl>\r\n </section>\r\n }\r\n\r\n <section\r\n class=\"flex flex-col gap-0 overflow-hidden rounded-md border border-surface-200 bg-surface-0\"\r\n >\r\n <h3\r\n class=\"m-0 border-b border-surface-200 bg-surface-50 px-4 py-3 text-lg font-semibold text-color\"\r\n >\r\n {{ t(\"credential-status\") }}\r\n </h3>\r\n <div class=\"grid gap-3 p-4\">\r\n @for (credential of credentialItems(); track credential.key) {\r\n <div\r\n class=\"grid gap-3 rounded-md border border-surface-200 bg-surface-50 p-3 sm:grid-cols-3 sm:items-center\"\r\n >\r\n <div class=\"min-w-0\">\r\n <p class=\"m-0 break-words font-medium text-color\">\r\n {{ credential.label }}\r\n </p>\r\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\r\n {{ credential.key }}\r\n </p>\r\n </div>\r\n <div class=\"min-w-0\">\r\n <p class=\"m-0 text-sm font-medium text-color\">\r\n {{ credential.storageLabel }}\r\n </p>\r\n <p class=\"mb-0 mt-1 text-xs text-muted-color\">\r\n @if (credential.lastRotatedAtUtc) {\r\n {{ t(\"last-rotated\") }} \u00B7\r\n {{ credential.lastRotatedAtUtc | date: \"medium\" }}\r\n } @else {\r\n {{ t(\"last-rotated\") }} \u00B7 \u2014\r\n }\r\n </p>\r\n </div>\r\n <mt-email-delivery-status\r\n class=\"shrink-0 sm:justify-self-end\"\r\n kind=\"support\"\r\n [value]=\"\r\n credential.configured ? 'configured' : 'not-configured'\r\n \"\r\n />\r\n </div>\r\n } @empty {\r\n <p class=\"m-0 text-sm text-muted-color\">\r\n {{ t(\"no-credentials\") }}\r\n </p>\r\n }\r\n </div>\r\n </section>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('close')\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"close()\"\r\n />\r\n @if (actionMenuItems().length > 0) {\r\n <mt-button\r\n [label]=\"t('actions')\"\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"actionMenu.toggle($event)\"\r\n />\r\n <mt-menu\r\n #actionMenu\r\n [model]=\"actionMenuItems()\"\r\n appendTo=\"body\"\r\n [ariaLabel]=\"t('actions')\"\r\n />\r\n }\r\n <mt-button\r\n [label]=\"t('edit')\"\r\n icon=\"general.edit-01\"\r\n [disabled]=\"!facade.managementAvailable()\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"edit()\"\r\n />\r\n </div>\r\n } @else {\r\n <div [class]=\"modal.contentClass + ' p-4 sm:p-5'\">\r\n <mt-empty-state illustration=\"none\" [title]=\"t('connection-not-found')\" />\r\n </div>\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button [label]=\"t('close')\" variant=\"outlined\" (onClick)=\"close()\" />\r\n </div>\r\n }\r\n</ng-container>\r\n" }]
2373
2538
  }], propDecorators: { connectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionId", required: true }] }] } });
2539
+ function toKebabCase$1(value) {
2540
+ return value.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
2541
+ }
2374
2542
  function humanizeIdentifier(value) {
2375
2543
  return value
2376
2544
  .replace(/[._-]+/g, ' ')
@@ -2609,11 +2777,11 @@ class EmailDeliveryConnections {
2609
2777
  return this.transloco.translate(`email-delivery.${key}`);
2610
2778
  }
2611
2779
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryConnections, deps: [], target: i0.ɵɵFactoryTarget.Component });
2612
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryConnections, isStandalone: true, selector: "mt-email-delivery-connections", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-4\" aria-label=\"{{ t('connections-title') }}\">\n @if (\n !facade.statusLoading() &&\n !facade.catalogLoading() &&\n facade.providers().length === 0\n ) {\n <mt-empty-state\n illustration=\"none\"\n [title]=\"t('no-providers-title')\"\n [description]=\"t('no-providers-description')\"\n />\n } @else {\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"rowActions()\"\n [loading]=\"\n facade.statusLoading() ||\n facade.connectionsLoading() ||\n facade.catalogLoading()\n \"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-connections-title')\"\n [emptyDescription]=\"t('no-connections-description')\"\n [emptyActionLabel]=\"canCreate() ? t('create-connection') : undefined\"\n emptyActionIcon=\"general.plus\"\n filterMode=\"column\"\n actionShape=\"popover\"\n [clickableRows]=\"true\"\n dataKey=\"id\"\n storageKey=\"email-delivery-connections\"\n (emptyAction)=\"createConnection()\"\n (rowClick)=\"openDetails($event)\"\n >\n <ng-template #captionEnd>\n @if (canCreate()) {\n <mt-button\n [label]=\"t('create-connection')\"\n icon=\"general.plus\"\n (onClick)=\"createConnection()\"\n />\n }\n </ng-template>\n </mt-table>\n }\n </section>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2780
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryConnections, isStandalone: true, selector: "mt-email-delivery-connections", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-4\" aria-label=\"{{ t('connections-title') }}\">\r\n @if (\r\n !facade.statusLoading() &&\r\n !facade.catalogLoading() &&\r\n facade.providers().length === 0\r\n ) {\r\n <mt-empty-state\r\n illustration=\"none\"\r\n [title]=\"t('no-providers-title')\"\r\n [description]=\"t('no-providers-description')\"\r\n />\r\n } @else {\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"\r\n facade.statusLoading() ||\r\n facade.connectionsLoading() ||\r\n facade.catalogLoading()\r\n \"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-connections-title')\"\r\n [emptyDescription]=\"t('no-connections-description')\"\r\n [emptyActionLabel]=\"canCreate() ? t('create-connection') : undefined\"\r\n emptyActionIcon=\"general.plus\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n [clickableRows]=\"true\"\r\n dataKey=\"id\"\r\n storageKey=\"email-delivery-connections\"\r\n (emptyAction)=\"createConnection()\"\r\n (rowClick)=\"openDetails($event)\"\r\n >\r\n <ng-template #captionEnd>\r\n @if (canCreate()) {\r\n <mt-button\r\n [label]=\"t('create-connection')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"createConnection()\"\r\n />\r\n }\r\n </ng-template>\r\n </mt-table>\r\n }\r\n </section>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "captionStartTemplate", "captionEndTemplate", "emptyTitle", "emptyDescription", "emptyActionLabel", "emptyActionIcon", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy", "sortField", "sortDirection"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "emptyAction", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange", "sortFieldChange", "sortDirectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2613
2781
  }
2614
2782
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryConnections, decorators: [{
2615
2783
  type: Component,
2616
- args: [{ selector: 'mt-email-delivery-connections', imports: [TranslocoDirective, Button, EmptyState, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <section class=\"space-y-4\" aria-label=\"{{ t('connections-title') }}\">\n @if (\n !facade.statusLoading() &&\n !facade.catalogLoading() &&\n facade.providers().length === 0\n ) {\n <mt-empty-state\n illustration=\"none\"\n [title]=\"t('no-providers-title')\"\n [description]=\"t('no-providers-description')\"\n />\n } @else {\n <mt-table\n [data]=\"rows()\"\n [columns]=\"columns()\"\n [rowActions]=\"rowActions()\"\n [loading]=\"\n facade.statusLoading() ||\n facade.connectionsLoading() ||\n facade.catalogLoading()\n \"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [emptyTitle]=\"t('no-connections-title')\"\n [emptyDescription]=\"t('no-connections-description')\"\n [emptyActionLabel]=\"canCreate() ? t('create-connection') : undefined\"\n emptyActionIcon=\"general.plus\"\n filterMode=\"column\"\n actionShape=\"popover\"\n [clickableRows]=\"true\"\n dataKey=\"id\"\n storageKey=\"email-delivery-connections\"\n (emptyAction)=\"createConnection()\"\n (rowClick)=\"openDetails($event)\"\n >\n <ng-template #captionEnd>\n @if (canCreate()) {\n <mt-button\n [label]=\"t('create-connection')\"\n icon=\"general.plus\"\n (onClick)=\"createConnection()\"\n />\n }\n </ng-template>\n </mt-table>\n }\n </section>\n</ng-container>\n" }]
2784
+ args: [{ selector: 'mt-email-delivery-connections', imports: [TranslocoDirective, Button, EmptyState, Table], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <section class=\"space-y-4\" aria-label=\"{{ t('connections-title') }}\">\r\n @if (\r\n !facade.statusLoading() &&\r\n !facade.catalogLoading() &&\r\n facade.providers().length === 0\r\n ) {\r\n <mt-empty-state\r\n illustration=\"none\"\r\n [title]=\"t('no-providers-title')\"\r\n [description]=\"t('no-providers-description')\"\r\n />\r\n } @else {\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"\r\n facade.statusLoading() ||\r\n facade.connectionsLoading() ||\r\n facade.catalogLoading()\r\n \"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [emptyTitle]=\"t('no-connections-title')\"\r\n [emptyDescription]=\"t('no-connections-description')\"\r\n [emptyActionLabel]=\"canCreate() ? t('create-connection') : undefined\"\r\n emptyActionIcon=\"general.plus\"\r\n filterMode=\"column\"\r\n actionShape=\"popover\"\r\n [clickableRows]=\"true\"\r\n dataKey=\"id\"\r\n storageKey=\"email-delivery-connections\"\r\n (emptyAction)=\"createConnection()\"\r\n (rowClick)=\"openDetails($event)\"\r\n >\r\n <ng-template #captionEnd>\r\n @if (canCreate()) {\r\n <mt-button\r\n [label]=\"t('create-connection')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"createConnection()\"\r\n />\r\n }\r\n </ng-template>\r\n </mt-table>\r\n }\r\n </section>\r\n</ng-container>\r\n" }]
2617
2785
  }] });
2618
2786
  const connectionStates = [
2619
2787
  'Draft',
@@ -2747,7 +2915,7 @@ class EmailDeliveryShell {
2747
2915
  return this.transloco.translate(`email-delivery.${key}`);
2748
2916
  }
2749
2917
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryShell, deps: [], target: i0.ɵɵFactoryTarget.Component });
2750
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryShell, isStandalone: true, selector: "mt-email-delivery-shell", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <mt-page\n [title]=\"t('title')\"\n avatarIcon=\"communication.mail-01\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-blue-100)',\n '--p-avatar-color': 'var(--p-blue-700)',\n }\"\n [tabs]=\"canView ? tabs() : []\"\n [activeTab]=\"activeTab()\"\n contentClass=\"min-h-0 max-[1025px]:p-4 max-[640px]:p-3\"\n backButton\n (backButtonClick)=\"goBack()\"\n (tabChange)=\"onTabChange($event)\"\n >\n <!-- Declared unconditionally: a content query cannot reach a template that\n only exists inside a control-flow block, so the condition lives here. -->\n <ng-template #titleEnd>\n @if (canView && readiness(); as state) {\n <span class=\"shrink-0\" [mtTooltip]=\"readinessHint()\">\n <mt-email-delivery-status kind=\"readiness\" [value]=\"state\" />\n </span>\n }\n </ng-template>\n\n @if (canView) {\n <div\n class=\"flex min-h-0 flex-col gap-4 [&_.mt-actions-column]:w-[5rem] [&_mt-card]:rounded-md [&_mt-table_:has(>.p-datatable)]:rounded-md\"\n >\n <mt-breadcrumb\n [items]=\"breadcrumbItems()\"\n styleClass=\"mx-1 flex justify-start\"\n />\n\n @if (activeTab() === \"activity\") {\n <mt-email-delivery-activity />\n } @else {\n <mt-email-delivery-connections />\n }\n </div>\n } @else {\n <mt-empty-state\n illustration=\"none\"\n [title]=\"t('access-denied-title')\"\n [description]=\"t('access-denied-description')\"\n />\n }\n </mt-page>\n</ng-container>\n", 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: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Breadcrumb, selector: "mt-breadcrumb", inputs: ["items", "styleClass"], outputs: ["onItemClick"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "component", type: EmailDeliveryConnections, selector: "mt-email-delivery-connections" }, { kind: "component", type: EmailDeliveryActivity, selector: "mt-email-delivery-activity" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2918
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EmailDeliveryShell, isStandalone: true, selector: "mt-email-delivery-shell", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <mt-page\r\n [title]=\"t('title')\"\r\n avatarIcon=\"communication.mail-01\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-blue-100)',\r\n '--p-avatar-color': 'var(--p-blue-700)',\r\n }\"\r\n [tabs]=\"canView ? tabs() : []\"\r\n [activeTab]=\"activeTab()\"\r\n contentClass=\"min-h-0 max-[1025px]:p-4 max-[640px]:p-3\"\r\n backButton\r\n (backButtonClick)=\"goBack()\"\r\n (tabChange)=\"onTabChange($event)\"\r\n >\r\n <!-- Declared unconditionally: a content query cannot reach a template that\r\n only exists inside a control-flow block, so the condition lives here. -->\r\n <ng-template #titleEnd>\r\n @if (canView && readiness(); as state) {\r\n <span class=\"shrink-0\" [mtTooltip]=\"readinessHint()\">\r\n <mt-email-delivery-status kind=\"readiness\" [value]=\"state\" />\r\n </span>\r\n }\r\n </ng-template>\r\n\r\n @if (canView) {\r\n <div\r\n class=\"flex min-h-0 flex-col gap-4 [&_.mt-actions-column]:w-[5rem] [&_mt-card]:rounded-md [&_mt-table_:has(>.p-datatable)]:rounded-md\"\r\n >\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems()\"\r\n styleClass=\"mx-1 flex justify-start\"\r\n />\r\n\r\n @if (activeTab() === \"activity\") {\r\n <mt-email-delivery-activity />\r\n } @else {\r\n <mt-email-delivery-connections />\r\n }\r\n </div>\r\n } @else {\r\n <mt-empty-state\r\n illustration=\"none\"\r\n [title]=\"t('access-denied-title')\"\r\n [description]=\"t('access-denied-description')\"\r\n />\r\n }\r\n </mt-page>\r\n</ng-container>\r\n", 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: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Breadcrumb, selector: "mt-breadcrumb", inputs: ["items", "styleClass"], outputs: ["onItemClick"] }, { kind: "component", type: EmptyState, selector: "mt-empty-state", inputs: ["variant", "illustration", "title", "description", "actionLabel", "actionIcon"], outputs: ["actionClick"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: EmailDeliveryStatus, selector: "mt-email-delivery-status", inputs: ["value", "kind"] }, { kind: "component", type: EmailDeliveryConnections, selector: "mt-email-delivery-connections" }, { kind: "component", type: EmailDeliveryActivity, selector: "mt-email-delivery-activity" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2751
2919
  }
2752
2920
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EmailDeliveryShell, decorators: [{
2753
2921
  type: Component,
@@ -2760,9 +2928,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2760
2928
  EmailDeliveryStatus,
2761
2929
  EmailDeliveryConnections,
2762
2930
  EmailDeliveryActivity,
2763
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\n <mt-page\n [title]=\"t('title')\"\n avatarIcon=\"communication.mail-01\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-blue-100)',\n '--p-avatar-color': 'var(--p-blue-700)',\n }\"\n [tabs]=\"canView ? tabs() : []\"\n [activeTab]=\"activeTab()\"\n contentClass=\"min-h-0 max-[1025px]:p-4 max-[640px]:p-3\"\n backButton\n (backButtonClick)=\"goBack()\"\n (tabChange)=\"onTabChange($event)\"\n >\n <!-- Declared unconditionally: a content query cannot reach a template that\n only exists inside a control-flow block, so the condition lives here. -->\n <ng-template #titleEnd>\n @if (canView && readiness(); as state) {\n <span class=\"shrink-0\" [mtTooltip]=\"readinessHint()\">\n <mt-email-delivery-status kind=\"readiness\" [value]=\"state\" />\n </span>\n }\n </ng-template>\n\n @if (canView) {\n <div\n class=\"flex min-h-0 flex-col gap-4 [&_.mt-actions-column]:w-[5rem] [&_mt-card]:rounded-md [&_mt-table_:has(>.p-datatable)]:rounded-md\"\n >\n <mt-breadcrumb\n [items]=\"breadcrumbItems()\"\n styleClass=\"mx-1 flex justify-start\"\n />\n\n @if (activeTab() === \"activity\") {\n <mt-email-delivery-activity />\n } @else {\n <mt-email-delivery-connections />\n }\n </div>\n } @else {\n <mt-empty-state\n illustration=\"none\"\n [title]=\"t('access-denied-title')\"\n [description]=\"t('access-denied-description')\"\n />\n }\n </mt-page>\n</ng-container>\n" }]
2931
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'email-delivery'\">\r\n <mt-page\r\n [title]=\"t('title')\"\r\n avatarIcon=\"communication.mail-01\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-blue-100)',\r\n '--p-avatar-color': 'var(--p-blue-700)',\r\n }\"\r\n [tabs]=\"canView ? tabs() : []\"\r\n [activeTab]=\"activeTab()\"\r\n contentClass=\"min-h-0 max-[1025px]:p-4 max-[640px]:p-3\"\r\n backButton\r\n (backButtonClick)=\"goBack()\"\r\n (tabChange)=\"onTabChange($event)\"\r\n >\r\n <!-- Declared unconditionally: a content query cannot reach a template that\r\n only exists inside a control-flow block, so the condition lives here. -->\r\n <ng-template #titleEnd>\r\n @if (canView && readiness(); as state) {\r\n <span class=\"shrink-0\" [mtTooltip]=\"readinessHint()\">\r\n <mt-email-delivery-status kind=\"readiness\" [value]=\"state\" />\r\n </span>\r\n }\r\n </ng-template>\r\n\r\n @if (canView) {\r\n <div\r\n class=\"flex min-h-0 flex-col gap-4 [&_.mt-actions-column]:w-[5rem] [&_mt-card]:rounded-md [&_mt-table_:has(>.p-datatable)]:rounded-md\"\r\n >\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems()\"\r\n styleClass=\"mx-1 flex justify-start\"\r\n />\r\n\r\n @if (activeTab() === \"activity\") {\r\n <mt-email-delivery-activity />\r\n } @else {\r\n <mt-email-delivery-connections />\r\n }\r\n </div>\r\n } @else {\r\n <mt-empty-state\r\n illustration=\"none\"\r\n [title]=\"t('access-denied-title')\"\r\n [description]=\"t('access-denied-description')\"\r\n />\r\n }\r\n </mt-page>\r\n</ng-container>\r\n" }]
2764
2932
  }], ctorParameters: () => [] });
2765
2933
  const PRODUCT_SETTINGS_ROUTE = '/control-panel/product-settings';
2766
2934
 
2767
2935
  export { EmailDeliveryShell };
2768
- //# sourceMappingURL=masterteam-system-settings-email-delivery-shell-Co2SifYp.mjs.map
2936
+ //# sourceMappingURL=masterteam-system-settings-email-delivery-shell-C_AhRF1f.mjs.map