@eherve/angular-material-display-dialog 0.0.0-stage → 22.0.0

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.
@@ -0,0 +1,1153 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DOCUMENT, ElementRef, ErrorHandler, EventEmitter, Inject, Injectable, InjectionToken, Input, NgModule, Optional, inject, reflectComponentType } from "@angular/core";
3
+ import * as i1 from "@angular/material/dialog";
4
+ import { MAT_DIALOG_DATA, MatDialog, MatDialogModule } from "@angular/material/dialog";
5
+ import { Subject, firstValueFrom, isObservable, takeUntil } from "rxjs";
6
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
7
+ import * as i2$1 from "@angular/material/button";
8
+ import { MatButtonModule } from "@angular/material/button";
9
+ import * as i2 from "@angular/common";
10
+ import { CommonModule, JsonPipe } from "@angular/common";
11
+ import * as i4 from "@angular/material/icon";
12
+ import { MatIconModule } from "@angular/material/icon";
13
+ import * as i5 from "@angular/material/tabs";
14
+ import { MatTabsModule } from "@angular/material/tabs";
15
+ import * as i6 from "@angular/material/tooltip";
16
+ import { MatTooltipModule } from "@angular/material/tooltip";
17
+ import * as i7 from "@eherve/angular-material-section-tabs";
18
+ import { SectionTabsModule } from "@eherve/angular-material-section-tabs";
19
+ import * as i8 from "@angular/material/progress-spinner";
20
+ import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
21
+ var DisplayDialogIntl = class DisplayDialogIntl {
22
+ changes = new Subject();
23
+ messages = {
24
+ loadingLabel: "Chargement des données",
25
+ closeLabel: "Fermer",
26
+ emptyLabel: "Aucune donnée à afficher.",
27
+ errorLabel: "Impossible de charger les données.",
28
+ actionErrorLabel: "Impossible d’exécuter cette action.",
29
+ jsonTitle: "Données JSON",
30
+ jsonButtonLabel: "Afficher les données JSON",
31
+ recordLabel: "Record",
32
+ confirmTitle: "Confirmation",
33
+ confirmOk: "Oui",
34
+ confirmCancel: "Non",
35
+ emptyContentLabel: "Aucun contenu à afficher."
36
+ };
37
+ static ɵfac = i0.ɵɵngDeclareFactory({
38
+ minVersion: "12.0.0",
39
+ version: "22.2.1",
40
+ ngImport: i0,
41
+ type: DisplayDialogIntl,
42
+ deps: [],
43
+ target: i0.ɵɵFactoryTarget.Injectable
44
+ });
45
+ static ɵprov = i0.ɵɵngDeclareInjectable({
46
+ minVersion: "12.0.0",
47
+ version: "22.2.1",
48
+ ngImport: i0,
49
+ type: DisplayDialogIntl,
50
+ providedIn: "root"
51
+ });
52
+ };
53
+ i0.ɵɵngDeclareClassMetadata({
54
+ minVersion: "12.0.0",
55
+ version: "22.2.1",
56
+ ngImport: i0,
57
+ type: DisplayDialogIntl,
58
+ decorators: [{
59
+ type: Injectable,
60
+ args: [{ providedIn: "root" }]
61
+ }]
62
+ });
63
+ var DisplayConfirmationDialog = class DisplayConfirmationDialog {
64
+ data = inject(MAT_DIALOG_DATA);
65
+ intl = inject(DisplayDialogIntl);
66
+ constructor() {
67
+ const changeDetectorRef = inject(ChangeDetectorRef);
68
+ this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => changeDetectorRef.markForCheck());
69
+ }
70
+ static ɵfac = i0.ɵɵngDeclareFactory({
71
+ minVersion: "12.0.0",
72
+ version: "22.2.1",
73
+ ngImport: i0,
74
+ type: DisplayConfirmationDialog,
75
+ deps: [],
76
+ target: i0.ɵɵFactoryTarget.Component
77
+ });
78
+ static ɵcmp = i0.ɵɵngDeclareComponent({
79
+ minVersion: "14.0.0",
80
+ version: "22.2.1",
81
+ type: DisplayConfirmationDialog,
82
+ isStandalone: true,
83
+ selector: "ngx-mat-display-confirmation",
84
+ ngImport: i0,
85
+ template: `
86
+ <h2 mat-dialog-title>{{data.title ?? intl.messages.confirmTitle}}</h2>
87
+ <mat-dialog-content>{{data.message}}</mat-dialog-content>
88
+ <mat-dialog-actions align="end">
89
+ <button mat-button [mat-dialog-close]="false">{{data.cancel ?? intl.messages.confirmCancel}}</button>
90
+ <button mat-button [mat-dialog-close]="true">{{data.ok ?? intl.messages.confirmOk}}</button>
91
+ </mat-dialog-actions>`,
92
+ isInline: true,
93
+ dependencies: [
94
+ {
95
+ kind: "ngmodule",
96
+ type: MatDialogModule
97
+ },
98
+ {
99
+ kind: "directive",
100
+ type: i1.MatDialogClose,
101
+ selector: "[mat-dialog-close], [matDialogClose]",
102
+ inputs: [
103
+ "aria-label",
104
+ "type",
105
+ "mat-dialog-close",
106
+ "matDialogClose"
107
+ ],
108
+ exportAs: ["matDialogClose"]
109
+ },
110
+ {
111
+ kind: "directive",
112
+ type: i1.MatDialogTitle,
113
+ selector: "[mat-dialog-title], [matDialogTitle]",
114
+ inputs: ["id"],
115
+ exportAs: ["matDialogTitle"]
116
+ },
117
+ {
118
+ kind: "directive",
119
+ type: i1.MatDialogActions,
120
+ selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]",
121
+ inputs: ["align"]
122
+ },
123
+ {
124
+ kind: "directive",
125
+ type: i1.MatDialogContent,
126
+ selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]"
127
+ },
128
+ {
129
+ kind: "ngmodule",
130
+ type: MatButtonModule
131
+ },
132
+ {
133
+ kind: "component",
134
+ type: i2$1.MatButton,
135
+ selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ",
136
+ inputs: ["matButton"],
137
+ exportAs: ["matButton", "matAnchor"]
138
+ }
139
+ ],
140
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
141
+ });
142
+ };
143
+ i0.ɵɵngDeclareClassMetadata({
144
+ minVersion: "12.0.0",
145
+ version: "22.2.1",
146
+ ngImport: i0,
147
+ type: DisplayConfirmationDialog,
148
+ decorators: [{
149
+ type: Component,
150
+ args: [{
151
+ selector: "ngx-mat-display-confirmation",
152
+ imports: [MatDialogModule, MatButtonModule],
153
+ changeDetection: ChangeDetectionStrategy.OnPush,
154
+ template: `
155
+ <h2 mat-dialog-title>{{data.title ?? intl.messages.confirmTitle}}</h2>
156
+ <mat-dialog-content>{{data.message}}</mat-dialog-content>
157
+ <mat-dialog-actions align="end">
158
+ <button mat-button [mat-dialog-close]="false">{{data.cancel ?? intl.messages.confirmCancel}}</button>
159
+ <button mat-button [mat-dialog-close]="true">{{data.ok ?? intl.messages.confirmOk}}</button>
160
+ </mat-dialog-actions>`
161
+ }]
162
+ }],
163
+ ctorParameters: () => []
164
+ });
165
+ var DisplayJsonDialog = class DisplayJsonDialog {
166
+ data = inject(MAT_DIALOG_DATA);
167
+ intl = inject(DisplayDialogIntl);
168
+ constructor() {
169
+ const changeDetectorRef = inject(ChangeDetectorRef);
170
+ this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => changeDetectorRef.markForCheck());
171
+ }
172
+ static ɵfac = i0.ɵɵngDeclareFactory({
173
+ minVersion: "12.0.0",
174
+ version: "22.2.1",
175
+ ngImport: i0,
176
+ type: DisplayJsonDialog,
177
+ deps: [],
178
+ target: i0.ɵɵFactoryTarget.Component
179
+ });
180
+ static ɵcmp = i0.ɵɵngDeclareComponent({
181
+ minVersion: "17.0.0",
182
+ version: "22.2.1",
183
+ type: DisplayJsonDialog,
184
+ isStandalone: true,
185
+ selector: "ngx-mat-display-json",
186
+ ngImport: i0,
187
+ template: `
188
+ <h2 mat-dialog-title>{{data.title}}</h2>
189
+ <mat-dialog-content>
190
+ @for (source of data.sources; track $index) {
191
+ <h3>{{source.label}}</h3><pre>{{source.value | json}}</pre>
192
+ }
193
+ </mat-dialog-content>
194
+ <mat-dialog-actions><button mat-button mat-dialog-close>{{intl.messages.closeLabel}}</button></mat-dialog-actions>`,
195
+ isInline: true,
196
+ styles: ["pre{white-space:pre-wrap;overflow-wrap:anywhere}\n"],
197
+ dependencies: [
198
+ {
199
+ kind: "ngmodule",
200
+ type: MatDialogModule
201
+ },
202
+ {
203
+ kind: "directive",
204
+ type: i1.MatDialogClose,
205
+ selector: "[mat-dialog-close], [matDialogClose]",
206
+ inputs: [
207
+ "aria-label",
208
+ "type",
209
+ "mat-dialog-close",
210
+ "matDialogClose"
211
+ ],
212
+ exportAs: ["matDialogClose"]
213
+ },
214
+ {
215
+ kind: "directive",
216
+ type: i1.MatDialogTitle,
217
+ selector: "[mat-dialog-title], [matDialogTitle]",
218
+ inputs: ["id"],
219
+ exportAs: ["matDialogTitle"]
220
+ },
221
+ {
222
+ kind: "directive",
223
+ type: i1.MatDialogActions,
224
+ selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]",
225
+ inputs: ["align"]
226
+ },
227
+ {
228
+ kind: "directive",
229
+ type: i1.MatDialogContent,
230
+ selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]"
231
+ },
232
+ {
233
+ kind: "ngmodule",
234
+ type: MatButtonModule
235
+ },
236
+ {
237
+ kind: "component",
238
+ type: i2$1.MatButton,
239
+ selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ",
240
+ inputs: ["matButton"],
241
+ exportAs: ["matButton", "matAnchor"]
242
+ },
243
+ {
244
+ kind: "pipe",
245
+ type: JsonPipe,
246
+ name: "json"
247
+ }
248
+ ],
249
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
250
+ });
251
+ };
252
+ i0.ɵɵngDeclareClassMetadata({
253
+ minVersion: "12.0.0",
254
+ version: "22.2.1",
255
+ ngImport: i0,
256
+ type: DisplayJsonDialog,
257
+ decorators: [{
258
+ type: Component,
259
+ args: [{
260
+ selector: "ngx-mat-display-json",
261
+ imports: [
262
+ MatDialogModule,
263
+ MatButtonModule,
264
+ JsonPipe
265
+ ],
266
+ changeDetection: ChangeDetectionStrategy.OnPush,
267
+ template: `
268
+ <h2 mat-dialog-title>{{data.title}}</h2>
269
+ <mat-dialog-content>
270
+ @for (source of data.sources; track $index) {
271
+ <h3>{{source.label}}</h3><pre>{{source.value | json}}</pre>
272
+ }
273
+ </mat-dialog-content>
274
+ <mat-dialog-actions><button mat-button mat-dialog-close>{{intl.messages.closeLabel}}</button></mat-dialog-actions>`,
275
+ styles: ["pre{white-space:pre-wrap;overflow-wrap:anywhere}\n"]
276
+ }]
277
+ }],
278
+ ctorParameters: () => []
279
+ });
280
+ var DefaultDisplayDialogHost = class DefaultDisplayDialogHost {
281
+ dialog = inject(MatDialog);
282
+ async confirm(options) {
283
+ return await firstValueFrom(this.dialog.open(DisplayConfirmationDialog, { data: options }).afterClosed()) === true;
284
+ }
285
+ showJson(title, sources) {
286
+ this.dialog.open(DisplayJsonDialog, {
287
+ width: "80vw",
288
+ maxHeight: "90vh",
289
+ data: {
290
+ title,
291
+ sources
292
+ }
293
+ });
294
+ }
295
+ static ɵfac = i0.ɵɵngDeclareFactory({
296
+ minVersion: "12.0.0",
297
+ version: "22.2.1",
298
+ ngImport: i0,
299
+ type: DefaultDisplayDialogHost,
300
+ deps: [],
301
+ target: i0.ɵɵFactoryTarget.Injectable
302
+ });
303
+ static ɵprov = i0.ɵɵngDeclareInjectable({
304
+ minVersion: "12.0.0",
305
+ version: "22.2.1",
306
+ ngImport: i0,
307
+ type: DefaultDisplayDialogHost,
308
+ providedIn: "root"
309
+ });
310
+ };
311
+ i0.ɵɵngDeclareClassMetadata({
312
+ minVersion: "12.0.0",
313
+ version: "22.2.1",
314
+ ngImport: i0,
315
+ type: DefaultDisplayDialogHost,
316
+ decorators: [{
317
+ type: Injectable,
318
+ args: [{ providedIn: "root" }]
319
+ }]
320
+ });
321
+ const DISPLAY_DIALOG_HOST = new InjectionToken("DISPLAY_DIALOG_HOST", {
322
+ providedIn: "root",
323
+ factory: () => inject(DefaultDisplayDialogHost)
324
+ });
325
+ var DisplayDialog = class DisplayDialog {
326
+ dialogData;
327
+ dialogRef;
328
+ intl = inject(DisplayDialogIntl);
329
+ data;
330
+ loading = true;
331
+ loadingLabel = this.intl.messages.loadingLabel;
332
+ errorLabel = "";
333
+ title = "";
334
+ subtitle = "";
335
+ closeLabel = this.intl.messages.closeLabel;
336
+ showCloseButton = false;
337
+ handlingAction = false;
338
+ actions = [];
339
+ actionErrorLabel = "";
340
+ renderState = { kind: "empty" };
341
+ recordChange = new EventEmitter();
342
+ isDialog;
343
+ changeDetectorRef = inject(ChangeDetectorRef);
344
+ elementRef = inject(ElementRef);
345
+ componentInputNamesByType = /* @__PURE__ */ new WeakMap();
346
+ initializeVersion = 0;
347
+ destroyed = false;
348
+ recordErrorKind;
349
+ actionFailed = false;
350
+ connection;
351
+ cancelLoad = new Subject();
352
+ dialogDataResolved;
353
+ record;
354
+ host = inject(DISPLAY_DIALOG_HOST);
355
+ errorHandler = inject(ErrorHandler);
356
+ intlSubscription = this.intl.changes.subscribe(() => this.refreshIntlLabels());
357
+ constructor(dialogData, dialogRef) {
358
+ this.dialogData = dialogData;
359
+ this.dialogRef = dialogRef;
360
+ this.isDialog = this.dialogRef !== null;
361
+ }
362
+ ngOnInit() {
363
+ if (!this.data && this.dialogData) this.data = this.dialogData;
364
+ this.initialize();
365
+ }
366
+ ngOnChanges(changes) {
367
+ if (changes["data"] && !changes["data"].firstChange) this.initialize();
368
+ }
369
+ ngOnDestroy() {
370
+ this.destroyed = true;
371
+ this.intlSubscription.unsubscribe();
372
+ ++this.initializeVersion;
373
+ this.cancelLoad.next();
374
+ this.cancelLoad.complete();
375
+ this.releaseConnection();
376
+ this.recordChange.complete();
377
+ }
378
+ openJsonDataDialog() {
379
+ if (this.record === void 0) return;
380
+ this.host.showJson(this.resolveJsonDialogTitle(), [{
381
+ label: this.intl.messages.recordLabel,
382
+ value: this.record
383
+ }]);
384
+ }
385
+ close(result) {
386
+ this.dialogRef?.close(result);
387
+ }
388
+ getActions(position) {
389
+ return this.actions.filter((action) => (action.position ?? "bottom") === position && action.isVisible);
390
+ }
391
+ trackAction(index, action) {
392
+ return "component" in action ? index : action.label || action.icon || index;
393
+ }
394
+ async handleAction(action) {
395
+ if (this.record === void 0 || this.destroyed || !this.dialogDataResolved) return;
396
+ const context = this.buildActionContext(action);
397
+ if (!this.resolveActionState(action.visible, context, true) || this.resolveActionState(action.disabled, context, false)) return;
398
+ await this.runAction(action.confirm, () => action.handle(context), action.closeOnHandle);
399
+ }
400
+ async runAction(confirm, handle, closeOnHandle) {
401
+ if (this.handlingAction || this.destroyed) return;
402
+ const version = this.initializeVersion;
403
+ this.handlingAction = true;
404
+ this.actionErrorLabel = "";
405
+ this.actionFailed = false;
406
+ this.changeDetectorRef.markForCheck();
407
+ try {
408
+ if (!await this.confirmAction(confirm) || this.destroyed || version !== this.initializeVersion) return;
409
+ const result = await handle();
410
+ if (this.destroyed || version !== this.initializeVersion) return;
411
+ this.refreshDisplayState();
412
+ if (closeOnHandle) this.close(result);
413
+ } catch (error) {
414
+ this.reportError(error);
415
+ if (!this.destroyed && version === this.initializeVersion) {
416
+ this.actionFailed = true;
417
+ this.actionErrorLabel = this.intl.messages.actionErrorLabel;
418
+ }
419
+ } finally {
420
+ if (!this.destroyed && version === this.initializeVersion) {
421
+ this.handlingAction = false;
422
+ this.changeDetectorRef.markForCheck();
423
+ }
424
+ }
425
+ }
426
+ resolveJsonDialogTitle() {
427
+ return this.elementRef.nativeElement.querySelector(".display-dialog-title-content h2")?.textContent?.trim() || this.intl.messages.jsonTitle;
428
+ }
429
+ async initialize() {
430
+ if (this.destroyed) return;
431
+ const version = ++this.initializeVersion;
432
+ this.cancelLoad.next();
433
+ this.releaseConnection();
434
+ const data = this.data ?? this.dialogData ?? void 0;
435
+ this.loading = true;
436
+ this.errorLabel = "";
437
+ this.recordErrorKind = void 0;
438
+ this.actionErrorLabel = "";
439
+ this.actionFailed = false;
440
+ this.record = void 0;
441
+ this.dialogDataResolved = data;
442
+ this.actions = [];
443
+ this.handlingAction = false;
444
+ this.renderState = { kind: "empty" };
445
+ this.changeDetectorRef.markForCheck();
446
+ if (!data) {
447
+ this.finishWithoutRecord("empty");
448
+ return;
449
+ }
450
+ this.loadingLabel = data.loadingLabel ?? this.intl.messages.loadingLabel;
451
+ this.closeLabel = data.closeLabel ?? this.intl.messages.closeLabel;
452
+ this.showCloseButton = data.showCloseButton ?? !!this.dialogRef;
453
+ try {
454
+ this.connection = data.connect?.();
455
+ const record = "record" in data && data.record != null ? data.record : await this.resolveRecord(data);
456
+ if (this.destroyed || version !== this.initializeVersion) return;
457
+ if (!record) {
458
+ this.finishWithoutRecord("empty");
459
+ return;
460
+ }
461
+ this.record = record;
462
+ this.notifyRecord(record);
463
+ this.refreshDisplayState();
464
+ this.loading = false;
465
+ this.changeDetectorRef.detectChanges();
466
+ } catch (err) {
467
+ if (this.destroyed || version !== this.initializeVersion) return;
468
+ this.reportError(err);
469
+ this.finishWithoutRecord("error");
470
+ }
471
+ }
472
+ async resolveRecord(data) {
473
+ if ("record" in data && data.record !== void 0 && data.record !== null) return data.record;
474
+ if (!data.loadRecord) return null;
475
+ const loadedRecord = data.loadRecord();
476
+ if (isObservable(loadedRecord)) return firstValueFrom(loadedRecord.pipe(takeUntil(this.cancelLoad)), { defaultValue: null });
477
+ return loadedRecord;
478
+ }
479
+ buildRenderState(data, record) {
480
+ return this.buildOptionsRenderState(data, this.resolveDisplayOptions(data, record), record);
481
+ }
482
+ resolveDisplayOptions(data, record) {
483
+ if (typeof data.displayOptions !== "function") return data.displayOptions;
484
+ return data.displayOptions({
485
+ record,
486
+ data
487
+ });
488
+ }
489
+ buildOptionsRenderState(data, displayOptions, record) {
490
+ if (this.isTabsOptions(displayOptions)) return {
491
+ kind: "tabs",
492
+ tabs: displayOptions.tabs.map((tab) => this.buildTabRenderState(data, tab, record))
493
+ };
494
+ if (this.isSectionsOptions(displayOptions)) return {
495
+ kind: "sections",
496
+ sectionsMenuHeader: displayOptions.menuHeader,
497
+ sectionsOptions: this.buildSectionsOptions(displayOptions, record)
498
+ };
499
+ if (this.isComponentOptions(displayOptions)) return {
500
+ kind: "component",
501
+ component: displayOptions.component,
502
+ componentInputs: this.buildComponentInputs(data, displayOptions, record),
503
+ componentOverflow: displayOptions.overflow ?? true
504
+ };
505
+ if (this.isSingleSectionOptions(displayOptions)) return {
506
+ kind: "section",
507
+ singleSectionOptions: this.buildSingleSectionOptions(displayOptions, record)
508
+ };
509
+ return { kind: "empty" };
510
+ }
511
+ buildTabRenderState(data, tab, record) {
512
+ return {
513
+ label: tab.label,
514
+ icon: tab.icon,
515
+ svgIcon: tab.svgIcon,
516
+ badge: tab.badge,
517
+ renderState: this.buildOptionsRenderState(data, tab.displayOptions, record)
518
+ };
519
+ }
520
+ isTabsOptions(options) {
521
+ return "tabs" in options;
522
+ }
523
+ isSectionsOptions(options) {
524
+ return "sections" in options;
525
+ }
526
+ isComponentOptions(options) {
527
+ return "component" in options;
528
+ }
529
+ isSingleSectionOptions(options) {
530
+ return "section" in options;
531
+ }
532
+ buildSectionsOptions(options, record) {
533
+ const { menuHeader, sections, ...sectionTabsOptions } = options;
534
+ return {
535
+ ...sectionTabsOptions,
536
+ data: record,
537
+ sections: this.buildRuntimeSections(sections)
538
+ };
539
+ }
540
+ buildSingleSectionOptions(options, record) {
541
+ return {
542
+ data: record,
543
+ sections: this.buildRuntimeSections([options.section]),
544
+ showEmptyFields: options.showEmptyFields,
545
+ showEmptyFieldsToggle: options.showEmptyFieldsToggle,
546
+ showEmptyFieldsLabel: options.showEmptyFieldsLabel
547
+ };
548
+ }
549
+ buildRuntimeSections(sections) {
550
+ return sections.map((section) => ({
551
+ ...section,
552
+ cards: section.cards.map((card) => this.buildRuntimeCard(section, card))
553
+ }));
554
+ }
555
+ buildRuntimeCard(section, card) {
556
+ const { actions, ...sectionTabsCard } = card;
557
+ return {
558
+ ...sectionTabsCard,
559
+ actions: this.buildRuntimeCardActions(section, card, actions ?? [])
560
+ };
561
+ }
562
+ buildRuntimeCardActions(section, card, actions) {
563
+ return actions.flatMap((action) => {
564
+ if (this.isSectionTabsDisplayCardAction(action)) return [action];
565
+ const context = this.buildCardActionContext(section, card, action);
566
+ if (!this.resolveCardActionState(action.visible, context, true)) return [];
567
+ const menuOptions = this.buildRuntimeCardMenuOptions(section, card, action);
568
+ if (action.menuOptions?.length && !menuOptions.length) return [];
569
+ return [{
570
+ id: action.id,
571
+ type: action.type,
572
+ icon: action.icon,
573
+ label: action.label,
574
+ tooltip: action.tooltip,
575
+ ariaLabel: action.ariaLabel,
576
+ color: action.color,
577
+ disabled: this.resolveCardActionState(action.disabled, context, false),
578
+ menuOptions: menuOptions.length ? menuOptions : void 0,
579
+ handle: () => {
580
+ if (!menuOptions.length) this.handleCardAction(section, card, action);
581
+ }
582
+ }];
583
+ });
584
+ }
585
+ isSectionTabsDisplayCardAction(action) {
586
+ return "handle" in action && typeof action.handle === "function";
587
+ }
588
+ buildRuntimeCardMenuOptions(section, card, action) {
589
+ return (action.menuOptions ?? []).flatMap((option) => {
590
+ const context = this.buildCardActionContext(section, card, action, option);
591
+ if (!this.resolveCardActionState(option.visible, context, true)) return [];
592
+ return [{
593
+ id: option.id,
594
+ label: option.label,
595
+ icon: option.icon,
596
+ tooltip: option.tooltip,
597
+ ariaLabel: option.ariaLabel,
598
+ disabled: this.resolveCardActionState(option.disabled, context, false),
599
+ handle: () => void this.handleCardMenuOption(section, card, action, option)
600
+ }];
601
+ });
602
+ }
603
+ buildComponentInputs(data, displayOptions, record) {
604
+ const baseInputs = {
605
+ record,
606
+ data,
607
+ displayOptions
608
+ };
609
+ if (!displayOptions.input) return this.pickDeclaredComponentInputs(displayOptions.component, baseInputs);
610
+ const customInputs = typeof displayOptions.input === "function" ? displayOptions.input({
611
+ record,
612
+ data,
613
+ displayOptions
614
+ }) : displayOptions.input;
615
+ return this.pickDeclaredComponentInputs(displayOptions.component, {
616
+ ...baseInputs,
617
+ ...customInputs
618
+ });
619
+ }
620
+ pickDeclaredComponentInputs(component, inputs) {
621
+ if (!component || !inputs) return {};
622
+ const declaredInputNames = this.getDeclaredComponentInputNames(component);
623
+ if (!declaredInputNames.size) return {};
624
+ return Object.entries(inputs).reduce((filteredInputs, [name, value]) => {
625
+ if (declaredInputNames.has(name)) filteredInputs[name] = value;
626
+ return filteredInputs;
627
+ }, {});
628
+ }
629
+ getDeclaredComponentInputNames(component) {
630
+ const cachedInputNames = this.componentInputNamesByType.get(component);
631
+ if (cachedInputNames) return cachedInputNames;
632
+ const componentMirror = reflectComponentType(component);
633
+ const inputNames = new Set(componentMirror?.inputs.map((input) => input.templateName) ?? []);
634
+ this.componentInputNamesByType.set(component, inputNames);
635
+ return inputNames;
636
+ }
637
+ resolveText(value, record) {
638
+ if (!value) return "";
639
+ return typeof value === "function" ? value(record) : value;
640
+ }
641
+ refreshDisplayState() {
642
+ if (this.record === void 0 || !this.dialogDataResolved) return;
643
+ this.title = this.resolveText(this.dialogDataResolved.title, this.record);
644
+ this.subtitle = this.resolveText(this.dialogDataResolved.subtitle, this.record);
645
+ this.renderState = this.buildRenderState(this.dialogDataResolved, this.record);
646
+ this.refreshActions();
647
+ }
648
+ refreshActions() {
649
+ if (this.record === void 0 || !this.dialogDataResolved) {
650
+ this.actions = [];
651
+ return;
652
+ }
653
+ const data = this.dialogDataResolved;
654
+ const record = this.record;
655
+ this.actions = [...data.actions ?? [], ...this.connection?.actions ?? []].map((action) => {
656
+ if ("component" in action) {
657
+ const custom = typeof action.input === "function" ? action.input({
658
+ record,
659
+ data
660
+ }) : action.input;
661
+ return {
662
+ ...action,
663
+ isVisible: true,
664
+ componentInputs: this.pickDeclaredComponentInputs(action.component, {
665
+ record,
666
+ data,
667
+ ...custom
668
+ })
669
+ };
670
+ }
671
+ const context = this.buildActionContext(action);
672
+ return {
673
+ ...action,
674
+ isVisible: this.resolveActionState(action.visible, context, true),
675
+ isDisabled: this.resolveActionState(action.disabled, context, false)
676
+ };
677
+ });
678
+ }
679
+ resolveActionState(state, context, defaultValue) {
680
+ if (state === void 0) return defaultValue;
681
+ return typeof state === "function" ? state(context) : state;
682
+ }
683
+ buildActionContext(action) {
684
+ const version = this.initializeVersion;
685
+ return {
686
+ record: this.record,
687
+ data: this.dialogDataResolved,
688
+ action,
689
+ close: (result) => {
690
+ if (!this.destroyed && version === this.initializeVersion) this.close(result);
691
+ },
692
+ setRecord: (record) => {
693
+ if (!this.destroyed && version === this.initializeVersion) this.setRecord(record);
694
+ }
695
+ };
696
+ }
697
+ async handleCardAction(section, card, action) {
698
+ if (this.record === void 0 || this.destroyed || !this.dialogDataResolved) return;
699
+ const context = this.buildCardActionContext(section, card, action);
700
+ if (!this.resolveCardActionState(action.visible, context, true) || this.resolveCardActionState(action.disabled, context, false)) return;
701
+ await this.runAction(action.confirm, () => action.handler?.(context), action.closeOnHandle);
702
+ }
703
+ async handleCardMenuOption(section, card, action, option) {
704
+ if (this.record === void 0 || this.destroyed || !this.dialogDataResolved) return;
705
+ const context = this.buildCardActionContext(section, card, action, option);
706
+ if (!this.resolveCardActionState(action.visible, context, true) || !this.resolveCardActionState(option.visible, context, true) || this.resolveCardActionState(action.disabled, context, false) || this.resolveCardActionState(option.disabled, context, false)) return;
707
+ await this.runAction(action.confirm, () => action.menuHandler?.(option.id, context), action.closeOnHandle);
708
+ }
709
+ resolveCardActionState(state, context, defaultValue) {
710
+ if (state === void 0) return defaultValue;
711
+ return typeof state === "function" ? state(context) : state;
712
+ }
713
+ buildCardActionContext(section, card, action, option) {
714
+ const version = this.initializeVersion;
715
+ return {
716
+ record: this.record,
717
+ data: this.dialogDataResolved,
718
+ section,
719
+ card,
720
+ action,
721
+ option,
722
+ close: (result) => {
723
+ if (!this.destroyed && version === this.initializeVersion) this.close(result);
724
+ },
725
+ setRecord: (record) => {
726
+ if (!this.destroyed && version === this.initializeVersion) this.setRecord(record);
727
+ }
728
+ };
729
+ }
730
+ notifyRecord(record) {
731
+ this.recordChange.emit(record);
732
+ try {
733
+ this.connection?.recordChanged?.(record);
734
+ } catch (error) {
735
+ this.reportError(error);
736
+ }
737
+ }
738
+ releaseConnection() {
739
+ const connection = this.connection;
740
+ this.connection = void 0;
741
+ try {
742
+ connection?.destroy?.();
743
+ } catch (error) {
744
+ this.reportError(error);
745
+ }
746
+ }
747
+ reportError(error) {
748
+ try {
749
+ this.errorHandler.handleError(error);
750
+ } catch {}
751
+ }
752
+ setRecord(record) {
753
+ if (this.destroyed) return;
754
+ this.record = record;
755
+ this.notifyRecord(record);
756
+ this.refreshDisplayState();
757
+ this.changeDetectorRef.markForCheck();
758
+ }
759
+ async confirmAction(confirmOptions) {
760
+ if (!confirmOptions) return true;
761
+ if (typeof confirmOptions === "string") return this.confirm({ message: confirmOptions });
762
+ return this.confirm(confirmOptions);
763
+ }
764
+ async confirm(confirmOptions) {
765
+ return await this.host.confirm(confirmOptions) === true;
766
+ }
767
+ refreshIntlLabels() {
768
+ const data = this.dialogDataResolved;
769
+ const messages = this.intl.messages;
770
+ this.loadingLabel = data?.loadingLabel ?? messages.loadingLabel;
771
+ this.closeLabel = data?.closeLabel ?? messages.closeLabel;
772
+ if (this.recordErrorKind === "empty") this.errorLabel = data?.emptyLabel ?? data?.errorLabel ?? messages.emptyLabel;
773
+ if (this.recordErrorKind === "error") this.errorLabel = data?.errorLabel ?? messages.errorLabel;
774
+ if (this.actionFailed) this.actionErrorLabel = messages.actionErrorLabel;
775
+ this.changeDetectorRef.markForCheck();
776
+ }
777
+ finishWithoutRecord(kind) {
778
+ this.loading = false;
779
+ this.handlingAction = false;
780
+ this.recordErrorKind = kind;
781
+ this.refreshIntlLabels();
782
+ this.title = "";
783
+ this.subtitle = "";
784
+ this.actions = [];
785
+ this.renderState = { kind: "empty" };
786
+ this.changeDetectorRef.detectChanges();
787
+ }
788
+ static ɵfac = i0.ɵɵngDeclareFactory({
789
+ minVersion: "12.0.0",
790
+ version: "22.2.1",
791
+ ngImport: i0,
792
+ type: DisplayDialog,
793
+ deps: [{
794
+ token: MAT_DIALOG_DATA,
795
+ optional: true
796
+ }, {
797
+ token: i1.MatDialogRef,
798
+ optional: true
799
+ }],
800
+ target: i0.ɵɵFactoryTarget.Component
801
+ });
802
+ static ɵcmp = i0.ɵɵngDeclareComponent({
803
+ minVersion: "17.0.0",
804
+ version: "22.2.1",
805
+ type: DisplayDialog,
806
+ isStandalone: false,
807
+ selector: "app-display-dialog",
808
+ inputs: { data: "data" },
809
+ usesOnChanges: true,
810
+ ngImport: i0,
811
+ template: "<!-- @format -->\n\n@if (loading) {\n <div class=\"display-dialog-loading\">\n <mat-spinner [diameter]=\"72\"></mat-spinner>\n <span>{{ loadingLabel }}</span>\n </div>\n} @else if (errorLabel) {\n <div class=\"display-dialog-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ errorLabel }}</span>\n\n @if (showCloseButton) {\n <button mat-stroked-button type=\"button\" (click)=\"close()\">{{ closeLabel }}</button>\n }\n </div>\n} @else {\n @if (title || subtitle || showCloseButton || getActions('top').length) {\n <div mat-dialog-title class=\"display-dialog-title\">\n <div class=\"display-dialog-title-bar\">\n <div class=\"display-dialog-title-content\">\n @if (title) {\n <h2 [innerHTML]=\"title\"></h2>\n }\n @if (subtitle) {\n <p [innerHTML]=\"subtitle\"></p>\n }\n </div>\n\n <div class=\"display-dialog-title-actions\">\n @for (action of getActions('top'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n\n @if (isDialog && data?.showJsonDataButton === true) {\n <button\n mat-icon-button\n type=\"button\"\n \n [matTooltip]=\"intl.messages.jsonButtonLabel\"\n \n [attr.aria-label]=\"intl.messages.jsonButtonLabel\"\n (click)=\"openJsonDataDialog()\">\n <mat-icon>file_json</mat-icon>\n </button>\n }\n\n\n @if (showCloseButton) {\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"closeLabel\" (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n @if (actionErrorLabel) { <div class=\"display-dialog-action-error\" role=\"alert\">{{ actionErrorLabel }}</div> }\n <div mat-dialog-content class=\"display-dialog-content\">\n <ng-container *ngTemplateOutlet=\"displayDialogContent; context: { $implicit: renderState }\"></ng-container>\n </div>\n\n @if (getActions('bottom').length || getActions('bottom-end').length) {\n <footer class=\"display-dialog-actions\">\n <div class=\"display-dialog-actions-left\">\n @for (action of getActions('bottom'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n </div>\n\n <div class=\"display-dialog-actions-right\">\n @for (action of getActions('bottom-end'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n </div>\n </footer>\n }\n\n @if (handlingAction) {\n <div class=\"display-dialog-handling-action\">\n <mat-spinner [diameter]=\"72\"></mat-spinner>\n </div>\n }\n}\n\n<ng-template #displayDialogContent let-state>\n @switch (state.kind) {\n @case ('tabs') {\n @if (state.tabs?.length) {\n <mat-tab-group class=\"display-dialog-root-tabs\" mat-stretch-tabs=\"false\">\n @for (tab of state.tabs; track tab.label) {\n <mat-tab>\n <ng-template mat-tab-label>\n @if (tab.svgIcon) {\n <mat-icon class=\"display-dialog-root-tab-icon\" [svgIcon]=\"tab.svgIcon\"></mat-icon>\n } @else if (tab.icon) {\n <mat-icon class=\"display-dialog-root-tab-icon\">{{ tab.icon }}</mat-icon>\n }\n <span [innerHTML]=\"tab.label\"></span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <span class=\"display-dialog-root-tab-badge\">{{ tab.badge }}</span>\n }\n </ng-template>\n\n <ng-container\n *ngTemplateOutlet=\"displayDialogContent; context: { $implicit: tab.renderState }\"></ng-container>\n </mat-tab>\n }\n </mat-tab-group>\n }\n }\n\n @case ('sections') {\n @if (state.sectionsOptions) {\n <app-section-tabs-display\n class=\"display-dialog-section-tabs-display\"\n [menuHeader]=\"state.sectionsMenuHeader\"\n [options]=\"state.sectionsOptions\">\n </app-section-tabs-display>\n }\n }\n\n @case ('component') {\n <div class=\"display-dialog-component-page\" [class.overflow]=\"state.componentOverflow\">\n @if (state.component) {\n <ng-container *ngComponentOutlet=\"state.component; inputs: state.componentInputs\"></ng-container>\n }\n </div>\n }\n\n @case ('section') {\n @if (state.singleSectionOptions) {\n <app-section-tabs-display\n class=\"display-dialog-section-tabs-display display-dialog-single-section-display\"\n [options]=\"state.singleSectionOptions\">\n </app-section-tabs-display>\n }\n }\n\n @default {\n <div class=\"display-dialog-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ intl.messages.emptyContentLabel }}</span>\n </div>\n }\n }\n</ng-template>\n\n<ng-template #actionTemplate let-action=\"action\">\n @if (action.component) {\n <ng-container *ngComponentOutlet=\"action.component; inputs: action.componentInputs\"></ng-container>\n } @else if (action.buttonType === 'raised') {\n <button\n class=\"display-dialog-action-btn\"\n mat-raised-button\n type=\"button\"\n [style.--action-color]=\"action.contrastColor\"\n [style.--action-background-color]=\"action.color\"\n [disabled]=\"handlingAction || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"handleAction(action)\">\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n } @else {\n <button\n class=\"display-dialog-action-btn\"\n mat-button\n type=\"button\"\n [style.--action-color]=\"action.color\"\n [disabled]=\"handlingAction || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"handleAction(action)\">\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n</ng-template>\n",
812
+ styles: [":host{--display-dialog-background: var(--ngx-mat-display-dialog-background, #f4f6f8);--display-dialog-border: var(--ngx-mat-display-dialog-border, rgba(14, 43, 67, .12));--display-dialog-text: var(--ngx-mat-display-dialog-text, #102f49);--display-dialog-muted: var(--ngx-mat-display-dialog-muted, #61718a);--display-dialog-primary: var(--ngx-mat-display-dialog-primary, #0f334d);position:relative;display:flex;flex-direction:column;height:100%;min-height:0;color:var(--display-dialog-text)}.display-dialog-loading,.display-dialog-empty-state{display:flex;flex:1 1 auto;min-height:240px;align-items:center;justify-content:center;flex-direction:column;gap:18px;color:var(--display-dialog-primary)}.display-dialog-empty-state{padding:24px;color:var(--display-dialog-muted);text-align:center}.display-dialog-empty-state mat-icon{width:42px;height:42px;color:var(--display-dialog-primary);font-size:42px}.display-dialog-empty-state span{color:var(--display-dialog-text);font-size:15px;font-weight:700}.display-dialog-title{display:flex;min-height:48px;padding:8px 12px;margin:0;border-bottom:1px solid var(--display-dialog-border);box-sizing:border-box;background:var(--ngx-mat-display-dialog-header-background, #e9eef2);color:var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-title .display-dialog-title-bar{display:flex;flex:0 0 auto;align-items:center;justify-content:start;gap:80px;width:100%}.display-dialog-title .display-dialog-title-bar h2{margin:0;font-size:18px;font-weight:700;line-height:1.2}.display-dialog-title .display-dialog-title-bar p{margin:3px 0 0;color:var(--display-dialog-muted);font-size:13px}.display-dialog-title-content{min-width:0;overflow:hidden;--display-dialog-muted: var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-title-content h2,.display-dialog-title-content p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.display-dialog-title-actions{display:inline-flex;flex:0 0 auto;align-items:center;gap:8px;margin-left:auto}.display-dialog-title-actions .mat-mdc-icon-button{--mat-icon-button-icon-color: var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-content{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;max-height:none;padding:0!important;background:var(--display-dialog-background);box-sizing:border-box}.display-dialog-actions{display:flex;flex:0 0 auto;align-items:center;justify-content:space-between;gap:8px;min-height:54px;padding:8px;border-top:1px solid var(--display-dialog-border);background:#fff;box-sizing:border-box}.display-dialog-actions-left,.display-dialog-actions-right{display:inline-flex;align-items:center;gap:8px;min-width:0}.display-dialog-action-btn{--mat-button-filled-label-text-color: var(--action-color, #fff);--mat-button-filled-container-color: var(--action-background-color, var(--ngx-mat-display-dialog-primary, #0f334d));--mat-button-protected-label-text-color: var(--action-color, #fff);--mat-button-protected-container-color: var(--action-background-color, var(--ngx-mat-display-dialog-primary, #0f334d));--mat-button-text-label-text-color: var(--action-color, var(--display-dialog-primary))}.display-dialog-handling-action{position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;background:#ffffffb8}.display-dialog-section-tabs-display{flex:1 1 auto;min-height:0}.display-dialog-component-page{flex:1 1 auto;min-height:0;padding:12px 16px 16px;overflow:hidden;box-sizing:border-box}.display-dialog-component-page.overflow{overflow:auto}:host ::ng-deep .display-dialog-single-section-display .section-tabs{grid-template-columns:minmax(0,1fr)}:host ::ng-deep .display-dialog-single-section-display .section-tabs__sidebar{display:none}:host ::ng-deep .display-dialog-single-section-display .section-tabs__content-panel{padding:0 0 0 8px}.display-dialog-root-tabs{display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.display-dialog-root-tab-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.display-dialog-root-tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;margin-left:8px;border-radius:999px;background:#0f334d1a;color:var(--display-dialog-primary);font-size:11px;font-weight:700;line-height:1}:host ::ng-deep .display-dialog-root-tabs>.mat-mdc-tab-body-wrapper{flex:1 1 auto;min-height:0}:host ::ng-deep .display-dialog-root-tabs>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body{min-height:0}:host ::ng-deep .display-dialog-root-tabs .mat-mdc-tab-body-content{display:flex;flex-direction:column;min-height:0;overflow:hidden}@media(max-width:900px){.display-dialog-actions{align-items:stretch;flex-direction:column}.display-dialog-actions-left,.display-dialog-actions-right{justify-content:flex-end;width:100%}}.display-dialog-action-error{padding:12px 16px;color:#a01616;background:#fff1f1}\n"],
813
+ dependencies: [
814
+ {
815
+ kind: "directive",
816
+ type: i2.NgComponentOutlet,
817
+ selector: "[ngComponentOutlet]",
818
+ inputs: [
819
+ "ngComponentOutlet",
820
+ "ngComponentOutletInputs",
821
+ "ngComponentOutletInjector",
822
+ "ngComponentOutletEnvironmentInjector",
823
+ "ngComponentOutletContent",
824
+ "ngComponentOutletNgModule"
825
+ ],
826
+ exportAs: ["ngComponentOutlet"]
827
+ },
828
+ {
829
+ kind: "directive",
830
+ type: i2.NgTemplateOutlet,
831
+ selector: "[ngTemplateOutlet]",
832
+ inputs: [
833
+ "ngTemplateOutletContext",
834
+ "ngTemplateOutlet",
835
+ "ngTemplateOutletInjector"
836
+ ]
837
+ },
838
+ {
839
+ kind: "component",
840
+ type: i2$1.MatButton,
841
+ selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ",
842
+ inputs: ["matButton"],
843
+ exportAs: ["matButton", "matAnchor"]
844
+ },
845
+ {
846
+ kind: "component",
847
+ type: i2$1.MatIconButton,
848
+ selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]",
849
+ exportAs: ["matButton", "matAnchor"]
850
+ },
851
+ {
852
+ kind: "directive",
853
+ type: i1.MatDialogTitle,
854
+ selector: "[mat-dialog-title], [matDialogTitle]",
855
+ inputs: ["id"],
856
+ exportAs: ["matDialogTitle"]
857
+ },
858
+ {
859
+ kind: "directive",
860
+ type: i1.MatDialogContent,
861
+ selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]"
862
+ },
863
+ {
864
+ kind: "component",
865
+ type: i4.MatIcon,
866
+ selector: "mat-icon",
867
+ inputs: [
868
+ "color",
869
+ "inline",
870
+ "svgIcon",
871
+ "fontSet",
872
+ "fontIcon"
873
+ ],
874
+ exportAs: ["matIcon"]
875
+ },
876
+ {
877
+ kind: "directive",
878
+ type: i5.MatTabLabel,
879
+ selector: "[mat-tab-label], [matTabLabel]"
880
+ },
881
+ {
882
+ kind: "component",
883
+ type: i5.MatTab,
884
+ selector: "mat-tab",
885
+ inputs: [
886
+ "disabled",
887
+ "label",
888
+ "aria-label",
889
+ "aria-labelledby",
890
+ "labelClass",
891
+ "bodyClass",
892
+ "id"
893
+ ],
894
+ exportAs: ["matTab"]
895
+ },
896
+ {
897
+ kind: "component",
898
+ type: i5.MatTabGroup,
899
+ selector: "mat-tab-group",
900
+ inputs: [
901
+ "color",
902
+ "fitInkBarToContent",
903
+ "mat-stretch-tabs",
904
+ "mat-align-tabs",
905
+ "dynamicHeight",
906
+ "selectedIndex",
907
+ "headerPosition",
908
+ "animationDuration",
909
+ "contentTabIndex",
910
+ "disablePagination",
911
+ "disableRipple",
912
+ "preserveContent",
913
+ "backgroundColor",
914
+ "aria-label",
915
+ "aria-labelledby"
916
+ ],
917
+ outputs: [
918
+ "selectedIndexChange",
919
+ "focusChange",
920
+ "animationDone",
921
+ "selectedTabChange"
922
+ ],
923
+ exportAs: ["matTabGroup"]
924
+ },
925
+ {
926
+ kind: "directive",
927
+ type: i6.MatTooltip,
928
+ selector: "[matTooltip]",
929
+ inputs: [
930
+ "matTooltipPosition",
931
+ "matTooltipPositionAtOrigin",
932
+ "matTooltipDisabled",
933
+ "matTooltipShowDelay",
934
+ "matTooltipHideDelay",
935
+ "matTooltipTouchGestures",
936
+ "matTooltip",
937
+ "matTooltipClass"
938
+ ],
939
+ exportAs: ["matTooltip"]
940
+ },
941
+ {
942
+ kind: "component",
943
+ type: i7.SectionTabsDisplayComponent,
944
+ selector: "app-section-tabs-display",
945
+ inputs: [
946
+ "options",
947
+ "selectedIndex",
948
+ "queryParamKey",
949
+ "menuHeader",
950
+ "showEmptyFields"
951
+ ],
952
+ outputs: ["selectedIndexChange", "showEmptyFieldsChange"]
953
+ },
954
+ {
955
+ kind: "component",
956
+ type: i8.MatProgressSpinner,
957
+ selector: "mat-progress-spinner, mat-spinner",
958
+ inputs: [
959
+ "color",
960
+ "mode",
961
+ "value",
962
+ "diameter",
963
+ "strokeWidth"
964
+ ],
965
+ exportAs: ["matProgressSpinner"]
966
+ }
967
+ ],
968
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
969
+ });
970
+ };
971
+ i0.ɵɵngDeclareClassMetadata({
972
+ minVersion: "12.0.0",
973
+ version: "22.2.1",
974
+ ngImport: i0,
975
+ type: DisplayDialog,
976
+ decorators: [{
977
+ type: Component,
978
+ args: [{
979
+ selector: "app-display-dialog",
980
+ changeDetection: ChangeDetectionStrategy.OnPush,
981
+ standalone: false,
982
+ template: "<!-- @format -->\n\n@if (loading) {\n <div class=\"display-dialog-loading\">\n <mat-spinner [diameter]=\"72\"></mat-spinner>\n <span>{{ loadingLabel }}</span>\n </div>\n} @else if (errorLabel) {\n <div class=\"display-dialog-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ errorLabel }}</span>\n\n @if (showCloseButton) {\n <button mat-stroked-button type=\"button\" (click)=\"close()\">{{ closeLabel }}</button>\n }\n </div>\n} @else {\n @if (title || subtitle || showCloseButton || getActions('top').length) {\n <div mat-dialog-title class=\"display-dialog-title\">\n <div class=\"display-dialog-title-bar\">\n <div class=\"display-dialog-title-content\">\n @if (title) {\n <h2 [innerHTML]=\"title\"></h2>\n }\n @if (subtitle) {\n <p [innerHTML]=\"subtitle\"></p>\n }\n </div>\n\n <div class=\"display-dialog-title-actions\">\n @for (action of getActions('top'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n\n @if (isDialog && data?.showJsonDataButton === true) {\n <button\n mat-icon-button\n type=\"button\"\n \n [matTooltip]=\"intl.messages.jsonButtonLabel\"\n \n [attr.aria-label]=\"intl.messages.jsonButtonLabel\"\n (click)=\"openJsonDataDialog()\">\n <mat-icon>file_json</mat-icon>\n </button>\n }\n\n\n @if (showCloseButton) {\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"closeLabel\" (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n @if (actionErrorLabel) { <div class=\"display-dialog-action-error\" role=\"alert\">{{ actionErrorLabel }}</div> }\n <div mat-dialog-content class=\"display-dialog-content\">\n <ng-container *ngTemplateOutlet=\"displayDialogContent; context: { $implicit: renderState }\"></ng-container>\n </div>\n\n @if (getActions('bottom').length || getActions('bottom-end').length) {\n <footer class=\"display-dialog-actions\">\n <div class=\"display-dialog-actions-left\">\n @for (action of getActions('bottom'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n </div>\n\n <div class=\"display-dialog-actions-right\">\n @for (action of getActions('bottom-end'); track trackAction($index, action)) {\n <ng-container *ngTemplateOutlet=\"actionTemplate; context: { action }\"></ng-container>\n }\n </div>\n </footer>\n }\n\n @if (handlingAction) {\n <div class=\"display-dialog-handling-action\">\n <mat-spinner [diameter]=\"72\"></mat-spinner>\n </div>\n }\n}\n\n<ng-template #displayDialogContent let-state>\n @switch (state.kind) {\n @case ('tabs') {\n @if (state.tabs?.length) {\n <mat-tab-group class=\"display-dialog-root-tabs\" mat-stretch-tabs=\"false\">\n @for (tab of state.tabs; track tab.label) {\n <mat-tab>\n <ng-template mat-tab-label>\n @if (tab.svgIcon) {\n <mat-icon class=\"display-dialog-root-tab-icon\" [svgIcon]=\"tab.svgIcon\"></mat-icon>\n } @else if (tab.icon) {\n <mat-icon class=\"display-dialog-root-tab-icon\">{{ tab.icon }}</mat-icon>\n }\n <span [innerHTML]=\"tab.label\"></span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <span class=\"display-dialog-root-tab-badge\">{{ tab.badge }}</span>\n }\n </ng-template>\n\n <ng-container\n *ngTemplateOutlet=\"displayDialogContent; context: { $implicit: tab.renderState }\"></ng-container>\n </mat-tab>\n }\n </mat-tab-group>\n }\n }\n\n @case ('sections') {\n @if (state.sectionsOptions) {\n <app-section-tabs-display\n class=\"display-dialog-section-tabs-display\"\n [menuHeader]=\"state.sectionsMenuHeader\"\n [options]=\"state.sectionsOptions\">\n </app-section-tabs-display>\n }\n }\n\n @case ('component') {\n <div class=\"display-dialog-component-page\" [class.overflow]=\"state.componentOverflow\">\n @if (state.component) {\n <ng-container *ngComponentOutlet=\"state.component; inputs: state.componentInputs\"></ng-container>\n }\n </div>\n }\n\n @case ('section') {\n @if (state.singleSectionOptions) {\n <app-section-tabs-display\n class=\"display-dialog-section-tabs-display display-dialog-single-section-display\"\n [options]=\"state.singleSectionOptions\">\n </app-section-tabs-display>\n }\n }\n\n @default {\n <div class=\"display-dialog-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ intl.messages.emptyContentLabel }}</span>\n </div>\n }\n }\n</ng-template>\n\n<ng-template #actionTemplate let-action=\"action\">\n @if (action.component) {\n <ng-container *ngComponentOutlet=\"action.component; inputs: action.componentInputs\"></ng-container>\n } @else if (action.buttonType === 'raised') {\n <button\n class=\"display-dialog-action-btn\"\n mat-raised-button\n type=\"button\"\n [style.--action-color]=\"action.contrastColor\"\n [style.--action-background-color]=\"action.color\"\n [disabled]=\"handlingAction || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"handleAction(action)\">\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n } @else {\n <button\n class=\"display-dialog-action-btn\"\n mat-button\n type=\"button\"\n [style.--action-color]=\"action.color\"\n [disabled]=\"handlingAction || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"handleAction(action)\">\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n</ng-template>\n",
983
+ styles: [":host{--display-dialog-background: var(--ngx-mat-display-dialog-background, #f4f6f8);--display-dialog-border: var(--ngx-mat-display-dialog-border, rgba(14, 43, 67, .12));--display-dialog-text: var(--ngx-mat-display-dialog-text, #102f49);--display-dialog-muted: var(--ngx-mat-display-dialog-muted, #61718a);--display-dialog-primary: var(--ngx-mat-display-dialog-primary, #0f334d);position:relative;display:flex;flex-direction:column;height:100%;min-height:0;color:var(--display-dialog-text)}.display-dialog-loading,.display-dialog-empty-state{display:flex;flex:1 1 auto;min-height:240px;align-items:center;justify-content:center;flex-direction:column;gap:18px;color:var(--display-dialog-primary)}.display-dialog-empty-state{padding:24px;color:var(--display-dialog-muted);text-align:center}.display-dialog-empty-state mat-icon{width:42px;height:42px;color:var(--display-dialog-primary);font-size:42px}.display-dialog-empty-state span{color:var(--display-dialog-text);font-size:15px;font-weight:700}.display-dialog-title{display:flex;min-height:48px;padding:8px 12px;margin:0;border-bottom:1px solid var(--display-dialog-border);box-sizing:border-box;background:var(--ngx-mat-display-dialog-header-background, #e9eef2);color:var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-title .display-dialog-title-bar{display:flex;flex:0 0 auto;align-items:center;justify-content:start;gap:80px;width:100%}.display-dialog-title .display-dialog-title-bar h2{margin:0;font-size:18px;font-weight:700;line-height:1.2}.display-dialog-title .display-dialog-title-bar p{margin:3px 0 0;color:var(--display-dialog-muted);font-size:13px}.display-dialog-title-content{min-width:0;overflow:hidden;--display-dialog-muted: var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-title-content h2,.display-dialog-title-content p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.display-dialog-title-actions{display:inline-flex;flex:0 0 auto;align-items:center;gap:8px;margin-left:auto}.display-dialog-title-actions .mat-mdc-icon-button{--mat-icon-button-icon-color: var(--ngx-mat-display-dialog-header-text, #102f49)}.display-dialog-content{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;max-height:none;padding:0!important;background:var(--display-dialog-background);box-sizing:border-box}.display-dialog-actions{display:flex;flex:0 0 auto;align-items:center;justify-content:space-between;gap:8px;min-height:54px;padding:8px;border-top:1px solid var(--display-dialog-border);background:#fff;box-sizing:border-box}.display-dialog-actions-left,.display-dialog-actions-right{display:inline-flex;align-items:center;gap:8px;min-width:0}.display-dialog-action-btn{--mat-button-filled-label-text-color: var(--action-color, #fff);--mat-button-filled-container-color: var(--action-background-color, var(--ngx-mat-display-dialog-primary, #0f334d));--mat-button-protected-label-text-color: var(--action-color, #fff);--mat-button-protected-container-color: var(--action-background-color, var(--ngx-mat-display-dialog-primary, #0f334d));--mat-button-text-label-text-color: var(--action-color, var(--display-dialog-primary))}.display-dialog-handling-action{position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;background:#ffffffb8}.display-dialog-section-tabs-display{flex:1 1 auto;min-height:0}.display-dialog-component-page{flex:1 1 auto;min-height:0;padding:12px 16px 16px;overflow:hidden;box-sizing:border-box}.display-dialog-component-page.overflow{overflow:auto}:host ::ng-deep .display-dialog-single-section-display .section-tabs{grid-template-columns:minmax(0,1fr)}:host ::ng-deep .display-dialog-single-section-display .section-tabs__sidebar{display:none}:host ::ng-deep .display-dialog-single-section-display .section-tabs__content-panel{padding:0 0 0 8px}.display-dialog-root-tabs{display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.display-dialog-root-tab-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.display-dialog-root-tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;margin-left:8px;border-radius:999px;background:#0f334d1a;color:var(--display-dialog-primary);font-size:11px;font-weight:700;line-height:1}:host ::ng-deep .display-dialog-root-tabs>.mat-mdc-tab-body-wrapper{flex:1 1 auto;min-height:0}:host ::ng-deep .display-dialog-root-tabs>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body{min-height:0}:host ::ng-deep .display-dialog-root-tabs .mat-mdc-tab-body-content{display:flex;flex-direction:column;min-height:0;overflow:hidden}@media(max-width:900px){.display-dialog-actions{align-items:stretch;flex-direction:column}.display-dialog-actions-left,.display-dialog-actions-right{justify-content:flex-end;width:100%}}.display-dialog-action-error{padding:12px 16px;color:#a01616;background:#fff1f1}\n"]
984
+ }]
985
+ }],
986
+ ctorParameters: () => [{
987
+ type: void 0,
988
+ decorators: [{ type: Optional }, {
989
+ type: Inject,
990
+ args: [MAT_DIALOG_DATA]
991
+ }]
992
+ }, {
993
+ type: i1.MatDialogRef,
994
+ decorators: [{ type: Optional }]
995
+ }],
996
+ propDecorators: { data: [{ type: Input }] }
997
+ });
998
+ const DEFAULT_NESTED_OPTIONS = {
999
+ inset: 64,
1000
+ minWidth: 640,
1001
+ minHeight: 480,
1002
+ viewportMargin: 16
1003
+ };
1004
+ var DisplayDialogService = class DisplayDialogService {
1005
+ document = inject(DOCUMENT);
1006
+ matDialog = inject(MatDialog);
1007
+ open(data, config = {}) {
1008
+ const { nested, ...dialogOverrides } = config;
1009
+ const dialogConfig = {
1010
+ width: "90vw",
1011
+ height: "90vh",
1012
+ maxWidth: "90vw",
1013
+ maxHeight: "90vh",
1014
+ autoFocus: false,
1015
+ restoreFocus: false,
1016
+ panelClass: "display-dialog-panel",
1017
+ ...nested === null ? {} : this.buildNestedDialogConfig(nested),
1018
+ ...dialogOverrides,
1019
+ data
1020
+ };
1021
+ return this.matDialog.open(DisplayDialog, dialogConfig);
1022
+ }
1023
+ buildNestedDialogConfig(options) {
1024
+ const parentSurface = this.findParentDialogSurface();
1025
+ if (!parentSurface) return {};
1026
+ const resolvedOptions = {
1027
+ ...DEFAULT_NESTED_OPTIONS,
1028
+ ...options
1029
+ };
1030
+ const inset = Math.max(0, resolvedOptions.inset);
1031
+ const viewportMargin = Math.max(0, resolvedOptions.viewportMargin);
1032
+ const viewportWidth = this.document.documentElement.clientWidth;
1033
+ const viewportHeight = this.document.documentElement.clientHeight;
1034
+ const availableWidth = Math.max(0, viewportWidth - viewportMargin * 2);
1035
+ const availableHeight = Math.max(0, viewportHeight - viewportMargin * 2);
1036
+ if (availableWidth === 0 || availableHeight === 0) return {};
1037
+ const parentRect = parentSurface.getBoundingClientRect();
1038
+ const minWidth = Math.min(Math.max(0, resolvedOptions.minWidth), availableWidth);
1039
+ const minHeight = Math.min(Math.max(0, resolvedOptions.minHeight), availableHeight);
1040
+ const width = Math.max(minWidth, Math.min(parentRect.width - inset, availableWidth));
1041
+ const height = Math.max(minHeight, Math.min(parentRect.height - inset, availableHeight));
1042
+ return {
1043
+ width: `${Math.round(width)}px`,
1044
+ height: `${Math.round(height)}px`,
1045
+ maxWidth: `${Math.round(availableWidth)}px`,
1046
+ maxHeight: `${Math.round(availableHeight)}px`
1047
+ };
1048
+ }
1049
+ findParentDialogSurface() {
1050
+ const activeElement = this.document.activeElement;
1051
+ if (activeElement instanceof HTMLElement) {
1052
+ const activeSurface = activeElement.closest(".mat-mdc-dialog-surface");
1053
+ if (activeSurface) return activeSurface;
1054
+ }
1055
+ const visibleSurfaces = Array.from(this.document.querySelectorAll(".mat-mdc-dialog-surface")).filter((surface) => surface.getClientRects().length > 0);
1056
+ return visibleSurfaces[visibleSurfaces.length - 1] ?? null;
1057
+ }
1058
+ static ɵfac = i0.ɵɵngDeclareFactory({
1059
+ minVersion: "12.0.0",
1060
+ version: "22.2.1",
1061
+ ngImport: i0,
1062
+ type: DisplayDialogService,
1063
+ deps: [],
1064
+ target: i0.ɵɵFactoryTarget.Injectable
1065
+ });
1066
+ static ɵprov = i0.ɵɵngDeclareInjectable({
1067
+ minVersion: "12.0.0",
1068
+ version: "22.2.1",
1069
+ ngImport: i0,
1070
+ type: DisplayDialogService,
1071
+ providedIn: "root"
1072
+ });
1073
+ };
1074
+ i0.ɵɵngDeclareClassMetadata({
1075
+ minVersion: "12.0.0",
1076
+ version: "22.2.1",
1077
+ ngImport: i0,
1078
+ type: DisplayDialogService,
1079
+ decorators: [{
1080
+ type: Injectable,
1081
+ args: [{ providedIn: "root" }]
1082
+ }]
1083
+ });
1084
+ var DisplayDialogModule = class DisplayDialogModule {
1085
+ static ɵfac = i0.ɵɵngDeclareFactory({
1086
+ minVersion: "12.0.0",
1087
+ version: "22.2.1",
1088
+ ngImport: i0,
1089
+ type: DisplayDialogModule,
1090
+ deps: [],
1091
+ target: i0.ɵɵFactoryTarget.NgModule
1092
+ });
1093
+ static ɵmod = i0.ɵɵngDeclareNgModule({
1094
+ minVersion: "14.0.0",
1095
+ version: "22.2.1",
1096
+ ngImport: i0,
1097
+ type: DisplayDialogModule,
1098
+ declarations: [DisplayDialog],
1099
+ imports: [
1100
+ CommonModule,
1101
+ MatButtonModule,
1102
+ MatDialogModule,
1103
+ MatIconModule,
1104
+ MatTabsModule,
1105
+ MatTooltipModule,
1106
+ SectionTabsModule,
1107
+ MatProgressSpinnerModule
1108
+ ],
1109
+ exports: [DisplayDialog]
1110
+ });
1111
+ static ɵinj = i0.ɵɵngDeclareInjector({
1112
+ minVersion: "12.0.0",
1113
+ version: "22.2.1",
1114
+ ngImport: i0,
1115
+ type: DisplayDialogModule,
1116
+ imports: [
1117
+ CommonModule,
1118
+ MatButtonModule,
1119
+ MatDialogModule,
1120
+ MatIconModule,
1121
+ MatTabsModule,
1122
+ MatTooltipModule,
1123
+ SectionTabsModule,
1124
+ MatProgressSpinnerModule
1125
+ ]
1126
+ });
1127
+ };
1128
+ i0.ɵɵngDeclareClassMetadata({
1129
+ minVersion: "12.0.0",
1130
+ version: "22.2.1",
1131
+ ngImport: i0,
1132
+ type: DisplayDialogModule,
1133
+ decorators: [{
1134
+ type: NgModule,
1135
+ args: [{
1136
+ declarations: [DisplayDialog],
1137
+ imports: [
1138
+ CommonModule,
1139
+ MatButtonModule,
1140
+ MatDialogModule,
1141
+ MatIconModule,
1142
+ MatTabsModule,
1143
+ MatTooltipModule,
1144
+ SectionTabsModule,
1145
+ MatProgressSpinnerModule
1146
+ ],
1147
+ exports: [DisplayDialog]
1148
+ }]
1149
+ }]
1150
+ });
1151
+ export { DEFAULT_NESTED_OPTIONS, DISPLAY_DIALOG_HOST, DisplayDialog, DisplayDialogIntl, DisplayDialogModule, DisplayDialogService };
1152
+
1153
+ //# sourceMappingURL=eherve-angular-material-display-dialog.mjs.map