@messaia/cdk 21.1.0-rc.3 → 21.1.0-rc.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/messaia-cdk.mjs +856 -250
- package/fesm2022/messaia-cdk.mjs.map +1 -1
- package/lib/common/styles/_layout.scss +47 -0
- package/package.json +3 -2
- package/types/messaia-cdk.d.ts +491 -145
package/fesm2022/messaia-cdk.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i3$1 from '@angular/common';
|
|
2
|
-
import { Location, getLocaleNumberSymbol, NumberSymbol, CommonModule, DecimalPipe, JsonPipe } from '@angular/common';
|
|
2
|
+
import { Location, getLocaleNumberSymbol, NumberSymbol, CommonModule, DecimalPipe, NgClass, JsonPipe } from '@angular/common';
|
|
3
3
|
import * as i1$6 from '@angular/common/http';
|
|
4
4
|
import { HttpHeaders, HttpParams, HttpClient, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { Injectable, Component, Directive, ContentChildren, Optional, SkipSelf, NgZone, InjectionToken, Inject, EventEmitter, inject, ElementRef, ViewChildren, Output, Input, forwardRef, LOCALE_ID, NgModule, Pipe,
|
|
6
|
+
import { Injectable, Component, Directive, ContentChildren, Optional, SkipSelf, NgZone, InjectionToken, Inject, EventEmitter, inject, ElementRef, ViewChildren, Output, Input, HostListener, forwardRef, LOCALE_ID, NgModule, Pipe, input, computed, ViewChild, ChangeDetectorRef, HostAttributeToken, HostBinding, ContentChild, ViewContainerRef, TemplateRef, ChangeDetectionStrategy, Self, SimpleChange, Attribute, SecurityContext } from '@angular/core';
|
|
7
7
|
import * as i1 from '@angular/material/dialog';
|
|
8
|
-
import { MatDialogModule, MatDialogConfig, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
8
|
+
import { MatDialogModule, MatDialogConfig, MatDialog, MAT_DIALOG_DATA, MatDialogTitle } from '@angular/material/dialog';
|
|
9
9
|
import * as i6$3 from '@angular/material/expansion';
|
|
10
10
|
import { MatExpansionPanel, MatExpansionModule } from '@angular/material/expansion';
|
|
11
11
|
import * as i2$3 from '@angular/material/snack-bar';
|
|
@@ -14,7 +14,7 @@ import * as i1$3 from '@angular/platform-browser';
|
|
|
14
14
|
import { Title } from '@angular/platform-browser';
|
|
15
15
|
import * as i1$2 from '@angular/router';
|
|
16
16
|
import { Router, RouterModule } from '@angular/router';
|
|
17
|
-
import { fromEvent, Subject,
|
|
17
|
+
import { fromEvent, Subject, switchMap, timer, takeUntil as takeUntil$1, filter, map, tap, merge as merge$1, of, BehaviorSubject, firstValueFrom, throwError, distinctUntilChanged, debounceTime, Observable } from 'rxjs';
|
|
18
18
|
import * as i2 from '@angular/material/button';
|
|
19
19
|
import { MatButtonModule, MatIconButton } from '@angular/material/button';
|
|
20
20
|
import * as i8 from '@angular/material/icon';
|
|
@@ -25,16 +25,17 @@ import * as i7 from '@angular/material/form-field';
|
|
|
25
25
|
import { MatFormFieldModule, MatFormFieldControl } from '@angular/material/form-field';
|
|
26
26
|
import * as i3 from '@angular/material/progress-bar';
|
|
27
27
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
28
|
-
import { takeUntil, map as map$1, catchError, skip, switchMap, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, tap as tap$1, finalize } from 'rxjs/operators';
|
|
29
|
-
import
|
|
28
|
+
import { takeUntil, map as map$1, catchError, skip, switchMap as switchMap$1, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, tap as tap$1, finalize } from 'rxjs/operators';
|
|
29
|
+
import { CdkDragHandle, CdkDrag } from '@angular/cdk/drag-drop';
|
|
30
|
+
import * as i5$1 from '@angular/material/checkbox';
|
|
30
31
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
31
32
|
import * as i10 from '@angular/material/paginator';
|
|
32
33
|
import { MatPaginatorModule, MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
|
|
33
|
-
import { trigger, state,
|
|
34
|
+
import { trigger, state, style, AUTO_STYLE, transition, group, query, animateChild, animate } from '@angular/animations';
|
|
34
35
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
35
36
|
import * as i2$2 from '@angular/cdk/table';
|
|
36
37
|
import { DataSource, CdkTableModule } from '@angular/cdk/table';
|
|
37
|
-
import * as i5
|
|
38
|
+
import * as i5 from '@angular/material/chips';
|
|
38
39
|
import { MatChipsModule } from '@angular/material/chips';
|
|
39
40
|
import * as i6 from '@angular/material/input';
|
|
40
41
|
import { MatInputModule, MatInput } from '@angular/material/input';
|
|
@@ -47,7 +48,7 @@ import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
|
47
48
|
import * as i1$5 from '@angular/material/table';
|
|
48
49
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
49
50
|
import * as i3$2 from '@angular/material/tooltip';
|
|
50
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
51
|
+
import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
|
|
51
52
|
import { __decorate, __metadata } from 'tslib';
|
|
52
53
|
import 'reflect-metadata';
|
|
53
54
|
import * as i2$1 from '@angular/material/select';
|
|
@@ -1248,6 +1249,10 @@ class BaseComponent {
|
|
|
1248
1249
|
* Service for displaying snack bar notifications.
|
|
1249
1250
|
*/
|
|
1250
1251
|
snackBarService;
|
|
1252
|
+
/**
|
|
1253
|
+
* Reference to the currently displayed snack bar, if any.
|
|
1254
|
+
*/
|
|
1255
|
+
snackBarRef;
|
|
1251
1256
|
/**
|
|
1252
1257
|
* Service for displaying confirmation and prompt dialogs.
|
|
1253
1258
|
*/
|
|
@@ -1480,38 +1485,56 @@ class BaseComponent {
|
|
|
1480
1485
|
/* Otherwise, expand the panel based on the URL hash if set */
|
|
1481
1486
|
this.expandPanelPath(this.urlHash ?? '');
|
|
1482
1487
|
}
|
|
1483
|
-
/*
|
|
1488
|
+
/* Array to hold all panel event streams */
|
|
1489
|
+
const panelStateChanges$ = [];
|
|
1490
|
+
/* Used to cancel pending close events when another panel opens */
|
|
1491
|
+
const openedSignal$ = new Subject();
|
|
1492
|
+
/* Prepare observables for all panels */
|
|
1484
1493
|
this.matExpansionPanelQueryList?.forEach(y => {
|
|
1485
|
-
|
|
1494
|
+
/* Map closed events to their target parent hash */
|
|
1495
|
+
panelStateChanges$.push(y.closed.pipe(switchMap(_ => {
|
|
1496
|
+
/* Get the id of the current closed panel */
|
|
1497
|
+
const currentPanelId = y['_viewContainerRef']?.element?.nativeElement?.id;
|
|
1498
|
+
const currentPanelIdParts = currentPanelId?.split('.');
|
|
1499
|
+
/* Extract parent ID if nested */
|
|
1500
|
+
const parentHash = (currentPanelIdParts && currentPanelIdParts.length > 1)
|
|
1501
|
+
? currentPanelIdParts.slice(0, -1).join('.')
|
|
1502
|
+
: null;
|
|
1503
|
+
/* Delay close handling so a near-simultaneous open can cancel it */
|
|
1504
|
+
return timer(50).pipe(takeUntil$1(openedSignal$),
|
|
1505
|
+
/* Ignore close when another panel is opening/opened */
|
|
1506
|
+
filter(_ => !(this.matExpansionPanelQueryList?.toArray()?.some(panel => {
|
|
1507
|
+
const panelId = panel['_viewContainerRef']?.element?.nativeElement?.id;
|
|
1508
|
+
return panel.expanded && panelId && panelId !== currentPanelId;
|
|
1509
|
+
}) ?? false)), map(_ => ({ action: 'close', hash: parentHash })));
|
|
1510
|
+
})));
|
|
1511
|
+
/* Map opened events to their target hash */
|
|
1512
|
+
panelStateChanges$.push(y.opened.pipe(tap(_ => openedSignal$.next()), map(_ => {
|
|
1513
|
+
/* Get the id of the current opened panel */
|
|
1514
|
+
const currentPanelId = y['_viewContainerRef']?.element?.nativeElement?.id;
|
|
1515
|
+
return { action: 'open', hash: currentPanelId };
|
|
1516
|
+
})));
|
|
1517
|
+
});
|
|
1518
|
+
/* Merge all event streams to handle concurrent open/close actions */
|
|
1519
|
+
if (panelStateChanges$.length > 0) {
|
|
1520
|
+
this.matExpansionPanelSubscriptions.push(merge$1(...panelStateChanges$).subscribe(eventState => {
|
|
1486
1521
|
if (this.setUrlHash) {
|
|
1487
|
-
/*
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
if (currentPanelId) {
|
|
1491
|
-
this.router.navigate([], { fragment: currentPanelId, replaceUrl: true });
|
|
1522
|
+
/* If a valid hash exists, set it as url segment */
|
|
1523
|
+
if (eventState.hash) {
|
|
1524
|
+
this.router.navigate([], { fragment: eventState.hash, replaceUrl: true });
|
|
1492
1525
|
}
|
|
1493
|
-
/*
|
|
1494
|
-
|
|
1526
|
+
/*
|
|
1527
|
+
* Otherwise remove the segment from the url (only on open actions to prevent
|
|
1528
|
+
* clearing the hash when collapsing a nested child)
|
|
1529
|
+
*/
|
|
1530
|
+
else if (eventState.action === 'open') {
|
|
1495
1531
|
this.router.navigate([], { replaceUrl: true });
|
|
1496
1532
|
}
|
|
1497
1533
|
}
|
|
1498
|
-
/* Detect changes */
|
|
1499
|
-
this.changeDetectorRef.detectChanges();
|
|
1500
|
-
}));
|
|
1501
|
-
/* Detect changes for closed panels */
|
|
1502
|
-
this.matExpansionPanelSubscriptions.push(y.closed.subscribe(_ => {
|
|
1503
|
-
if (this.setUrlHash) {
|
|
1504
|
-
/* Get the id of the current opened panel */
|
|
1505
|
-
var currentPanelIdParts = y['_viewContainerRef']?.element?.nativeElement?.id?.split('.');
|
|
1506
|
-
/* If the panel ID is set, set it as url segment (hash) */
|
|
1507
|
-
if (currentPanelIdParts.length > 1) {
|
|
1508
|
-
this.router.navigate([], { fragment: currentPanelIdParts.slice(0, -1).join('.'), replaceUrl: true });
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
/* Detect changes */
|
|
1534
|
+
/* Detect changes ONCE after the concurrent event storm settles */
|
|
1512
1535
|
this.changeDetectorRef.detectChanges();
|
|
1513
1536
|
}));
|
|
1514
|
-
}
|
|
1537
|
+
}
|
|
1515
1538
|
});
|
|
1516
1539
|
/* Notify expansion panel list changes */
|
|
1517
1540
|
if (this.matExpansionPanelQueryList) {
|
|
@@ -1716,12 +1739,18 @@ class BaseComponent {
|
|
|
1716
1739
|
break;
|
|
1717
1740
|
}
|
|
1718
1741
|
/* Display the message in the snack bar, with specified duration and CSS class */
|
|
1719
|
-
|
|
1742
|
+
this.snackBarRef = this.snackBarService.open(message, actionLabel, {
|
|
1720
1743
|
duration: duration,
|
|
1721
1744
|
panelClass: [snackBarClass]
|
|
1722
1745
|
});
|
|
1723
1746
|
/* Emits when the action button is clicked */
|
|
1724
|
-
return snackBarRef.onAction().pipe(map(() => { }));
|
|
1747
|
+
return this.snackBarRef.onAction().pipe(map(() => { }));
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Closes the currently displayed snack bar message, if any.
|
|
1751
|
+
*/
|
|
1752
|
+
closeMessage() {
|
|
1753
|
+
this.snackBarRef?.dismiss();
|
|
1725
1754
|
}
|
|
1726
1755
|
/**
|
|
1727
1756
|
* Initializes the TinyMCE editor with custom configuration.
|
|
@@ -2007,6 +2036,171 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2007
2036
|
args: [MatExpansionPanel]
|
|
2008
2037
|
}] } });
|
|
2009
2038
|
|
|
2039
|
+
/**
|
|
2040
|
+
* Directive that allows a dialog to be maximized via double-click on the handle.
|
|
2041
|
+
*/
|
|
2042
|
+
class VdDialogMaximizeDirective {
|
|
2043
|
+
elementRef;
|
|
2044
|
+
renderer;
|
|
2045
|
+
/**
|
|
2046
|
+
* The selector used to identify the root overlay pane to be resized.
|
|
2047
|
+
* @type {string}
|
|
2048
|
+
*/
|
|
2049
|
+
rootElementSelector = '.cdk-overlay-pane';
|
|
2050
|
+
/**
|
|
2051
|
+
* Whether the dialog is currently maximized.
|
|
2052
|
+
* @type {boolean}
|
|
2053
|
+
*/
|
|
2054
|
+
isMaximized = false;
|
|
2055
|
+
/**
|
|
2056
|
+
* Constructor that injects ElementRef and Renderer2 for DOM manipulation.
|
|
2057
|
+
* @param elementRef The ElementRef of the host element.
|
|
2058
|
+
* @param renderer The Renderer2 instance for DOM manipulation.
|
|
2059
|
+
*/
|
|
2060
|
+
constructor(elementRef, renderer) {
|
|
2061
|
+
this.elementRef = elementRef;
|
|
2062
|
+
this.renderer = renderer;
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Listens for the double-click event on the host element to toggle maximization.
|
|
2066
|
+
*/
|
|
2067
|
+
toggle() {
|
|
2068
|
+
/* Find the closest ancestor element that matches the rootElementSelector. This is typically the overlay pane that contains the dialog. */
|
|
2069
|
+
const pane = this.elementRef.nativeElement.closest(this.rootElementSelector);
|
|
2070
|
+
if (!pane) {
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
/* Toggle the maximized state */
|
|
2074
|
+
this.isMaximized = !this.isMaximized;
|
|
2075
|
+
/* Add or remove the 'dialog-maximized' class based on the maximized state */
|
|
2076
|
+
if (this.isMaximized) {
|
|
2077
|
+
this.renderer.addClass(pane, 'dialog-maximized');
|
|
2078
|
+
/* Reset the transform style to ensure the maximized dialog isn't offset by drag coordinates */
|
|
2079
|
+
this.renderer.setStyle(pane, 'transform', 'none', 1);
|
|
2080
|
+
}
|
|
2081
|
+
else {
|
|
2082
|
+
this.renderer.removeClass(pane, 'dialog-maximized');
|
|
2083
|
+
/* Removing the style allows cdkDrag to re-apply its internal transforms when dragged again */
|
|
2084
|
+
this.renderer.removeStyle(pane, 'transform');
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogMaximizeDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2088
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: VdDialogMaximizeDirective, isStandalone: true, selector: "[vdDialogMaximize]", inputs: { rootElementSelector: "rootElementSelector" }, host: { listeners: { "dblclick": "toggle()" } }, exportAs: ["dialogMaximize"], ngImport: i0 });
|
|
2089
|
+
}
|
|
2090
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogMaximizeDirective, decorators: [{
|
|
2091
|
+
type: Directive,
|
|
2092
|
+
args: [{
|
|
2093
|
+
selector: '[vdDialogMaximize]',
|
|
2094
|
+
exportAs: 'dialogMaximize',
|
|
2095
|
+
standalone: true
|
|
2096
|
+
}]
|
|
2097
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { rootElementSelector: [{
|
|
2098
|
+
type: Input
|
|
2099
|
+
}], toggle: [{
|
|
2100
|
+
type: HostListener,
|
|
2101
|
+
args: ['dblclick']
|
|
2102
|
+
}] } });
|
|
2103
|
+
|
|
2104
|
+
/**
|
|
2105
|
+
* Component that provides standard maximize and close actions for dialogs.
|
|
2106
|
+
*/
|
|
2107
|
+
class VdDialogHeaderActionsComponent {
|
|
2108
|
+
/**
|
|
2109
|
+
* Reference to the maximize directive instance.
|
|
2110
|
+
* @type {VdDialogMaximizeDirective}
|
|
2111
|
+
*/
|
|
2112
|
+
maximize;
|
|
2113
|
+
/**
|
|
2114
|
+
* Reference to the parent dialog to allow closing.
|
|
2115
|
+
* @type {MatDialogRef<any>}
|
|
2116
|
+
*/
|
|
2117
|
+
dialogRef;
|
|
2118
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogHeaderActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2119
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: VdDialogHeaderActionsComponent, isStandalone: true, selector: "vd-dialog-header-actions", inputs: { maximize: "maximize", dialogRef: "dialogRef" }, ngImport: i0, template: `
|
|
2120
|
+
<div class="dialog-actions" layout="row" layout-align="start center">
|
|
2121
|
+
<button mat-icon-button (click)="maximize.toggle()" type="button">
|
|
2122
|
+
<mat-icon>{{ maximize.isMaximized ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
|
|
2123
|
+
</button>
|
|
2124
|
+
<button mat-icon-button (click)="dialogRef.close()" type="button">
|
|
2125
|
+
<mat-icon>close</mat-icon>
|
|
2126
|
+
</button>
|
|
2127
|
+
</div>`, isInline: true, styles: [".dialog-actions{display:flex;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
2128
|
+
}
|
|
2129
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogHeaderActionsComponent, decorators: [{
|
|
2130
|
+
type: Component,
|
|
2131
|
+
args: [{ selector: 'vd-dialog-header-actions', template: `
|
|
2132
|
+
<div class="dialog-actions" layout="row" layout-align="start center">
|
|
2133
|
+
<button mat-icon-button (click)="maximize.toggle()" type="button">
|
|
2134
|
+
<mat-icon>{{ maximize.isMaximized ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
|
|
2135
|
+
</button>
|
|
2136
|
+
<button mat-icon-button (click)="dialogRef.close()" type="button">
|
|
2137
|
+
<mat-icon>close</mat-icon>
|
|
2138
|
+
</button>
|
|
2139
|
+
</div>`, imports: [
|
|
2140
|
+
MatButtonModule,
|
|
2141
|
+
MatIconModule
|
|
2142
|
+
], styles: [".dialog-actions{display:flex;gap:4px}\n"] }]
|
|
2143
|
+
}], propDecorators: { maximize: [{
|
|
2144
|
+
type: Input,
|
|
2145
|
+
args: [{ required: true }]
|
|
2146
|
+
}], dialogRef: [{
|
|
2147
|
+
type: Input,
|
|
2148
|
+
args: [{ required: true }]
|
|
2149
|
+
}] } });
|
|
2150
|
+
|
|
2151
|
+
/** * Reusable dialog header that handles dragging, maximizing, and closing.
|
|
2152
|
+
*/
|
|
2153
|
+
class VdDialogHeaderComponent {
|
|
2154
|
+
/**
|
|
2155
|
+
* Reference to the dialog instance to allow the close button to work.
|
|
2156
|
+
* @type {MatDialogRef<any>}
|
|
2157
|
+
*/
|
|
2158
|
+
dialogRef;
|
|
2159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2160
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: VdDialogHeaderComponent, isStandalone: true, selector: "vd-dialog-header", inputs: { dialogRef: "dialogRef" }, ngImport: i0, template: `
|
|
2161
|
+
<div vdDialogMaximize
|
|
2162
|
+
#maximize="dialogMaximize"
|
|
2163
|
+
cdkDrag
|
|
2164
|
+
cdkDragRootElement=".cdk-overlay-pane"
|
|
2165
|
+
[cdkDragDisabled]="maximize.isMaximized"
|
|
2166
|
+
cdkDragHandle
|
|
2167
|
+
class="dialog-header-container pad-right-sm push-none"
|
|
2168
|
+
layout="row"
|
|
2169
|
+
layout-align="space-between center">
|
|
2170
|
+
<span mat-dialog-title class="pad-left-sm push-left-sm" flex>
|
|
2171
|
+
<ng-content></ng-content>
|
|
2172
|
+
</span>
|
|
2173
|
+
<vd-dialog-header-actions [maximize]="maximize" [dialogRef]="dialogRef"></vd-dialog-header-actions>
|
|
2174
|
+
</div>`, isInline: true, styles: [".dialog-header-container{cursor:move;display:flex;width:100%}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: VdDialogMaximizeDirective, selector: "[vdDialogMaximize]", inputs: ["rootElementSelector"], exportAs: ["dialogMaximize"] }, { kind: "component", type: VdDialogHeaderActionsComponent, selector: "vd-dialog-header-actions", inputs: ["maximize", "dialogRef"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }] });
|
|
2175
|
+
}
|
|
2176
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDialogHeaderComponent, decorators: [{
|
|
2177
|
+
type: Component,
|
|
2178
|
+
args: [{ selector: 'vd-dialog-header', template: `
|
|
2179
|
+
<div vdDialogMaximize
|
|
2180
|
+
#maximize="dialogMaximize"
|
|
2181
|
+
cdkDrag
|
|
2182
|
+
cdkDragRootElement=".cdk-overlay-pane"
|
|
2183
|
+
[cdkDragDisabled]="maximize.isMaximized"
|
|
2184
|
+
cdkDragHandle
|
|
2185
|
+
class="dialog-header-container pad-right-sm push-none"
|
|
2186
|
+
layout="row"
|
|
2187
|
+
layout-align="space-between center">
|
|
2188
|
+
<span mat-dialog-title class="pad-left-sm push-left-sm" flex>
|
|
2189
|
+
<ng-content></ng-content>
|
|
2190
|
+
</span>
|
|
2191
|
+
<vd-dialog-header-actions [maximize]="maximize" [dialogRef]="dialogRef"></vd-dialog-header-actions>
|
|
2192
|
+
</div>`, imports: [
|
|
2193
|
+
MatDialogTitle,
|
|
2194
|
+
VdDialogMaximizeDirective,
|
|
2195
|
+
VdDialogHeaderActionsComponent,
|
|
2196
|
+
CdkDragHandle,
|
|
2197
|
+
CdkDrag
|
|
2198
|
+
], styles: [".dialog-header-container{cursor:move;display:flex;width:100%}\n"] }]
|
|
2199
|
+
}], propDecorators: { dialogRef: [{
|
|
2200
|
+
type: Input,
|
|
2201
|
+
args: [{ required: true }]
|
|
2202
|
+
}] } });
|
|
2203
|
+
|
|
2010
2204
|
/**
|
|
2011
2205
|
* This class sets up a blueprint for creating typed forms by providing a property (formGroup)
|
|
2012
2206
|
* for handling form data of a specific type (T). Users can extend this class and implement
|
|
@@ -11803,6 +11997,139 @@ function mixinDisabled(base) {
|
|
|
11803
11997
|
};
|
|
11804
11998
|
}
|
|
11805
11999
|
|
|
12000
|
+
class MsaEnumDisplayComponent {
|
|
12001
|
+
/**
|
|
12002
|
+
* The numeric value of the enum to convert.
|
|
12003
|
+
*/
|
|
12004
|
+
value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
12005
|
+
/**
|
|
12006
|
+
* The enum type (as an object) that defines the mapping of values to their string representations.
|
|
12007
|
+
* @type {any}
|
|
12008
|
+
*/
|
|
12009
|
+
enumType = input(...(ngDevMode ? [undefined, { debugName: "enumType" }] : /* istanbul ignore next */ []));
|
|
12010
|
+
/**
|
|
12011
|
+
* Optional metadata for the enum values, which can be used to provide additional display information.
|
|
12012
|
+
* This can be either a string prefix or an object containing EnumMetadata for each enum value.
|
|
12013
|
+
*/
|
|
12014
|
+
metadata = input(...(ngDevMode ? [undefined, { debugName: "metadata" }] : /* istanbul ignore next */ []));
|
|
12015
|
+
/**
|
|
12016
|
+
* Determines whether to display the icon alongside the text.
|
|
12017
|
+
* Defaults to false (hidden).
|
|
12018
|
+
*/
|
|
12019
|
+
showIcon = input(false, ...(ngDevMode ? [{ debugName: "showIcon" }] : /* istanbul ignore next */ []));
|
|
12020
|
+
/**
|
|
12021
|
+
* Optional entity context passed down to evaluate dynamic icon functions.
|
|
12022
|
+
*/
|
|
12023
|
+
entity = input(...(ngDevMode ? [undefined, { debugName: "entity" }] : /* istanbul ignore next */ []));
|
|
12024
|
+
/**
|
|
12025
|
+
* Optional execution context passed down to evaluate dynamic icon functions.
|
|
12026
|
+
*/
|
|
12027
|
+
context = input(...(ngDevMode ? [undefined, { debugName: "context" }] : /* istanbul ignore next */ []));
|
|
12028
|
+
/**
|
|
12029
|
+
* Extracts the current metadata object if it exists for the given value.
|
|
12030
|
+
*/
|
|
12031
|
+
currentMetadata = computed(() => {
|
|
12032
|
+
/* Get the current value and metadata */
|
|
12033
|
+
const val = this.value();
|
|
12034
|
+
const meta = this.metadata();
|
|
12035
|
+
/* Check if the metadata is an object and contains the current value */
|
|
12036
|
+
if (val !== null && val !== undefined && meta && typeof meta === 'object' && val in meta) {
|
|
12037
|
+
return meta[val];
|
|
12038
|
+
}
|
|
12039
|
+
return null;
|
|
12040
|
+
}, ...(ngDevMode ? [{ debugName: "currentMetadata" }] : /* istanbul ignore next */ []));
|
|
12041
|
+
/**
|
|
12042
|
+
* Dynamically evaluates the Icon configuration properties based on whether they are static values or context functions.
|
|
12043
|
+
*/
|
|
12044
|
+
resolvedIcon = computed(() => {
|
|
12045
|
+
/* Early exit if icons are explicitly configured to be hidden */
|
|
12046
|
+
if (!this.showIcon()) {
|
|
12047
|
+
return null;
|
|
12048
|
+
}
|
|
12049
|
+
/* Retrieve the current metadata and extract the icon configuration */
|
|
12050
|
+
const meta = this.currentMetadata();
|
|
12051
|
+
const iconConfig = meta?.icon;
|
|
12052
|
+
if (!iconConfig) {
|
|
12053
|
+
return null;
|
|
12054
|
+
}
|
|
12055
|
+
/* Retrieve the entity and context for dynamic evaluation */
|
|
12056
|
+
const x = this.entity();
|
|
12057
|
+
const ctx = this.context();
|
|
12058
|
+
/* Evaluate visibility rule from layout configurations */
|
|
12059
|
+
const shouldHide = typeof iconConfig.hide === 'function' ? iconConfig.hide(x, ctx) : iconConfig.hide;
|
|
12060
|
+
if (shouldHide) {
|
|
12061
|
+
return null;
|
|
12062
|
+
}
|
|
12063
|
+
/* Helper to resolve string values or callback functions dynamically */
|
|
12064
|
+
const resolve = (prop) => typeof prop === 'function' ? prop(x, ctx) : prop;
|
|
12065
|
+
/* Return the resolved icon configuration with evaluated properties */
|
|
12066
|
+
return {
|
|
12067
|
+
matIcon: resolve(iconConfig.matIcon),
|
|
12068
|
+
svgIcon: resolve(iconConfig.svgIcon),
|
|
12069
|
+
fontIcon: resolve(iconConfig.fontIcon),
|
|
12070
|
+
fontSet: iconConfig.fontSet ?? 'material-symbols-outlined',
|
|
12071
|
+
color: resolve(iconConfig.iconColor),
|
|
12072
|
+
cssClass: resolve(iconConfig.cssClass)
|
|
12073
|
+
};
|
|
12074
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedIcon" }] : /* istanbul ignore next */ []));
|
|
12075
|
+
/**
|
|
12076
|
+
* Resolves the text to display based on metadata or enum lookup.
|
|
12077
|
+
*/
|
|
12078
|
+
resolvedText = computed(() => {
|
|
12079
|
+
/* Get the current value */
|
|
12080
|
+
const val = this.value();
|
|
12081
|
+
if (val === null || val === undefined) {
|
|
12082
|
+
return '';
|
|
12083
|
+
}
|
|
12084
|
+
/* Attempt to retrieve the display string from the metadata if available */
|
|
12085
|
+
const metaObj = this.currentMetadata();
|
|
12086
|
+
if (metaObj) {
|
|
12087
|
+
return metaObj.display ?? '';
|
|
12088
|
+
}
|
|
12089
|
+
/* Fallback to enum type lookup if metadata is not available */
|
|
12090
|
+
const type = this.enumType();
|
|
12091
|
+
const metaStr = this.metadata();
|
|
12092
|
+
/* If the enum type is an object and contains the value, return the corresponding string representation with optional prefix */
|
|
12093
|
+
if (type && typeof type === 'object' && val in type) {
|
|
12094
|
+
const prefix = typeof metaStr === 'string' ? metaStr : '';
|
|
12095
|
+
return `${prefix}${type[val]}`;
|
|
12096
|
+
}
|
|
12097
|
+
return '';
|
|
12098
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedText" }] : /* istanbul ignore next */ []));
|
|
12099
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MsaEnumDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12100
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MsaEnumDisplayComponent, isStandalone: true, selector: "msa-enum-display", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, enumType: { classPropertyName: "enumType", publicName: "enumType", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
12101
|
+
@if (resolvedIcon(); as iconConfig) {
|
|
12102
|
+
<mat-icon
|
|
12103
|
+
[svgIcon]="iconConfig.svgIcon"
|
|
12104
|
+
[fontIcon]="iconConfig.fontIcon"
|
|
12105
|
+
[fontSet]="iconConfig.fontSet"
|
|
12106
|
+
[style.color]="iconConfig.color"
|
|
12107
|
+
[ngClass]="iconConfig.cssClass"
|
|
12108
|
+
class="enum-icon">
|
|
12109
|
+
@if (iconConfig.matIcon) { {{ iconConfig.matIcon }} }
|
|
12110
|
+
</mat-icon>
|
|
12111
|
+
}
|
|
12112
|
+
@let text = resolvedText();
|
|
12113
|
+
<span class="enum-text" i18n="@@selection">{ text, select, type {type} other { {{text}}} }</span>`, isInline: true, styles: [".enum-icon{margin-right:.2rem;vertical-align:middle}.enum-text{vertical-align:middle}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
12114
|
+
}
|
|
12115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MsaEnumDisplayComponent, decorators: [{
|
|
12116
|
+
type: Component,
|
|
12117
|
+
args: [{ selector: 'msa-enum-display', standalone: true, imports: [MatIcon, NgClass], template: `
|
|
12118
|
+
@if (resolvedIcon(); as iconConfig) {
|
|
12119
|
+
<mat-icon
|
|
12120
|
+
[svgIcon]="iconConfig.svgIcon"
|
|
12121
|
+
[fontIcon]="iconConfig.fontIcon"
|
|
12122
|
+
[fontSet]="iconConfig.fontSet"
|
|
12123
|
+
[style.color]="iconConfig.color"
|
|
12124
|
+
[ngClass]="iconConfig.cssClass"
|
|
12125
|
+
class="enum-icon">
|
|
12126
|
+
@if (iconConfig.matIcon) { {{ iconConfig.matIcon }} }
|
|
12127
|
+
</mat-icon>
|
|
12128
|
+
}
|
|
12129
|
+
@let text = resolvedText();
|
|
12130
|
+
<span class="enum-text" i18n="@@selection">{ text, select, type {type} other { {{text}}} }</span>`, styles: [".enum-icon{margin-right:.2rem;vertical-align:middle}.enum-text{vertical-align:middle}\n"] }]
|
|
12131
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], enumType: [{ type: i0.Input, args: [{ isSignal: true, alias: "enumType", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }], showIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcon", required: false }] }], entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
|
|
12132
|
+
|
|
11806
12133
|
const headerMetadataKey = 'customer:vdHeader';
|
|
11807
12134
|
const endpointMetadataKey = 'customer:vdEndpoint';
|
|
11808
12135
|
|
|
@@ -12117,6 +12444,15 @@ function getDisplay(origin) {
|
|
|
12117
12444
|
return Reflect.getMetadata(headerMetadataKey, origin);
|
|
12118
12445
|
}
|
|
12119
12446
|
|
|
12447
|
+
/**
|
|
12448
|
+
* @method graphql
|
|
12449
|
+
* @description A tag function that tells IDEs (VS Code/WebStorm)
|
|
12450
|
+
* to provide GraphQL syntax highlighting without adding runtime dependencies.
|
|
12451
|
+
*/
|
|
12452
|
+
function graphql(strings, ...values) {
|
|
12453
|
+
return strings.reduce((acc, str, i) => acc + str + (values[i] || ''), '');
|
|
12454
|
+
}
|
|
12455
|
+
|
|
12120
12456
|
//@dynamic
|
|
12121
12457
|
class AppStorage {
|
|
12122
12458
|
/**
|
|
@@ -12355,6 +12691,18 @@ class TableColumn {
|
|
|
12355
12691
|
* @property
|
|
12356
12692
|
*/
|
|
12357
12693
|
filterOptionText;
|
|
12694
|
+
/**
|
|
12695
|
+
* @property filterTooltip
|
|
12696
|
+
* @description Tooltip for the filter input.
|
|
12697
|
+
* @type {(ctx?: IGenericListComponent<TEntity>) => any}
|
|
12698
|
+
*/
|
|
12699
|
+
filterTooltip;
|
|
12700
|
+
/**
|
|
12701
|
+
* @property filterTooltipClass
|
|
12702
|
+
* @description CSS class for the filter tooltip.
|
|
12703
|
+
* @type {string}
|
|
12704
|
+
*/
|
|
12705
|
+
filterTooltipClass;
|
|
12358
12706
|
/**
|
|
12359
12707
|
* The header text for the column.
|
|
12360
12708
|
* @property
|
|
@@ -13138,6 +13486,12 @@ class EnumMetadata {
|
|
|
13138
13486
|
* @type {string}
|
|
13139
13487
|
*/
|
|
13140
13488
|
display;
|
|
13489
|
+
/**
|
|
13490
|
+
* @property Hint
|
|
13491
|
+
* @description An optional hint string associated with the enum value. This string can be used to provide additional information or guidance in the UI.
|
|
13492
|
+
* @type {string}
|
|
13493
|
+
*/
|
|
13494
|
+
hint;
|
|
13141
13495
|
/**
|
|
13142
13496
|
* @property Icon
|
|
13143
13497
|
* @description An optional icon associated with the enum value. This can be used to visually represent the enum value in the UI.
|
|
@@ -13446,6 +13800,10 @@ class EnumPipe {
|
|
|
13446
13800
|
* or undefined if the value is not recognized in the provided enum type.
|
|
13447
13801
|
*/
|
|
13448
13802
|
transform(value, enumType, prefixOrMetadata, suffix = '') {
|
|
13803
|
+
/* Return undefined if the value is null or undefined */
|
|
13804
|
+
if (value === null || value === undefined) {
|
|
13805
|
+
return undefined;
|
|
13806
|
+
}
|
|
13449
13807
|
/* Determine if prefixOrMetadata is an object containing EnumMetadata for the given value */
|
|
13450
13808
|
if (prefixOrMetadata && typeof prefixOrMetadata === 'object' && value in prefixOrMetadata) {
|
|
13451
13809
|
const metadata = prefixOrMetadata[value];
|
|
@@ -14195,30 +14553,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
14195
14553
|
}]
|
|
14196
14554
|
}] });
|
|
14197
14555
|
|
|
14556
|
+
/**
|
|
14557
|
+
* @method parseProjectionString
|
|
14558
|
+
* @description Parses projection input (string, string array, or raw multi-line string) into a flattened API-friendly projection string.
|
|
14559
|
+
* @param {string | string[]} projection The raw selection input
|
|
14560
|
+
* @returns {string} The formatted comma-separated string with no whitespace
|
|
14561
|
+
*/
|
|
14562
|
+
const parseProjectionString = (projection) => {
|
|
14563
|
+
/* Handle array input: join and proceed to cleaning */
|
|
14564
|
+
let input = Array.isArray(projection) ? projection.join(',') : projection;
|
|
14565
|
+
/* If it's already a clean, flat, comma-separated string without braces, return it */
|
|
14566
|
+
if (!input.includes('{') && !input.includes('}')) {
|
|
14567
|
+
return input.replace(/\s+/g, '');
|
|
14568
|
+
}
|
|
14569
|
+
/* Clean the string: remove newlines, extra spaces, and replace { with ( and } with ) */
|
|
14570
|
+
let cleaned = input
|
|
14571
|
+
.replace(/\s+/g, ' ')
|
|
14572
|
+
.replace(/\s?\{\s?/g, '(')
|
|
14573
|
+
.replace(/\s?\}\s?/g, ')')
|
|
14574
|
+
.trim();
|
|
14575
|
+
/* Remove trailing commas before closing parentheses */
|
|
14576
|
+
cleaned = cleaned.replace(/,\s*\)/g, ')');
|
|
14577
|
+
/* Replace spaces between alphanumeric characters with commas and remove all remaining whitespace */
|
|
14578
|
+
return cleaned
|
|
14579
|
+
.replace(/([a-zA-Z0-9])\s+([a-zA-Z0-9])/g, '$1,$2')
|
|
14580
|
+
.replace(/\)([a-zA-Z_])/g, '),$1')
|
|
14581
|
+
.replace(/\s+/g, '');
|
|
14582
|
+
};
|
|
14583
|
+
|
|
14198
14584
|
class GenericService {
|
|
14199
14585
|
endpoint;
|
|
14200
14586
|
/**
|
|
14201
|
-
*
|
|
14587
|
+
* Injected Angular HttpClient instance
|
|
14202
14588
|
*/
|
|
14203
14589
|
http = inject(HttpClient);
|
|
14204
14590
|
/**
|
|
14205
|
-
*
|
|
14591
|
+
* BehaviorSubject holding the current list of entities
|
|
14206
14592
|
*/
|
|
14207
14593
|
list = new BehaviorSubject([]);
|
|
14208
14594
|
/**
|
|
14209
14595
|
* Constructor
|
|
14210
|
-
*
|
|
14211
|
-
* @param http
|
|
14596
|
+
* @param endpoint Optional API endpoint for the service
|
|
14212
14597
|
*/
|
|
14213
14598
|
constructor(endpoint) {
|
|
14214
14599
|
this.endpoint = endpoint;
|
|
14215
14600
|
}
|
|
14216
14601
|
/**
|
|
14217
|
-
*
|
|
14218
|
-
*
|
|
14219
|
-
* @param
|
|
14220
|
-
* @param
|
|
14221
|
-
* @param
|
|
14602
|
+
* Retrieves a single entity by ID or relative path
|
|
14603
|
+
* @param id The entity ID or relative path
|
|
14604
|
+
* @param params Optional query parameters
|
|
14605
|
+
* @param headers Optional HTTP headers
|
|
14606
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14607
|
+
* @param observeResponse Whether to observe the full response (default: false)
|
|
14222
14608
|
*/
|
|
14223
14609
|
get(id, params, headers, handleError = true, observeResponse = false) {
|
|
14224
14610
|
let request = this.http
|
|
@@ -14230,12 +14616,20 @@ class GenericService {
|
|
|
14230
14616
|
return request;
|
|
14231
14617
|
}
|
|
14232
14618
|
/**
|
|
14233
|
-
*
|
|
14234
|
-
*
|
|
14235
|
-
* @param params
|
|
14236
|
-
* @
|
|
14237
|
-
|
|
14238
|
-
|
|
14619
|
+
* Asynchronously retrieves a single entity by ID or relative path
|
|
14620
|
+
* @param id The entity ID or relative path
|
|
14621
|
+
* @param params Optional query parameters
|
|
14622
|
+
* @returns Promise resolving to the entity
|
|
14623
|
+
*/
|
|
14624
|
+
async getAsync(id, params) {
|
|
14625
|
+
return await firstValueFrom(this.get(id, params));
|
|
14626
|
+
}
|
|
14627
|
+
/**
|
|
14628
|
+
* Counts entities on the server
|
|
14629
|
+
* @param params Optional query parameters
|
|
14630
|
+
* @param path Optional relative path to the count action
|
|
14631
|
+
* @param headers Optional HTTP headers
|
|
14632
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14239
14633
|
*/
|
|
14240
14634
|
count(params, path, headers, handleError = true) {
|
|
14241
14635
|
let request = this.http
|
|
@@ -14247,41 +14641,81 @@ class GenericService {
|
|
|
14247
14641
|
return request.pipe(map$1(x => { return x.value; }));
|
|
14248
14642
|
}
|
|
14249
14643
|
/**
|
|
14250
|
-
*
|
|
14251
|
-
*
|
|
14252
|
-
* @param
|
|
14253
|
-
* @
|
|
14254
|
-
|
|
14255
|
-
|
|
14644
|
+
* Asynchronously counts entities on the server
|
|
14645
|
+
* @param params Optional query parameters
|
|
14646
|
+
* @param path Optional relative path to the count action
|
|
14647
|
+
* @returns Promise resolving to the count
|
|
14648
|
+
*/
|
|
14649
|
+
async countAsync(params, path) {
|
|
14650
|
+
return await firstValueFrom(this.count(params, path));
|
|
14651
|
+
}
|
|
14652
|
+
/**
|
|
14653
|
+
* Retrieves a list of entities
|
|
14654
|
+
* @param params Optional query parameters
|
|
14655
|
+
* @param path Optional relative path to the action
|
|
14656
|
+
* @param headers Optional HTTP headers
|
|
14657
|
+
* @returns Observable with the response data
|
|
14256
14658
|
*/
|
|
14257
14659
|
getList(params, path, headers) {
|
|
14660
|
+
const parsedParams = this.normalizeProjectionParam(params);
|
|
14258
14661
|
return this.http
|
|
14259
|
-
.get(`${this.endpoint}${path ? path : ''}`, {
|
|
14662
|
+
.get(`${this.endpoint}${path ? path : ''}`, {
|
|
14663
|
+
params: parsedParams instanceof HttpParams ? parsedParams : Utils.toHttpParams(parsedParams),
|
|
14664
|
+
headers: this.toHttpHeaders(headers)
|
|
14665
|
+
})
|
|
14260
14666
|
.pipe(catchError(this.handleError('getList')));
|
|
14261
14667
|
}
|
|
14262
14668
|
/**
|
|
14263
|
-
*
|
|
14264
|
-
* @param params
|
|
14265
|
-
* @param path
|
|
14266
|
-
* @param headers
|
|
14669
|
+
* Asynchronously retrieves a list of entities
|
|
14670
|
+
* @param params Optional query parameters
|
|
14671
|
+
* @param path Optional relative path to the action
|
|
14672
|
+
* @param headers Optional HTTP headers
|
|
14673
|
+
* @returns Promise resolving to the response data
|
|
14674
|
+
*/
|
|
14675
|
+
async getListAsync(params, path, headers) {
|
|
14676
|
+
/* Calling the observable-based method and converting to promise */
|
|
14677
|
+
const request$ = this.getList(params, path, headers);
|
|
14678
|
+
/* Using firstValueFrom to handle the single response value */
|
|
14679
|
+
return await firstValueFrom(request$);
|
|
14680
|
+
}
|
|
14681
|
+
/**
|
|
14682
|
+
* Loads data into the BehaviorSubject list
|
|
14683
|
+
* @param params Optional query parameters
|
|
14684
|
+
* @param path Optional relative path to the action
|
|
14685
|
+
* @param headers Optional HTTP headers
|
|
14267
14686
|
*/
|
|
14268
14687
|
loadList(params, path, headers) {
|
|
14269
14688
|
this.getList(params, path, headers)
|
|
14270
14689
|
.subscribe(x => this.list.next(x));
|
|
14271
14690
|
}
|
|
14272
14691
|
/**
|
|
14273
|
-
*
|
|
14692
|
+
* Loads data into the BehaviorSubject list asynchronously
|
|
14693
|
+
* @param params Optional query parameters
|
|
14694
|
+
* @param path Optional relative path to the action
|
|
14695
|
+
* @param headers Optional HTTP headers
|
|
14696
|
+
*/
|
|
14697
|
+
/**
|
|
14698
|
+
* Asynchronously loads data into the BehaviorSubject list
|
|
14699
|
+
* @param params Optional query parameters
|
|
14700
|
+
* @param path Optional relative path to the action
|
|
14701
|
+
* @param headers Optional HTTP headers
|
|
14702
|
+
*/
|
|
14703
|
+
async loadListAsync(params, path, headers) {
|
|
14704
|
+
const data = await this.getListAsync(params, path, headers);
|
|
14705
|
+
this.list.next(data);
|
|
14706
|
+
}
|
|
14707
|
+
/**
|
|
14708
|
+
* Returns the list BehaviorSubject as an Observable
|
|
14274
14709
|
*/
|
|
14275
14710
|
getListAsObservable() {
|
|
14276
14711
|
return this.list.asObservable();
|
|
14277
14712
|
}
|
|
14278
14713
|
/**
|
|
14279
|
-
* Creates
|
|
14280
|
-
*
|
|
14714
|
+
* Creates a new entity
|
|
14281
14715
|
* @param entity The entity to create
|
|
14282
|
-
* @param path
|
|
14283
|
-
* @param httpOptions
|
|
14284
|
-
* @param handleError
|
|
14716
|
+
* @param path Optional relative path to the action
|
|
14717
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14718
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14285
14719
|
*/
|
|
14286
14720
|
create(entity, path, httpOptions, handleError = true) {
|
|
14287
14721
|
let request = this.http
|
|
@@ -14293,12 +14727,22 @@ class GenericService {
|
|
|
14293
14727
|
return request;
|
|
14294
14728
|
}
|
|
14295
14729
|
/**
|
|
14296
|
-
*
|
|
14297
|
-
*
|
|
14298
|
-
* @param
|
|
14299
|
-
* @param
|
|
14300
|
-
* @
|
|
14301
|
-
|
|
14730
|
+
* Asynchronously creates a new entity
|
|
14731
|
+
* @param entity The entity to create
|
|
14732
|
+
* @param path Optional relative path to the action
|
|
14733
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14734
|
+
* @returns Promise resolving to the created entity
|
|
14735
|
+
*/
|
|
14736
|
+
async createAsync(entity, path, httpOptions) {
|
|
14737
|
+
return await firstValueFrom(this.create(entity, path, httpOptions));
|
|
14738
|
+
}
|
|
14739
|
+
/**
|
|
14740
|
+
* Updates an existing entity asynchronously
|
|
14741
|
+
* @param id The ID of the entity to update
|
|
14742
|
+
* @param entity The updated entity data
|
|
14743
|
+
* @param path Optional relative path to the action
|
|
14744
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14745
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14302
14746
|
*/
|
|
14303
14747
|
update(id, entity, path, httpOptions, handleError = true) {
|
|
14304
14748
|
let request = this.http
|
|
@@ -14310,13 +14754,23 @@ class GenericService {
|
|
|
14310
14754
|
return request;
|
|
14311
14755
|
}
|
|
14312
14756
|
/**
|
|
14313
|
-
*
|
|
14314
|
-
*
|
|
14315
|
-
* @param
|
|
14316
|
-
* @param
|
|
14317
|
-
* @param
|
|
14318
|
-
* @
|
|
14319
|
-
|
|
14757
|
+
* Asynchronously updates an existing entity
|
|
14758
|
+
* @param id The ID of the entity to update
|
|
14759
|
+
* @param entity The updated entity data
|
|
14760
|
+
* @param path Optional relative path to the action
|
|
14761
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14762
|
+
* @returns Promise resolving to the updated entity
|
|
14763
|
+
*/
|
|
14764
|
+
async updateAsync(id, entity, path, httpOptions) {
|
|
14765
|
+
return await firstValueFrom(this.update(id, entity, path, httpOptions));
|
|
14766
|
+
}
|
|
14767
|
+
/**
|
|
14768
|
+
* Applies a JSON Patch to an entity
|
|
14769
|
+
* @param id The ID of the item to patch
|
|
14770
|
+
* @param body The patch body
|
|
14771
|
+
* @param path Optional relative path to the action
|
|
14772
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14773
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14320
14774
|
*/
|
|
14321
14775
|
patch(id, body, path, httpOptions, handleError = true) {
|
|
14322
14776
|
/* Ensure correct content-type for patch */
|
|
@@ -14339,13 +14793,23 @@ class GenericService {
|
|
|
14339
14793
|
return request;
|
|
14340
14794
|
}
|
|
14341
14795
|
/**
|
|
14342
|
-
*
|
|
14343
|
-
*
|
|
14344
|
-
* @param
|
|
14345
|
-
* @param
|
|
14346
|
-
* @param
|
|
14347
|
-
* @
|
|
14348
|
-
|
|
14796
|
+
* Asynchronously applies a JSON Patch to an entity
|
|
14797
|
+
* @param id The ID of the item to patch
|
|
14798
|
+
* @param body The patch body
|
|
14799
|
+
* @param path Optional relative path to the action
|
|
14800
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14801
|
+
* @returns Promise resolving to the patched entity
|
|
14802
|
+
*/
|
|
14803
|
+
async patchAsync(id, body, path, httpOptions) {
|
|
14804
|
+
return await firstValueFrom(this.patch(id, body, path, httpOptions));
|
|
14805
|
+
}
|
|
14806
|
+
/**
|
|
14807
|
+
* Applies a JSON Patch to multiple entities
|
|
14808
|
+
* @param ids The IDs of the items to patch
|
|
14809
|
+
* @param body The patch body
|
|
14810
|
+
* @param path Optional relative path to the action
|
|
14811
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14812
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14349
14813
|
*/
|
|
14350
14814
|
patchList(ids, body, path, httpOptions, handleError = true) {
|
|
14351
14815
|
let request = this.http
|
|
@@ -14357,12 +14821,22 @@ class GenericService {
|
|
|
14357
14821
|
return request;
|
|
14358
14822
|
}
|
|
14359
14823
|
/**
|
|
14360
|
-
*
|
|
14361
|
-
*
|
|
14362
|
-
* @param
|
|
14363
|
-
* @param path
|
|
14364
|
-
* @param httpOptions
|
|
14365
|
-
* @
|
|
14824
|
+
* Asynchronously applies a JSON Patch to multiple entities
|
|
14825
|
+
* @param ids The IDs of the items to patch
|
|
14826
|
+
* @param body The patch body
|
|
14827
|
+
* @param path Optional relative path to the action
|
|
14828
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14829
|
+
* @returns Promise resolving to the patched entities
|
|
14830
|
+
*/
|
|
14831
|
+
async patchListAsync(ids, body, path, httpOptions) {
|
|
14832
|
+
return await firstValueFrom(this.patchList(ids, body, path, httpOptions));
|
|
14833
|
+
}
|
|
14834
|
+
/**
|
|
14835
|
+
* Deletes an entity by ID
|
|
14836
|
+
* @param id The ID of the item to delete
|
|
14837
|
+
* @param path Optional relative path to the action
|
|
14838
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14839
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14366
14840
|
*/
|
|
14367
14841
|
delete(id, path, httpOptions, handleError = true) {
|
|
14368
14842
|
let request = this.http
|
|
@@ -14374,12 +14848,21 @@ class GenericService {
|
|
|
14374
14848
|
return request;
|
|
14375
14849
|
}
|
|
14376
14850
|
/**
|
|
14377
|
-
*
|
|
14378
|
-
*
|
|
14379
|
-
* @param
|
|
14380
|
-
* @param
|
|
14381
|
-
* @
|
|
14382
|
-
|
|
14851
|
+
* Asynchronously deletes an entity by ID
|
|
14852
|
+
* @param id The ID of the item to delete
|
|
14853
|
+
* @param path Optional relative path to the action
|
|
14854
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14855
|
+
* @returns Promise resolving to the delete result
|
|
14856
|
+
*/
|
|
14857
|
+
async deleteAsync(id, path, httpOptions) {
|
|
14858
|
+
return await firstValueFrom(this.delete(id, path, httpOptions));
|
|
14859
|
+
}
|
|
14860
|
+
/**
|
|
14861
|
+
* Deletes multiple entities by IDs
|
|
14862
|
+
* @param ids The IDs of the items to delete
|
|
14863
|
+
* @param path Optional relative path to the action
|
|
14864
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14865
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14383
14866
|
*/
|
|
14384
14867
|
deleteList(ids, path, httpOptions, handleError = true) {
|
|
14385
14868
|
let request = this.http.delete(`${this.endpoint}${path ? path : ''}`, Object.assign(httpOptions || {}, { params: Utils.toHttpParams({ ids: ids }) }));
|
|
@@ -14390,10 +14873,20 @@ class GenericService {
|
|
|
14390
14873
|
return request;
|
|
14391
14874
|
}
|
|
14392
14875
|
/**
|
|
14393
|
-
*
|
|
14394
|
-
*
|
|
14395
|
-
* @param path
|
|
14396
|
-
* @param
|
|
14876
|
+
* Asynchronously deletes multiple entities by IDs
|
|
14877
|
+
* @param ids The IDs of the items to delete
|
|
14878
|
+
* @param path Optional relative path to the action
|
|
14879
|
+
* @param httpOptions Optional HTTP options (headers, etc.)
|
|
14880
|
+
* @returns Promise resolving to the delete result
|
|
14881
|
+
*/
|
|
14882
|
+
async deleteListAsync(ids, path, httpOptions) {
|
|
14883
|
+
return await firstValueFrom(this.deleteList(ids, path, httpOptions));
|
|
14884
|
+
}
|
|
14885
|
+
/**
|
|
14886
|
+
* Downloads a file from the server
|
|
14887
|
+
* @param path Relative path to the download action
|
|
14888
|
+
* @param params Optional query parameters
|
|
14889
|
+
* @param handleError Whether to handle errors (default: true)
|
|
14397
14890
|
*/
|
|
14398
14891
|
download(path, params, handleError = true) {
|
|
14399
14892
|
let request = this.http
|
|
@@ -14406,17 +14899,35 @@ class GenericService {
|
|
|
14406
14899
|
return request;
|
|
14407
14900
|
}
|
|
14408
14901
|
/**
|
|
14409
|
-
*
|
|
14410
|
-
* @param
|
|
14902
|
+
* Asynchronously downloads a file from the server
|
|
14903
|
+
* @param path Relative path to the download action
|
|
14904
|
+
* @param params Optional query parameters
|
|
14905
|
+
* @returns Promise resolving to the download result
|
|
14906
|
+
*/
|
|
14907
|
+
async downloadAsync(path, params) {
|
|
14908
|
+
return await firstValueFrom(this.download(path, params));
|
|
14909
|
+
}
|
|
14910
|
+
/**
|
|
14911
|
+
* Duplicates a record by ID
|
|
14912
|
+
* @param id The ID of the record to duplicate
|
|
14411
14913
|
*/
|
|
14412
14914
|
duplicate(id) {
|
|
14413
14915
|
return this.create(null, `/duplicate/${id}`);
|
|
14414
14916
|
}
|
|
14415
14917
|
/**
|
|
14416
|
-
*
|
|
14417
|
-
*
|
|
14918
|
+
* Asynchronously duplicates a record by ID
|
|
14919
|
+
* @param id The ID of the record to duplicate
|
|
14920
|
+
* @returns Promise resolving to the duplicated record
|
|
14921
|
+
*/
|
|
14922
|
+
async duplicateAsync(id) {
|
|
14923
|
+
return await firstValueFrom(this.duplicate(id));
|
|
14924
|
+
}
|
|
14925
|
+
/**
|
|
14926
|
+
* Uploads a file to the server
|
|
14418
14927
|
* @param file The file to upload
|
|
14419
|
-
* @param path
|
|
14928
|
+
* @param path Optional relative path to the upload action (default: 'upload')
|
|
14929
|
+
* @param extraData Optional extra form data to include
|
|
14930
|
+
* @returns Observable of HttpEvent for upload progress tracking
|
|
14420
14931
|
*/
|
|
14421
14932
|
upload(file, path = 'upload', extraData) {
|
|
14422
14933
|
/* Creates form data object */
|
|
@@ -14440,11 +14951,21 @@ class GenericService {
|
|
|
14440
14951
|
return this.http.request(req);
|
|
14441
14952
|
}
|
|
14442
14953
|
;
|
|
14954
|
+
/**
|
|
14955
|
+
* Asynchronously uploads a file to the server
|
|
14956
|
+
* @param file The file to upload
|
|
14957
|
+
* @param path Optional relative path to the upload action (default: 'upload')
|
|
14958
|
+
* @param extraData Optional extra form data to include
|
|
14959
|
+
* @returns Promise resolving to the upload result
|
|
14960
|
+
*/
|
|
14961
|
+
async uploadAsync(file, path = 'upload', extraData) {
|
|
14962
|
+
return await firstValueFrom(this.upload(file, path, extraData));
|
|
14963
|
+
}
|
|
14443
14964
|
///#region Helpers
|
|
14444
14965
|
/**
|
|
14445
|
-
*
|
|
14446
|
-
*
|
|
14447
|
-
* @
|
|
14966
|
+
* Converts an object to FormData
|
|
14967
|
+
* @param body The object to convert
|
|
14968
|
+
* @returns FormData instance
|
|
14448
14969
|
*/
|
|
14449
14970
|
toFormData(body) {
|
|
14450
14971
|
if (!body) {
|
|
@@ -14455,9 +14976,9 @@ class GenericService {
|
|
|
14455
14976
|
.reduce((p, key) => { p.append(key, body[key]); return p; }, new FormData());
|
|
14456
14977
|
}
|
|
14457
14978
|
/**
|
|
14458
|
-
*
|
|
14459
|
-
*
|
|
14460
|
-
* @
|
|
14979
|
+
* Converts an object to HttpHeaders
|
|
14980
|
+
* @param body The object to convert
|
|
14981
|
+
* @returns HttpHeaders instance
|
|
14461
14982
|
*/
|
|
14462
14983
|
toHttpHeaders(body) {
|
|
14463
14984
|
if (!body) {
|
|
@@ -14468,8 +14989,39 @@ class GenericService {
|
|
|
14468
14989
|
.reduce((p, key) => p.set(key, body[key]), new HttpHeaders());
|
|
14469
14990
|
}
|
|
14470
14991
|
/**
|
|
14471
|
-
*
|
|
14472
|
-
* @param
|
|
14992
|
+
* Normalizes the 'projection' parameter in query parameters
|
|
14993
|
+
* @param params The query parameters (HttpParams or object)
|
|
14994
|
+
* @returns Normalized query parameters with 'projection' formatted
|
|
14995
|
+
*/
|
|
14996
|
+
normalizeProjectionParam(params) {
|
|
14997
|
+
/* If params is null or undefined, return it as is */
|
|
14998
|
+
if (!params) {
|
|
14999
|
+
return params;
|
|
15000
|
+
}
|
|
15001
|
+
/* If params is an instance of HttpParams, extract and normalize the 'projection' parameter */
|
|
15002
|
+
if (params instanceof HttpParams) {
|
|
15003
|
+
const projection = params.get('projection');
|
|
15004
|
+
if (!projection) {
|
|
15005
|
+
return params;
|
|
15006
|
+
}
|
|
15007
|
+
/* If projection is present, normalize it and return a new HttpParams instance with the updated projection */
|
|
15008
|
+
return params.set('projection', parseProjectionString(projection));
|
|
15009
|
+
}
|
|
15010
|
+
/* If params is a plain object, normalize the 'projection' property */
|
|
15011
|
+
const typedParams = params;
|
|
15012
|
+
if (typedParams['projection'] == null || typedParams['projection'] === '') {
|
|
15013
|
+
return params;
|
|
15014
|
+
}
|
|
15015
|
+
/* Normalize the 'projection' property and return a new object with the updated projection */
|
|
15016
|
+
return {
|
|
15017
|
+
...typedParams,
|
|
15018
|
+
projection: parseProjectionString(typedParams['projection'])
|
|
15019
|
+
};
|
|
15020
|
+
}
|
|
15021
|
+
/**
|
|
15022
|
+
* Extracts file name from Content-Disposition header
|
|
15023
|
+
* @param headers HttpHeaders containing Content-Disposition
|
|
15024
|
+
* @returns The extracted file name or empty string
|
|
14473
15025
|
*/
|
|
14474
15026
|
getFileNameFromHeaders(headers) {
|
|
14475
15027
|
/* Extract the Content-Disposition header from the HTTP headers */
|
|
@@ -14490,12 +15042,9 @@ class GenericService {
|
|
|
14490
15042
|
}
|
|
14491
15043
|
/**
|
|
14492
15044
|
* Handles an HTTP operation that failed.
|
|
14493
|
-
*
|
|
14494
|
-
*
|
|
14495
|
-
* @
|
|
14496
|
-
* @param operation The name of the operation that failed. Defaults to 'operation'.
|
|
14497
|
-
* @param result An optional value to return as the observable result.
|
|
14498
|
-
* @returns A function that processes the error and returns an observable.
|
|
15045
|
+
* Throws a parsed error for the application to handle.
|
|
15046
|
+
* @param operation The name of the operation that failed (for logging)
|
|
15047
|
+
* @returns A function that processes the error and returns an observable
|
|
14499
15048
|
*/
|
|
14500
15049
|
handleError(operation = 'operation') {
|
|
14501
15050
|
return (error) => throwError(() => {
|
|
@@ -14507,10 +15056,10 @@ class GenericService {
|
|
|
14507
15056
|
});
|
|
14508
15057
|
}
|
|
14509
15058
|
/**
|
|
14510
|
-
*
|
|
14511
|
-
*
|
|
14512
|
-
* @param
|
|
14513
|
-
* @
|
|
15059
|
+
* Returns a distinct message for upload events
|
|
15060
|
+
* @param event The HttpEvent from the upload
|
|
15061
|
+
* @param file The file being uploaded
|
|
15062
|
+
* @returns A user-friendly status message
|
|
14514
15063
|
*/
|
|
14515
15064
|
getEventMessage(event, file) {
|
|
14516
15065
|
switch (event.type) {
|
|
@@ -14529,9 +15078,8 @@ class GenericService {
|
|
|
14529
15078
|
}
|
|
14530
15079
|
}
|
|
14531
15080
|
/**
|
|
14532
|
-
*
|
|
14533
|
-
*
|
|
14534
|
-
* @param message
|
|
15081
|
+
* Logs upload progress messages to the console
|
|
15082
|
+
* @param message The message to log
|
|
14535
15083
|
*/
|
|
14536
15084
|
showProgress(message) {
|
|
14537
15085
|
console.debug(message);
|
|
@@ -14621,6 +15169,7 @@ class EnumService {
|
|
|
14621
15169
|
return {
|
|
14622
15170
|
id: key,
|
|
14623
15171
|
name: metadata?.display ?? enumObj[key],
|
|
15172
|
+
hint: metadata?.hint,
|
|
14624
15173
|
icon: metadata?.icon,
|
|
14625
15174
|
textColor: metadata?.textColor,
|
|
14626
15175
|
disabled: metadata?.disabled || metadata?.disable?.(context) || false,
|
|
@@ -15395,7 +15944,15 @@ class AbstractSelectFormField extends AbstractMatFormField {
|
|
|
15395
15944
|
* @type {boolean}
|
|
15396
15945
|
*/
|
|
15397
15946
|
get multiple() { return this._multiple; }
|
|
15398
|
-
set multiple(multi) {
|
|
15947
|
+
set multiple(multi) {
|
|
15948
|
+
/* Update the control type based on the multiple value */
|
|
15949
|
+
if (multi) {
|
|
15950
|
+
this.controlType = `${this.controlType}${multi ? '-multiple' : ''}`;
|
|
15951
|
+
}
|
|
15952
|
+
/* Update the multiple value and trigger state change */
|
|
15953
|
+
this._multiple = coerceBooleanProperty(multi);
|
|
15954
|
+
this.stateChanges.next();
|
|
15955
|
+
}
|
|
15399
15956
|
/**
|
|
15400
15957
|
* @property sorted
|
|
15401
15958
|
* @description Whether the options should be sorted.
|
|
@@ -15836,22 +16393,6 @@ class VdSelectComponent extends AbstractSelectFormField {
|
|
|
15836
16393
|
this._triggerCssClass = triggerCssClass;
|
|
15837
16394
|
this.stateChanges.next();
|
|
15838
16395
|
}
|
|
15839
|
-
/**
|
|
15840
|
-
* Mode of the trigger.
|
|
15841
|
-
*/
|
|
15842
|
-
get triggerMode() { return this._triggerMode; }
|
|
15843
|
-
set triggerMode(triggerMode) {
|
|
15844
|
-
/* Update the trigger mode value */
|
|
15845
|
-
this._triggerMode = triggerMode;
|
|
15846
|
-
/* Update the CSS class based on the trigger mode */
|
|
15847
|
-
this.triggerCssClass = triggerMode;
|
|
15848
|
-
/* If trigger mode is defined, append it to the control type */
|
|
15849
|
-
if (triggerMode) {
|
|
15850
|
-
this.controlType = `${this.controlType}-${triggerMode}`;
|
|
15851
|
-
}
|
|
15852
|
-
/* Notify that the state has changed */
|
|
15853
|
-
this.stateChanges.next();
|
|
15854
|
-
}
|
|
15855
16396
|
/**
|
|
15856
16397
|
* Gets the display values of the selected options for the trigger.
|
|
15857
16398
|
*
|
|
@@ -15948,13 +16489,13 @@ class VdSelectComponent extends AbstractSelectFormField {
|
|
|
15948
16489
|
});
|
|
15949
16490
|
}
|
|
15950
16491
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15951
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdSelectComponent, isStandalone: true, selector: "vd-select", inputs: { triggerCssClass: "triggerCssClass"
|
|
16492
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdSelectComponent, isStandalone: true, selector: "vd-select", inputs: { triggerCssClass: "triggerCssClass" }, providers: [
|
|
15952
16493
|
{ provide: MatFormFieldControl, useExisting: VdSelectComponent },
|
|
15953
16494
|
{
|
|
15954
16495
|
provide: MAT_SELECT_CONFIG,
|
|
15955
16496
|
useValue: { overlayPanelClass: 'vd-select-filter-overlay' }
|
|
15956
16497
|
}
|
|
15957
|
-
], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdSelectOptionDirective, descendants: true }, { propertyName: "triggerTemplate", first: true, predicate: VdSelectTriggerDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelect, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex>\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observers.length > 0) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observers.length && triggerTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n @if (triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"triggerTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n }\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observers.length && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplateDefault [ngTemplateOutlet]=\"optionIconTemplateDefault\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"option?.disabled\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n @if (!optionTemplate?.templateRef) {\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n }\n @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n <div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{currentValue[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"currentValue[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <span> </span>\n <span i18n=\"@@selection\">{currentValue[optionTextProperty], select, option {option} other {{{currentValue[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span>, </span>\n }\n }\n </span>\n </span>\n }\n @if (triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"triggerTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n }\n @if (optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n }\n </div>\n @if (onLaunch.observers.length > 0) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n </div>\n }\n @if (!currentValue) {\n <div> </div>\n }\n </div>\n }\n <!-- #endregion -->", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-chip .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-vd-select-chip .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i2$1.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
16498
|
+
], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdSelectOptionDirective, descendants: true }, { propertyName: "triggerTemplate", first: true, predicate: VdSelectTriggerDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelect, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex>\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\">{ label, select, option {option} other { {{ label }} } }</span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span layout=\"column\" class=\"option-text\" [ngClass]=\"{'option-has-hint': option.hint?.length > 0}\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </mat-chip>\n } @else {\n <ng-template [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"option?.disabled\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Text -->\n <span layout=\"column\" layout-align=\"start center\" class=\"option-text\" [ngClass]=\"{'option-has-hint':option.hint?.length>0}\">\n @if (!optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n }\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n <!-- #endregion -->\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n <div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) {\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"></ng-template>\n }\n\n @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </span>\n }\n @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n </span>\n }\n @if (optionTemplate && optionTemplate.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n </div>\n }\n @if (!currentValue) {\n <div> </div>\n }\n </div>\n}\n<!-- #endregion -->", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:8px!important;padding-bottom:8px!important}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i2$1.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i5.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
15958
16499
|
}
|
|
15959
16500
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdSelectComponent, decorators: [{
|
|
15960
16501
|
type: Component,
|
|
@@ -15964,6 +16505,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15964
16505
|
MatInputModule,
|
|
15965
16506
|
MatIconModule,
|
|
15966
16507
|
MatChipsModule,
|
|
16508
|
+
MatTooltip,
|
|
15967
16509
|
FormsModule
|
|
15968
16510
|
], providers: [
|
|
15969
16511
|
{ provide: MatFormFieldControl, useExisting: VdSelectComponent },
|
|
@@ -15971,7 +16513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15971
16513
|
provide: MAT_SELECT_CONFIG,
|
|
15972
16514
|
useValue: { overlayPanelClass: 'vd-select-filter-overlay' }
|
|
15973
16515
|
}
|
|
15974
|
-
], template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex>\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observers.length > 0) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observers.length && triggerTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n @if (triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"triggerTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n }\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observers.length && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplateDefault [ngTemplateOutlet]=\"optionIconTemplateDefault\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"option?.disabled\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n @if (!optionTemplate?.templateRef) {\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other {{{option[optionTextProperty]}}}}</span>\n }\n @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n <div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{currentValue[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"currentValue[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <span> </span>\n <span i18n=\"@@selection\">{currentValue[optionTextProperty], select, option {option} other {{{currentValue[optionTextProperty]}}}}</span>\n </span>\n @if (!last) {\n <span>, </span>\n }\n }\n </span>\n </span>\n }\n @if (triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"triggerTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n }\n @if (optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n }\n </div>\n @if (onLaunch.observers.length > 0) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n </div>\n }\n @if (!currentValue) {\n <div> </div>\n }\n </div>\n }\n <!-- #endregion -->", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-chip .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-vd-select-chip .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important}\n"] }]
|
|
16516
|
+
], template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex>\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\">{ label, select, option {option} other { {{ label }} } }</span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span layout=\"column\" class=\"option-text\" [ngClass]=\"{'option-has-hint': option.hint?.length > 0}\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </mat-chip>\n } @else {\n <ng-template [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"option?.disabled\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"option.icon?.svgIcon\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Text -->\n <span layout=\"column\" layout-align=\"start center\" class=\"option-text\" [ngClass]=\"{'option-has-hint':option.hint?.length>0}\">\n @if (!optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n }\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n <!-- #endregion -->\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n <div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) {\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"></ng-template>\n }\n\n @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span> </span>\n }\n }\n </span>\n </span>\n }\n @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n </span>\n }\n @if (optionTemplate && optionTemplate.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span> </span>\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n </div>\n }\n @if (!currentValue) {\n <div> </div>\n }\n </div>\n}\n<!-- #endregion -->", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:8px!important;padding-bottom:8px!important}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"] }]
|
|
15975
16517
|
}], ctorParameters: () => [], propDecorators: { optionTemplate: [{
|
|
15976
16518
|
type: ContentChild,
|
|
15977
16519
|
args: [VdSelectOptionDirective]
|
|
@@ -15986,8 +16528,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
15986
16528
|
args: ['filterInput', { static: false }]
|
|
15987
16529
|
}], triggerCssClass: [{
|
|
15988
16530
|
type: Input
|
|
15989
|
-
}], triggerMode: [{
|
|
15990
|
-
type: Input
|
|
15991
16531
|
}] } });
|
|
15992
16532
|
|
|
15993
16533
|
/**
|
|
@@ -16201,14 +16741,14 @@ class TableDataSource extends DataSource {
|
|
|
16201
16741
|
this.onSortChange.subscribe(() => { this.paginator.pageIndex = 0; });
|
|
16202
16742
|
}
|
|
16203
16743
|
return merge$1(...displayDataChanges)
|
|
16204
|
-
.pipe(skip(1), switchMap(() => {
|
|
16744
|
+
.pipe(skip(1), switchMap$1(() => {
|
|
16205
16745
|
/* Flip flag to show that loading has begun */
|
|
16206
16746
|
this.isLoading = true;
|
|
16207
16747
|
/* Remove empty filters */
|
|
16208
16748
|
Utils.cleanObject(this.fieldFilters);
|
|
16209
16749
|
Utils.cleanObject(this.staticFieldFilters);
|
|
16210
|
-
/*
|
|
16211
|
-
|
|
16750
|
+
/* Build parameters for the data query */
|
|
16751
|
+
var params = Object.assign({
|
|
16212
16752
|
includes: this.includes,
|
|
16213
16753
|
projection: Array.isArray(this.projection) ? this.projection.join(',') : this.projection,
|
|
16214
16754
|
page: (this.paginator?.pageIndex ?? 0) + 1,
|
|
@@ -16216,7 +16756,9 @@ class TableDataSource extends DataSource {
|
|
|
16216
16756
|
search: this.filter.toLowerCase(),
|
|
16217
16757
|
sortBy: this.sort?.active,
|
|
16218
16758
|
sortOrder: this.sort?.direction
|
|
16219
|
-
}, this.fieldFilters ?? {}, this.staticFieldFilters ?? {})
|
|
16759
|
+
}, this.fieldFilters ?? {}, this.staticFieldFilters ?? {});
|
|
16760
|
+
/* Load data and return it */
|
|
16761
|
+
return this.service.getList(Utils.cleanObject(params), this.path ?? '', { 'CheckOut': 'Yes' });
|
|
16220
16762
|
}), map$1((result) => {
|
|
16221
16763
|
/* Flip flag to show that loading has finished */
|
|
16222
16764
|
this.isLoading = false;
|
|
@@ -16836,25 +17378,28 @@ class FilterInputComponent {
|
|
|
16836
17378
|
* @param event
|
|
16837
17379
|
*/
|
|
16838
17380
|
onKeyDown(event) {
|
|
16839
|
-
let e = event;
|
|
16840
17381
|
if (this.onlyNumber) {
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
(e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
|
|
16846
|
-
/* Allow: Ctrl+V */
|
|
16847
|
-
(e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
|
|
16848
|
-
/* Allow: Ctrl+X */
|
|
16849
|
-
(e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
|
|
16850
|
-
/* Allow: home, end, left, right */
|
|
16851
|
-
(e.keyCode >= 35 && e.keyCode <= 39)) {
|
|
16852
|
-
/* let it happen, don't do anything */
|
|
17382
|
+
/* Allow navigation keys and control keys */
|
|
17383
|
+
const allowedKeys = ['Backspace', 'Delete', 'Tab', 'Escape', 'Enter', 'ArrowLeft', 'ArrowRight', 'Home', 'End'];
|
|
17384
|
+
/* Allow Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X */
|
|
17385
|
+
if ((event.ctrlKey || event.metaKey) && ['a', 'c', 'v', 'x'].includes(event.key.toLowerCase())) {
|
|
16853
17386
|
return;
|
|
16854
17387
|
}
|
|
16855
|
-
/*
|
|
16856
|
-
if ((
|
|
16857
|
-
|
|
17388
|
+
/* Allow Ctrl+Z, Ctrl+Y */
|
|
17389
|
+
if ((event.ctrlKey || event.metaKey) && ['z', 'y'].includes(event.key.toLowerCase())) {
|
|
17390
|
+
return;
|
|
17391
|
+
}
|
|
17392
|
+
/* Allow control keys */
|
|
17393
|
+
if (event.ctrlKey || event.metaKey) {
|
|
17394
|
+
return;
|
|
17395
|
+
}
|
|
17396
|
+
/* Allow navigation keys */
|
|
17397
|
+
if (allowedKeys.includes(event.key)) {
|
|
17398
|
+
return;
|
|
17399
|
+
}
|
|
17400
|
+
/* Block non-numeric characters */
|
|
17401
|
+
if (event.key < '0' || event.key > '9') {
|
|
17402
|
+
event.preventDefault();
|
|
16858
17403
|
}
|
|
16859
17404
|
}
|
|
16860
17405
|
}
|
|
@@ -17956,9 +18501,9 @@ class VdDynamicTableComponent {
|
|
|
17956
18501
|
this.changeDetector.detectChanges();
|
|
17957
18502
|
}
|
|
17958
18503
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDynamicTableComponent, deps: [{ token: DynamicBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
17959
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdDynamicTableComponent, isStandalone: true, selector: "vd-dynamic-table", inputs: { dataSource: "dataSource", data: "data", parentControl: "parentControl", entityObject: "entityObject", formArray: "formArray", debugValue: "debugValue", classType: "classType", context: "context", dataSourceFilter: "dataSourceFilter", static: "static", filterable: "filterable", sticky: "sticky", tableWidth: "tableWidth", useFilterOperator: "useFilterOperator", paginable: "paginable", selectable: "selectable", sortActive: "sortActive", sortDirection: "sortDirection", stickyHeader: "stickyHeader", stickyFilter: "stickyFilter", columnSets: "columnSets", rowNgClass: "rowNgClass", detailsTemplate: "detailsTemplate", readonly: "readonly", selectAllFilter: "selectAllFilter", paginatorRef: "paginatorRef", columns: "columns", rowMenuItems: "rowMenuItems", rowAction: "rowAction", excludedColumns: "excludedColumns", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions" }, outputs: { rowClick: "rowClick" }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, static: true }, { propertyName: "detailsTemplateRef", predicate: ["detailsTemplate"], descendants: true, read: ViewContainerRef }, { propertyName: "rowContextMenuTriggers", predicate: MatMenuTrigger, descendants: true }], ngImport: i0, template: "@if (!static) {\n <div class=\"loading-progress\">\n @if (dataSource?.isLoading) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </div>\n}\n\n<!-- #region Data table -->\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\n <!-- #region Column def -->\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\n @if (column.type == ColumnType.Checkbox) {\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\n }\n @if (column.type != ColumnType.Checkbox) {\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\n }\n </th>\n </ng-template>\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\n @switch (column.type) {\n <!-- #region Checkbox column -->\n @case (ColumnType.Checkbox) {\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\n }\n <!-- #endregion -->\n <!-- #region Enum column -->\n @case (ColumnType.Enum) {\n <span>\n @if (column.enumMetadata) {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index) {\n @if (i < 2) {\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\n }\n @if (i === 1 && rowValue?.length > 2) {\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\n }\n }\n <ng-template #template let-displayValue=\"displayValue\">\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\n <span>{{ displayValue }}</span>\n </mat-chip-row>\n </ng-template>\n } @else {\n @if (rowValue >= 0) {\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\n }\n }\n } @else {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index; let last = $last) {\n <div>\n @if (i<2) {\n <small i18n=\"@@selection\">{item | enum:column.enumType:column.enumPrefix, select, type {type} other {{{item | enum:column.enumType:column.enumPrefix}}}}</small>\n }\n @if (i==1 && rowValue?.length > 2) {\n <small>, ...</small>\n }\n </div>\n }\n } @else {\n @if (rowValue >= 0) {\n <span i18n=\"@@selection\">{rowValue | enum:column.enumType:column.enumPrefix, select, type {type} other {{{rowValue | enum:column.enumType:column.enumPrefix}}}}</span>\n }\n }\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n @if (!formArray) {\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Date column -->\n @case (ColumnType.Date) {\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\">\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column?.enumFilter | func:row:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Action -->\n @case (ColumnType.Action) {\n @if (column.menu) {\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed;\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\n }\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region Menu -->\n @case (ColumnType.Menu) {\n @if (column.menu) {\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region icon -->\n @case (ColumnType.Icon) {\n <span layout=\"row\" layout-align=\"start center\">\n @if (column.icon?.matIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\">{{handleExpression(column.icon?.matIcon!, row)}}</mat-icon>\n }\n @if (column.icon?.svgIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [svgIcon]=\"handleExpression(column.icon?.svgIcon!, row)!\"></mat-icon>\n }\n @if (column.icon?.fontIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [fontIcon]=\"handleExpression(column.icon?.fontIcon!, row)!\"></mat-icon>\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region icon button -->\n @case (ColumnType.IconButton) {\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton?.event(row, context):null\">\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\n </a>\n }\n <!-- #endregion -->\n <!-- #region Other column types -->\n @default {\n <span [innerHtml]=\"rowValue??''\"></span>\n }\n <!-- #endregion -->\n }\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\n @if (formGroup) {\n <ng-container [formGroup]=\"formGroup\">\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\n @if (!columnNameSegments.length) {\n @switch (column.type) {\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\">\n </mat-form-field>\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n </mat-form-field>\n }\n <!-- #endregion -->\n }\n } @else {\n <!-- If not the last segment, create a nested form group -->\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\n <!-- Recursive call to handle nested segments -->\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\n </ng-container>\n }\n </ng-container>\n }\n </ng-template>\n </ng-template>\n </td>\n </ng-container>\n <!-- #endregion -->\n }\n\n <!-- #region Filter row -->\n @if (dataSource && filterable) {\n @for (column of columns$ | async; track column) {\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\n <!-- #region Select filter -->\n @if(column.endpoint || column.enumType || column.options){\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\n }\n <!-- #region Text filter -->\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\n }\n <!-- #endregion -->\n <!-- #region Date filter -->\n @else if (column.type == ColumnType.Date) {\n <span filter-date></span>\n }\n <!-- #endregion -->\n <!-- #region Action filter (clear) -->\n @else if (column.type == ColumnType.Action) {\n <span filter-clear></span>\n }\n <!-- #endregion -->\n </th>\n </ng-container>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Details column -->\n <ng-container cdkColumnDef=\"expandedDetail\">\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\n @if (templateRef && row === expandedRow) {\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\n }\n </div>\n </td>\n </ng-container>\n <!-- #endregion -->\n\n <!-- #region Filter header -->\n @if (filterable) {\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\n }\n <!-- #endregion -->\n\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\n\n <!-- #region Detrails row -->\n @if (detailsTemplate || templateRef) {\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\n }\n <!-- #endregion -->\n </table>\n\n <!-- #region Modern No Results Message -->\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\n <div class=\"no-results-overlay\">\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\n <div class=\"no-results-text mat-body-1\">\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\n <p i18n=\"@@tryAdjustFilters\">Try adjusting your filters or search criteria.</p>\n </div>\n </div>\n }\n <!-- #endregion -->\n</div>\n<!-- #endregion -->\n\n<!-- #region Debug value -->\n@if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n}\n<!-- #endregion -->\n\n<div class=\"table-footer\" layout=\"row\">\n <ng-content select=\"[table-footer]\"></ng-content>\n <span flex></span>\n @if (paginable) {\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\n }\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i2$2.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "directive", type: i2$2.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i2$2.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: i2$2.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: i2$2.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5$1.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i10.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i3.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i12.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i16.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type:
|
|
18504
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdDynamicTableComponent, isStandalone: true, selector: "vd-dynamic-table", inputs: { dataSource: "dataSource", data: "data", parentControl: "parentControl", entityObject: "entityObject", formArray: "formArray", debugValue: "debugValue", classType: "classType", context: "context", dataSourceFilter: "dataSourceFilter", static: "static", filterable: "filterable", sticky: "sticky", tableWidth: "tableWidth", useFilterOperator: "useFilterOperator", paginable: "paginable", selectable: "selectable", sortActive: "sortActive", sortDirection: "sortDirection", stickyHeader: "stickyHeader", stickyFilter: "stickyFilter", columnSets: "columnSets", rowNgClass: "rowNgClass", detailsTemplate: "detailsTemplate", readonly: "readonly", selectAllFilter: "selectAllFilter", paginatorRef: "paginatorRef", columns: "columns", rowMenuItems: "rowMenuItems", rowAction: "rowAction", excludedColumns: "excludedColumns", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions" }, outputs: { rowClick: "rowClick" }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, static: true }, { propertyName: "detailsTemplateRef", predicate: ["detailsTemplate"], descendants: true, read: ViewContainerRef }, { propertyName: "rowContextMenuTriggers", predicate: MatMenuTrigger, descendants: true }], ngImport: i0, template: "@if (!static) {\n <div class=\"loading-progress\">\n @if (dataSource?.isLoading) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </div>\n}\n\n<!-- #region Data table -->\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\n <!-- #region Column def -->\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\n @if (column.type == ColumnType.Checkbox) {\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\n }\n @if (column.type != ColumnType.Checkbox) {\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\n }\n </th>\n </ng-template>\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\n @switch (column.type) {\n <!-- #region Checkbox column -->\n @case (ColumnType.Checkbox) {\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\n }\n <!-- #endregion -->\n <!-- #region Enum column -->\n @case (ColumnType.Enum) {\n <span>\n @if (column.enumMetadata) {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index) {\n @if (i < 2) {\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\n }\n @if (i === 1 && rowValue?.length > 2) {\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\n }\n }\n <ng-template #template let-displayValue=\"displayValue\">\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\n <span>{{ displayValue }}</span>\n </mat-chip-row>\n </ng-template>\n } @else {\n @if (rowValue >= 0) {\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\n }\n }\n } @else {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index; let last = $last) {\n <div>\n @if (i<2) {\n <small i18n=\"@@selection\">{item | enum:column.enumType:column.enumPrefix, select, type {type} other {{{item | enum:column.enumType:column.enumPrefix}}}}</small>\n }\n @if (i==1 && rowValue?.length > 2) {\n <small>, ...</small>\n }\n </div>\n }\n } @else {\n @if (rowValue >= 0) {\n <span i18n=\"@@selection\">{rowValue | enum:column.enumType:column.enumPrefix, select, type {type} other {{{rowValue | enum:column.enumType:column.enumPrefix}}}}</span>\n }\n }\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n @if (!formArray) {\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Date column -->\n @case (ColumnType.Date) {\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\">\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column?.enumFilter | func:row:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Action -->\n @case (ColumnType.Action) {\n @if (column.menu) {\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed;\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\n }\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region Menu -->\n @case (ColumnType.Menu) {\n @if (column.menu) {\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region icon -->\n @case (ColumnType.Icon) {\n <span layout=\"row\" layout-align=\"start center\">\n @if (column.icon?.matIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\">{{handleExpression(column.icon?.matIcon!, row)}}</mat-icon>\n }\n @if (column.icon?.svgIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [svgIcon]=\"handleExpression(column.icon?.svgIcon!, row)!\"></mat-icon>\n }\n @if (column.icon?.fontIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [fontIcon]=\"handleExpression(column.icon?.fontIcon!, row)!\"></mat-icon>\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region icon button -->\n @case (ColumnType.IconButton) {\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton?.event(row, context):null\">\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\n </a>\n }\n <!-- #endregion -->\n <!-- #region Other column types -->\n @default {\n <span [innerHtml]=\"rowValue??''\"></span>\n }\n <!-- #endregion -->\n }\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\n @if (formGroup) {\n <ng-container [formGroup]=\"formGroup\">\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\n @if (!columnNameSegments.length) {\n @switch (column.type) {\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\">\n </mat-form-field>\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n </mat-form-field>\n }\n <!-- #endregion -->\n }\n } @else {\n <!-- If not the last segment, create a nested form group -->\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\n <!-- Recursive call to handle nested segments -->\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\n </ng-container>\n }\n </ng-container>\n }\n </ng-template>\n </ng-template>\n </td>\n </ng-container>\n <!-- #endregion -->\n }\n\n <!-- #region Filter row -->\n @if (dataSource && filterable) {\n @for (column of columns$ | async; track column) {\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\n <!-- #region Select filter -->\n @if(column.endpoint || column.enumType || column.options){\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\n }\n <!-- #region Text filter -->\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\n }\n <!-- #endregion -->\n <!-- #region Date filter -->\n @else if (column.type == ColumnType.Date) {\n <span filter-date></span>\n }\n <!-- #endregion -->\n <!-- #region Action filter (clear) -->\n @else if (column.type == ColumnType.Action) {\n <span filter-clear></span>\n }\n <!-- #endregion -->\n </th>\n </ng-container>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Details column -->\n <ng-container cdkColumnDef=\"expandedDetail\">\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\n @if (templateRef && row === expandedRow) {\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\n }\n </div>\n </td>\n </ng-container>\n <!-- #endregion -->\n\n <!-- #region Filter header -->\n @if (filterable) {\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\n }\n <!-- #endregion -->\n\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\n\n <!-- #region Detrails row -->\n @if (detailsTemplate || templateRef) {\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\n }\n <!-- #endregion -->\n </table>\n\n <!-- #region Modern No Results Message -->\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\n <div class=\"no-results-overlay\">\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\n <div class=\"no-results-text mat-body-1\">\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\n <p i18n=\"@@tryAdjustFilters\">Try adjusting your filters or search criteria.</p>\n </div>\n </div>\n }\n <!-- #endregion -->\n</div>\n<!-- #endregion -->\n\n<!-- #region Debug value -->\n@if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n}\n<!-- #endregion -->\n\n<div class=\"table-footer\" layout=\"row\">\n <ng-content select=\"[table-footer]\"></ng-content>\n <span flex></span>\n @if (paginable) {\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\n }\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i2$2.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "directive", type: i2$2.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i2$2.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: i2$2.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: i2$2.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i10.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i3.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i12.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i16.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type:
|
|
17960
18505
|
//----------------------
|
|
17961
|
-
DataSourceFilterDirective, selector: "[dataSourceFilter]", inputs: ["dataSource", "dataSourceFilter"] }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "component", type: FilterDateComponent, selector: "mat-header-cell[filter-date], [mat-header-cell][filter-date], [filter-date]", inputs: ["field", "debounce", "placeholder"] }, { kind: "component", type: FilterInputComponent, selector: "mat-header-cell[filter-input], [mat-header-cell][filter-input], [filter-input]", inputs: ["field", "operator", "onlyNumber", "debounce", "placeholder"] }, { kind: "component", type: FilterSelectComponent, selector: "mat-header-cell[filter-select], [mat-header-cell][filter-select], [filter-select]", inputs: ["endpoint", "params", "projection", "sortBy", "sorted", "enumFilter", "enum", "enumMetadata", "key", "text", "prefix", "multiple", "options", "filteredOptions", "filterable", "field", "placeholder", "cache"] }, { kind: "component", type: FilterClearComponent, selector: "mat-header-cell[filter-clear], [mat-header-cell][filter-clear], [filter-clear]" }, { kind: "component", type: VdDynamicMenuComponent, selector: "vd-dynamic-menu", inputs: ["items", "data", "index", "context", "contextMenu"] }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"
|
|
18506
|
+
DataSourceFilterDirective, selector: "[dataSourceFilter]", inputs: ["dataSource", "dataSourceFilter"] }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "component", type: FilterDateComponent, selector: "mat-header-cell[filter-date], [mat-header-cell][filter-date], [filter-date]", inputs: ["field", "debounce", "placeholder"] }, { kind: "component", type: FilterInputComponent, selector: "mat-header-cell[filter-input], [mat-header-cell][filter-input], [filter-input]", inputs: ["field", "operator", "onlyNumber", "debounce", "placeholder"] }, { kind: "component", type: FilterSelectComponent, selector: "mat-header-cell[filter-select], [mat-header-cell][filter-select], [filter-select]", inputs: ["endpoint", "params", "projection", "sortBy", "sorted", "enumFilter", "enum", "enumMetadata", "key", "text", "prefix", "multiple", "options", "filteredOptions", "filterable", "field", "placeholder", "cache"] }, { kind: "component", type: FilterClearComponent, selector: "mat-header-cell[filter-clear], [mat-header-cell][filter-clear], [filter-clear]" }, { kind: "component", type: VdDynamicMenuComponent, selector: "vd-dynamic-menu", inputs: ["items", "data", "index", "context", "contextMenu"] }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"] }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.JsonPipe, name: "json" }, { kind: "pipe", type: i3$1.SlicePipe, name: "slice" }, { kind: "pipe", type: i3$1.DatePipe, name: "date" }, { kind: "pipe", type:
|
|
17962
18507
|
//----------------------
|
|
17963
18508
|
MapPipe, name: "map" }, { kind: "pipe", type: EnumPipe, name: "enum" }, { kind: "pipe", type: FormGroupPipe, name: "formGroup" }, { kind: "pipe", type: FuncPipe, name: "func" }, { kind: "pipe", type: JoinPipe, name: "join" }, { kind: "pipe", type: PropertyPipe, name: "property" }], animations: [
|
|
17964
18509
|
trigger('detailExpand', [
|
|
@@ -18010,7 +18555,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18010
18555
|
state('expanded', style({ height: AUTO_STYLE })),
|
|
18011
18556
|
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
|
|
18012
18557
|
]),
|
|
18013
|
-
], template: "@if (!static) {\n <div class=\"loading-progress\">\n @if (dataSource?.isLoading) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </div>\n}\n\n<!-- #region Data table -->\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\n <!-- #region Column def -->\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\n @if (column.type == ColumnType.Checkbox) {\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\n }\n @if (column.type != ColumnType.Checkbox) {\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\n }\n </th>\n </ng-template>\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\n @switch (column.type) {\n <!-- #region Checkbox column -->\n @case (ColumnType.Checkbox) {\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\n }\n <!-- #endregion -->\n <!-- #region Enum column -->\n @case (ColumnType.Enum) {\n <span>\n @if (column.enumMetadata) {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index) {\n @if (i < 2) {\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\n }\n @if (i === 1 && rowValue?.length > 2) {\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\n }\n }\n <ng-template #template let-displayValue=\"displayValue\">\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\n <span>{{ displayValue }}</span>\n </mat-chip-row>\n </ng-template>\n } @else {\n @if (rowValue >= 0) {\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\n }\n }\n } @else {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index; let last = $last) {\n <div>\n @if (i<2) {\n <small i18n=\"@@selection\">{item | enum:column.enumType:column.enumPrefix, select, type {type} other {{{item | enum:column.enumType:column.enumPrefix}}}}</small>\n }\n @if (i==1 && rowValue?.length > 2) {\n <small>, ...</small>\n }\n </div>\n }\n } @else {\n @if (rowValue >= 0) {\n <span i18n=\"@@selection\">{rowValue | enum:column.enumType:column.enumPrefix, select, type {type} other {{{rowValue | enum:column.enumType:column.enumPrefix}}}}</span>\n }\n }\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n @if (!formArray) {\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Date column -->\n @case (ColumnType.Date) {\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\">\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column?.enumFilter | func:row:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Action -->\n @case (ColumnType.Action) {\n @if (column.menu) {\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed;\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\n }\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region Menu -->\n @case (ColumnType.Menu) {\n @if (column.menu) {\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region icon -->\n @case (ColumnType.Icon) {\n <span layout=\"row\" layout-align=\"start center\">\n @if (column.icon?.matIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\">{{handleExpression(column.icon?.matIcon!, row)}}</mat-icon>\n }\n @if (column.icon?.svgIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [svgIcon]=\"handleExpression(column.icon?.svgIcon!, row)!\"></mat-icon>\n }\n @if (column.icon?.fontIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [fontIcon]=\"handleExpression(column.icon?.fontIcon!, row)!\"></mat-icon>\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region icon button -->\n @case (ColumnType.IconButton) {\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton?.event(row, context):null\">\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\n </a>\n }\n <!-- #endregion -->\n <!-- #region Other column types -->\n @default {\n <span [innerHtml]=\"rowValue??''\"></span>\n }\n <!-- #endregion -->\n }\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\n @if (formGroup) {\n <ng-container [formGroup]=\"formGroup\">\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\n @if (!columnNameSegments.length) {\n @switch (column.type) {\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\">\n </mat-form-field>\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n </mat-form-field>\n }\n <!-- #endregion -->\n }\n } @else {\n <!-- If not the last segment, create a nested form group -->\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\n <!-- Recursive call to handle nested segments -->\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\n </ng-container>\n }\n </ng-container>\n }\n </ng-template>\n </ng-template>\n </td>\n </ng-container>\n <!-- #endregion -->\n }\n\n <!-- #region Filter row -->\n @if (dataSource && filterable) {\n @for (column of columns$ | async; track column) {\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\n <!-- #region Select filter -->\n @if(column.endpoint || column.enumType || column.options){\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\n }\n <!-- #region Text filter -->\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\n }\n <!-- #endregion -->\n <!-- #region Date filter -->\n @else if (column.type == ColumnType.Date) {\n <span filter-date></span>\n }\n <!-- #endregion -->\n <!-- #region Action filter (clear) -->\n @else if (column.type == ColumnType.Action) {\n <span filter-clear></span>\n }\n <!-- #endregion -->\n </th>\n </ng-container>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Details column -->\n <ng-container cdkColumnDef=\"expandedDetail\">\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\n @if (templateRef && row === expandedRow) {\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\n }\n </div>\n </td>\n </ng-container>\n <!-- #endregion -->\n\n <!-- #region Filter header -->\n @if (filterable) {\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\n }\n <!-- #endregion -->\n\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\n\n <!-- #region Detrails row -->\n @if (detailsTemplate || templateRef) {\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\n }\n <!-- #endregion -->\n </table>\n\n <!-- #region Modern No Results Message -->\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\n <div class=\"no-results-overlay\">\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\n <div class=\"no-results-text mat-body-1\">\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\n <p i18n=\"@@tryAdjustFilters\">Try adjusting your filters or search criteria.</p>\n </div>\n </div>\n }\n <!-- #endregion -->\n</div>\n<!-- #endregion -->\n\n<!-- #region Debug value -->\n@if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n}\n<!-- #endregion -->\n\n<div class=\"table-footer\" layout=\"row\">\n <ng-content select=\"[table-footer]\"></ng-content>\n <span flex></span>\n @if (paginable) {\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\n }\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"] }]
|
|
18558
|
+
], template: "@if (!static) {\n <div class=\"loading-progress\">\n @if (dataSource?.isLoading) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </div>\n}\n\n<!-- #region Data table -->\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\n <!-- #region Column def -->\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\n @if (column.type == ColumnType.Checkbox) {\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\n }\n @if (column.type != ColumnType.Checkbox) {\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\n }\n </th>\n </ng-template>\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\n @switch (column.type) {\n <!-- #region Checkbox column -->\n @case (ColumnType.Checkbox) {\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\n }\n <!-- #endregion -->\n <!-- #region Enum column -->\n @case (ColumnType.Enum) {\n <span>\n @if (column.enumMetadata) {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index) {\n @if (i < 2) {\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\n }\n @if (i === 1 && rowValue?.length > 2) {\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\n }\n }\n <ng-template #template let-displayValue=\"displayValue\">\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\n <span>{{ displayValue }}</span>\n </mat-chip-row>\n </ng-template>\n } @else {\n @if (rowValue >= 0) {\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\n }\n }\n } @else {\n @if (column.multiple) {\n @for (item of rowValue; track item; let i = $index; let last = $last) {\n <div>\n @if (i<2) {\n <small i18n=\"@@selection\">{item | enum:column.enumType:column.enumPrefix, select, type {type} other {{{item | enum:column.enumType:column.enumPrefix}}}}</small>\n }\n @if (i==1 && rowValue?.length > 2) {\n <small>, ...</small>\n }\n </div>\n }\n } @else {\n @if (rowValue >= 0) {\n <span i18n=\"@@selection\">{rowValue | enum:column.enumType:column.enumPrefix, select, type {type} other {{{rowValue | enum:column.enumType:column.enumPrefix}}}}</span>\n }\n }\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n @if (!formArray) {\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Date column -->\n @case (ColumnType.Date) {\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\">\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n @if (!formArray) {\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\n @if (!formArray) {\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column?.enumFilter | func:row:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n }\n </mat-form-field>\n }\n @if (formArray) {\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\n </ng-container>\n }\n }\n <!-- #endregion -->\n <!-- #region Action -->\n @case (ColumnType.Action) {\n @if (column.menu) {\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed;\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\n }\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region Menu -->\n @case (ColumnType.Menu) {\n @if (column.menu) {\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\n }\n }\n <!-- #endregion -->\n <!-- #region icon -->\n @case (ColumnType.Icon) {\n <span layout=\"row\" layout-align=\"start center\">\n @if (column.icon?.matIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\">{{handleExpression(column.icon?.matIcon!, row)}}</mat-icon>\n }\n @if (column.icon?.svgIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [svgIcon]=\"handleExpression(column.icon?.svgIcon!, row)!\"></mat-icon>\n }\n @if (column.icon?.fontIcon) {\n <mat-icon fontSet=\"{{column.icon?.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon?.cssClass??'', row)\" [fontIcon]=\"handleExpression(column.icon?.fontIcon!, row)!\"></mat-icon>\n }\n </span>\n }\n <!-- #endregion -->\n <!-- #region icon button -->\n @case (ColumnType.IconButton) {\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton?.event(row, context):null\">\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\n </a>\n }\n <!-- #endregion -->\n <!-- #region Other column types -->\n @default {\n <span [innerHtml]=\"rowValue??''\"></span>\n }\n <!-- #endregion -->\n }\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\n @if (formGroup) {\n <ng-container [formGroup]=\"formGroup\">\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\n @if (!columnNameSegments.length) {\n @switch (column.type) {\n <!-- #region Toggle column -->\n @case (ColumnType.Toggle) {\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\n }\n <!-- #endregion -->\n <!-- #region Text Input column -->\n @case (ColumnType.TextInput) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\">\n </mat-form-field>\n }\n <!-- #endregion -->\n <!-- #region VD-Select column -->\n @case (ColumnType.Select) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\n </mat-form-field>\n }\n <!-- #endregion -->\n }\n } @else {\n <!-- If not the last segment, create a nested form group -->\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\n <!-- Recursive call to handle nested segments -->\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\n </ng-container>\n }\n </ng-container>\n }\n </ng-template>\n </ng-template>\n </td>\n </ng-container>\n <!-- #endregion -->\n }\n\n <!-- #region Filter row -->\n @if (dataSource && filterable) {\n @for (column of columns$ | async; track column) {\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\n <!-- #region Select filter -->\n @if(column.endpoint || column.enumType || column.options){\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [prefix]=\"column.enumPrefix\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\n }\n <!-- #region Text filter -->\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\n }\n <!-- #endregion -->\n <!-- #region Date filter -->\n @else if (column.type == ColumnType.Date) {\n <span filter-date></span>\n }\n <!-- #endregion -->\n <!-- #region Action filter (clear) -->\n @else if (column.type == ColumnType.Action) {\n <span filter-clear></span>\n }\n <!-- #endregion -->\n </th>\n </ng-container>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Details column -->\n <ng-container cdkColumnDef=\"expandedDetail\">\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\n @if (templateRef && row === expandedRow) {\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\n }\n </div>\n </td>\n </ng-container>\n <!-- #endregion -->\n\n <!-- #region Filter header -->\n @if (filterable) {\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\n }\n <!-- #endregion -->\n\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\n\n <!-- #region Detrails row -->\n @if (detailsTemplate || templateRef) {\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\n }\n <!-- #endregion -->\n </table>\n\n <!-- #region Modern No Results Message -->\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\n <div class=\"no-results-overlay\">\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\n <div class=\"no-results-text mat-body-1\">\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\n <p i18n=\"@@tryAdjustFilters\">Try adjusting your filters or search criteria.</p>\n </div>\n </div>\n }\n <!-- #endregion -->\n</div>\n<!-- #endregion -->\n\n<!-- #region Debug value -->\n@if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n}\n<!-- #endregion -->\n\n<div class=\"table-footer\" layout=\"row\">\n <ng-content select=\"[table-footer]\"></ng-content>\n <span flex></span>\n @if (paginable) {\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\n }\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"] }]
|
|
18014
18559
|
}], ctorParameters: () => [{ type: DynamicBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { table: [{
|
|
18015
18560
|
type: ViewChild,
|
|
18016
18561
|
args: ['table']
|
|
@@ -18380,7 +18925,7 @@ class VdDynamicTableConfigDialogComponent extends BaseComponent {
|
|
|
18380
18925
|
this.genericList?.updateColumns();
|
|
18381
18926
|
}
|
|
18382
18927
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDynamicTableConfigDialogComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i0.ChangeDetectorRef }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: RxFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
18383
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdDynamicTableConfigDialogComponent, isStandalone: true, selector: "vd-dynamic-table-config-dialog", usesInheritance: true, ngImport: i0, template: "<!-- Title bar with close button -->\r\n<
|
|
18928
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdDynamicTableConfigDialogComponent, isStandalone: true, selector: "vd-dynamic-table-config-dialog", usesInheritance: true, ngImport: i0, template: "<!-- Title bar with close button -->\r\n<vd-dialog-header [dialogRef]=\"dialogRef\" i18n=\"@@tableConfiguration\">Table configuration</vd-dialog-header>\r\n\r\n@if (configForm) {\r\n <div class=\"pad-xs flex\" layout=\"column\">\r\n <div class=\"pad-bottom-sm\">\r\n @if (configForm) {\r\n <form [formGroup]=\"configForm\" class=\"pad-xs\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <mat-checkbox formControlName=\"sticky\">\r\n <span i18n=\"@@sticky\">Sticky</span>\r\n <span class=\"description\" i18n=\"@@tableStickyDescription\"> - Select to make the table headers fixed during scrolling.</span>\r\n </mat-checkbox>\r\n @if (false) {\r\n <mat-form-field layout-margin flex>\r\n <mat-label i18n=\"@@tableWidth\">Table width</mat-label>\r\n <input matInput type=\"number\" formControlName=\"tableWidth\" />\r\n </mat-form-field>\r\n }\r\n </div>\r\n </form>\r\n }\r\n </div>\r\n </div>\r\n <div layout-gt-sm=\"row\" class=\"dialog-container\" flex>\r\n <vd-dynamic-table #table [data]=\"columns\" [paginatorRef]=\"paginator\" [classType]=\"tableColumnConfigClassType\" [filterable]=\"true\" [paginable]=\"false\" [useFilterOperator]=\"false\" [pageSize]=\"10\" [context]=\"this\"></vd-dynamic-table>\r\n </div>\r\n <mat-dialog-actions>\r\n <a mat-flat-button color=\"primary\" (click)=\"save()\" i18n=\"@@save\">Save</a>\r\n <a mat-button (click)=\"apply()\" i18n=\"@@apply\">Apply</a>\r\n <a mat-button (click)=\"dialogRef.close()\" i18n=\"@@close\">Close</a>\r\n <span flex></span>\r\n <mat-paginator #paginator [length]=\"table.dataSource.total\" [pageIndex]=\"table.dataSource.pageIndex\" [pageSize]=\"table.dataSource.pageSize\" [pageSizeOptions]=\"table.pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n </mat-dialog-actions>\r\n}", styles: [".dialog-container{box-sizing:border-box;margin:0;overflow:auto;max-height:100%}.dialog-container vd-dynamic-table{max-height:100%!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RxReactiveFormsModule }, { kind: "directive", type: AsyncValidationDirective, selector: "[ngModel],[formControlName],[formControl]", inputs: ["async"] }, { kind: "directive", type: RxwebFormDirective, selector: "[formGroup],[rxwebForm]", inputs: ["formGroup", "rxwebForm"] }, { kind: "directive", type: RxFormControlDirective, selector: "[ngModel],[formControlName],[formControl]", inputs: ["rxalpha", "rxalphaNumeric", "rxascii", "rxcompare", "rxcompose", "rxcontains", "rxcreditCard", "rxdataUri", "rxdifferent", "rxdigit", "rxemail", "rxendsWith", "rxeven", "rxextension", "rxfactor", "rxfileSize", "rxgreaterThanEqualTo", "rxgreaterThan", "rxhexColor", "rxjson", "rxlatitude", "rxlatLong", "rxleapYear", "rxlessThan", "rxlessThanEqualTo", "rxlongitude", "rxlowerCase", "rxmac", "rxmaxDate", "rxmaxLength", "rxmaxNumber", "rxminDate", "rxminLength", "rxminNumber", "rxnumeric", "rxodd", "rxpassword", "rxport", "rxprimeNumber", "rxrequired", "rxrange", "rxrule", "rxstartsWith", "rxtime", "rxupperCase", "rxurl", "rxunique", "rxnotEmpty", "rxcusip", "rxgrid", "rxdate"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i10.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, 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] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: VdDynamicTableComponent, selector: "vd-dynamic-table", inputs: ["dataSource", "data", "parentControl", "entityObject", "formArray", "debugValue", "classType", "context", "dataSourceFilter", "static", "filterable", "sticky", "tableWidth", "useFilterOperator", "paginable", "selectable", "sortActive", "sortDirection", "stickyHeader", "stickyFilter", "columnSets", "rowNgClass", "detailsTemplate", "readonly", "selectAllFilter", "paginatorRef", "columns", "rowMenuItems", "rowAction", "excludedColumns", "pageSize", "pageSizeOptions"], outputs: ["rowClick"] }, { kind: "component", type: VdDialogHeaderComponent, selector: "vd-dialog-header", inputs: ["dialogRef"] }] });
|
|
18384
18929
|
}
|
|
18385
18930
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdDynamicTableConfigDialogComponent, decorators: [{
|
|
18386
18931
|
type: Component,
|
|
@@ -18393,8 +18938,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18393
18938
|
MatDialogModule,
|
|
18394
18939
|
MatPaginatorModule,
|
|
18395
18940
|
MatButtonModule,
|
|
18396
|
-
VdDynamicTableComponent
|
|
18397
|
-
|
|
18941
|
+
VdDynamicTableComponent,
|
|
18942
|
+
VdDialogHeaderComponent
|
|
18943
|
+
], template: "<!-- Title bar with close button -->\r\n<vd-dialog-header [dialogRef]=\"dialogRef\" i18n=\"@@tableConfiguration\">Table configuration</vd-dialog-header>\r\n\r\n@if (configForm) {\r\n <div class=\"pad-xs flex\" layout=\"column\">\r\n <div class=\"pad-bottom-sm\">\r\n @if (configForm) {\r\n <form [formGroup]=\"configForm\" class=\"pad-xs\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <mat-checkbox formControlName=\"sticky\">\r\n <span i18n=\"@@sticky\">Sticky</span>\r\n <span class=\"description\" i18n=\"@@tableStickyDescription\"> - Select to make the table headers fixed during scrolling.</span>\r\n </mat-checkbox>\r\n @if (false) {\r\n <mat-form-field layout-margin flex>\r\n <mat-label i18n=\"@@tableWidth\">Table width</mat-label>\r\n <input matInput type=\"number\" formControlName=\"tableWidth\" />\r\n </mat-form-field>\r\n }\r\n </div>\r\n </form>\r\n }\r\n </div>\r\n </div>\r\n <div layout-gt-sm=\"row\" class=\"dialog-container\" flex>\r\n <vd-dynamic-table #table [data]=\"columns\" [paginatorRef]=\"paginator\" [classType]=\"tableColumnConfigClassType\" [filterable]=\"true\" [paginable]=\"false\" [useFilterOperator]=\"false\" [pageSize]=\"10\" [context]=\"this\"></vd-dynamic-table>\r\n </div>\r\n <mat-dialog-actions>\r\n <a mat-flat-button color=\"primary\" (click)=\"save()\" i18n=\"@@save\">Save</a>\r\n <a mat-button (click)=\"apply()\" i18n=\"@@apply\">Apply</a>\r\n <a mat-button (click)=\"dialogRef.close()\" i18n=\"@@close\">Close</a>\r\n <span flex></span>\r\n <mat-paginator #paginator [length]=\"table.dataSource.total\" [pageIndex]=\"table.dataSource.pageIndex\" [pageSize]=\"table.dataSource.pageSize\" [pageSizeOptions]=\"table.pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n </mat-dialog-actions>\r\n}", styles: [".dialog-container{box-sizing:border-box;margin:0;overflow:auto;max-height:100%}.dialog-container vd-dynamic-table{max-height:100%!important}\n"] }]
|
|
18398
18944
|
}], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
18399
18945
|
type: Inject,
|
|
18400
18946
|
args: [MAT_DIALOG_DATA]
|
|
@@ -20379,9 +20925,13 @@ class GenericFormBaseComponent extends BaseComponent {
|
|
|
20379
20925
|
: $localize `:@@snackbar.error.required-fields:All fields marked with an asterisk (*) are required.`;
|
|
20380
20926
|
/* Show a notice */
|
|
20381
20927
|
this.snackBarService.open(message, 'Ok', { duration: 3000, panelClass: ['error'] });
|
|
20928
|
+
/* Call the onAfterFormInvalid hook with the collected errors */
|
|
20929
|
+
this.onAfterFormInvalid(errors);
|
|
20382
20930
|
})();
|
|
20383
20931
|
return false;
|
|
20384
20932
|
}
|
|
20933
|
+
/* Call the onAfterFormValid hook if the form is valid */
|
|
20934
|
+
this.onAfterFormValid();
|
|
20385
20935
|
return true;
|
|
20386
20936
|
}
|
|
20387
20937
|
/**
|
|
@@ -20427,46 +20977,6 @@ class GenericFormBaseComponent extends BaseComponent {
|
|
|
20427
20977
|
});
|
|
20428
20978
|
}
|
|
20429
20979
|
}
|
|
20430
|
-
/**
|
|
20431
|
-
* Checks if the form is valid.
|
|
20432
|
-
* This method validates the form, marks invalid controls, and shows error messages if any.
|
|
20433
|
-
* @param form The form to check for validity.
|
|
20434
|
-
* @returns A boolean indicating whether the form is valid.
|
|
20435
|
-
*/
|
|
20436
|
-
isFormValidOld(form) {
|
|
20437
|
-
/* Print some debug information */
|
|
20438
|
-
this.debugForm(form);
|
|
20439
|
-
/* If the form is not valid */
|
|
20440
|
-
if (form && !form.valid) {
|
|
20441
|
-
/* Mark invalid controls as dirty and touched */
|
|
20442
|
-
Object.keys(form.controls)
|
|
20443
|
-
.filter(x => !form.controls[x].valid)
|
|
20444
|
-
.forEach(key => this.invalidateControl(form.controls[key]));
|
|
20445
|
-
/* Show error messages */
|
|
20446
|
-
(async () => {
|
|
20447
|
-
/* Wait until 'mat-error' is displayed */
|
|
20448
|
-
await new Promise(y => setTimeout(y, 200));
|
|
20449
|
-
/* Parse the error messages */
|
|
20450
|
-
var errors = Array();
|
|
20451
|
-
Object.keys(form.controls)
|
|
20452
|
-
.filter(x => !form.controls[x].valid)
|
|
20453
|
-
.forEach(key => {
|
|
20454
|
-
/* Get error text */
|
|
20455
|
-
var error = this.getElementError(form.controls[key]?.nativeElement);
|
|
20456
|
-
if (error) {
|
|
20457
|
-
errors.push(error);
|
|
20458
|
-
}
|
|
20459
|
-
});
|
|
20460
|
-
/* Build error message */
|
|
20461
|
-
var message = errors.length ? errors.slice(0, 3).join('\n') : $localize `:@@snackbar.error.required-fields:All fields marked with an asterisk (*) are required.`;
|
|
20462
|
-
/* Show a notice */
|
|
20463
|
-
this.snackBarService.open(message, 'Ok', { duration: 3000, panelClass: ['error'] });
|
|
20464
|
-
return false;
|
|
20465
|
-
})();
|
|
20466
|
-
return false;
|
|
20467
|
-
}
|
|
20468
|
-
return true;
|
|
20469
|
-
}
|
|
20470
20980
|
/**
|
|
20471
20981
|
* Resets form controls.
|
|
20472
20982
|
* This method marks all controls in the form as pristine, untouched, and updates their validity.
|
|
@@ -20546,24 +21056,6 @@ class GenericFormBaseComponent extends BaseComponent {
|
|
|
20546
21056
|
}
|
|
20547
21057
|
}
|
|
20548
21058
|
}
|
|
20549
|
-
// /**
|
|
20550
|
-
// * Shows form errors.
|
|
20551
|
-
// * This method logs form control errors to the console if debugging is enabled.
|
|
20552
|
-
// * @param form The form to debug.
|
|
20553
|
-
// */
|
|
20554
|
-
// protected debugForm(form?: NgForm | FormGroup | FormArray): void {
|
|
20555
|
-
// if (form && this.debug) {
|
|
20556
|
-
// console.log('Form:', form);
|
|
20557
|
-
// Object.keys(form.controls).forEach(key => {
|
|
20558
|
-
// const controlErrors: ValidationErrors | null = form.controls[key].errors;
|
|
20559
|
-
// if (controlErrors != null) {
|
|
20560
|
-
// Object.keys(controlErrors).forEach(keyError => {
|
|
20561
|
-
// console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
|
|
20562
|
-
// });
|
|
20563
|
-
// }
|
|
20564
|
-
// });
|
|
20565
|
-
// }
|
|
20566
|
-
// }
|
|
20567
21059
|
/**
|
|
20568
21060
|
* Adds toolbar menu items.
|
|
20569
21061
|
* This method adds the 'Delete' menu item to the toolbar if the entity is deletable.
|
|
@@ -20755,6 +21247,17 @@ class GenericFormBaseComponent extends BaseComponent {
|
|
|
20755
21247
|
});
|
|
20756
21248
|
}
|
|
20757
21249
|
}
|
|
21250
|
+
/**
|
|
21251
|
+
* Event emitted when the form is invalid.
|
|
21252
|
+
* This method allows performing operations when the form is found to be invalid.
|
|
21253
|
+
* @param errors The validation errors found in the form.
|
|
21254
|
+
*/
|
|
21255
|
+
onAfterFormInvalid(errors) { }
|
|
21256
|
+
/**
|
|
21257
|
+
* Event emitted when the form is valid.
|
|
21258
|
+
* This method allows performing operations when the form is found to be valid.
|
|
21259
|
+
*/
|
|
21260
|
+
onAfterFormValid() { }
|
|
20758
21261
|
/**
|
|
20759
21262
|
* Event emitted when the entity has been created.
|
|
20760
21263
|
*/
|
|
@@ -21504,7 +22007,7 @@ class VdChipsComponent extends AbstractMatFormField {
|
|
|
21504
22007
|
/**
|
|
21505
22008
|
* Current active sort column.
|
|
21506
22009
|
*/
|
|
21507
|
-
sortActive;
|
|
22010
|
+
sortActive = 'id';
|
|
21508
22011
|
/**
|
|
21509
22012
|
* Current direction of sorting.
|
|
21510
22013
|
*/
|
|
@@ -21836,6 +22339,10 @@ class VdChipsComponent extends AbstractMatFormField {
|
|
|
21836
22339
|
this.dataSourceSubscription?.unsubscribe();
|
|
21837
22340
|
this.dataSourceSubscription = this.dataSource?.connect().subscribe();
|
|
21838
22341
|
}
|
|
22342
|
+
/* Reload the data source if it is already connected */
|
|
22343
|
+
else if (this.dataSource?.isConnected) {
|
|
22344
|
+
this.dataSource?.reload();
|
|
22345
|
+
}
|
|
21839
22346
|
/* Trigger change detection */
|
|
21840
22347
|
this.changeDetectorRef.detectChanges();
|
|
21841
22348
|
}
|
|
@@ -22061,7 +22568,7 @@ class VdChipsComponent extends AbstractMatFormField {
|
|
|
22061
22568
|
provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
|
|
22062
22569
|
useValue: { overlayPanelClass: 'vd-chips-autocomplete' }
|
|
22063
22570
|
}
|
|
22064
|
-
], queries: [{ propertyName: "chipTemplate", first: true, predicate: VdChipDirective, descendants: true }, { propertyName: "autocompleteOptionTemplate", first: true, predicate: VdAutocompleteOptionDirective, descendants: true }], viewQueries: [{ propertyName: "dynamicTable", first: true, predicate: VdDynamicTableComponent, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\n <!-- #region Chips -->\n @for (chip of chips; track chip; let first = $first; let index = $index) {\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\n <span class=\"vd-chip-content\">\n @if (!chipTemplate?.templateRef) {\n <span>\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{ chip }}</span>\n }\n @if (autocompleteOptionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\n }\n </span>\n }\n @if (chipTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"chipTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\n }\n </span>\n @for (button of suffixButtons; track button; let first = $first) {\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\n </a>\n }\n @if ((onLaunch.observers.length) > 0) {\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\n </a>\n }\n @if (!readonly) {\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\n </a>\n }\n </mat-chip-row>\n }\n <!-- #endregion -->\n\n <!-- #region Search box -->\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\n <!-- #endregion -->\n\n <!-- #region Reset button -->\n @if ((!value || empty) && !readonly && !disabled) {\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\n </svg>\n </a>\n }\n <!-- #endregion -->\n</mat-chip-grid>\n\n<!-- #region Autocomplete -->\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\n @if(!classType && opened)\n {\n @for (item of dataSource?.items; track item; let first = $first; let last = $last) {\n <mat-option [value]=\"item\">\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{item}}</span>\n }\n @if (autocompleteOptionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\n }\n </mat-option>\n <mat-divider *ngIf=\"!last\"></mat-divider>\n }\n }\n @if (classType && opened) {\n <mat-option hide=\"true\"></mat-option>\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive||'id'\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\n }\n <div class=\"vd-chips-paginator\">\n <mat-divider></mat-divider>\n <mat-paginator [length]=\"dataSource?.total\" [pageIndex]=\"dataSource?.pageIndex\" [pageSize]=\"dataSource?.pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\n </div>\n</mat-autocomplete>\n<!-- #endregion -->\n\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;width:100%;padding:0 5px;justify-content:center;background-color:transparent!important;margin-right:0!important;margin-left:0!important;padding:0!important;margin:0;height:initial}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.6;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__action--primary:before,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__action--primary:before{border-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i4.MatAutocompleteOrigin, selector: "[matAutocompleteOrigin]", exportAs: ["matAutocompleteOrigin"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5$1.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i5$1.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "component", type: i5$1.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: i5$1.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: VdDynamicTableComponent, selector: "vd-dynamic-table", inputs: ["dataSource", "data", "parentControl", "entityObject", "formArray", "debugValue", "classType", "context", "dataSourceFilter", "static", "filterable", "sticky", "tableWidth", "useFilterOperator", "paginable", "selectable", "sortActive", "sortDirection", "stickyHeader", "stickyFilter", "columnSets", "rowNgClass", "detailsTemplate", "readonly", "selectAllFilter", "paginatorRef", "columns", "rowMenuItems", "rowAction", "excludedColumns", "pageSize", "pageSizeOptions"], outputs: ["rowClick"] }] });
|
|
22571
|
+
], queries: [{ propertyName: "chipTemplate", first: true, predicate: VdChipDirective, descendants: true }, { propertyName: "autocompleteOptionTemplate", first: true, predicate: VdAutocompleteOptionDirective, descendants: true }], viewQueries: [{ propertyName: "dynamicTable", first: true, predicate: VdDynamicTableComponent, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\n <!-- #region Chips -->\n @for (chip of chips; track chip; let first = $first; let index = $index) {\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\n <span class=\"vd-chip-content\">\n @if (!chipTemplate?.templateRef) {\n <span>\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{ chip }}</span>\n }\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\n }\n </span>\n }\n @if (chipTemplate && chipTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\n }\n </span>\n @for (button of suffixButtons; track button; let first = $first) {\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\n </a>\n }\n @if ((onLaunch.observers.length) > 0) {\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\n </a>\n }\n @if (!readonly) {\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\n </a>\n }\n </mat-chip-row>\n }\n <!-- #endregion -->\n\n <!-- #region Search box -->\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\n <!-- #endregion -->\n\n <!-- #region Reset button -->\n @if ((!value || empty) && !readonly && !disabled) {\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\n </svg>\n </a>\n }\n <!-- #endregion -->\n</mat-chip-grid>\n\n<!-- #region Autocomplete -->\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\n @if(!classType && opened)\n {\n @for (item of dataSource?.items; track item; let first = $first; let last = $last) {\n <mat-option [value]=\"item\">\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{item}}</span>\n }\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\n }\n </mat-option>\n <mat-divider *ngIf=\"!last\"></mat-divider>\n }\n }\n @if (classType && opened) {\n <mat-option hide=\"true\"></mat-option>\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\n }\n <div class=\"vd-chips-paginator\">\n <mat-divider></mat-divider>\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\n </div>\n</mat-autocomplete>\n<!-- #endregion -->\n\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;width:100%;padding:0 5px;justify-content:center;background-color:transparent!important;margin-right:0!important;margin-left:0!important;padding:0!important;margin:0;height:initial}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.6;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__action--primary:before,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__action--primary:before{border-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i4.MatAutocompleteOrigin, selector: "[matAutocompleteOrigin]", exportAs: ["matAutocompleteOrigin"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i5.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "component", type: i5.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: i5.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: VdDynamicTableComponent, selector: "vd-dynamic-table", inputs: ["dataSource", "data", "parentControl", "entityObject", "formArray", "debugValue", "classType", "context", "dataSourceFilter", "static", "filterable", "sticky", "tableWidth", "useFilterOperator", "paginable", "selectable", "sortActive", "sortDirection", "stickyHeader", "stickyFilter", "columnSets", "rowNgClass", "detailsTemplate", "readonly", "selectAllFilter", "paginatorRef", "columns", "rowMenuItems", "rowAction", "excludedColumns", "pageSize", "pageSizeOptions"], outputs: ["rowClick"] }] });
|
|
22065
22572
|
}
|
|
22066
22573
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdChipsComponent, decorators: [{
|
|
22067
22574
|
type: Component,
|
|
@@ -22081,7 +22588,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
22081
22588
|
MatIconModule,
|
|
22082
22589
|
MatInputModule,
|
|
22083
22590
|
VdDynamicTableComponent,
|
|
22084
|
-
], template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\n <!-- #region Chips -->\n @for (chip of chips; track chip; let first = $first; let index = $index) {\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\n <span class=\"vd-chip-content\">\n @if (!chipTemplate?.templateRef) {\n <span>\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{ chip }}</span>\n }\n @if (autocompleteOptionTemplate
|
|
22591
|
+
], template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\n <!-- #region Chips -->\n @for (chip of chips; track chip; let first = $first; let index = $index) {\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\n <span class=\"vd-chip-content\">\n @if (!chipTemplate?.templateRef) {\n <span>\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{ chip }}</span>\n }\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\n }\n </span>\n }\n @if (chipTemplate && chipTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\n }\n </span>\n @for (button of suffixButtons; track button; let first = $first) {\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\n </a>\n }\n @if ((onLaunch.observers.length) > 0) {\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\n </a>\n }\n @if (!readonly) {\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\n </a>\n }\n </mat-chip-row>\n }\n <!-- #endregion -->\n\n <!-- #region Search box -->\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\n <!-- #endregion -->\n\n <!-- #region Reset button -->\n @if ((!value || empty) && !readonly && !disabled) {\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\n </svg>\n </a>\n }\n <!-- #endregion -->\n</mat-chip-grid>\n\n<!-- #region Autocomplete -->\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\n @if(!classType && opened)\n {\n @for (item of dataSource?.items; track item; let first = $first; let last = $last) {\n <mat-option [value]=\"item\">\n @if (!autocompleteOptionTemplate?.templateRef) {\n <span>{{item}}</span>\n }\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\n }\n </mat-option>\n <mat-divider *ngIf=\"!last\"></mat-divider>\n }\n }\n @if (classType && opened) {\n <mat-option hide=\"true\"></mat-option>\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\n }\n <div class=\"vd-chips-paginator\">\n <mat-divider></mat-divider>\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\n </div>\n</mat-autocomplete>\n<!-- #endregion -->\n\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;width:100%;padding:0 5px;justify-content:center;background-color:transparent!important;margin-right:0!important;margin-left:0!important;padding:0!important;margin:0;height:initial}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.6;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__action--primary:before,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__action--primary:before{border-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"] }]
|
|
22085
22592
|
}], ctorParameters: () => [{ type: VdMediaService }], propDecorators: { dynamicTable: [{
|
|
22086
22593
|
type: ViewChild,
|
|
22087
22594
|
args: [VdDynamicTableComponent, { static: false }]
|
|
@@ -22594,6 +23101,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
22594
23101
|
args: [MAT_DATE_FORMATS]
|
|
22595
23102
|
}] }, { type: i0.ChangeDetectorRef }] });
|
|
22596
23103
|
|
|
23104
|
+
/**
|
|
23105
|
+
* @component EditFormActionsComponent
|
|
23106
|
+
* @description
|
|
23107
|
+
* Reusable action row for edit forms.
|
|
23108
|
+
* Uses the provided form context to derive button states and trigger
|
|
23109
|
+
* standard form actions (save, apply, cancel/back).
|
|
23110
|
+
*/
|
|
23111
|
+
class MsaEditFormActionsComponent {
|
|
23112
|
+
/**
|
|
23113
|
+
* Reference to the generic form context used by this action row.
|
|
23114
|
+
* @type {IGenericFormBaseComponent<any>}
|
|
23115
|
+
*/
|
|
23116
|
+
context;
|
|
23117
|
+
/**
|
|
23118
|
+
* Determines if the save action is disabled.
|
|
23119
|
+
* Save is disabled while saving is in progress or when form is readonly.
|
|
23120
|
+
* @type {boolean}
|
|
23121
|
+
*/
|
|
23122
|
+
get isSaveDisabled() {
|
|
23123
|
+
return !!(this.context.isSaving || this.context.readonly);
|
|
23124
|
+
}
|
|
23125
|
+
/**
|
|
23126
|
+
* Determines whether the apply button should be displayed.
|
|
23127
|
+
* Apply is only visible when the form is in edit mode.
|
|
23128
|
+
* @type {boolean}
|
|
23129
|
+
*/
|
|
23130
|
+
get isApplyVisible() {
|
|
23131
|
+
return !!this.context.isEditMode;
|
|
23132
|
+
}
|
|
23133
|
+
/**
|
|
23134
|
+
* Determines if the apply action is disabled.
|
|
23135
|
+
* Apply is disabled while saving is in progress or when form is readonly.
|
|
23136
|
+
* @type {boolean}
|
|
23137
|
+
*/
|
|
23138
|
+
get isApplyDisabled() {
|
|
23139
|
+
return !!(this.context.isSaving || this.context.readonly);
|
|
23140
|
+
}
|
|
23141
|
+
/**
|
|
23142
|
+
* Determines if the cancel action is disabled.
|
|
23143
|
+
* Cancel remains enabled by default.
|
|
23144
|
+
* @type {boolean}
|
|
23145
|
+
*/
|
|
23146
|
+
get isCancelDisabled() {
|
|
23147
|
+
return false;
|
|
23148
|
+
}
|
|
23149
|
+
/**
|
|
23150
|
+
* Triggers the context save action.
|
|
23151
|
+
*/
|
|
23152
|
+
onSave() {
|
|
23153
|
+
this.context.save();
|
|
23154
|
+
}
|
|
23155
|
+
/**
|
|
23156
|
+
* Triggers the context apply action.
|
|
23157
|
+
*/
|
|
23158
|
+
onApply() {
|
|
23159
|
+
this.context.apply();
|
|
23160
|
+
}
|
|
23161
|
+
/**
|
|
23162
|
+
* Triggers the context back action.
|
|
23163
|
+
*/
|
|
23164
|
+
onCancel() {
|
|
23165
|
+
this.context.back();
|
|
23166
|
+
}
|
|
23167
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MsaEditFormActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
23168
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MsaEditFormActionsComponent, isStandalone: true, selector: "[msa-edit-form-actions]", inputs: { context: "context" }, ngImport: i0, template: "<button type=\"button\" mat-flat-button color=\"primary\" [disabled]=\"isSaveDisabled\" (click)=\"onSave()\" i18n=\"@@save\">Save</button>\r\n@if (isApplyVisible) {\r\n <button type=\"button\" mat-button [disabled]=\"isApplyDisabled\" (click)=\"onApply()\" i18n=\"@@apply\">Apply</button>\r\n}\r\n<button type=\"button\" mat-button [disabled]=\"isCancelDisabled\" (click)=\"onCancel()\" i18n=\"@@cancel\">Cancel</button>\r\n<span class=\"spacer\"></span>", styles: [".spacer{flex:1 1 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, 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] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }] });
|
|
23169
|
+
}
|
|
23170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MsaEditFormActionsComponent, decorators: [{
|
|
23171
|
+
type: Component,
|
|
23172
|
+
args: [{ selector: '[msa-edit-form-actions]', imports: [
|
|
23173
|
+
CommonModule,
|
|
23174
|
+
MatButtonModule,
|
|
23175
|
+
MatExpansionModule
|
|
23176
|
+
], template: "<button type=\"button\" mat-flat-button color=\"primary\" [disabled]=\"isSaveDisabled\" (click)=\"onSave()\" i18n=\"@@save\">Save</button>\r\n@if (isApplyVisible) {\r\n <button type=\"button\" mat-button [disabled]=\"isApplyDisabled\" (click)=\"onApply()\" i18n=\"@@apply\">Apply</button>\r\n}\r\n<button type=\"button\" mat-button [disabled]=\"isCancelDisabled\" (click)=\"onCancel()\" i18n=\"@@cancel\">Cancel</button>\r\n<span class=\"spacer\"></span>", styles: [".spacer{flex:1 1 auto}\n"] }]
|
|
23177
|
+
}], propDecorators: { context: [{
|
|
23178
|
+
type: Input
|
|
23179
|
+
}] } });
|
|
23180
|
+
|
|
22597
23181
|
/**
|
|
22598
23182
|
* VdListOptionDirective class
|
|
22599
23183
|
*/
|
|
@@ -23422,6 +24006,13 @@ class VdGenericFormComponent {
|
|
|
23422
24006
|
* @type {boolean}
|
|
23423
24007
|
*/
|
|
23424
24008
|
readonly;
|
|
24009
|
+
/**
|
|
24010
|
+
* @property onInit
|
|
24011
|
+
* @description Emitted after fields are built and filtered, allowing parent components to mutate `formGroup`,
|
|
24012
|
+
* `fieldRows`, or `fields` before dynamic subscriptions are attached.
|
|
24013
|
+
* @type {EventEmitter<VdGenericFormInitEvent>}
|
|
24014
|
+
*/
|
|
24015
|
+
onInit = new EventEmitter();
|
|
23425
24016
|
/**
|
|
23426
24017
|
* @property Key codes used for separating input values.
|
|
23427
24018
|
* @description The `separatorKeysCodes` is an array of key codes (e.g., for comma or enter) used for
|
|
@@ -23542,8 +24133,15 @@ class VdGenericFormComponent {
|
|
|
23542
24133
|
if (fields) {
|
|
23543
24134
|
this.fields = fields.map(a => ({ ...a }));
|
|
23544
24135
|
}
|
|
24136
|
+
/* Allow parent components to adjust form controls and field metadata before subscriptions are created. */
|
|
24137
|
+
this.onInit.emit({
|
|
24138
|
+
formGroup: this.formGroup,
|
|
24139
|
+
fieldRows: this.fieldRows,
|
|
24140
|
+
fields: this.fields,
|
|
24141
|
+
context: this.context
|
|
24142
|
+
});
|
|
23545
24143
|
/* Subscribe to value change events for fields with custom 'change' handlers */
|
|
23546
|
-
fields
|
|
24144
|
+
this.fields
|
|
23547
24145
|
?.filter(y => y.type != FormFieldType.File && y.change)
|
|
23548
24146
|
?.forEach(x => {
|
|
23549
24147
|
this.formGroup
|
|
@@ -23582,7 +24180,7 @@ class VdGenericFormComponent {
|
|
|
23582
24180
|
}
|
|
23583
24181
|
};
|
|
23584
24182
|
/* Update dynamic properties for each field and subscribe to form value changes */
|
|
23585
|
-
fields?.forEach(x => {
|
|
24183
|
+
this.fields?.forEach(x => {
|
|
23586
24184
|
const orgField = this.fields?.find(y => y.name == x.name);
|
|
23587
24185
|
if (orgField) {
|
|
23588
24186
|
updateFormField(orgField, x);
|
|
@@ -23778,11 +24376,11 @@ class VdGenericFormComponent {
|
|
|
23778
24376
|
console.log(message, optionalParams);
|
|
23779
24377
|
}
|
|
23780
24378
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdGenericFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
23781
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdGenericFormComponent, isStandalone: true, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input matInput\n [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\"\n [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n parseDecimal\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <textarea matInput\n [formControlName]=\"field.name!\"\n rows=\"field.rows||2\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n </textarea>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [enum]=\"field.enumType\"\n [enumMetadata]=\"field.enumMetadata\"\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [triggerMode]=\"field.triggerMode\"\n [context]=\"context\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #enumOptionIconTemplate\n [ngTemplateOutlet]=\"enumOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [matIconKey]=\"field.optionMatIconProperty\"\n [svgIconKey]=\"field.optionSvgIconProperty\"\n [fontSet]=\"field.optionIconFontSet\"\n [multiple]=\"field.multiple\"\n [selectFirst]=\"field.selectFirst\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [triggerMode]=\"field.triggerMode\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.triggerMapper && field.multiple && field.triggerMode == 'chip'; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <mat-chip-set>\n @for (item of trigger; track item) {\n <mat-chip [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\n </mat-chip>\n }\n </mat-chip-set>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #selectOptionIconTemplate\n [ngTemplateOutlet]=\"selectOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-list [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\"\n [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n [style.max-width]=\"field.maxWidth\"\n [style.max-height]=\"field.maxHeight\"\n flex>\n @if (field.optionTemplate; as option) {\n <ng-template vd-list-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n </vd-list>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (chip of $any(formGroup.controls[field.name!])?.value; track chip) {\n <mat-chip-row\n (removed)=\"removeChip(field, chip)\"\n [color]=\"field.chipColor\"\n selectable=\"true\"\n highlighted\n selected>\n <span>{{chip}}</span>\n <button matChipRemove>\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input [placeholder]=\"$any(field.label)\"\n #chipInput\n [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n [matAutocomplete]=\"chipAutocomplete\"\n (input)=\"filterAutocomplete(field, chipInput)\"\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\n (paste)=\"onPasteChips(field, $event)\"\n autocomplete=\"off\">\n </mat-chip-grid>\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-chips #vdChip\n [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\n [searchField]=\"field.searchField\"\n [searchFields]=\"field.searchFields\"\n [filters]=\"field.filters\"\n [selectFirst]=\"field.selectFirst\"\n [classType]=\"field.classType\"\n [projection]=\"field.projection\"\n [key]=\"field.optionValueProperty\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [removable]=\"!field.clear\"\n [context]=\"context\"\n [suffixButtons]=\"field.suffixButtons\"\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\n [customValue]=\"field.customValue\"\n layout=\"row\"\n flex>\n @if (field.chipTemplate; as chip) {\n <ng-template vd-chip let-chip=\"chip\">\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n @if (field.autocompleteTemplate; as option) {\n <ng-template vd-autocomplete-option let-option=\"option\">\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n </vd-chips>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @if (vdChip.emptyResult) {\n <mat-hint class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-select [formControlName]=\"field.name!\"\n [multiple]=\"field.multiple\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n @for (option of $any(field.options); track option) {\n <mat-option [value]=\"option.id\">{{option.name}}</mat-option>\n }\n </mat-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input type=\"text\"\n matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\n autocomplete=\"off\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n #autocompleteInput>\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <!-- Row container inside one mat-form-field -->\n <div flex layout=\"row\" layout-align=\"start center\" [class]=\"{'has-time': field.showTime}\">\n <!-- Date input -->\n <input matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n autocomplete=\"off\"\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"field.dateFilter\"\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <!-- Time display -->\n @if(field.showTime) {\n <input matInput [value]=\"formGroup.get(field.name!)?.value | date:field.timeFormat\" readonly>\n }\n </div>\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\n <mat-calendar #calendar\n [selected]=\"formGroup.get(field.name!)?.value\"\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\n [headerComponent]=\"datePickerHeaderComponent\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n style=\"width: 100%;\"></mat-calendar>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <div [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\n <mat-checkbox [formControlName]=\"field.name!\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n {{field.label}}\n </mat-checkbox>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass || 'radio-form-field'\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-radio-group radioMatFormControl [formControlName]=\"field.name!\" layout=\"row\" class=\"radio-group-inside-field\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (option of $any(field.options); track option) {\n <mat-radio-button [value]=\"option.id\" class=\"mat-radio-button-wrap\">\n {{option.name}}\n </mat-radio-button>\n }\n </mat-radio-group>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n @if (editorTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n @if (codeTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <div vd-file-input\n [formControlName]=\"field.name!\"\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n </div>\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n @if (customTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n }\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == (((fields[0]?.row | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type:
|
|
24379
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdGenericFormComponent, isStandalone: true, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, outputs: { onInit: "init" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input matInput\n [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\"\n [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n parseDecimal\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <textarea matInput\n [formControlName]=\"field.name!\"\n rows=\"field.rows||2\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n </textarea>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [enum]=\"field.enumType\"\n [enumMetadata]=\"field.enumMetadata\"\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [context]=\"context\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #enumOptionIconTemplate\n [ngTemplateOutlet]=\"enumOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [matIconKey]=\"field.optionMatIconProperty\"\n [svgIconKey]=\"field.optionSvgIconProperty\"\n [fontSet]=\"field.optionIconFontSet\"\n [multiple]=\"field.multiple\"\n [selectFirst]=\"field.selectFirst\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.triggerMapper && field.multiple && field.triggerMode == 'chip'; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <mat-chip-set>\n @for (item of trigger; track item) {\n <mat-chip [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\n </mat-chip>\n }\n </mat-chip-set>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #selectOptionIconTemplate\n [ngTemplateOutlet]=\"selectOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-list [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\"\n [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n [style.max-width]=\"field.maxWidth\"\n [style.max-height]=\"field.maxHeight\"\n flex>\n @if (field.optionTemplate; as option) {\n <ng-template vd-list-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n </vd-list>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (chip of $any(formGroup.controls[field.name!])?.value; track chip) {\n <mat-chip-row\n (removed)=\"removeChip(field, chip)\"\n [color]=\"field.chipColor\"\n selectable=\"true\"\n highlighted\n selected>\n <span>{{chip}}</span>\n <button matChipRemove>\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input [placeholder]=\"$any(field.label)\"\n #chipInput\n [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n [matAutocomplete]=\"chipAutocomplete\"\n (input)=\"filterAutocomplete(field, chipInput)\"\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\n (paste)=\"onPasteChips(field, $event)\"\n autocomplete=\"off\">\n </mat-chip-grid>\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-chips #vdChip\n [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\n [searchField]=\"field.searchField\"\n [searchFields]=\"field.searchFields\"\n [filters]=\"field.filters\"\n [selectFirst]=\"field.selectFirst\"\n [classType]=\"field.classType\"\n [projection]=\"field.projection\"\n [key]=\"field.optionValueProperty\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [removable]=\"!field.clear\"\n [context]=\"context\"\n [suffixButtons]=\"field.suffixButtons\"\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\n [customValue]=\"field.customValue\"\n layout=\"row\"\n flex>\n @if (field.chipTemplate; as chip) {\n <ng-template vd-chip let-chip=\"chip\">\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n @if (field.autocompleteTemplate; as option) {\n <ng-template vd-autocomplete-option let-option=\"option\">\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n </vd-chips>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @if (vdChip.emptyResult) {\n <mat-hint class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-select [formControlName]=\"field.name!\"\n [multiple]=\"field.multiple\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (selectionChange)=\"field.itemSelect && field.itemSelect($event.value, formValue, formGroup, context);\"\n flex>\n @for (option of (field?.options | func:formValue:formGroup:context) ?? []; track option.id) {\n <mat-option [value]=\"option.id\">{{option.name}}</mat-option>\n }\n </mat-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input type=\"text\"\n matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\n autocomplete=\"off\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n #autocompleteInput>\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <!-- Row container inside one mat-form-field -->\n <div flex layout=\"row\" layout-align=\"start center\" [class]=\"{'has-time': field.showTime}\">\n <!-- Date input -->\n <input matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n autocomplete=\"off\"\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"field.dateFilter\"\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <!-- Time display -->\n @if(field.showTime) {\n <input matInput [value]=\"formGroup.get(field.name!)?.value | date:field.timeFormat\" readonly>\n }\n </div>\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\n <mat-calendar #calendar\n [selected]=\"formGroup.get(field.name!)?.value\"\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\n [headerComponent]=\"datePickerHeaderComponent\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n style=\"width: 100%;\"></mat-calendar>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <div [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\n <mat-checkbox [formControlName]=\"field.name!\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n {{field.label}}\n </mat-checkbox>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass || 'radio-form-field'\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-radio-group radioMatFormControl [formControlName]=\"field.name!\" layout=\"row\" class=\"radio-group-inside-field\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (option of $any(field.options); track option) {\n <mat-radio-button [value]=\"option.id\" class=\"mat-radio-button-wrap\">\n {{option.name}}\n </mat-radio-button>\n }\n </mat-radio-group>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n @if (editorTemplate && editorTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"editorTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n @if (codeTemplate && codeTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"codeTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <div vd-file-input\n [formControlName]=\"field.name!\"\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n </div>\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n @if (customTemplate && customTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"customTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n }\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == (((fields[0]?.row | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type:
|
|
23782
24380
|
//--------------------
|
|
23783
|
-
MatAutocompleteModule }, { kind: "component", type: i4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5
|
|
24381
|
+
MatAutocompleteModule }, { kind: "component", type: i4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i5.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i5.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i5.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i5.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i5.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i6$1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "component", type: i6$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i6$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i6$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i7.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i11.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i11.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "component", type:
|
|
23784
24382
|
//--------------------
|
|
23785
|
-
VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "filters", "removable", "selectFirst", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "component", type: VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "ngmodule", type: VdFileModule }, { kind: "component", type: VdListComponent, selector: "vd-list" }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"
|
|
24383
|
+
VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "filters", "removable", "selectFirst", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "component", type: VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "ngmodule", type: VdFileModule }, { kind: "component", type: VdListComponent, selector: "vd-list" }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"] }, { kind: "directive", type: VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "directive", type: VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "directive", type: VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type:
|
|
23786
24384
|
//--------------------
|
|
23787
24385
|
AutofocusDirective, selector: "[autoFocus]", inputs: ["focusDelay", "selectText", "autoFocus"] }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "ngmodule", type:
|
|
23788
24386
|
//--------------------
|
|
@@ -23827,7 +24425,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
23827
24425
|
RemoveWhitespaceDirective,
|
|
23828
24426
|
NativeElementInjectorDirective,
|
|
23829
24427
|
MatFormFieldRadioDirective
|
|
23830
|
-
], template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input matInput\n [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\"\n [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n parseDecimal\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <textarea matInput\n [formControlName]=\"field.name!\"\n rows=\"field.rows||2\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n </textarea>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [enum]=\"field.enumType\"\n [enumMetadata]=\"field.enumMetadata\"\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [triggerMode]=\"field.triggerMode\"\n [context]=\"context\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #enumOptionIconTemplate\n [ngTemplateOutlet]=\"enumOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [matIconKey]=\"field.optionMatIconProperty\"\n [svgIconKey]=\"field.optionSvgIconProperty\"\n [fontSet]=\"field.optionIconFontSet\"\n [multiple]=\"field.multiple\"\n [selectFirst]=\"field.selectFirst\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [triggerMode]=\"field.triggerMode\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.triggerMapper && field.multiple && field.triggerMode == 'chip'; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <mat-chip-set>\n @for (item of trigger; track item) {\n <mat-chip [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\n </mat-chip>\n }\n </mat-chip-set>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #selectOptionIconTemplate\n [ngTemplateOutlet]=\"selectOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-list [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\"\n [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n [style.max-width]=\"field.maxWidth\"\n [style.max-height]=\"field.maxHeight\"\n flex>\n @if (field.optionTemplate; as option) {\n <ng-template vd-list-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n </vd-list>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (chip of $any(formGroup.controls[field.name!])?.value; track chip) {\n <mat-chip-row\n (removed)=\"removeChip(field, chip)\"\n [color]=\"field.chipColor\"\n selectable=\"true\"\n highlighted\n selected>\n <span>{{chip}}</span>\n <button matChipRemove>\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input [placeholder]=\"$any(field.label)\"\n #chipInput\n [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n [matAutocomplete]=\"chipAutocomplete\"\n (input)=\"filterAutocomplete(field, chipInput)\"\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\n (paste)=\"onPasteChips(field, $event)\"\n autocomplete=\"off\">\n </mat-chip-grid>\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-chips #vdChip\n [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\n [searchField]=\"field.searchField\"\n [searchFields]=\"field.searchFields\"\n [filters]=\"field.filters\"\n [selectFirst]=\"field.selectFirst\"\n [classType]=\"field.classType\"\n [projection]=\"field.projection\"\n [key]=\"field.optionValueProperty\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [removable]=\"!field.clear\"\n [context]=\"context\"\n [suffixButtons]=\"field.suffixButtons\"\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\n [customValue]=\"field.customValue\"\n layout=\"row\"\n flex>\n @if (field.chipTemplate; as chip) {\n <ng-template vd-chip let-chip=\"chip\">\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n @if (field.autocompleteTemplate; as option) {\n <ng-template vd-autocomplete-option let-option=\"option\">\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n </vd-chips>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @if (vdChip.emptyResult) {\n <mat-hint class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-select [formControlName]=\"field.name!\"\n [multiple]=\"field.multiple\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n @for (option of $any(field.options); track option) {\n <mat-option [value]=\"option.id\">{{option.name}}</mat-option>\n }\n </mat-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input type=\"text\"\n matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\n autocomplete=\"off\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n #autocompleteInput>\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <!-- Row container inside one mat-form-field -->\n <div flex layout=\"row\" layout-align=\"start center\" [class]=\"{'has-time': field.showTime}\">\n <!-- Date input -->\n <input matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n autocomplete=\"off\"\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"field.dateFilter\"\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <!-- Time display -->\n @if(field.showTime) {\n <input matInput [value]=\"formGroup.get(field.name!)?.value | date:field.timeFormat\" readonly>\n }\n </div>\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\n <mat-calendar #calendar\n [selected]=\"formGroup.get(field.name!)?.value\"\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\n [headerComponent]=\"datePickerHeaderComponent\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n style=\"width: 100%;\"></mat-calendar>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <div [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\n <mat-checkbox [formControlName]=\"field.name!\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n {{field.label}}\n </mat-checkbox>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass || 'radio-form-field'\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-radio-group radioMatFormControl [formControlName]=\"field.name!\" layout=\"row\" class=\"radio-group-inside-field\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (option of $any(field.options); track option) {\n <mat-radio-button [value]=\"option.id\" class=\"mat-radio-button-wrap\">\n {{option.name}}\n </mat-radio-button>\n }\n </mat-radio-group>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n @if (editorTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n @if (codeTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <div vd-file-input\n [formControlName]=\"field.name!\"\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n </div>\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n @if (customTemplate?.templateRef!) {\n <ng-template [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n }\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == (((fields[0]?.row | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"] }]
|
|
24428
|
+
], template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input matInput\n [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\"\n [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [autoFocus]=\"((field.focus | func:formValue:formGroup:context)??false)\"\n [selectText]=\"((field.selectText | func:formValue:formGroup:context)??false)\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n parseDecimal\n [parseDecimalEnabled]=\"(field.parseDecimal??false)\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <textarea matInput\n [formControlName]=\"field.name!\"\n rows=\"field.rows||2\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n [removeWhitespace]=\"(field.removeWhitespace??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n </textarea>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [enum]=\"field.enumType\"\n [enumMetadata]=\"field.enumMetadata\"\n [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n [context]=\"context\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #enumOptionIconTemplate\n [ngTemplateOutlet]=\"enumOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-select [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\" [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [defaultOption]=\"field.defaultOption??true\"\n [matIconKey]=\"field.optionMatIconProperty\"\n [svgIconKey]=\"field.optionSvgIconProperty\"\n [fontSet]=\"field.optionIconFontSet\"\n [multiple]=\"field.multiple\"\n [selectFirst]=\"field.selectFirst\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [triggerCssClass]=\"field.triggerCssClass\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n layout=\"row\"\n flex>\n @if (field.triggerTemplate; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if (field.triggerMapper && field.multiple && field.triggerMode == 'chip'; as trigger) {\n <ng-template vd-select-trigger let-trigger=\"trigger\">\n <mat-chip-set>\n @for (item of trigger; track item) {\n <mat-chip [color]=\"field.chipColor\" [color]=\"field.chipColor\" highlighted selected>\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\n </mat-chip>\n }\n </mat-chip-set>\n </ng-template>\n }\n @if (field.optionTemplate; as option) {\n <ng-template vd-select-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n @if(field.optionIcon && !field.optionTemplate){\n <ng-template vd-select-option let-option=\"option\" let-text=\"text\">\n <div layout=\"row\" layout-align=\"start center\">\n <ng-template #selectOptionIconTemplate\n [ngTemplateOutlet]=\"selectOptionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: field.optionIcon(option, formValue, formGroup, context) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: optionIcon.iconColor??'' }\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n <span>{{text}}</span>\n </div>\n </ng-template>\n }\n </vd-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-list [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params ??{} | func:formValue:formGroup:context\"\n [projection]=\"field.projection\"\n [mapper]=\"field.mapper\"\n [compareWith]=\"field.compareWith\"\n [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\"\n [optionValueProperty]=\"field.optionValueProperty\"\n [optionTextProperty]=\"field.optionTextProperty\"\n [multiple]=\"field.multiple\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\"\n [style.max-width]=\"field.maxWidth\"\n [style.max-height]=\"field.maxHeight\"\n flex>\n @if (field.optionTemplate; as option) {\n <ng-template vd-list-option let-option=\"option\">\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\n </ng-template>\n }\n </vd-list>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (chip of $any(formGroup.controls[field.name!])?.value; track chip) {\n <mat-chip-row\n (removed)=\"removeChip(field, chip)\"\n [color]=\"field.chipColor\"\n selectable=\"true\"\n highlighted\n selected>\n <span>{{chip}}</span>\n <button matChipRemove>\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n }\n <input [placeholder]=\"$any(field.label)\"\n #chipInput\n [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n [matAutocomplete]=\"chipAutocomplete\"\n (input)=\"filterAutocomplete(field, chipInput)\"\n (matChipInputTokenEnd)=\"addChip(field, $event)\"\n (paste)=\"onPasteChips(field, $event)\"\n autocomplete=\"off\">\n </mat-chip-grid>\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <vd-chips #vdChip\n [formControlName]=\"field.name!\"\n [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\"\n [params]=\"field.params || {} | func:formValue:formGroup:context\"\n [searchField]=\"field.searchField\"\n [searchFields]=\"field.searchFields\"\n [filters]=\"field.filters\"\n [selectFirst]=\"field.selectFirst\"\n [classType]=\"field.classType\"\n [projection]=\"field.projection\"\n [key]=\"field.optionValueProperty\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [removable]=\"!field.clear\"\n [context]=\"context\"\n [suffixButtons]=\"field.suffixButtons\"\n [autocompleteCssClass]=\"field.autocompleteCssClass\"\n (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\"\n (selected)=\"!field.itemChange ? $event.callback(true) : $event.callback(field.itemChange($event.value, formValue, formGroup, context) !== false)\"\n (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\"\n [customValue]=\"field.customValue\"\n layout=\"row\"\n flex>\n @if (field.chipTemplate; as chip) {\n <ng-template vd-chip let-chip=\"chip\">\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n @if (field.autocompleteTemplate; as option) {\n <ng-template vd-autocomplete-option let-option=\"option\">\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\n </ng-template>\n }\n </vd-chips>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @if (vdChip.emptyResult) {\n <mat-hint class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-select [formControlName]=\"field.name!\"\n [multiple]=\"field.multiple\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n (selectionChange)=\"field.itemSelect && field.itemSelect($event.value, formValue, formGroup, context);\"\n flex>\n @for (option of (field?.options | func:formValue:formGroup:context) ?? []; track option.id) {\n <mat-option [value]=\"option.id\">{{option.name}}</mat-option>\n }\n </mat-select>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input type=\"text\"\n matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterAutocomplete(field, autocompleteInput)\"\n autocomplete=\"off\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [prefix]=\"field.prefix | func:formValue:formGroup:context\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n #autocompleteInput>\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\n @for (option of autocompleteFilteredOptions[field.name!]; track option) {\n <mat-option [value]=\"option.id\">\n {{option.name}}\n </mat-option>\n }\n </mat-autocomplete>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <!-- Row container inside one mat-form-field -->\n <div flex layout=\"row\" layout-align=\"start center\" [class]=\"{'has-time': field.showTime}\">\n <!-- Date input -->\n <input matInput\n [formControlName]=\"field.name!\"\n [min]=\"field.min\"\n [max]=\"field.max\"\n autocomplete=\"off\"\n [matDatepicker]=\"datePicker\"\n [matDatepickerFilter]=\"field.dateFilter\"\n [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <!-- Time display -->\n @if(field.showTime) {\n <input matInput [value]=\"formGroup.get(field.name!)?.value | date:field.timeFormat\" readonly>\n }\n </div>\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\n <mat-calendar #calendar\n [selected]=\"formGroup.get(field.name!)?.value\"\n (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\"\n (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\"\n [headerComponent]=\"datePickerHeaderComponent\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\"\n style=\"width: 100%;\"></mat-calendar>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <input [type]=\"field.inputType ?? 'text'\"\n [minlength]=\"field.minLength | func:formValue:formGroup:context\"\n [maxlength]=\"field.maxLength | func:formValue:formGroup:context\"\n [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\"\n [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n [pattern]=\"((field.pattern | func:formValue:formGroup:context)??'')\"\n [onlyNumber]=\"(field.numbersOnly??false)\"\n (keydown)=\"field.keydown && field.keydown($event, formValue, formGroup, context)\">\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n @if (field.hint) {\n <mat-hint>{{field.hint}}</mat-hint>\n }\n @for (errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <div [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\n <mat-checkbox [formControlName]=\"field.name!\"\n [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n {{field.label}}\n </mat-checkbox>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error layout-margin>{{errorMessage}}</mat-error>\n }\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <mat-form-field [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass || 'radio-form-field'\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <mat-radio-group radioMatFormControl [formControlName]=\"field.name!\" layout=\"row\" class=\"radio-group-inside-field\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\n @for (option of $any(field.options); track option) {\n <mat-radio-button [value]=\"option.id\" class=\"mat-radio-button-wrap\">\n {{option.name}}\n </mat-radio-button>\n }\n </mat-radio-group>\n @for (errorMessage of $any(formGroup.controls[field.name!])['errorMessages']; track errorMessage) {\n <mat-error>{{errorMessage}}</mat-error>\n }\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n @if (editorTemplate && editorTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"editorTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n @if (codeTemplate && codeTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"codeTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\n <mat-label>{{field.label}}</mat-label>\n <div vd-file-input\n [formControlName]=\"field.name!\"\n (select)=\"field.change && field.change(field, $event, formGroup, context)\"\n [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"\n flex>\n </div>\n </mat-form-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n @if (customTemplate && customTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"customTemplate.templateRef\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n }\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == (((fields[0]?.row | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"] }]
|
|
23831
24429
|
}], propDecorators: { formGroup: [{
|
|
23832
24430
|
type: Input
|
|
23833
24431
|
}], classType: [{
|
|
@@ -23846,6 +24444,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
23846
24444
|
type: Input
|
|
23847
24445
|
}], readonly: [{
|
|
23848
24446
|
type: Input
|
|
24447
|
+
}], onInit: [{
|
|
24448
|
+
type: Output,
|
|
24449
|
+
args: ['init']
|
|
23849
24450
|
}], separatorKeysCodes: [{
|
|
23850
24451
|
type: Input
|
|
23851
24452
|
}], editorTemplate: [{
|
|
@@ -24634,6 +25235,7 @@ class FormFieldDefinition {
|
|
|
24634
25235
|
triggerMapper;
|
|
24635
25236
|
/**
|
|
24636
25237
|
* Mode of the trigger (e.g., chip).
|
|
25238
|
+
* @deprecated This property is no longer used and will be removed in a future version.
|
|
24637
25239
|
*/
|
|
24638
25240
|
triggerMode;
|
|
24639
25241
|
/**
|
|
@@ -25283,6 +25885,12 @@ class VdMenuComponent {
|
|
|
25283
25885
|
*/
|
|
25284
25886
|
ngOnInit() {
|
|
25285
25887
|
this.media.registerQuery(`gt-sm`).subscribe((x) => { this.mobile = !x; });
|
|
25888
|
+
// if (this.items.length > 0) {
|
|
25889
|
+
// var testMenuItem = this.items.find((x: MenuItem) => x.id === 9);
|
|
25890
|
+
// if (testMenuItem) {
|
|
25891
|
+
// this.itemMouseEnter({ type: 'mouseenter' }, testMenuItem);
|
|
25892
|
+
// }
|
|
25893
|
+
// }
|
|
25286
25894
|
}
|
|
25287
25895
|
/**
|
|
25288
25896
|
* Event emitted when a meni item is clicked.
|
|
@@ -25310,10 +25918,10 @@ class VdMenuComponent {
|
|
|
25310
25918
|
* Event emitted when the cursor of the mouse is moved out of it.
|
|
25311
25919
|
*/
|
|
25312
25920
|
itemMouseLeave($event, item) {
|
|
25313
|
-
this.onMouseLeave.emit({ event: $event, item: item });
|
|
25921
|
+
// this.onMouseLeave.emit({ event: $event, item: item });
|
|
25314
25922
|
}
|
|
25315
25923
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdMenuComponent, deps: [{ token: VdMediaService }], target: i0.ɵɵFactoryTarget.Component });
|
|
25316
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdMenuComponent, isStandalone: true, selector: "vd-menu", inputs: { items: "items", activeExact: "activeExact", fontSet: "fontSet", avatar: "avatar", mobile: "mobile" }, outputs: { onClick: "click", onMouseEnter: "over", onMouseLeave: "out" }, ngImport: i0, template: "<mat-nav-list>\r\n <mat-accordion displayMode=\"flat\">\r\n @for (item of items; track item; let last = $last) {\r\n @if ((item?.items?.length ?? 0) > 0 && mobile) {\r\n <mat-expansion-panel class=\"mat-elevation-z raw\"\r\n (click)=\"$event.stopPropagation();\"\r\n [disabled]=\"!mobile\"\r\n [hideToggle]=\"!mobile || !item?.items?.length\"\r\n [ngClass]=\"{'icon-only': !item.title, 'mobile': mobile}\"\r\n (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\"\r\n (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\"\r\n [routerLinkActive]=\"['active']\"\r\n [routerLinkActiveOptions]=\"{exact:false}\">\r\n <mat-expansion-panel-header [expandedHeight]=\"'48px'\">\r\n <mat-panel-title>\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\">{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{item.title}}</h3>\r\n }\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <mat-nav-list>\r\n @for (subItem of item.items; track subItem; let subLast = $last) {\r\n @if (subItem.enabled) {\r\n <a mat-list-item\r\n [style.backgroundColor]=\"subItem.backgroundColor\"\r\n [routerLink]=\"subItem.path\"\r\n target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\"\r\n [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !subItem.title}\"\r\n [routerLinkActiveOptions]=\"{exact:subItem.activeExact??false}\"\r\n [fragment]=\"subItem.fragment\"\r\n (click)=\"itemClicked($event, subItem)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"subItem.iconColor\"\r\n [matBadge]=\"subItem.badge ? subItem.badge() : null\"\r\n [matBadgeHidden]=\"!subItem.badge || subItem.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && subItem.title) {\r\n <span [style.color]=\"subItem.textColor\">{{subItem.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{subItem.title}}</h3>\r\n }\r\n @if (avatar && subItem.description) {\r\n <p>{{subItem.description}}</p>\r\n }\r\n </a>\r\n }\r\n @if (subItem.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!subItem.divider && avatar && !subLast) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n }\r\n </mat-nav-list>\r\n </mat-expansion-panel>\r\n } @else {\r\n @if (item.enabled) {\r\n <a mat-list-item [style.backgroundColor]=\"item.backgroundColor\" [routerLink]=\"item.path\" target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\" [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !item.title}\" [routerLinkActiveOptions]=\"{exact:item.activeExact??false}\" [fragment]=\"item.fragment\" (click)=\"itemClicked($event, item)\" (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\" (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\"\r\n matListItemIcon>\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\" matListItemTitle>{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" matListAvatar>{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3 matLine>{{item.title}}</h3>\r\n }\r\n @if (avatar && item.description) {\r\n <p matLine>{{item.description}}</p>\r\n }\r\n </a>\r\n }\r\n @if (item.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!item.divider && avatar && !last) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n }\r\n }\r\n </mat-accordion>\r\n</mat-nav-list>", styles: [":host ::ng-deep .mat-mdc-nav-list .mat-mdc-list-item.icon-only .mdc-list-item__content{display:none!important}:host ::ng-deep .mat-expansion-panel{background-color:transparent}:host ::ng-deep .mat-mdc-list-item:not(.active),:host ::ng-deep .mat-mdc-list-item:active,:host ::ng-deep .mat-mdc-list-item:focus,:host ::ng-deep .mat-expansion-panel:not(.active),:host ::ng-deep .mat-expansion-panel:active,:host ::ng-deep .mat-expansion-panel:focus{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item:not(.active):before,:host ::ng-deep .mat-mdc-list-item:active:before,:host ::ng-deep .mat-mdc-list-item:focus:before,:host ::ng-deep .mat-expansion-panel:not(.active):before,:host ::ng-deep .mat-expansion-panel:active:before,:host ::ng-deep .mat-expansion-panel:focus:before{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item,:host ::ng-deep .mat-expansion-panel{font-family:var(--mat-expansion-header-text-font, var(--mat-sys-title-medium-font));font-weight:var(--mat-expansion-header-text-weight, var(--mat-sys-title-medium-weight));line-height:var(--mat-expansion-header-text-line-height, var(--mat-sys-title-medium-line-height));letter-spacing:var(--mat-expansion-header-text-tracking, var(--mat-sys-title-medium-tracking))}:host ::ng-deep .mat-mdc-list-item mat-icon,:host ::ng-deep .mat-expansion-panel mat-icon{margin-right:18px;margin-bottom:3px}:host ::ng-deep .mat-mdc-list-item ::ng-deep .mat-expansion-panel-body,:host ::ng-deep .mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding-bottom:0!important}:host ::ng-deep .mat-mdc-list-item:not(.mobile)>.mat-expansion-panel-header,:host ::ng-deep .mat-expansion-panel:not(.mobile)>.mat-expansion-panel-header{padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i4$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i4$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i4$2.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i6$3.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i6$3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i6$3.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i6$3.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i8$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: VdDelayedHoverDirective, selector: "[delayedHover]", inputs: ["duration"], outputs: ["delayedHover"], exportAs: ["hesitation"] }, { kind: "pipe", type: FuncPipe, name: "func" }] });
|
|
25924
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: VdMenuComponent, isStandalone: true, selector: "vd-menu", inputs: { items: "items", activeExact: "activeExact", fontSet: "fontSet", avatar: "avatar", mobile: "mobile" }, outputs: { onClick: "click", onMouseEnter: "over", onMouseLeave: "out" }, ngImport: i0, template: "<mat-nav-list>\r\n <!-- #region main-menu-accordion -->\r\n <mat-accordion displayMode=\"flat\">\r\n @for (item of items; track item; let last = $last) {\r\n <!-- #region mobile-item-with-submenu -->\r\n @if ((item?.items?.length ?? 0) > 0 && mobile) {\r\n <mat-expansion-panel class=\"mat-elevation-z raw\"\r\n (click)=\"$event.stopPropagation();\"\r\n [disabled]=\"!mobile\"\r\n [hideToggle]=\"!mobile || !item?.items?.length\"\r\n [ngClass]=\"{'icon-only': !item.title, 'mobile': mobile}\"\r\n (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\"\r\n (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\"\r\n [routerLinkActive]=\"['active']\"\r\n [routerLinkActiveOptions]=\"{exact:false}\">\r\n <!-- #region mobile-parent-item-header -->\r\n <mat-expansion-panel-header [expandedHeight]=\"'48px'\">\r\n <mat-panel-title>\r\n <!-- #region parent-item-icon-and-title -->\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\">{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{item.title}}</h3>\r\n }\r\n <!-- #endregion -->\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- #endregion -->\r\n\r\n <!-- #region mobile-submenu-items -->\r\n <mat-nav-list>\r\n @for (subItem of item.items; track subItem; let subLast = $last) {\r\n <!-- #region visible-submenu-link -->\r\n @if (subItem.enabled) {\r\n <a mat-list-item\r\n [style.backgroundColor]=\"subItem.backgroundColor\"\r\n [routerLink]=\"subItem.path\"\r\n target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\"\r\n [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !subItem.title}\"\r\n [routerLinkActiveOptions]=\"{exact:subItem.activeExact??false}\"\r\n [fragment]=\"subItem.fragment\"\r\n (click)=\"itemClicked($event, subItem)\">\r\n <!-- #region submenu-icon-and-text -->\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" [style.color]=\"subItem.iconColor\" aria-hidden=\"false\">\r\n {{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n\r\n @if (!avatar && subItem.title) {\r\n <span [style.color]=\"subItem.textColor\">{{subItem.title}}</span>\r\n }\r\n\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n\r\n @if (avatar) {\r\n <h3>{{subItem.title}}</h3>\r\n }\r\n\r\n @if (avatar && subItem.description) {\r\n <p>{{subItem.description}}</p>\r\n }\r\n\r\n @if (subItem.badge && subItem.badge() !== 0) {\r\n <span matListItemMeta\r\n [matBadge]=\"subItem.badge()\"\r\n matBadgeOverlap=\"false\"\r\n matBadgePosition=\"above before\"\r\n class=\"menu-badge-align\">\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region submenu-divider-lines -->\r\n @if (subItem.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!subItem.divider && avatar && !subLast) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n <!-- #endregion -->\r\n }\r\n </mat-nav-list>\r\n <!-- #endregion -->\r\n </mat-expansion-panel>\r\n <!-- #endregion -->\r\n\r\n <!-- #region regular-menu-item -->\r\n } @else {\r\n <!-- #region regular-item-link -->\r\n @if (item.enabled) {\r\n <a mat-list-item [style.backgroundColor]=\"item.backgroundColor\" [routerLink]=\"item.path\" target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\" [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !item.title}\" [routerLinkActiveOptions]=\"{exact:item.activeExact??false}\" [fragment]=\"item.fragment\" (click)=\"itemClicked($event, item)\" (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\" (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n aria-hidden=\"false\"\r\n matListItemIcon>\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\" matListItemTitle>{{item.title}}</span>\r\n }\r\n\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" matListAvatar>{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n\r\n @if (avatar) {\r\n <h3 matLine>{{item.title}}</h3>\r\n }\r\n\r\n @if (avatar && item.description) {\r\n <p matLine>{{item.description}}</p>\r\n }\r\n\r\n @if (item.badge && item.badge() !== 0) {\r\n <span matListItemMeta\r\n [matBadge]=\"item.badge()\"\r\n matBadgeOverlap=\"false\"\r\n matBadgePosition=\"above before\"\r\n class=\"menu-badge-align\">\r\n </span>\r\n }\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region regular-item-divider-lines -->\r\n @if (item.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!item.divider && avatar && !last) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <!-- #endregion -->\r\n }\r\n </mat-accordion>\r\n <!-- #endregion -->\r\n</mat-nav-list>", styles: [":host ::ng-deep .mat-mdc-nav-list .mat-mdc-list-item.icon-only .mdc-list-item__content{display:none!important}:host ::ng-deep .mat-expansion-panel{background-color:transparent}:host ::ng-deep .mat-mdc-list-item:not(.active),:host ::ng-deep .mat-mdc-list-item:active,:host ::ng-deep .mat-mdc-list-item:focus,:host ::ng-deep .mat-expansion-panel:not(.active),:host ::ng-deep .mat-expansion-panel:active,:host ::ng-deep .mat-expansion-panel:focus{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item:not(.active):before,:host ::ng-deep .mat-mdc-list-item:active:before,:host ::ng-deep .mat-mdc-list-item:focus:before,:host ::ng-deep .mat-expansion-panel:not(.active):before,:host ::ng-deep .mat-expansion-panel:active:before,:host ::ng-deep .mat-expansion-panel:focus:before{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item,:host ::ng-deep .mat-expansion-panel{font-family:var(--mat-expansion-header-text-font, var(--mat-sys-title-medium-font));font-weight:var(--mat-expansion-header-text-weight, var(--mat-sys-title-medium-weight));line-height:var(--mat-expansion-header-text-line-height, var(--mat-sys-title-medium-line-height));letter-spacing:var(--mat-expansion-header-text-tracking, var(--mat-sys-title-medium-tracking))}:host ::ng-deep .mat-mdc-list-item mat-icon,:host ::ng-deep .mat-expansion-panel mat-icon{margin-right:18px;margin-bottom:3px}:host ::ng-deep .mat-mdc-list-item ::ng-deep .mat-expansion-panel-body,:host ::ng-deep .mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding-bottom:0!important}:host ::ng-deep .mat-mdc-list-item:not(.mobile)>.mat-expansion-panel-header,:host ::ng-deep .mat-expansion-panel:not(.mobile)>.mat-expansion-panel-header{padding:4px 8px}:host ::ng-deep .menu-badge-align{padding-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i4$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i4$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i4$2.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i4$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: i4$2.MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i6$3.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i6$3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i6$3.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i6$3.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i8$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: VdDelayedHoverDirective, selector: "[delayedHover]", inputs: ["duration"], outputs: ["delayedHover"], exportAs: ["hesitation"] }, { kind: "pipe", type: FuncPipe, name: "func" }] });
|
|
25317
25925
|
}
|
|
25318
25926
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VdMenuComponent, decorators: [{
|
|
25319
25927
|
type: Component,
|
|
@@ -25327,7 +25935,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
25327
25935
|
MatBadgeModule,
|
|
25328
25936
|
VdDelayedHoverDirective,
|
|
25329
25937
|
FuncPipe
|
|
25330
|
-
], template: "<mat-nav-list>\r\n <mat-accordion displayMode=\"flat\">\r\n @for (item of items; track item; let last = $last) {\r\n @if ((item?.items?.length ?? 0) > 0 && mobile) {\r\n <mat-expansion-panel class=\"mat-elevation-z raw\"\r\n (click)=\"$event.stopPropagation();\"\r\n [disabled]=\"!mobile\"\r\n [hideToggle]=\"!mobile || !item?.items?.length\"\r\n [ngClass]=\"{'icon-only': !item.title, 'mobile': mobile}\"\r\n (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\"\r\n (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\"\r\n [routerLinkActive]=\"['active']\"\r\n [routerLinkActiveOptions]=\"{exact:false}\">\r\n <mat-expansion-panel-header [expandedHeight]=\"'48px'\">\r\n <mat-panel-title>\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\">{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{item.title}}</h3>\r\n }\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <mat-nav-list>\r\n @for (subItem of item.items; track subItem; let subLast = $last) {\r\n @if (subItem.enabled) {\r\n <a mat-list-item\r\n [style.backgroundColor]=\"subItem.backgroundColor\"\r\n [routerLink]=\"subItem.path\"\r\n target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\"\r\n [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !subItem.title}\"\r\n [routerLinkActiveOptions]=\"{exact:subItem.activeExact??false}\"\r\n [fragment]=\"subItem.fragment\"\r\n (click)=\"itemClicked($event, subItem)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"subItem.iconColor\"\r\n [matBadge]=\"subItem.badge ? subItem.badge() : null\"\r\n [matBadgeHidden]=\"!subItem.badge || subItem.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && subItem.title) {\r\n <span [style.color]=\"subItem.textColor\">{{subItem.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{subItem.title}}</h3>\r\n }\r\n @if (avatar && subItem.description) {\r\n <p>{{subItem.description}}</p>\r\n }\r\n </a>\r\n }\r\n @if (subItem.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!subItem.divider && avatar && !subLast) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n }\r\n </mat-nav-list>\r\n </mat-expansion-panel>\r\n } @else {\r\n @if (item.enabled) {\r\n <a mat-list-item [style.backgroundColor]=\"item.backgroundColor\" [routerLink]=\"item.path\" target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\" [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !item.title}\" [routerLinkActiveOptions]=\"{exact:item.activeExact??false}\" [fragment]=\"item.fragment\" (click)=\"itemClicked($event, item)\" (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\" (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\"\r\n matListItemIcon>\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\" matListItemTitle>{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" matListAvatar>{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3 matLine>{{item.title}}</h3>\r\n }\r\n @if (avatar && item.description) {\r\n <p matLine>{{item.description}}</p>\r\n }\r\n </a>\r\n }\r\n @if (item.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!item.divider && avatar && !last) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n }\r\n }\r\n </mat-accordion>\r\n</mat-nav-list>", styles: [":host ::ng-deep .mat-mdc-nav-list .mat-mdc-list-item.icon-only .mdc-list-item__content{display:none!important}:host ::ng-deep .mat-expansion-panel{background-color:transparent}:host ::ng-deep .mat-mdc-list-item:not(.active),:host ::ng-deep .mat-mdc-list-item:active,:host ::ng-deep .mat-mdc-list-item:focus,:host ::ng-deep .mat-expansion-panel:not(.active),:host ::ng-deep .mat-expansion-panel:active,:host ::ng-deep .mat-expansion-panel:focus{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item:not(.active):before,:host ::ng-deep .mat-mdc-list-item:active:before,:host ::ng-deep .mat-mdc-list-item:focus:before,:host ::ng-deep .mat-expansion-panel:not(.active):before,:host ::ng-deep .mat-expansion-panel:active:before,:host ::ng-deep .mat-expansion-panel:focus:before{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item,:host ::ng-deep .mat-expansion-panel{font-family:var(--mat-expansion-header-text-font, var(--mat-sys-title-medium-font));font-weight:var(--mat-expansion-header-text-weight, var(--mat-sys-title-medium-weight));line-height:var(--mat-expansion-header-text-line-height, var(--mat-sys-title-medium-line-height));letter-spacing:var(--mat-expansion-header-text-tracking, var(--mat-sys-title-medium-tracking))}:host ::ng-deep .mat-mdc-list-item mat-icon,:host ::ng-deep .mat-expansion-panel mat-icon{margin-right:18px;margin-bottom:3px}:host ::ng-deep .mat-mdc-list-item ::ng-deep .mat-expansion-panel-body,:host ::ng-deep .mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding-bottom:0!important}:host ::ng-deep .mat-mdc-list-item:not(.mobile)>.mat-expansion-panel-header,:host ::ng-deep .mat-expansion-panel:not(.mobile)>.mat-expansion-panel-header{padding:4px 8px}\n"] }]
|
|
25938
|
+
], template: "<mat-nav-list>\r\n <!-- #region main-menu-accordion -->\r\n <mat-accordion displayMode=\"flat\">\r\n @for (item of items; track item; let last = $last) {\r\n <!-- #region mobile-item-with-submenu -->\r\n @if ((item?.items?.length ?? 0) > 0 && mobile) {\r\n <mat-expansion-panel class=\"mat-elevation-z raw\"\r\n (click)=\"$event.stopPropagation();\"\r\n [disabled]=\"!mobile\"\r\n [hideToggle]=\"!mobile || !item?.items?.length\"\r\n [ngClass]=\"{'icon-only': !item.title, 'mobile': mobile}\"\r\n (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\"\r\n (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\"\r\n [routerLinkActive]=\"['active']\"\r\n [routerLinkActiveOptions]=\"{exact:false}\">\r\n <!-- #region mobile-parent-item-header -->\r\n <mat-expansion-panel-header [expandedHeight]=\"'48px'\">\r\n <mat-panel-title>\r\n <!-- #region parent-item-icon-and-title -->\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n [matBadge]=\"item.badge ? item.badge() : null\"\r\n [matBadgeHidden]=\"!item.badge || item.badge() === 0\"\r\n aria-hidden=\"false\">\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\">{{item.title}}</span>\r\n }\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n @if (avatar) {\r\n <h3>{{item.title}}</h3>\r\n }\r\n <!-- #endregion -->\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- #endregion -->\r\n\r\n <!-- #region mobile-submenu-items -->\r\n <mat-nav-list>\r\n @for (subItem of item.items; track subItem; let subLast = $last) {\r\n <!-- #region visible-submenu-link -->\r\n @if (subItem.enabled) {\r\n <a mat-list-item\r\n [style.backgroundColor]=\"subItem.backgroundColor\"\r\n [routerLink]=\"subItem.path\"\r\n target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\"\r\n [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !subItem.title}\"\r\n [routerLinkActiveOptions]=\"{exact:subItem.activeExact??false}\"\r\n [fragment]=\"subItem.fragment\"\r\n (click)=\"itemClicked($event, subItem)\">\r\n <!-- #region submenu-icon-and-text -->\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" [style.color]=\"subItem.iconColor\" aria-hidden=\"false\">\r\n {{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n\r\n @if (!avatar && subItem.title) {\r\n <span [style.color]=\"subItem.textColor\">{{subItem.title}}</span>\r\n }\r\n\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\">{{(subItem.icon | func:subItem) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n\r\n @if (avatar) {\r\n <h3>{{subItem.title}}</h3>\r\n }\r\n\r\n @if (avatar && subItem.description) {\r\n <p>{{subItem.description}}</p>\r\n }\r\n\r\n @if (subItem.badge && subItem.badge() !== 0) {\r\n <span matListItemMeta\r\n [matBadge]=\"subItem.badge()\"\r\n matBadgeOverlap=\"false\"\r\n matBadgePosition=\"above before\"\r\n class=\"menu-badge-align\">\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region submenu-divider-lines -->\r\n @if (subItem.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!subItem.divider && avatar && !subLast) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n <!-- #endregion -->\r\n }\r\n </mat-nav-list>\r\n <!-- #endregion -->\r\n </mat-expansion-panel>\r\n <!-- #endregion -->\r\n\r\n <!-- #region regular-menu-item -->\r\n } @else {\r\n <!-- #region regular-item-link -->\r\n @if (item.enabled) {\r\n <a mat-list-item [style.backgroundColor]=\"item.backgroundColor\" [routerLink]=\"item.path\" target=\"_{{MenuItemTarget[item.target??0].toLowerCase()}}\" [routerLinkActive]=\"['active']\" [ngClass]=\"{'icon-only': !item.title}\" [routerLinkActiveOptions]=\"{exact:item.activeExact??false}\" [fragment]=\"item.fragment\" (click)=\"itemClicked($event, item)\" (delayedHover)=\"(item.items?.length ?? 0) > 0 && itemMouseEnter(item.event ? item.event : $event, item)\" (mouseleave)=\"(item.items?.length ?? 0) >0 && false&& itemMouseLeave(item.event ? item.event : $event, item)\">\r\n @if (!avatar) {\r\n <mat-icon [fontSet]=\"fontSet\"\r\n [style.color]=\"item.iconColor\"\r\n aria-hidden=\"false\"\r\n matListItemIcon>\r\n {{(item.icon | func:item) || 'radio_button_unchecked'}}\r\n </mat-icon>\r\n }\r\n\r\n @if (!avatar && item.title) {\r\n <span [style.color]=\"item.textColor\" matListItemTitle>{{item.title}}</span>\r\n }\r\n\r\n @if (avatar) {\r\n <mat-icon [fontSet]=\"fontSet\" matListAvatar>{{(item.icon | func:item) || 'radio_button_unchecked'}}</mat-icon>\r\n }\r\n\r\n @if (avatar) {\r\n <h3 matLine>{{item.title}}</h3>\r\n }\r\n\r\n @if (avatar && item.description) {\r\n <p matLine>{{item.description}}</p>\r\n }\r\n\r\n @if (item.badge && item.badge() !== 0) {\r\n <span matListItemMeta\r\n [matBadge]=\"item.badge()\"\r\n matBadgeOverlap=\"false\"\r\n matBadgePosition=\"above before\"\r\n class=\"menu-badge-align\">\r\n </span>\r\n }\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region regular-item-divider-lines -->\r\n @if (item.divider && !avatar) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (!item.divider && avatar && !last) {\r\n <mat-divider [inset]=\"avatar\"></mat-divider>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <!-- #endregion -->\r\n }\r\n </mat-accordion>\r\n <!-- #endregion -->\r\n</mat-nav-list>", styles: [":host ::ng-deep .mat-mdc-nav-list .mat-mdc-list-item.icon-only .mdc-list-item__content{display:none!important}:host ::ng-deep .mat-expansion-panel{background-color:transparent}:host ::ng-deep .mat-mdc-list-item:not(.active),:host ::ng-deep .mat-mdc-list-item:active,:host ::ng-deep .mat-mdc-list-item:focus,:host ::ng-deep .mat-expansion-panel:not(.active),:host ::ng-deep .mat-expansion-panel:active,:host ::ng-deep .mat-expansion-panel:focus{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item:not(.active):before,:host ::ng-deep .mat-mdc-list-item:active:before,:host ::ng-deep .mat-mdc-list-item:focus:before,:host ::ng-deep .mat-expansion-panel:not(.active):before,:host ::ng-deep .mat-expansion-panel:active:before,:host ::ng-deep .mat-expansion-panel:focus:before{background-color:transparent!important}:host ::ng-deep .mat-mdc-list-item,:host ::ng-deep .mat-expansion-panel{font-family:var(--mat-expansion-header-text-font, var(--mat-sys-title-medium-font));font-weight:var(--mat-expansion-header-text-weight, var(--mat-sys-title-medium-weight));line-height:var(--mat-expansion-header-text-line-height, var(--mat-sys-title-medium-line-height));letter-spacing:var(--mat-expansion-header-text-tracking, var(--mat-sys-title-medium-tracking))}:host ::ng-deep .mat-mdc-list-item mat-icon,:host ::ng-deep .mat-expansion-panel mat-icon{margin-right:18px;margin-bottom:3px}:host ::ng-deep .mat-mdc-list-item ::ng-deep .mat-expansion-panel-body,:host ::ng-deep .mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding-bottom:0!important}:host ::ng-deep .mat-mdc-list-item:not(.mobile)>.mat-expansion-panel-header,:host ::ng-deep .mat-expansion-panel:not(.mobile)>.mat-expansion-panel-header{padding:4px 8px}:host ::ng-deep .menu-badge-align{padding-top:8px}\n"] }]
|
|
25331
25939
|
}], ctorParameters: () => [{ type: VdMediaService }], propDecorators: { items: [{
|
|
25332
25940
|
type: Input
|
|
25333
25941
|
}], activeExact: [{
|
|
@@ -25815,7 +26423,6 @@ __decorate([
|
|
|
25815
26423
|
};
|
|
25816
26424
|
},
|
|
25817
26425
|
multiple: true,
|
|
25818
|
-
triggerMode: 'chip',
|
|
25819
26426
|
hide: (_, __, ctx) => !ctx.isAdmin || (!ctx.settings?.multitenantable && !ctx.settings?.multiClients),
|
|
25820
26427
|
compareWith: (o, v) => o.clientId === v.clientId,
|
|
25821
26428
|
mapper: (x) => x.map(y => new MenuItemClient({ clientId: y.id, clientName: y.displayName })),
|
|
@@ -25848,7 +26455,6 @@ __decorate([
|
|
|
25848
26455
|
};
|
|
25849
26456
|
},
|
|
25850
26457
|
multiple: true,
|
|
25851
|
-
triggerMode: 'chip',
|
|
25852
26458
|
hide: (_, __, ctx) => (!ctx.isAdmin && !ctx.isClientAdmin) || (!ctx.settings?.multitenantable && !ctx.settings?.multiDepartments),
|
|
25853
26459
|
compareWith: (o, v) => o.departmentId === v.departmentId,
|
|
25854
26460
|
mapper: (x) => x.map(y => new MenuItemDepartment({ departmentId: y.id, departmentName: y.displayName })),
|
|
@@ -28302,5 +28908,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
28302
28908
|
* Generated bundle index. Do not edit.
|
|
28303
28909
|
*/
|
|
28304
28910
|
|
|
28305
|
-
export { AbstractMatFormField, AbstractSelectFormField, ActionItem, Api, ApiResponse, AppEvent, AppEventType, AppSetting, AppStorage, AsyncValidationDirective, AuditEntity, AuditUser, AuthHelper, AuthUser, AutofocusDirective, BaseComponent, BaseDirective, BaseEntity, BaseInterceptor, BaseService, BindPipe, CachingInterceptor, Column, ColumnObject, Common, CommonError, CommonHandlerContext, ConfirmExitGuard, ContextHelper, DIALOG_PROVIDER, DIALOG_PROVIDER_FACTORY, DataSourceFilterDirective, DataSourcePipe, DatePickerHeaderComponent, DisableControlDirective, Display, DisplayNameNumberProjection, DisplayNameProjection, DynamicBuilder, DynamicComponentCompiler, EXPORT_DIALOG_COMPONENT, EmptyStringResetDirective, EnumMetadata, EnumPipe, EnumService, EqualValidator, ErrorMessageBindingStrategy, EventQueueService, Facet, FacetValue, FieldFuncPipe, FileControlDirective, FileService, FileSizePipe, FilterClearComponent, FilterDateComponent, FilterGlue, FilterInputComponent, FilterOperator, FilterPipe, FilterSelectComponent, FirstLetterPipe, Form, FormArrayPipe, FormBuilderConfiguration, FormControlPipe, FormDefinition, FormField, FormFieldDefinition, FormFieldGroup, FormFieldGroupDefinition, FormFieldType, FormGroupPipe, FuncPipe, GenericEmbeddedListComponent, GenericFormBaseComponent, GenericFormComponent, GenericListComponent, GenericReactiveFormComponent, GenericService, GlobalRoles, Grid, GroupFilterPipe, HtmlControlTemplateDirective, IAbstractControl, Icon, ImageFileControlDirective, IpVersion, KeyValue, KeysPipe, LayoutToggle, LoadingScreenInterceptor, LoadingScreenService, MEDIA_PROVIDER, MEDIA_PROVIDER_FACTORY, MatFormFieldEditorDirective, MatFormFieldRadioDirective, MatFormFieldReadonlyDirective, Menu, MenuClient, MenuDepartment, MenuFormIncludesResolve, MenuItem, MenuItemClient, MenuItemDepartment, MenuItemFormIncludesResolve, MenuItemService, MenuItemTarget, MenuListProjectionResolve, MenuResolve, MenuScope, MenuSettings, MenuSettingsResolve, MessageType, ModifiableEntity, MonthNamePipe, NameNumberProjection, NameProjection, NativeElementInjectorDirective, NumericValueType, OnlyNumberDirective, OrderPipe, Pagination, PaginatorIntl, ParseDecimalDirective, Permission, PlaceholderPipe, PrefixDirective, PrintService, PropertyJoinPipe, ReactiveFormConfig, ReactiveTypedFormsModule, RemoveWhitespaceDirective, ResetFormType, RxFormArray, RxFormBuilder, RxFormControl, RxFormControlDirective, RxFormGroup, RxReactiveFormsModule, RxwebFormDirective, RxwebValidators, SafeHtmlPipe, Salutation, SaveAction, SplitPipe, SubMenuResolve, SuffixButton, Table, TableColumn, TableColumnConfig, TableColumnType, TableConfig, TableDataSource, TableDefinition, TableQueryConfig, TableStaticDataSource, TaskDialogData, Templates, TimePipe, TitleCase, TitleProjection, TruncatePipe, TypedForm, TypedFormBuilder, UniqueValidatorDirective, UrlValidationType, Utils, ValidationAlphabetLocale, ValueAccessorBase, ValuesPipe, VdAlertDialogComponent, VdChipsComponent, VdCodeDirective, VdConfirmDialogComponent, VdCustomDirective, VdDelayedHoverDirective, VdDialogActionsDirective, VdDialogComponent, VdDialogContentDirective, VdDialogService, VdDialogTitleDirective, VdDynamicMenuComponent, VdDynamicTableComponent, VdDynamicTableConfigDialogComponent, VdEditorDirective, VdFileDirective, VdFileInputComponent, VdFileModule, VdFilterOptionDirective, VdGenericFormComponent, VdGenericFormCustomFieldDirective, VdLayoutCardOverComponent, VdLayoutCloseDirective, VdLayoutCompactComponent, VdLayoutComponent, VdLayoutFooterComponent, VdLayoutManageListCloseDirective, VdLayoutManageListComponent, VdLayoutManageListOpenDirective, VdLayoutManageListToggleDirective, VdLayoutNavComponent, VdLayoutNavListCloseDirective, VdLayoutNavListComponent, VdLayoutNavListOpenDirective, VdLayoutNavListToggleDirective, VdLayoutOpenDirective, VdLayoutToggleDirective, VdListOptionDirective, VdListToolbarComponent, VdMediaService, VdMediaToggleDirective, VdMenuComponent, VdNavigationDrawerComponent, VdNavigationDrawerMenuDirective, VdNavigationDrawerToolbarDirective, VdPromptDialogComponent, VdSelectComponent, VdSelectOptionDirective, VdSelectTriggerDirective, VdTableFieldDirective, VdTaskDialogComponent, allOf, allOfAsync, alpha, alphaAsync, alphaNumeric, alphaNumericAsync, and, ascii, async, blacklist, choice, choiceAsync, compare, compose, contains, containsAsync, creditCard, creditCardAsync, cusip, custom, customAsync, dataUri, date, dateAsync, different, digit, disable, elementClass, email, endpointMetadataKey, endsWith, endsWithAsync, error, escape, even, extension, extensionAsync, factor, factorAsync, file, fileAsync, fileSize, fileSizeAsync, formDefinitionMetadataKey, formFieldGroupsMetadataKey, formFieldsMetadataKey, getDisplay, getEndpoint, getFormDefinition, getFormGroups, getTableDefinition, greaterThan, greaterThanAsync, greaterThanEqualTo, greaterThanEqualToAsync, grid, headerMetadataKey, hexColor, iban, ibanAsync, image, imageAsync, json, latLong, latitude, leapYear, lessThan, lessThanAsync, lessThanEqualTo, lessThanEqualToAsync, longitude, lowerCase, ltrim, mac, mask, maxDate, maxDateAsync, maxLength, maxLengthAsync, maxNumber, maxNumberAsync, maxTime, maxTimeAsync, minDate, minDateAsync, minLength, minLengthAsync, minNumber, minNumberAsync, minTime, minTimeAsync, mixinDisableRipple, mixinDisabled, model, noneOf, noneOfAsync, not, notEmpty, numeric, numericAsync, odd, oneOf, oneOfAsync, or, password, passwordAsync, pattern, patternAsync, port, prefix, primeNumber, prop, propArray, propObject, range, rangeAsync, required, requiredTrue, rtrim, rule, sanitize, startsWith, startsWithAsync, stripLow, suffix, tableColumnsMetadataKey, tableDefinitionMetadataKey, time, timeAsync, toBoolean, toDate, toDouble, toFloat, toInt, toString, trim, unique, updateOn, upperCase, url, urlAsync, vdCollapseAnimation, whitelist };
|
|
28911
|
+
export { AbstractMatFormField, AbstractSelectFormField, ActionItem, Api, ApiResponse, AppEvent, AppEventType, AppSetting, AppStorage, AsyncValidationDirective, AuditEntity, AuditUser, AuthHelper, AuthUser, AutofocusDirective, BaseComponent, BaseDirective, BaseEntity, BaseInterceptor, BaseService, BindPipe, CachingInterceptor, Column, ColumnObject, Common, CommonError, CommonHandlerContext, ConfirmExitGuard, ContextHelper, DIALOG_PROVIDER, DIALOG_PROVIDER_FACTORY, DataSourceFilterDirective, DataSourcePipe, DatePickerHeaderComponent, DisableControlDirective, Display, DisplayNameNumberProjection, DisplayNameProjection, DynamicBuilder, DynamicComponentCompiler, EXPORT_DIALOG_COMPONENT, EmptyStringResetDirective, EnumMetadata, EnumPipe, EnumService, EqualValidator, ErrorMessageBindingStrategy, EventQueueService, Facet, FacetValue, FieldFuncPipe, FileControlDirective, FileService, FileSizePipe, FilterClearComponent, FilterDateComponent, FilterGlue, FilterInputComponent, FilterOperator, FilterPipe, FilterSelectComponent, FirstLetterPipe, Form, FormArrayPipe, FormBuilderConfiguration, FormControlPipe, FormDefinition, FormField, FormFieldDefinition, FormFieldGroup, FormFieldGroupDefinition, FormFieldType, FormGroupPipe, FuncPipe, GenericEmbeddedListComponent, GenericFormBaseComponent, GenericFormComponent, GenericListComponent, GenericReactiveFormComponent, GenericService, GlobalRoles, Grid, GroupFilterPipe, HtmlControlTemplateDirective, IAbstractControl, Icon, ImageFileControlDirective, IpVersion, KeyValue, KeysPipe, LayoutToggle, LoadingScreenInterceptor, LoadingScreenService, MEDIA_PROVIDER, MEDIA_PROVIDER_FACTORY, MatFormFieldEditorDirective, MatFormFieldRadioDirective, MatFormFieldReadonlyDirective, Menu, MenuClient, MenuDepartment, MenuFormIncludesResolve, MenuItem, MenuItemClient, MenuItemDepartment, MenuItemFormIncludesResolve, MenuItemService, MenuItemTarget, MenuListProjectionResolve, MenuResolve, MenuScope, MenuSettings, MenuSettingsResolve, MessageType, ModifiableEntity, MonthNamePipe, MsaEditFormActionsComponent, MsaEnumDisplayComponent, NameNumberProjection, NameProjection, NativeElementInjectorDirective, NumericValueType, OnlyNumberDirective, OrderPipe, Pagination, PaginatorIntl, ParseDecimalDirective, Permission, PlaceholderPipe, PrefixDirective, PrintService, PropertyJoinPipe, ReactiveFormConfig, ReactiveTypedFormsModule, RemoveWhitespaceDirective, ResetFormType, RxFormArray, RxFormBuilder, RxFormControl, RxFormControlDirective, RxFormGroup, RxReactiveFormsModule, RxwebFormDirective, RxwebValidators, SafeHtmlPipe, Salutation, SaveAction, SplitPipe, SubMenuResolve, SuffixButton, Table, TableColumn, TableColumnConfig, TableColumnType, TableConfig, TableDataSource, TableDefinition, TableQueryConfig, TableStaticDataSource, TaskDialogData, Templates, TimePipe, TitleCase, TitleProjection, TruncatePipe, TypedForm, TypedFormBuilder, UniqueValidatorDirective, UrlValidationType, Utils, ValidationAlphabetLocale, ValueAccessorBase, ValuesPipe, VdAlertDialogComponent, VdChipsComponent, VdCodeDirective, VdConfirmDialogComponent, VdCustomDirective, VdDelayedHoverDirective, VdDialogActionsDirective, VdDialogComponent, VdDialogContentDirective, VdDialogHeaderActionsComponent, VdDialogHeaderComponent, VdDialogMaximizeDirective, VdDialogService, VdDialogTitleDirective, VdDynamicMenuComponent, VdDynamicTableComponent, VdDynamicTableConfigDialogComponent, VdEditorDirective, VdFileDirective, VdFileInputComponent, VdFileModule, VdFilterOptionDirective, VdGenericFormComponent, VdGenericFormCustomFieldDirective, VdLayoutCardOverComponent, VdLayoutCloseDirective, VdLayoutCompactComponent, VdLayoutComponent, VdLayoutFooterComponent, VdLayoutManageListCloseDirective, VdLayoutManageListComponent, VdLayoutManageListOpenDirective, VdLayoutManageListToggleDirective, VdLayoutNavComponent, VdLayoutNavListCloseDirective, VdLayoutNavListComponent, VdLayoutNavListOpenDirective, VdLayoutNavListToggleDirective, VdLayoutOpenDirective, VdLayoutToggleDirective, VdListOptionDirective, VdListToolbarComponent, VdMediaService, VdMediaToggleDirective, VdMenuComponent, VdNavigationDrawerComponent, VdNavigationDrawerMenuDirective, VdNavigationDrawerToolbarDirective, VdPromptDialogComponent, VdSelectComponent, VdSelectOptionDirective, VdSelectTriggerDirective, VdTableFieldDirective, VdTaskDialogComponent, allOf, allOfAsync, alpha, alphaAsync, alphaNumeric, alphaNumericAsync, and, ascii, async, blacklist, choice, choiceAsync, compare, compose, contains, containsAsync, creditCard, creditCardAsync, cusip, custom, customAsync, dataUri, date, dateAsync, different, digit, disable, elementClass, email, endpointMetadataKey, endsWith, endsWithAsync, error, escape, even, extension, extensionAsync, factor, factorAsync, file, fileAsync, fileSize, fileSizeAsync, formDefinitionMetadataKey, formFieldGroupsMetadataKey, formFieldsMetadataKey, getDisplay, getEndpoint, getFormDefinition, getFormGroups, getTableDefinition, graphql, greaterThan, greaterThanAsync, greaterThanEqualTo, greaterThanEqualToAsync, grid, headerMetadataKey, hexColor, iban, ibanAsync, image, imageAsync, json, latLong, latitude, leapYear, lessThan, lessThanAsync, lessThanEqualTo, lessThanEqualToAsync, longitude, lowerCase, ltrim, mac, mask, maxDate, maxDateAsync, maxLength, maxLengthAsync, maxNumber, maxNumberAsync, maxTime, maxTimeAsync, minDate, minDateAsync, minLength, minLengthAsync, minNumber, minNumberAsync, minTime, minTimeAsync, mixinDisableRipple, mixinDisabled, model, noneOf, noneOfAsync, not, notEmpty, numeric, numericAsync, odd, oneOf, oneOfAsync, or, parseProjectionString, password, passwordAsync, pattern, patternAsync, port, prefix, primeNumber, prop, propArray, propObject, range, rangeAsync, required, requiredTrue, rtrim, rule, sanitize, startsWith, startsWithAsync, stripLow, suffix, tableColumnsMetadataKey, tableDefinitionMetadataKey, time, timeAsync, toBoolean, toDate, toDouble, toFloat, toInt, toString, trim, unique, updateOn, upperCase, url, urlAsync, vdCollapseAnimation, whitelist };
|
|
28306
28912
|
//# sourceMappingURL=messaia-cdk.mjs.map
|