@masterteam/client-components 0.0.81 → 0.0.83

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.
@@ -153,7 +153,7 @@ class EscalationAddDialog {
153
153
  };
154
154
  }
155
155
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EscalationAddDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
156
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EscalationAddDialog, isStandalone: true, selector: "mt-escalation-add-dialog", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, currentUserDisplayName: { classPropertyName: "currentUserDisplayName", publicName: "currentUserDisplayName", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"modal.contentClass + ' p-4 flex flex-col gap-4'\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfig()\"\r\n [formControl]=\"escalationFormControl\"\r\n />\r\n </form>\r\n\r\n @if (submitError(); as errorMessage) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700\"\r\n role=\"alert\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass + ' flex items-center justify-end gap-2'\">\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"isSubmitting()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.escalationUp' | transloco\"\r\n [loading]=\"isSubmitting()\"\r\n [disabled]=\"isSubmitting() || !escalationFormControl.valid\"\r\n (onClick)=\"createEscalation()\"\r\n />\r\n</div>\r\n", dependencies: [{ 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: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues", "serverFieldErrors"], outputs: ["runtimeMessagesChange"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
156
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EscalationAddDialog, isStandalone: true, selector: "mt-escalation-add-dialog", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, currentUserDisplayName: { classPropertyName: "currentUserDisplayName", publicName: "currentUserDisplayName", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"modal.contentClass + ' p-4 flex flex-col gap-4'\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfig()\"\r\n [formControl]=\"escalationFormControl\"\r\n />\r\n </form>\r\n\r\n @if (submitError(); as errorMessage) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700\"\r\n role=\"alert\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass + ' flex items-center justify-end gap-2'\">\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"isSubmitting()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.escalationUp' | transloco\"\r\n [loading]=\"isSubmitting()\"\r\n [disabled]=\"isSubmitting() || !escalationFormControl.valid\"\r\n (onClick)=\"createEscalation()\"\r\n />\r\n</div>\r\n", dependencies: [{ 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: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues"], outputs: ["runtimeMessagesChange"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
157
157
  }
158
158
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EscalationAddDialog, decorators: [{
159
159
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"masterteam-client-components-escalation-runtime.mjs","sources":["../../../../packages/masterteam/client-components/escalation-runtime/escalation-runtime.service.ts","../../../../packages/masterteam/client-components/escalation-runtime/escalation-add-dialog.ts","../../../../packages/masterteam/client-components/escalation-runtime/escalation-add-dialog.html","../../../../packages/masterteam/client-components/escalation-runtime/masterteam-client-components-escalation-runtime.ts"],"sourcesContent":["import { HttpClient } from '@angular/common/http';\r\nimport { Injectable, inject } from '@angular/core';\r\nimport { map } from 'rxjs';\r\nimport {\r\n CreateEscalationPayload,\r\n CreateEscalationResponseData,\r\n EscalationRuntimeContext,\r\n Response,\r\n} from './escalation-runtime.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class EscalationRuntimeService {\r\n private readonly http = inject(HttpClient);\r\n\r\n createEscalation(\r\n context: EscalationRuntimeContext,\r\n payload: CreateEscalationPayload,\r\n ) {\r\n return this.http\r\n .post<\r\n Response<CreateEscalationResponseData>\r\n >(`levels/${context.levelId}/${context.levelDataId}/escalations`, payload)\r\n .pipe(map((response) => response.data));\r\n }\r\n}\r\n","import {\r\n Component,\r\n DestroyRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n signal,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\r\nimport { TranslocoPipe, TranslocoService } from '@jsverse/transloco';\r\nimport {\r\n DateFieldConfig,\r\n DynamicFormConfig,\r\n TextFieldConfig,\r\n TextareaFieldConfig,\r\n UploadFileFieldConfig,\r\n ValidatorConfig,\r\n} from '@masterteam/components';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { ModalRef } from '@masterteam/components/dialog';\r\nimport { ModalService } from '@masterteam/components/modal';\r\nimport { DynamicForm } from '@masterteam/forms/dynamic-form';\r\nimport { finalize } from 'rxjs';\r\nimport { EscalationRuntimeService } from './escalation-runtime.service';\r\nimport {\r\n CreateEscalationPayload,\r\n EscalationCreateResult,\r\n EscalationRuntimeContext,\r\n} from './escalation-runtime.model';\r\n\r\ninterface EscalationAddFormValue {\r\n startDate: Date;\r\n escalatedBy: string;\r\n reason: string;\r\n attachments: EscalationAttachmentValue | null;\r\n}\r\n\r\ninterface EscalationAttachmentValue {\r\n fileName?: string | null;\r\n}\r\n\r\n@Component({\r\n selector: 'mt-escalation-add-dialog',\r\n standalone: true,\r\n imports: [Button, DynamicForm, ReactiveFormsModule, TranslocoPipe],\r\n templateUrl: './escalation-add-dialog.html',\r\n})\r\nexport default class EscalationAddDialog {\r\n readonly modal = inject(ModalService);\r\n readonly ref = inject(ModalRef);\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly escalationRuntimeService = inject(EscalationRuntimeService);\r\n private readonly transloco = inject(TranslocoService);\r\n private readonly startedAt = new Date();\r\n\r\n readonly context = input.required<EscalationRuntimeContext>();\r\n readonly currentUserDisplayName = input(\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.currentUser',\r\n ),\r\n );\r\n readonly escalationFormControl = new FormControl<EscalationAddFormValue>(\r\n {\r\n startDate: this.startedAt,\r\n escalatedBy: '',\r\n reason: '',\r\n attachments: null,\r\n },\r\n { nonNullable: true },\r\n );\r\n\r\n readonly resolvedCurrentUserDisplayName = computed(\r\n () =>\r\n this.currentUserDisplayName().trim() ||\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.currentUser',\r\n ),\r\n );\r\n readonly isSubmitting = signal(false);\r\n readonly submitError = signal<string | null>(null);\r\n readonly dynamicFormConfig = computed<DynamicFormConfig>(() => ({\r\n sections: [\r\n {\r\n key: 'escalation-runtime',\r\n type: 'header',\r\n label: '',\r\n fields: [\r\n new TextFieldConfig({\r\n key: 'escalatedBy',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.escalatedBy',\r\n ),\r\n disabled: true,\r\n colSpan: 12,\r\n order: 1,\r\n }),\r\n new DateFieldConfig({\r\n key: 'startDate',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.startDate',\r\n ),\r\n disabled: true,\r\n showIcon: true,\r\n colSpan: 6,\r\n order: 2,\r\n }),\r\n new TextareaFieldConfig({\r\n key: 'reason',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.reason',\r\n ),\r\n placeholder: this.transloco.translate(\r\n 'components.clientComponents.escalation.reasonPlaceholder',\r\n ),\r\n validators: [ValidatorConfig.required()],\r\n rows: 3,\r\n autoResize: true,\r\n colSpan: 12,\r\n order: 3,\r\n }),\r\n new UploadFileFieldConfig({\r\n key: 'attachments',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.attachments',\r\n ),\r\n title: this.transloco.translate(\r\n 'components.clientComponents.escalation.attachments',\r\n ),\r\n description: this.transloco.translate(\r\n 'components.clientComponents.escalation.uploadHelp',\r\n ),\r\n shape: 'card',\r\n colSpan: 12,\r\n order: 4,\r\n }),\r\n ],\r\n },\r\n ],\r\n }));\r\n\r\n constructor() {\r\n effect(() => {\r\n this.escalationFormControl.setValue(\r\n {\r\n ...this.escalationFormControl.getRawValue(),\r\n startDate: this.startedAt,\r\n escalatedBy: this.resolvedCurrentUserDisplayName(),\r\n },\r\n { emitEvent: false },\r\n );\r\n });\r\n }\r\n\r\n createEscalation(): void {\r\n if (this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.submitError.set(null);\r\n\r\n if (this.escalationFormControl.invalid) {\r\n this.escalationFormControl.markAllAsTouched();\r\n return;\r\n }\r\n\r\n const payload = this.buildPayload();\r\n if (!payload.reason) {\r\n this.submitError.set(\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.reasonRequired',\r\n ),\r\n );\r\n this.escalationFormControl.markAllAsTouched();\r\n return;\r\n }\r\n\r\n this.isSubmitting.set(true);\r\n\r\n this.escalationRuntimeService\r\n .createEscalation(this.context(), payload)\r\n .pipe(\r\n finalize(() => this.isSubmitting.set(false)),\r\n takeUntilDestroyed(this.destroyRef),\r\n )\r\n .subscribe({\r\n next: (response) => {\r\n const result: EscalationCreateResult = {\r\n instanceId: response.instanceId,\r\n moduleDataId: payload.moduleDataId,\r\n };\r\n this.ref.close(result);\r\n },\r\n error: (error) => {\r\n this.submitError.set(\r\n error?.error?.message ??\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.createFailed',\r\n ),\r\n );\r\n },\r\n });\r\n }\r\n\r\n close(): void {\r\n if (this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.ref.close();\r\n }\r\n\r\n private buildPayload(): CreateEscalationPayload {\r\n const formValue = this.escalationFormControl.getRawValue();\r\n\r\n return {\r\n moduleDataId: this.context().moduleDataId,\r\n reason: formValue.reason.trim(),\r\n notes: '',\r\n attachments: formValue.attachments?.fileName\r\n ? [formValue.attachments.fileName]\r\n : [],\r\n };\r\n }\r\n}\r\n","<div [class]=\"modal.contentClass + ' p-4 flex flex-col gap-4'\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfig()\"\r\n [formControl]=\"escalationFormControl\"\r\n />\r\n </form>\r\n\r\n @if (submitError(); as errorMessage) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700\"\r\n role=\"alert\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass + ' flex items-center justify-end gap-2'\">\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"isSubmitting()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.escalationUp' | transloco\"\r\n [loading]=\"isSubmitting()\"\r\n [disabled]=\"isSubmitting() || !escalationFormControl.valid\"\r\n (onClick)=\"createEscalation()\"\r\n />\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;MAaa,wBAAwB,CAAA;AAClB,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IAE1C,gBAAgB,CACd,OAAiC,EACjC,OAAgC,EAAA;QAEhC,OAAO,IAAI,CAAC;AACT,aAAA,IAAI,CAEH,CAAA,OAAA,EAAU,OAAO,CAAC,OAAO,CAAA,CAAA,EAAI,OAAO,CAAC,WAAW,CAAA,YAAA,CAAc,EAAE,OAAO;AACxE,aAAA,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3C;uGAZW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cAFvB,MAAM,EAAA,CAAA;;2FAEP,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAHpC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACqCa,MAAO,mBAAmB,CAAA;AAC7B,IAAA,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;AAC5B,IAAA,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;AACd,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,wBAAwB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAC3D,IAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACpC,IAAA,SAAS,GAAG,IAAI,IAAI,EAAE;AAE9B,IAAA,OAAO,GAAG,KAAK,CAAC,QAAQ,6EAA4B;AACpD,IAAA,sBAAsB,GAAG,KAAK,CACrC,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,oDAAoD,CACrD,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,wBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CACF;IACQ,qBAAqB,GAAG,IAAI,WAAW,CAC9C;QACE,SAAS,EAAE,IAAI,CAAC,SAAS;AACzB,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,MAAM,EAAE,EAAE;AACV,QAAA,WAAW,EAAE,IAAI;AAClB,KAAA,EACD,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB;AAEQ,IAAA,8BAA8B,GAAG,QAAQ,CAChD,MACE,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,EAAE;QACpC,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,oDAAoD,CACrD,qGACJ;AACQ,IAAA,YAAY,GAAG,MAAM,CAAC,KAAK,mFAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAgB,IAAI,kFAAC;AACzC,IAAA,iBAAiB,GAAG,QAAQ,CAAoB,OAAO;AAC9D,QAAA,QAAQ,EAAE;AACR,YAAA;AACE,gBAAA,GAAG,EAAE,oBAAoB;AACzB,gBAAA,IAAI,EAAE,QAAQ;AACd,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,MAAM,EAAE;AACN,oBAAA,IAAI,eAAe,CAAC;AAClB,wBAAA,GAAG,EAAE,aAAa;wBAClB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAC7B,oDAAoD,CACrD;AACD,wBAAA,QAAQ,EAAE,IAAI;AACd,wBAAA,OAAO,EAAE,EAAE;AACX,wBAAA,KAAK,EAAE,CAAC;qBACT,CAAC;AACF,oBAAA,IAAI,eAAe,CAAC;AAClB,wBAAA,GAAG,EAAE,WAAW;wBAChB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAC7B,kDAAkD,CACnD;AACD,wBAAA,QAAQ,EAAE,IAAI;AACd,wBAAA,QAAQ,EAAE,IAAI;AACd,wBAAA,OAAO,EAAE,CAAC;AACV,wBAAA,KAAK,EAAE,CAAC;qBACT,CAAC;AACF,oBAAA,IAAI,mBAAmB,CAAC;AACtB,wBAAA,GAAG,EAAE,QAAQ;wBACb,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAC7B,+CAA+C,CAChD;wBACD,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CACnC,0DAA0D,CAC3D;AACD,wBAAA,UAAU,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;AACxC,wBAAA,IAAI,EAAE,CAAC;AACP,wBAAA,UAAU,EAAE,IAAI;AAChB,wBAAA,OAAO,EAAE,EAAE;AACX,wBAAA,KAAK,EAAE,CAAC;qBACT,CAAC;AACF,oBAAA,IAAI,qBAAqB,CAAC;AACxB,wBAAA,GAAG,EAAE,aAAa;wBAClB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAC7B,oDAAoD,CACrD;wBACD,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAC7B,oDAAoD,CACrD;wBACD,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CACnC,mDAAmD,CACpD;AACD,wBAAA,KAAK,EAAE,MAAM;AACb,wBAAA,OAAO,EAAE,EAAE;AACX,wBAAA,KAAK,EAAE,CAAC;qBACT,CAAC;AACH,iBAAA;AACF,aAAA;AACF,SAAA;AACF,KAAA,CAAC,wFAAC;AAEH,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CACjC;AACE,gBAAA,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE;gBAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;AACzB,gBAAA,WAAW,EAAE,IAAI,CAAC,8BAA8B,EAAE;AACnD,aAAA,EACD,EAAE,SAAS,EAAE,KAAK,EAAE,CACrB;AACH,QAAA,CAAC,CAAC;IACJ;IAEA,gBAAgB,GAAA;AACd,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;YACvB;QACF;AAEA,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAE1B,QAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE;AACtC,YAAA,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,EAAE;YAC7C;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE;AACnC,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;AACnB,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAClB,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,uDAAuD,CACxD,CACF;AACD,YAAA,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,EAAE;YAC7C;QACF;AAEA,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAE3B,QAAA,IAAI,CAAC;AACF,aAAA,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO;aACxC,IAAI,CACH,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAC5C,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AAEpC,aAAA,SAAS,CAAC;AACT,YAAA,IAAI,EAAE,CAAC,QAAQ,KAAI;AACjB,gBAAA,MAAM,MAAM,GAA2B;oBACrC,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,YAAY,EAAE,OAAO,CAAC,YAAY;iBACnC;AACD,gBAAA,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;YACxB,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,KAAK,KAAI;gBACf,IAAI,CAAC,WAAW,CAAC,GAAG,CAClB,KAAK,EAAE,KAAK,EAAE,OAAO;oBACnB,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,qDAAqD,CACtD,CACJ;YACH,CAAC;AACF,SAAA,CAAC;IACN;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;YACvB;QACF;AAEA,QAAA,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE;IAClB;IAEQ,YAAY,GAAA;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE;QAE1D,OAAO;AACL,YAAA,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,YAAY;AACzC,YAAA,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE;AAC/B,YAAA,KAAK,EAAE,EAAE;AACT,YAAA,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE;AAClC,kBAAE,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ;AACjC,kBAAE,EAAE;SACP;IACH;uGA/KmB,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,sBAAA,EAAA,EAAA,iBAAA,EAAA,wBAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjDxC,0gCAiCA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDaY,MAAM,yWAAE,WAAW,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,gBAAA,EAAA,mBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,aAAa,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,CAAA;;2FAG9C,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBANvC,SAAS;+BACE,0BAA0B,EAAA,UAAA,EACxB,IAAI,EAAA,OAAA,EACP,CAAC,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAA,QAAA,EAAA,0gCAAA,EAAA;;;AE9CpE;;AAEG;;;;"}
1
+ {"version":3,"file":"masterteam-client-components-escalation-runtime.mjs","sources":["../../../../packages/masterteam/client-components/escalation-runtime/escalation-runtime.service.ts","../../../../packages/masterteam/client-components/escalation-runtime/escalation-add-dialog.ts","../../../../packages/masterteam/client-components/escalation-runtime/escalation-add-dialog.html","../../../../packages/masterteam/client-components/escalation-runtime/masterteam-client-components-escalation-runtime.ts"],"sourcesContent":["import { HttpClient } from '@angular/common/http';\r\nimport { Injectable, inject } from '@angular/core';\r\nimport { map } from 'rxjs';\r\nimport {\r\n CreateEscalationPayload,\r\n CreateEscalationResponseData,\r\n EscalationRuntimeContext,\r\n Response,\r\n} from './escalation-runtime.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class EscalationRuntimeService {\r\n private readonly http = inject(HttpClient);\r\n\r\n createEscalation(\r\n context: EscalationRuntimeContext,\r\n payload: CreateEscalationPayload,\r\n ) {\r\n return this.http\r\n .post<\r\n Response<CreateEscalationResponseData>\r\n >(`levels/${context.levelId}/${context.levelDataId}/escalations`, payload)\r\n .pipe(map((response) => response.data));\r\n }\r\n}\r\n","import {\r\n Component,\r\n DestroyRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n signal,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\r\nimport { TranslocoPipe, TranslocoService } from '@jsverse/transloco';\r\nimport {\r\n DateFieldConfig,\r\n DynamicFormConfig,\r\n TextFieldConfig,\r\n TextareaFieldConfig,\r\n UploadFileFieldConfig,\r\n ValidatorConfig,\r\n} from '@masterteam/components';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { ModalRef } from '@masterteam/components/dialog';\r\nimport { ModalService } from '@masterteam/components/modal';\r\nimport { DynamicForm } from '@masterteam/forms/dynamic-form';\r\nimport { finalize } from 'rxjs';\r\nimport { EscalationRuntimeService } from './escalation-runtime.service';\r\nimport {\r\n CreateEscalationPayload,\r\n EscalationCreateResult,\r\n EscalationRuntimeContext,\r\n} from './escalation-runtime.model';\r\n\r\ninterface EscalationAddFormValue {\r\n startDate: Date;\r\n escalatedBy: string;\r\n reason: string;\r\n attachments: EscalationAttachmentValue | null;\r\n}\r\n\r\ninterface EscalationAttachmentValue {\r\n fileName?: string | null;\r\n}\r\n\r\n@Component({\r\n selector: 'mt-escalation-add-dialog',\r\n standalone: true,\r\n imports: [Button, DynamicForm, ReactiveFormsModule, TranslocoPipe],\r\n templateUrl: './escalation-add-dialog.html',\r\n})\r\nexport default class EscalationAddDialog {\r\n readonly modal = inject(ModalService);\r\n readonly ref = inject(ModalRef);\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly escalationRuntimeService = inject(EscalationRuntimeService);\r\n private readonly transloco = inject(TranslocoService);\r\n private readonly startedAt = new Date();\r\n\r\n readonly context = input.required<EscalationRuntimeContext>();\r\n readonly currentUserDisplayName = input(\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.currentUser',\r\n ),\r\n );\r\n readonly escalationFormControl = new FormControl<EscalationAddFormValue>(\r\n {\r\n startDate: this.startedAt,\r\n escalatedBy: '',\r\n reason: '',\r\n attachments: null,\r\n },\r\n { nonNullable: true },\r\n );\r\n\r\n readonly resolvedCurrentUserDisplayName = computed(\r\n () =>\r\n this.currentUserDisplayName().trim() ||\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.currentUser',\r\n ),\r\n );\r\n readonly isSubmitting = signal(false);\r\n readonly submitError = signal<string | null>(null);\r\n readonly dynamicFormConfig = computed<DynamicFormConfig>(() => ({\r\n sections: [\r\n {\r\n key: 'escalation-runtime',\r\n type: 'header',\r\n label: '',\r\n fields: [\r\n new TextFieldConfig({\r\n key: 'escalatedBy',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.escalatedBy',\r\n ),\r\n disabled: true,\r\n colSpan: 12,\r\n order: 1,\r\n }),\r\n new DateFieldConfig({\r\n key: 'startDate',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.startDate',\r\n ),\r\n disabled: true,\r\n showIcon: true,\r\n colSpan: 6,\r\n order: 2,\r\n }),\r\n new TextareaFieldConfig({\r\n key: 'reason',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.reason',\r\n ),\r\n placeholder: this.transloco.translate(\r\n 'components.clientComponents.escalation.reasonPlaceholder',\r\n ),\r\n validators: [ValidatorConfig.required()],\r\n rows: 3,\r\n autoResize: true,\r\n colSpan: 12,\r\n order: 3,\r\n }),\r\n new UploadFileFieldConfig({\r\n key: 'attachments',\r\n label: this.transloco.translate(\r\n 'components.clientComponents.escalation.attachments',\r\n ),\r\n title: this.transloco.translate(\r\n 'components.clientComponents.escalation.attachments',\r\n ),\r\n description: this.transloco.translate(\r\n 'components.clientComponents.escalation.uploadHelp',\r\n ),\r\n shape: 'card',\r\n colSpan: 12,\r\n order: 4,\r\n }),\r\n ],\r\n },\r\n ],\r\n }));\r\n\r\n constructor() {\r\n effect(() => {\r\n this.escalationFormControl.setValue(\r\n {\r\n ...this.escalationFormControl.getRawValue(),\r\n startDate: this.startedAt,\r\n escalatedBy: this.resolvedCurrentUserDisplayName(),\r\n },\r\n { emitEvent: false },\r\n );\r\n });\r\n }\r\n\r\n createEscalation(): void {\r\n if (this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.submitError.set(null);\r\n\r\n if (this.escalationFormControl.invalid) {\r\n this.escalationFormControl.markAllAsTouched();\r\n return;\r\n }\r\n\r\n const payload = this.buildPayload();\r\n if (!payload.reason) {\r\n this.submitError.set(\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.reasonRequired',\r\n ),\r\n );\r\n this.escalationFormControl.markAllAsTouched();\r\n return;\r\n }\r\n\r\n this.isSubmitting.set(true);\r\n\r\n this.escalationRuntimeService\r\n .createEscalation(this.context(), payload)\r\n .pipe(\r\n finalize(() => this.isSubmitting.set(false)),\r\n takeUntilDestroyed(this.destroyRef),\r\n )\r\n .subscribe({\r\n next: (response) => {\r\n const result: EscalationCreateResult = {\r\n instanceId: response.instanceId,\r\n moduleDataId: payload.moduleDataId,\r\n };\r\n this.ref.close(result);\r\n },\r\n error: (error) => {\r\n this.submitError.set(\r\n error?.error?.message ??\r\n this.transloco.translate(\r\n 'components.clientComponents.escalation.createFailed',\r\n ),\r\n );\r\n },\r\n });\r\n }\r\n\r\n close(): void {\r\n if (this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.ref.close();\r\n }\r\n\r\n private buildPayload(): CreateEscalationPayload {\r\n const formValue = this.escalationFormControl.getRawValue();\r\n\r\n return {\r\n moduleDataId: this.context().moduleDataId,\r\n reason: formValue.reason.trim(),\r\n notes: '',\r\n attachments: formValue.attachments?.fileName\r\n ? [formValue.attachments.fileName]\r\n : [],\r\n };\r\n }\r\n}\r\n","<div [class]=\"modal.contentClass + ' p-4 flex flex-col gap-4'\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfig()\"\r\n [formControl]=\"escalationFormControl\"\r\n />\r\n </form>\r\n\r\n @if (submitError(); as errorMessage) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700\"\r\n role=\"alert\"\r\n >\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass + ' flex items-center justify-end gap-2'\">\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.cancel' | transloco\"\r\n variant=\"outlined\"\r\n [disabled]=\"isSubmitting()\"\r\n (onClick)=\"close()\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"'components.clientComponents.escalation.escalationUp' | transloco\"\r\n [loading]=\"isSubmitting()\"\r\n [disabled]=\"isSubmitting() || !escalationFormControl.valid\"\r\n (onClick)=\"createEscalation()\"\r\n />\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masterteam/client-components",
3
- "version": "0.0.81",
3
+ "version": "0.0.83",
4
4
  "publishConfig": {
5
5
  "directory": "../../../dist/masterteam/client-components",
6
6
  "linkDirectory": true,
@@ -16,10 +16,10 @@
16
16
  "rxjs": "^7.8.2",
17
17
  "tailwindcss": "^4.2.2",
18
18
  "tailwindcss-primeui": "^0.6.1",
19
- "@masterteam/forms": "^0.0.137",
20
- "@masterteam/components": "^0.0.268",
21
19
  "@masterteam/icons": "^0.0.17",
22
- "@masterteam/dashboard-builder": "^0.0.73"
20
+ "@masterteam/components": "^0.0.272",
21
+ "@masterteam/dashboard-builder": "^0.0.80",
22
+ "@masterteam/forms": "^0.0.136"
23
23
  },
24
24
  "dependencies": {
25
25
  "tslib": "^2.8.1"
@@ -7,6 +7,18 @@ import { DashboardBuilderData } from '@masterteam/dashboard-builder';
7
7
  import { RuntimeAction } from '@masterteam/components/runtime-action';
8
8
  import { Observable } from 'rxjs';
9
9
 
10
+ /**
11
+ * How a client list arranges MORE THAN ONE list. Ignored for a single list,
12
+ * which always renders on its own with no rail and no chrome around it.
13
+ *
14
+ * - `navigator` (default): a module rail beside the content, one list
15
+ * rendered at a time — the master/detail shape. Only the selected list is
16
+ * in the DOM, so a seven-module tab mounts one table instead of seven.
17
+ * - `stacked`: every list rendered one under the other, collapsible — the
18
+ * pre-navigator layout, kept for hosts that genuinely want all lists on
19
+ * screen at once (e.g. a printable summary).
20
+ */
21
+ type ClientListMultiLayout = 'navigator' | 'stacked';
10
22
  type ClientListMode = 'auto' | 'override';
11
23
  type ClientListAreaType = 'table' | 'cards';
12
24
  type ClientListType = 'form' | 'informative';
@@ -187,6 +199,23 @@ interface ClientListInformativeConfiguration extends ClientListBaseConfiguration
187
199
  areaType?: 'table';
188
200
  }
189
201
  type ClientListConfiguration = ClientListFormConfiguration | ClientListInformativeConfiguration;
202
+ /**
203
+ * One row in the navigator rail. Derived from a {@link ClientListState}; it
204
+ * carries only what the rail draws so the rail never has to reason about
205
+ * projections, paging or runtime actions.
206
+ */
207
+ interface ClientListNavigatorEntry {
208
+ key: string;
209
+ label: string;
210
+ /**
211
+ * Records behind this list, or `null` when the list has no meaningful
212
+ * count (informative dashboards) or has not resolved one yet. `null` draws
213
+ * a neutral placeholder rather than a misleading `0`.
214
+ */
215
+ count: number | null;
216
+ loading: boolean;
217
+ hasError: boolean;
218
+ }
190
219
  interface ClientListCollapseConfig {
191
220
  enabled?: boolean;
192
221
  expandedByDefault?: boolean;
@@ -514,20 +543,83 @@ declare class ClientList implements OnDestroy {
514
543
  private readonly runtimeActions;
515
544
  private readonly runtimeRunner;
516
545
  private readonly transloco;
546
+ private readonly host;
517
547
  readonly configurations: _angular_core.InputSignal<ClientListConfiguration[]>;
518
548
  readonly defaultTake: _angular_core.InputSignal<number>;
549
+ /**
550
+ * Arrangement for MORE THAN ONE configuration — see
551
+ * {@link ClientListMultiLayout}. A single configuration ignores it and
552
+ * renders exactly as it always has.
553
+ */
554
+ readonly multiLayout: _angular_core.InputSignal<ClientListMultiLayout>;
519
555
  readonly loaded: _angular_core.OutputEmitterRef<string>;
520
556
  readonly errored: _angular_core.OutputEmitterRef<{
521
557
  key: string;
522
558
  message: string;
523
559
  }>;
524
560
  readonly itemClicked: _angular_core.OutputEmitterRef<ClientListItemClickedEvent>;
561
+ /** The list the navigator switched to. Never fires in `stacked`. */
562
+ readonly activeListChanged: _angular_core.OutputEmitterRef<string>;
525
563
  protected readonly items: _angular_core.Signal<ClientListState[]>;
564
+ /** Ties each rail tab to the pane it controls, for screen readers. */
565
+ protected readonly panelId: string;
566
+ private readonly activeKeyOverride;
567
+ private readonly railLayout;
568
+ private resizeObserver;
569
+ protected readonly useNavigator: _angular_core.Signal<boolean>;
570
+ protected readonly isRailLayout: _angular_core.Signal<boolean>;
571
+ /**
572
+ * The selected list. Falls back to the first one whenever the override is
573
+ * unset or points at a list the host has since removed — so a config change
574
+ * can never leave the pane blank.
575
+ */
576
+ protected readonly activeKey: _angular_core.Signal<string | null>;
577
+ /**
578
+ * Identity of the current SET of lists. A string so it settles: every load
579
+ * tick rebuilds the items array, but the signature only changes when the
580
+ * host adds, removes or re-keys a list.
581
+ */
582
+ private readonly groupSignature;
583
+ protected readonly activeItem: _angular_core.Signal<ClientListState | null>;
584
+ protected readonly navigatorEntries: _angular_core.Signal<ClientListNavigatorEntry[]>;
526
585
  private readonly subscriptions;
527
586
  private readonly inFlightRequestSignatures;
528
587
  private readonly fulfilledRequestSignatures;
529
588
  private readonly runtimeFilters;
530
589
  constructor();
590
+ /**
591
+ * Switches the pane. Remembered per list group, so coming back to a
592
+ * workspace tab lands on the module you were last reading rather than
593
+ * resetting to the first one.
594
+ */
595
+ setActiveKey(key: string): void;
596
+ /**
597
+ * Subtitle under the pane title: the load failure if there is one, the
598
+ * record count once it is known, nothing while the first page is still in
599
+ * flight (a "0 records" that flips to "12 records" reads as a bug).
600
+ */
601
+ protected paneMeta(item: ClientListState): string;
602
+ /**
603
+ * Both layouts render a list body through one `ng-template`, whose context
604
+ * is untyped. Re-narrowing here keeps strict template checking on every
605
+ * binding inside it instead of silently degrading them to `any`.
606
+ */
607
+ protected asItem(value: unknown): ClientListState;
608
+ /**
609
+ * Rail beside the content, or chip strip above it. Measured from the host
610
+ * rather than the viewport: this component renders inside an app shell, so
611
+ * viewport width says nothing about the room it actually has.
612
+ */
613
+ private observeHostWidth;
614
+ private restoreActiveKey;
615
+ /**
616
+ * Identifies this exact set of lists, so the remembered selection follows
617
+ * the workspace tab it belongs to and a different tab starts fresh. Hashed
618
+ * because the keys themselves carry ids and filters and get long.
619
+ */
620
+ private groupStorageKey;
621
+ private readStoredActiveKey;
622
+ private persistActiveKey;
531
623
  onLazyLoad(itemKey: string, event: ClientListLazyLoadEvent): void;
532
624
  /**
533
625
  * Fetches the next page of cards and appends it to the currently loaded
@@ -616,7 +708,7 @@ declare class ClientList implements OnDestroy {
616
708
  private serializeFilters;
617
709
  private resolveFetchFilters;
618
710
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ClientList, never>;
619
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ClientList, "mt-client-list", never, { "configurations": { "alias": "configurations"; "required": true; "isSignal": true; }; "defaultTake": { "alias": "defaultTake"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "errored": "errored"; "itemClicked": "itemClicked"; }, never, never, true, never>;
711
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ClientList, "mt-client-list", never, { "configurations": { "alias": "configurations"; "required": true; "isSignal": true; }; "defaultTake": { "alias": "defaultTake"; "required": false; "isSignal": true; }; "multiLayout": { "alias": "multiLayout"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "errored": "errored"; "itemClicked": "itemClicked"; "activeListChanged": "activeListChanged"; }, never, never, true, never>;
620
712
  }
621
713
 
622
714
  declare class ClientListApiService {
@@ -699,4 +791,4 @@ declare class ClientListToolbarService {
699
791
  }
700
792
 
701
793
  export { CLIENT_LIST_RECORD_STATE_KEY, ClientList, ClientListApiService, ClientListRuntimeActionsService, ClientListStateService, ClientListToolbarService, defaultResolveRecordId };
702
- export type { ClientListAreaType, ClientListBaseConfiguration, ClientListBaseState, ClientListCard, ClientListCardModule, ClientListCardProperty, ClientListCardsPayload, ClientListCardsState, ClientListClickableItem, ClientListCollapseConfig, ClientListConfiguration, ClientListContentTemplateContext, ClientListDataLoadedHandler, ClientListFetchCardDisplayOrderItem, ClientListFetchCardGroup, ClientListFetchCatalog, ClientListFetchProjection, ClientListFetchProjectionMeta, ClientListFetchPropertyMeta, ClientListFetchQueryRequest, ClientListFetchQueryResponse, ClientListFetchRecord, ClientListFetchRecordState, ClientListFetchRequestDisplay, ClientListFetchRequestFilter, ClientListFetchSchema, ClientListFetchStateKey, ClientListFetchTableColumn, ClientListFetchValueCell, ClientListFormConfiguration, ClientListInformativeChartLink, ClientListInformativeConfiguration, ClientListInformativeDashboardPayload, ClientListInformativeState, ClientListItemClickedEvent, ClientListLayoutConfig, ClientListLazyLoadEvent, ClientListMode, ClientListRecordEscalationState, ClientListRuntimeContext, ClientListRuntimeRecordActionsConfig, ClientListRuntimeRecordActionsContext, ClientListState, ClientListTableDisplayConfig, ClientListTablePersistStateKey, ClientListTableQuery, ClientListTableSettingsCatalogResponse, ClientListTableSettingsColumn, ClientListTableState, ClientListTableTransform, ClientListTableTransformResult, ClientListToolbarBucket, ClientListType, NormalizedClientListConfiguration, NormalizedClientListTableDisplayConfig, Response, RuntimeEntityColumnDef, RuntimeTableDisplayRow, RuntimeTableRowsResponse };
794
+ export type { ClientListAreaType, ClientListBaseConfiguration, ClientListBaseState, ClientListCard, ClientListCardModule, ClientListCardProperty, ClientListCardsPayload, ClientListCardsState, ClientListClickableItem, ClientListCollapseConfig, ClientListConfiguration, ClientListContentTemplateContext, ClientListDataLoadedHandler, ClientListFetchCardDisplayOrderItem, ClientListFetchCardGroup, ClientListFetchCatalog, ClientListFetchProjection, ClientListFetchProjectionMeta, ClientListFetchPropertyMeta, ClientListFetchQueryRequest, ClientListFetchQueryResponse, ClientListFetchRecord, ClientListFetchRecordState, ClientListFetchRequestDisplay, ClientListFetchRequestFilter, ClientListFetchSchema, ClientListFetchStateKey, ClientListFetchTableColumn, ClientListFetchValueCell, ClientListFormConfiguration, ClientListInformativeChartLink, ClientListInformativeConfiguration, ClientListInformativeDashboardPayload, ClientListInformativeState, ClientListItemClickedEvent, ClientListLayoutConfig, ClientListLazyLoadEvent, ClientListMode, ClientListMultiLayout, ClientListNavigatorEntry, ClientListRecordEscalationState, ClientListRuntimeContext, ClientListRuntimeRecordActionsConfig, ClientListRuntimeRecordActionsContext, ClientListState, ClientListTableDisplayConfig, ClientListTablePersistStateKey, ClientListTableQuery, ClientListTableSettingsCatalogResponse, ClientListTableSettingsColumn, ClientListTableState, ClientListTableTransform, ClientListTableTransformResult, ClientListToolbarBucket, ClientListType, NormalizedClientListConfiguration, NormalizedClientListTableDisplayConfig, Response, RuntimeEntityColumnDef, RuntimeTableDisplayRow, RuntimeTableRowsResponse };