@gloww/gloww 20.0.0-beta.40 → 20.0.0-beta.42

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.
@@ -1,25 +1,32 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Injectable, HostListener, Input, Directive, Pipe, Inject, Component, EventEmitter, Output, HostBinding, ViewChild, ContentChildren, Optional, PLATFORM_ID, ContentChild, ViewEncapsulation, makeEnvironmentProviders, NgModule, SecurityContext, forwardRef } from '@angular/core';
3
- import { Subject, firstValueFrom, BehaviorSubject, of, Subscription, combineLatest, forkJoin, throwError } from 'rxjs';
3
+ import { Subject, firstValueFrom, BehaviorSubject, of, combineLatest, forkJoin, throwError } from 'rxjs';
4
4
  import * as i1 from '@angular/common/http';
5
5
  import { HttpClient, HttpParams, HttpEventType, HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi, HttpResponse } from '@angular/common/http';
6
6
  import * as i3 from '@angular/common';
7
- import { Location, PlatformLocation, AsyncPipe, NgClass, isPlatformBrowser, NgStyle, CommonModule } from '@angular/common';
7
+ import { Location, PlatformLocation, AsyncPipe, NgClass, isPlatformBrowser, NgStyle, CommonModule, DatePipe } from '@angular/common';
8
8
  import * as i1$2 from '@angular/material/dialog';
9
9
  import { MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogConfig, MatDialogModule } from '@angular/material/dialog';
10
10
  import { CdkScrollable } from '@angular/cdk/scrolling';
11
11
  import * as i2 from '@angular/router';
12
12
  import { NavigationEnd, RouterLink, RouterModule } from '@angular/router';
13
+ import * as i4$1 from '@angular/material/button';
13
14
  import { MatButton, MatButtonModule } from '@angular/material/button';
14
15
  import * as i1$1 from '@angular/platform-browser';
15
16
  import * as i5 from '@kolkov/angular-editor';
16
17
  import { AngularEditorModule } from '@kolkov/angular-editor';
17
- import { switchMap, map, tap, filter, catchError, take, mergeMap, retryWhen, scan, delay, first, distinctUntilChanged, debounceTime } from 'rxjs/operators';
18
+ import { switchMap, map, tap, filter, catchError, take, mergeMap, retryWhen, scan, delay, first, distinctUntilChanged, debounceTime, finalize } from 'rxjs/operators';
19
+ import * as i9 from '@angular/material/sort';
18
20
  import { MatSort, MatSortModule } from '@angular/material/sort';
21
+ import * as i7 from '@angular/material/paginator';
19
22
  import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
23
+ import * as i10 from '@angular/material/table';
20
24
  import { MatColumnDef, MatTableDataSource, MatTable, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatTableModule } from '@angular/material/table';
25
+ import * as i8 from '@angular/material/progress-spinner';
21
26
  import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner';
27
+ import * as i5$1 from '@angular/material/card';
22
28
  import { MatCard, MatCardContent, MatCardActions, MatCardHeader, MatCardTitle, MatCardModule } from '@angular/material/card';
29
+ import * as i6 from '@angular/material/icon';
23
30
  import { MatIcon, MatIconModule } from '@angular/material/icon';
24
31
  import { MatError, MatFormField, MatInput, MatLabel, MatInputModule, MatSuffix } from '@angular/material/input';
25
32
  import * as i4 from '@ctrl/ngx-codemirror';
@@ -1021,6 +1028,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
1021
1028
 
1022
1029
  ;
1023
1030
  class DisplayObjectsComponent {
1031
+ static { this.DISPLAY_PARAM = '__display'; }
1032
+ static { this.DISPLAY_FORM = 'form'; }
1033
+ static { this.DISPLAY_RESULT = 'result'; }
1034
+ static { this.INTERNAL_QUERY_KEYS = new Set(['__guid', DisplayObjectsComponent.DISPLAY_PARAM]); }
1024
1035
  constructor(glowwService, changeDetectorRef, dialog, router, location, authenticationService, formBuilder, route, i18n) {
1025
1036
  this.changeDetectorRef = changeDetectorRef;
1026
1037
  this.dialog = dialog;
@@ -1041,7 +1052,7 @@ class DisplayObjectsComponent {
1041
1052
  this.displayform = true;
1042
1053
  this.displayresult = false;
1043
1054
  this.queryParams = {};
1044
- this.navSubscription = new Subscription();
1055
+ this.viewInitialized = false;
1045
1056
  this.currentFilter = null;
1046
1057
  this.glowwService = glowwService;
1047
1058
  const component = this;
@@ -1054,8 +1065,15 @@ class DisplayObjectsComponent {
1054
1065
  this.routeParams = this.route.snapshot.params;
1055
1066
  route.params.subscribe(routeParams => {
1056
1067
  this.routeParams = routeParams;
1057
- if (this.displayresult)
1058
- this.Search();
1068
+ if (this.viewInitialized) {
1069
+ this.applyRouteState(this.route.snapshot.queryParams);
1070
+ }
1071
+ });
1072
+ route.queryParams.subscribe(queryParams => {
1073
+ this.queryParams = { ...queryParams };
1074
+ if (this.viewInitialized) {
1075
+ this.applyRouteState(queryParams);
1076
+ }
1059
1077
  });
1060
1078
  }
1061
1079
  ngOnChanges(changes) {
@@ -1128,55 +1146,19 @@ class DisplayObjectsComponent {
1128
1146
  }
1129
1147
  //debugger;
1130
1148
  console.log(`INIT : formLayout:${this.searchFormLayout}-displayform:${this.displayform}`);
1131
- if (!this.searchFormLayout && this.resultLayout) {
1132
- this.displayform = false;
1133
- this.displayresult = true;
1134
- }
1135
- if (Object.keys(this.data).length > 0 && (this.data["__mode"] !== "edit")) {
1136
- this.displayform = false;
1137
- this.displayresult = true;
1138
- }
1139
- if (Object.keys(this.route.snapshot.params).length > 0 && (this.data["__mode"] !== "edit")) {
1140
- this.displayform = false;
1141
- this.displayresult = true;
1142
- }
1143
1149
  this.glowwService.basePathChange.subscribe(newUrl => {
1144
1150
  console.log(`basePathChange ${newUrl}: fromLayout:${this.searchFormLayout}-displayform:${this.displayform}`);
1145
1151
  this.parent.form?.reset();
1146
- if (!this.searchFormLayout && this.resultLayout) {
1147
- this.displayform = false;
1148
- this.displayresult = true;
1149
- }
1150
- if (this.displayresult) {
1151
- this.Search();
1152
- }
1152
+ this.applyRouteState(this.route.snapshot.queryParams);
1153
1153
  });
1154
- if (this.displayresult) {
1155
- this.Search();
1156
- }
1154
+ this.viewInitialized = true;
1155
+ this.applyRouteState(this.route.snapshot.queryParams);
1157
1156
  }
1158
1157
  ngAfterContentInit() {
1159
1158
  }
1160
1159
  ngOnInit() {
1161
- this.navSubscription = this.router.events.subscribe((e) => {
1162
- if (e instanceof NavigationEnd) {
1163
- this.parent.form?.reset();
1164
- this.displayform = true;
1165
- this.displayresult = false;
1166
- this.changeDetectorRef.detectChanges();
1167
- this.dataSource = null;
1168
- if (!this.searchFormLayout && this.resultLayout) {
1169
- this.displayform = false;
1170
- this.displayresult = true;
1171
- }
1172
- if (this.displayresult) {
1173
- this.Search();
1174
- }
1175
- }
1176
- });
1177
1160
  }
1178
1161
  ngOnDestroy() {
1179
- this.navSubscription?.unsubscribe(); // this prevents a memory leak
1180
1162
  }
1181
1163
  t(key, fallback) {
1182
1164
  return this.i18n.instant(key, fallback);
@@ -1186,6 +1168,27 @@ class DisplayObjectsComponent {
1186
1168
  this.Search(data);
1187
1169
  }
1188
1170
  }
1171
+ hasSearchState() {
1172
+ return this.displayresult || this.hasSearchQueryParams(this.route.snapshot.queryParams);
1173
+ }
1174
+ onBack() {
1175
+ const searchQuery = this.buildSearchQueryParams();
1176
+ if (!Object.keys(searchQuery).length) {
1177
+ this.showForm();
1178
+ this.syncFormWithQueryParams({});
1179
+ return;
1180
+ }
1181
+ this.router.navigate([], {
1182
+ relativeTo: this.route,
1183
+ queryParams: {
1184
+ ...searchQuery,
1185
+ [DisplayObjectsComponent.DISPLAY_PARAM]: DisplayObjectsComponent.DISPLAY_FORM
1186
+ }
1187
+ });
1188
+ }
1189
+ onRefresh() {
1190
+ this.Search();
1191
+ }
1189
1192
  SetFilterPredicate() {
1190
1193
  this.dataSource.filterPredicate = function (record, filterString) {
1191
1194
  console.log(filterString);
@@ -1239,9 +1242,9 @@ class DisplayObjectsComponent {
1239
1242
  console.log(`Search ${this.glowwService.InternalBasePath}`);
1240
1243
  if (data)
1241
1244
  this.data = data;
1242
- this.displayresult = true;
1243
- this.displayform = false;
1245
+ this.showResult();
1244
1246
  this.resultException = null;
1247
+ this.queryParams = {};
1245
1248
  if (this.data) {
1246
1249
  Object.keys(this.data).forEach(name => {
1247
1250
  this.queryParams[name] = this.data[name];
@@ -1252,9 +1255,15 @@ class DisplayObjectsComponent {
1252
1255
  this.queryParams[name] = this.routeParams[name];
1253
1256
  });
1254
1257
  }
1258
+ const routeQueryParams = this.route.snapshot.queryParams ?? {};
1259
+ Object.keys(routeQueryParams).forEach(name => {
1260
+ if (!DisplayObjectsComponent.INTERNAL_QUERY_KEYS.has(name)) {
1261
+ this.queryParams[name] = routeQueryParams[name];
1262
+ }
1263
+ });
1255
1264
  if (this.mandatoryParams) {
1256
1265
  Object.keys(this.mandatoryParams).forEach(name => {
1257
- this.queryParams[name] = this.queryParams[name];
1266
+ this.queryParams[name] = this.mandatoryParams[name];
1258
1267
  });
1259
1268
  }
1260
1269
  Object.keys(this.queryParams).forEach(name => {
@@ -1276,8 +1285,7 @@ class DisplayObjectsComponent {
1276
1285
  this.changeDetectorRef.detectChanges();
1277
1286
  this.UpdateTable();
1278
1287
  }, error => {
1279
- this.displayresult = false;
1280
- this.displayform = true;
1288
+ this.showForm();
1281
1289
  this.resultException = this.toErrorMessage(error);
1282
1290
  });
1283
1291
  }
@@ -1289,21 +1297,13 @@ class DisplayObjectsComponent {
1289
1297
  }
1290
1298
  }
1291
1299
  onSearch() {
1292
- this.queryParams = {};
1293
- const searchData = this.parent.form.value.searchData;
1294
- if (searchData) {
1295
- Object.keys(searchData).forEach(name => {
1296
- this.queryParams[name] = this.serializeQueryParamValue(searchData[name]);
1297
- });
1298
- }
1299
- if (this.form2.value._MaxRow_) {
1300
- this.queryParams._MaxRow_ = this.form2.value._MaxRow_;
1301
- }
1302
- this.clean(this.queryParams);
1303
- const params = new HttpParams({ fromObject: this.queryParams });
1304
- const currentstate = this.location.getState();
1305
- this.location.replaceState(this.router.url, params.toString());
1306
- this.Search();
1300
+ this.router.navigate([], {
1301
+ relativeTo: this.route,
1302
+ queryParams: {
1303
+ ...this.buildSearchQueryParams(),
1304
+ [DisplayObjectsComponent.DISPLAY_PARAM]: DisplayObjectsComponent.DISPLAY_RESULT
1305
+ }
1306
+ });
1307
1307
  }
1308
1308
  serializeQueryParamValue(value) {
1309
1309
  if (value === undefined || value === null || value === '') {
@@ -1622,12 +1622,102 @@ class DisplayObjectsComponent {
1622
1622
  const details = error.error?.message || error.error || error.message || error.statusText || `${error}`;
1623
1623
  return `${this.t('GLOWW.UNABLE_TO_QUERY', 'Unable to query')} : ${details}`;
1624
1624
  }
1625
+ applyRouteState(queryParams) {
1626
+ this.dataSource = null;
1627
+ this.resultException = null;
1628
+ this.queryParams = { ...(queryParams ?? {}) };
1629
+ this.syncFormWithQueryParams(this.queryParams);
1630
+ if (this.shouldDisplayForm(this.queryParams)) {
1631
+ this.showForm();
1632
+ this.changeDetectorRef.detectChanges();
1633
+ return;
1634
+ }
1635
+ if (this.shouldDisplayResult(this.queryParams)) {
1636
+ this.showResult();
1637
+ this.changeDetectorRef.detectChanges();
1638
+ this.Search();
1639
+ return;
1640
+ }
1641
+ this.showForm();
1642
+ this.changeDetectorRef.detectChanges();
1643
+ }
1644
+ shouldDisplayForm(queryParams) {
1645
+ if (!this.searchFormLayout) {
1646
+ return false;
1647
+ }
1648
+ return queryParams?.[DisplayObjectsComponent.DISPLAY_PARAM] === DisplayObjectsComponent.DISPLAY_FORM;
1649
+ }
1650
+ shouldDisplayResult(queryParams) {
1651
+ if (!this.searchFormLayout && this.resultLayout) {
1652
+ return true;
1653
+ }
1654
+ if (Object.keys(this.data ?? {}).length > 0 && (this.data["__mode"] !== "edit")) {
1655
+ return true;
1656
+ }
1657
+ if (Object.keys(this.routeParams ?? {}).length > 0 && (this.data["__mode"] !== "edit")) {
1658
+ return true;
1659
+ }
1660
+ return queryParams?.[DisplayObjectsComponent.DISPLAY_PARAM] === DisplayObjectsComponent.DISPLAY_RESULT
1661
+ || this.hasSearchQueryParams(queryParams);
1662
+ }
1663
+ hasSearchQueryParams(queryParams) {
1664
+ if (!queryParams) {
1665
+ return false;
1666
+ }
1667
+ return Object.keys(queryParams).some(key => !DisplayObjectsComponent.INTERNAL_QUERY_KEYS.has(key) &&
1668
+ queryParams[key] !== null &&
1669
+ queryParams[key] !== undefined &&
1670
+ queryParams[key] !== '');
1671
+ }
1672
+ syncFormWithQueryParams(queryParams) {
1673
+ const searchData = {};
1674
+ Object.keys(queryParams ?? {}).forEach(key => {
1675
+ if (DisplayObjectsComponent.INTERNAL_QUERY_KEYS.has(key) || key === '_MaxRow_') {
1676
+ return;
1677
+ }
1678
+ searchData[key] = queryParams[key];
1679
+ });
1680
+ const parentForm = this.parent?.form;
1681
+ if (parentForm?.contains('searchData')) {
1682
+ parentForm.patchValue({
1683
+ searchData: Object.keys(searchData).length ? searchData : null
1684
+ }, { emitEvent: false });
1685
+ }
1686
+ if (this.form2?.contains('_MaxRow_')) {
1687
+ this.form2.patchValue({
1688
+ _MaxRow_: queryParams?._MaxRow_ ?? null
1689
+ }, { emitEvent: false });
1690
+ }
1691
+ }
1692
+ buildSearchQueryParams() {
1693
+ const nextQueryParams = {};
1694
+ const searchData = this.parent?.form?.value?.searchData;
1695
+ const form2Value = this.form2.value;
1696
+ if (searchData) {
1697
+ Object.keys(searchData).forEach(name => {
1698
+ nextQueryParams[name] = this.serializeQueryParamValue(searchData[name]);
1699
+ });
1700
+ }
1701
+ if (form2Value._MaxRow_) {
1702
+ nextQueryParams._MaxRow_ = form2Value._MaxRow_;
1703
+ }
1704
+ this.clean(nextQueryParams);
1705
+ return nextQueryParams;
1706
+ }
1707
+ showForm() {
1708
+ this.displayform = true;
1709
+ this.displayresult = false;
1710
+ }
1711
+ showResult() {
1712
+ this.displayform = false;
1713
+ this.displayresult = true;
1714
+ }
1625
1715
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DisplayObjectsComponent, deps: [{ token: 'glowwService' }, { token: i0.ChangeDetectorRef }, { token: i1$2.MatDialog }, { token: i2.Router }, { token: i3.Location }, { token: AuthenticationService }, { token: i1$3.UntypedFormBuilder }, { token: i2.ActivatedRoute }, { token: GlowwI18nService }], target: i0.ɵɵFactoryTarget.Component }); }
1626
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DisplayObjectsComponent, isStandalone: true, selector: "glw-display-objects", inputs: { configuration: "configuration", displayObjLink: "displayObjLink", canDisplayObj: "canDisplayObj", canEdit: "canEdit", canDelete: "canDelete", canAdd: "canAdd", form: "form", SearchForm: "SearchForm", searchRequest: "searchRequest", postRequest: "postRequest", deleteRequest: "deleteRequest", putRequest: "putRequest", maxrows: "maxrows", mandatoryParams: "mandatoryParams", actions: "actions", dialogConfig: "dialogConfig", parent: "parent", columns: "columns", objectName: "objectName", primaryKey: "primaryKey", Editor: "Editor", AddEditor: "AddEditor" }, queries: [{ propertyName: "header", first: true, predicate: HeaderComponent, descendants: true }, { propertyName: "searchFormLayout", first: true, predicate: SearchFormComponent, descendants: true }, { propertyName: "filterFormLayout", first: true, predicate: FilterFormComponent, descendants: true }, { propertyName: "resultLayout", first: true, predicate: ResultTableComponent, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div>\n <ng-content select=\"glw-header\"></ng-content>\n</div>\n\n@if (displayform) {\n <div>\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n @if (resultException) {\n <mat-error>\n {{ resultException }}\n </mat-error>\n }\n <ng-content select=\"glw-search-form\"></ng-content>\n <!--<ng-container *ngComponentOutlet=\"SearchForm; injector: objInjector\"></ng-container>-->\n @if (maxrows) {\n <div [formGroup]=\"form2\">\n <br />\n <mat-form-field>\n <mat-select [placeholder]=\"t('COMMON.MAX_ROW', 'MaxRow')\" formControlName=\"_MaxRow_\">\n @for (maxrow of maxrows; track maxrow) {\n <mat-option [value]=\"maxrow\">\n @if (maxrow) {\n <span>{{maxrow}} {{ t('COMMON.OBJECTS_SUFFIX', 'objects') }}</span>\n }\n @if (!maxrow) {\n <span>{{ t('COMMON.DEFAULT', 'Default') }}</span>\n }\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n </mat-card-content>\n <mat-card-actions>\n <button mat-stroked-button color=\"accent\" (click)=\"onSearch()\">\n <mat-icon>search</mat-icon>\n {{ t('COMMON.SEARCH', 'Search') }}\n </button>\n </mat-card-actions>\n </mat-card>\n </div>\n}\n\n<div [hidden]=\"!displayresult\">\n <!--*ngIf=\"displayresult\"-->\n <div class=\"mat-elevation-z8\" [hidden]=\"!dataSource\">\n <ng-content select=\"[filter]\"></ng-content>\n\n <!--*ngIf=\"dataSource; else Spinner\"-->\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef>\n @if (canAddThis()) {\n <i class=\"fal fa-plus\" (click)=\"AddObj()\">\n </i>\n }\n </th>\n <td mat-cell *matCellDef=\"let obj\">\n @if (canDisplayObjThis(obj)) {\n <i class=\"fal fa-eye\" [routerLink]=\"displayObjLinkThis(obj)\">\n </i>\n }\n @for (action of actions; track action) {\n @if (action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\">\n </i>\n }\n @if (!action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\"></i>\n }\n }\n @if (canDeleteThis(obj)) {\n <i class=\"fal fa-trash-alt\" (click)=\"DeleteObj(obj)\">\n </i>\n }\n @if (canEditThis(obj)) {\n <i class=\"fal fa-pencil\" (click)=\"EditObj(obj)\">\n </i>\n }\n </td>\n </ng-container>\n <ng-content select=\"glw-result-table\"></ng-content>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </div>\n <div #Spinner [hidden]=\"dataSource\">\n <mat-spinner></mat-spinner>\n </div>\n</div>\n", styles: ["table{width:100%}i{cursor:pointer;padding:5px}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: 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: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: 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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatDialogModule }] }); }
1716
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DisplayObjectsComponent, isStandalone: true, selector: "glw-display-objects", inputs: { configuration: "configuration", displayObjLink: "displayObjLink", canDisplayObj: "canDisplayObj", canEdit: "canEdit", canDelete: "canDelete", canAdd: "canAdd", form: "form", SearchForm: "SearchForm", searchRequest: "searchRequest", postRequest: "postRequest", deleteRequest: "deleteRequest", putRequest: "putRequest", maxrows: "maxrows", mandatoryParams: "mandatoryParams", actions: "actions", dialogConfig: "dialogConfig", parent: "parent", columns: "columns", objectName: "objectName", primaryKey: "primaryKey", Editor: "Editor", AddEditor: "AddEditor" }, queries: [{ propertyName: "header", first: true, predicate: HeaderComponent, descendants: true }, { propertyName: "searchFormLayout", first: true, predicate: SearchFormComponent, descendants: true }, { propertyName: "filterFormLayout", first: true, predicate: FilterFormComponent, descendants: true }, { propertyName: "resultLayout", first: true, predicate: ResultTableComponent, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div>\n <ng-content select=\"glw-header\"></ng-content>\n</div>\n\n@if (displayform) {\n <div>\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n @if (resultException) {\n <mat-error>\n {{ resultException }}\n </mat-error>\n }\n <ng-content select=\"glw-search-form\"></ng-content>\n <!--<ng-container *ngComponentOutlet=\"SearchForm; injector: objInjector\"></ng-container>-->\n @if (maxrows) {\n <div [formGroup]=\"form2\">\n <br />\n <mat-form-field>\n <mat-select [placeholder]=\"t('COMMON.MAX_ROW', 'MaxRow')\" formControlName=\"_MaxRow_\">\n @for (maxrow of maxrows; track maxrow) {\n <mat-option [value]=\"maxrow\">\n @if (maxrow) {\n <span>{{maxrow}} {{ t('COMMON.OBJECTS_SUFFIX', 'objects') }}</span>\n }\n @if (!maxrow) {\n <span>{{ t('COMMON.DEFAULT', 'Default') }}</span>\n }\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n </mat-card-content>\n <mat-card-actions>\n <button mat-stroked-button color=\"accent\" (click)=\"onSearch()\">\n <mat-icon>search</mat-icon>\n {{ t('COMMON.SEARCH', 'Search') }}\n </button>\n </mat-card-actions>\n </mat-card>\n </div>\n}\n\n<div [hidden]=\"!displayresult\">\n <!--*ngIf=\"displayresult\"-->\n <div class=\"mat-elevation-z8\" [hidden]=\"!dataSource\">\n <ng-content select=\"[filter]\"></ng-content>\n\n <!--*ngIf=\"dataSource; else Spinner\"-->\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef>\n @if (hasSearchState()) {\n <i class=\"fal fa-arrow-left\" (click)=\"onBack()\" [attr.title]=\"t('COMMON.BACK', 'Back')\">\n </i>\n <i class=\"fal fa-rotate-right\" (click)=\"onRefresh()\" [attr.title]=\"t('COMMON.REFRESH', 'Refresh')\">\n </i>\n }\n @if (canAddThis()) {\n <i class=\"fal fa-plus\" (click)=\"AddObj()\">\n </i>\n }\n </th>\n <td mat-cell *matCellDef=\"let obj\">\n @if (canDisplayObjThis(obj)) {\n <i class=\"fal fa-eye\" [routerLink]=\"displayObjLinkThis(obj)\">\n </i>\n }\n @for (action of actions; track action) {\n @if (action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\">\n </i>\n }\n @if (!action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\"></i>\n }\n }\n @if (canDeleteThis(obj)) {\n <i class=\"fal fa-trash-alt\" (click)=\"DeleteObj(obj)\">\n </i>\n }\n @if (canEditThis(obj)) {\n <i class=\"fal fa-pencil\" (click)=\"EditObj(obj)\">\n </i>\n }\n </td>\n </ng-container>\n <ng-content select=\"glw-result-table\"></ng-content>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </div>\n <div #Spinner [hidden]=\"dataSource\">\n <mat-spinner></mat-spinner>\n </div>\n</div>\n", styles: ["table{width:100%}i{cursor:pointer;padding:5px}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: 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: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: 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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatDialogModule }] }); }
1627
1717
  }
1628
1718
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DisplayObjectsComponent, decorators: [{
1629
1719
  type: Component,
1630
- args: [{ selector: 'glw-display-objects', imports: [MatCard, MatCardContent, MatError, FormsModule, ReactiveFormsModule, MatFormField, MatSelect, MatOption, MatCardActions, MatButton, MatIcon, MatTable, MatSort, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, RouterLink, NgClass, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatPaginator, MatProgressSpinner, MatDialogModule], template: "<div>\n <ng-content select=\"glw-header\"></ng-content>\n</div>\n\n@if (displayform) {\n <div>\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n @if (resultException) {\n <mat-error>\n {{ resultException }}\n </mat-error>\n }\n <ng-content select=\"glw-search-form\"></ng-content>\n <!--<ng-container *ngComponentOutlet=\"SearchForm; injector: objInjector\"></ng-container>-->\n @if (maxrows) {\n <div [formGroup]=\"form2\">\n <br />\n <mat-form-field>\n <mat-select [placeholder]=\"t('COMMON.MAX_ROW', 'MaxRow')\" formControlName=\"_MaxRow_\">\n @for (maxrow of maxrows; track maxrow) {\n <mat-option [value]=\"maxrow\">\n @if (maxrow) {\n <span>{{maxrow}} {{ t('COMMON.OBJECTS_SUFFIX', 'objects') }}</span>\n }\n @if (!maxrow) {\n <span>{{ t('COMMON.DEFAULT', 'Default') }}</span>\n }\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n </mat-card-content>\n <mat-card-actions>\n <button mat-stroked-button color=\"accent\" (click)=\"onSearch()\">\n <mat-icon>search</mat-icon>\n {{ t('COMMON.SEARCH', 'Search') }}\n </button>\n </mat-card-actions>\n </mat-card>\n </div>\n}\n\n<div [hidden]=\"!displayresult\">\n <!--*ngIf=\"displayresult\"-->\n <div class=\"mat-elevation-z8\" [hidden]=\"!dataSource\">\n <ng-content select=\"[filter]\"></ng-content>\n\n <!--*ngIf=\"dataSource; else Spinner\"-->\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef>\n @if (canAddThis()) {\n <i class=\"fal fa-plus\" (click)=\"AddObj()\">\n </i>\n }\n </th>\n <td mat-cell *matCellDef=\"let obj\">\n @if (canDisplayObjThis(obj)) {\n <i class=\"fal fa-eye\" [routerLink]=\"displayObjLinkThis(obj)\">\n </i>\n }\n @for (action of actions; track action) {\n @if (action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\">\n </i>\n }\n @if (!action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\"></i>\n }\n }\n @if (canDeleteThis(obj)) {\n <i class=\"fal fa-trash-alt\" (click)=\"DeleteObj(obj)\">\n </i>\n }\n @if (canEditThis(obj)) {\n <i class=\"fal fa-pencil\" (click)=\"EditObj(obj)\">\n </i>\n }\n </td>\n </ng-container>\n <ng-content select=\"glw-result-table\"></ng-content>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </div>\n <div #Spinner [hidden]=\"dataSource\">\n <mat-spinner></mat-spinner>\n </div>\n</div>\n", styles: ["table{width:100%}i{cursor:pointer;padding:5px}\n"] }]
1720
+ args: [{ selector: 'glw-display-objects', imports: [MatCard, MatCardContent, MatError, FormsModule, ReactiveFormsModule, MatFormField, MatSelect, MatOption, MatCardActions, MatButton, MatIcon, MatTable, MatSort, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, RouterLink, NgClass, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatPaginator, MatProgressSpinner, MatDialogModule], template: "<div>\n <ng-content select=\"glw-header\"></ng-content>\n</div>\n\n@if (displayform) {\n <div>\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n @if (resultException) {\n <mat-error>\n {{ resultException }}\n </mat-error>\n }\n <ng-content select=\"glw-search-form\"></ng-content>\n <!--<ng-container *ngComponentOutlet=\"SearchForm; injector: objInjector\"></ng-container>-->\n @if (maxrows) {\n <div [formGroup]=\"form2\">\n <br />\n <mat-form-field>\n <mat-select [placeholder]=\"t('COMMON.MAX_ROW', 'MaxRow')\" formControlName=\"_MaxRow_\">\n @for (maxrow of maxrows; track maxrow) {\n <mat-option [value]=\"maxrow\">\n @if (maxrow) {\n <span>{{maxrow}} {{ t('COMMON.OBJECTS_SUFFIX', 'objects') }}</span>\n }\n @if (!maxrow) {\n <span>{{ t('COMMON.DEFAULT', 'Default') }}</span>\n }\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n </mat-card-content>\n <mat-card-actions>\n <button mat-stroked-button color=\"accent\" (click)=\"onSearch()\">\n <mat-icon>search</mat-icon>\n {{ t('COMMON.SEARCH', 'Search') }}\n </button>\n </mat-card-actions>\n </mat-card>\n </div>\n}\n\n<div [hidden]=\"!displayresult\">\n <!--*ngIf=\"displayresult\"-->\n <div class=\"mat-elevation-z8\" [hidden]=\"!dataSource\">\n <ng-content select=\"[filter]\"></ng-content>\n\n <!--*ngIf=\"dataSource; else Spinner\"-->\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef>\n @if (hasSearchState()) {\n <i class=\"fal fa-arrow-left\" (click)=\"onBack()\" [attr.title]=\"t('COMMON.BACK', 'Back')\">\n </i>\n <i class=\"fal fa-rotate-right\" (click)=\"onRefresh()\" [attr.title]=\"t('COMMON.REFRESH', 'Refresh')\">\n </i>\n }\n @if (canAddThis()) {\n <i class=\"fal fa-plus\" (click)=\"AddObj()\">\n </i>\n }\n </th>\n <td mat-cell *matCellDef=\"let obj\">\n @if (canDisplayObjThis(obj)) {\n <i class=\"fal fa-eye\" [routerLink]=\"displayObjLinkThis(obj)\">\n </i>\n }\n @for (action of actions; track action) {\n @if (action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\">\n </i>\n }\n @if (!action.icon.icon && (!action.display || action.display(obj, action.name))) {\n <i [ngClass]=\"action.icon\" [routerLink]=\"action.routerLinkFct(obj)\"></i>\n }\n }\n @if (canDeleteThis(obj)) {\n <i class=\"fal fa-trash-alt\" (click)=\"DeleteObj(obj)\">\n </i>\n }\n @if (canEditThis(obj)) {\n <i class=\"fal fa-pencil\" (click)=\"EditObj(obj)\">\n </i>\n }\n </td>\n </ng-container>\n <ng-content select=\"glw-result-table\"></ng-content>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </div>\n <div #Spinner [hidden]=\"dataSource\">\n <mat-spinner></mat-spinner>\n </div>\n</div>\n", styles: ["table{width:100%}i{cursor:pointer;padding:5px}\n"] }]
1631
1721
  }], ctorParameters: () => [{ type: GlowwService, decorators: [{
1632
1722
  type: Inject,
1633
1723
  args: ['glowwService']
@@ -3489,6 +3579,7 @@ class AutoCompleteComponent {
3489
3579
  this.onTouched = () => { };
3490
3580
  this.items = [];
3491
3581
  this.parser = new TranslateDefaultParser();
3582
+ this.pendingExternalValue = undefined;
3492
3583
  this.options = []; //Observable<unknown>;
3493
3584
  this.propagateChange = (_) => { };
3494
3585
  this.glowwService = glowwService;
@@ -3522,9 +3613,21 @@ class AutoCompleteComponent {
3522
3613
  },
3523
3614
  error: (error) => { this.error = error; }
3524
3615
  });
3616
+ if (this.pendingExternalValue !== undefined) {
3617
+ this.applyExternalValue(this.pendingExternalValue);
3618
+ this.pendingExternalValue = undefined;
3619
+ }
3525
3620
  }
3526
3621
  writeValue(val) {
3527
- val && this.form.setValue({ __result: val }, { emitEvent: false });
3622
+ if (val === undefined || val === null || val === '') {
3623
+ this.form.setValue({ __result: null }, { emitEvent: false });
3624
+ return;
3625
+ }
3626
+ if (!this.searchRequest) {
3627
+ this.pendingExternalValue = val;
3628
+ return;
3629
+ }
3630
+ this.applyExternalValue(val);
3528
3631
  }
3529
3632
  registerOnChange(fn) {
3530
3633
  this.onChange = fn;
@@ -3547,6 +3650,9 @@ class AutoCompleteComponent {
3547
3650
  displayObj(item) {
3548
3651
  if (!item)
3549
3652
  return null;
3653
+ if (typeof item !== 'object') {
3654
+ return item;
3655
+ }
3550
3656
  console.log("displayOf");
3551
3657
  if (this.displayField) {
3552
3658
  return item[this.displayField];
@@ -3559,6 +3665,30 @@ class AutoCompleteComponent {
3559
3665
  return this.displayFct(item);
3560
3666
  }
3561
3667
  }
3668
+ applyExternalValue(val) {
3669
+ if (typeof val === 'object') {
3670
+ this.form.setValue({ __result: val }, { emitEvent: false });
3671
+ this.ref.markForCheck();
3672
+ return;
3673
+ }
3674
+ if (!this.returnField || !this.searchRequest) {
3675
+ this.form.setValue({ __result: val }, { emitEvent: false });
3676
+ this.ref.markForCheck();
3677
+ return;
3678
+ }
3679
+ const searchObj = {};
3680
+ if (this.data) {
3681
+ Object.keys(this.data).forEach(k => {
3682
+ searchObj[k] = this.data[k];
3683
+ });
3684
+ }
3685
+ searchObj[this.returnField] = val;
3686
+ this.searchRequest.call(this.glowwService, searchObj).pipe(catchError(() => of([]))).subscribe((results) => {
3687
+ const match = results.find(item => item?.[this.returnField] == val) ?? results[0] ?? val;
3688
+ this.form.setValue({ __result: match }, { emitEvent: false });
3689
+ this.ref.markForCheck();
3690
+ });
3691
+ }
3562
3692
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AutoCompleteComponent, deps: [{ token: 'glowwService' }, { token: i1$3.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3563
3693
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AutoCompleteComponent, isStandalone: true, selector: "gloww-auto-complete", inputs: { _value: ["value", "_value"], objectName: "objectName", searchField: "searchField", returnField: "returnField", displayField: "displayField", displayExpr: "displayExpr", displayFct: "displayFct", placeHolder: "placeHolder", data: "data", searchRequest: "searchRequest" }, providers: [
3564
3694
  {
@@ -3627,13 +3757,13 @@ class DatetimeComponent {
3627
3757
  'YYYY-MM-DDTHH:mm'
3628
3758
  ]; }
3629
3759
  static { this.CLOCK_CENTER = 50; }
3630
- static { this.CLOCK_OUTER_RADIUS = 40; }
3631
- static { this.CLOCK_INNER_RADIUS = 27; }
3760
+ static { this.CLOCK_OUTER_RADIUS = 36; }
3761
+ static { this.CLOCK_INNER_RADIUS = 25; }
3632
3762
  static { this.CLOCK_TICK_OUTER_RADIUS = 48; }
3633
3763
  static { this.CLOCK_TICK_INNER_RADIUS = 41; }
3634
3764
  static { this.CLOCK_TICK_LABEL_RADIUS = 34; }
3635
- static { this.CLOCK_OUTER_HAND_HEIGHT = '40%'; }
3636
- static { this.CLOCK_INNER_HAND_HEIGHT = '27%'; }
3765
+ static { this.CLOCK_OUTER_HAND_HEIGHT = '34%'; }
3766
+ static { this.CLOCK_INNER_HAND_HEIGHT = '23%'; }
3637
3767
  static { this.CLOCK_MINUTE_HAND_HEIGHT = '48%'; }
3638
3768
  constructor(locale) {
3639
3769
  this.locale = locale;
@@ -3841,6 +3971,10 @@ class DatetimeComponent {
3841
3971
  get minuteHandHeight() {
3842
3972
  return DatetimeComponent.CLOCK_MINUTE_HAND_HEIGHT;
3843
3973
  }
3974
+ get selectedHourMarker() {
3975
+ const hour = this.toNumber(this.hourControl.value);
3976
+ return this.buildClockMarker(hour, hour < 12 ? DatetimeComponent.CLOCK_OUTER_RADIUS : DatetimeComponent.CLOCK_INNER_RADIUS, hour.toString().padStart(2, '0'));
3977
+ }
3844
3978
  setValueFromOutside(value, emit) {
3845
3979
  const normalized = this.normalizeDateValue(value);
3846
3980
  this._value = normalized;
@@ -3959,7 +4093,7 @@ class DatetimeComponent {
3959
4093
  multi: true,
3960
4094
  useExisting: forwardRef(() => DatetimeComponent)
3961
4095
  }
3962
- ], ngImport: i0, template: "<div class=\"datetime-wrapper\" [class.datetime-mode]=\"isDateTime\" [class.has-seconds]=\"showSeconds\">\n <mat-form-field class=\"date-field\">\n @if (display) {\n <mat-label>{{ display }}</mat-label>\n }\n <input\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeHolder\"\n [formControl]=\"dateControl\"\n [disabled]=\"isDisabled\"\n (dateChange)=\"markTouched()\"\n (blur)=\"markTouched()\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n @if (isDateTime) {\n <div class=\"middle-actions\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Clear date and time\"\n aria-label=\"Clear date and time\"\n (click)=\"clear()\">\n <i class=\"fal fa-eraser\"></i>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Open time clock\"\n aria-label=\"Open time clock\"\n (click)=\"openClock()\">\n <i class=\"fal fa-clock\"></i>\n </button>\n </div>\n\n <div class=\"time-row\">\n <mat-form-field class=\"time-field\">\n <mat-label>HH</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"23\"\n inputmode=\"numeric\"\n [formControl]=\"hourControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('hour')\"\n (blur)=\"onTimePartBlur('hour')\">\n </mat-form-field>\n\n <mat-form-field class=\"time-field\">\n <mat-label>MM</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"minuteControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('minute')\"\n (blur)=\"onTimePartBlur('minute')\">\n </mat-form-field>\n\n @if (showSeconds) {\n <mat-form-field class=\"time-field\">\n <mat-label>SS</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"secondControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('second')\"\n (blur)=\"onTimePartBlur('second')\">\n </mat-form-field>\n }\n </div>\n\n @if (isClockOpen) {\n <div class=\"clock-backdrop\" (click)=\"closeClock()\"></div>\n\n <div class=\"clock-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"clock-panel\">\n <div class=\"clock-panel-header\">\n <div class=\"clock-panel-title\">{{ clockTitle }}</div>\n <button\n mat-button\n type=\"button\"\n class=\"clock-close\"\n [disabled]=\"isDisabled\"\n (click)=\"closeClock()\">\n Close\n </button>\n </div>\n\n <div class=\"clock-summary\">\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'hour'\" (click)=\"goToClockStep('hour')\">\n {{ hourControl.value || '00' }}\n </button>\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'minute'\" (click)=\"goToClockStep('minute')\">\n {{ minuteControl.value || '00' }}\n </button>\n @if (showSeconds) {\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'second'\" (click)=\"goToClockStep('second')\">\n {{ secondControl.value || '00' }}\n </button>\n }\n </div>\n\n <div class=\"clock-face\" [class.clickable-face]=\"clockStep !== 'hour'\" [class.hour-face]=\"clockStep === 'hour'\" (click)=\"onClockFaceClick($event)\">\n <div class=\"clock-hand clock-hour-hand\" [style.transform]=\"hourHandTransform\" [style.height]=\"hourHandHeight\"></div>\n <div class=\"clock-hand clock-minute-hand\" [style.transform]=\"minuteHandTransform\" [style.height]=\"minuteHandHeight\"></div>\n\n @if (clockStep === 'hour') {\n @for (marker of hourMarkers; track marker.value) {\n <button\n type=\"button\"\n class=\"clock-hour-label\"\n [class.selected]=\"isHourSelected(marker.value)\"\n [class.inner-ring]=\"marker.value >= 12\"\n [style.left]=\"marker.left\"\n [style.top]=\"marker.top\"\n (click)=\"selectClockHour(marker.value, $event)\">\n {{ marker.label }}\n </button>\n }\n }\n\n @if (clockStep === 'minute') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of minuteTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of minuteTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n @if (clockStep === 'second') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of secondTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of secondTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n <div class=\"clock-center-dot\"></div>\n </div>\n\n <div class=\"clock-help\">\n @if (clockStep === 'hour') {\n <span>Outer ring 00-11, inner ring 12-23.</span>\n }\n @if (clockStep === 'minute') {\n <span>Click the dial. The nearest minute will be selected.</span>\n }\n @if (clockStep === 'second') {\n <span>Click the dial. The nearest second will be selected.</span>\n }\n </div>\n\n <div class=\"clock-footer\">\n <span>{{ timeSummary }}</span>\n </div>\n </div>\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%}.datetime-wrapper{display:flex;flex-direction:column;gap:8px;width:100%}.date-field,.time-field{width:100%}.middle-actions{display:flex;align-items:center;gap:4px;justify-content:flex-start}.icon-action{flex:0 0 auto}.icon-action i{font-size:1rem;line-height:1}.time-row{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}.clock-backdrop{position:fixed;inset:0;z-index:1000;background:#0000002e}.clock-dialog{position:fixed;z-index:1001;top:50%;left:50%;width:min(92vw,360px);transform:translate(-50%,-50%)}.clock-panel{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid rgba(0,0,0,.12);border-radius:16px;background:#fff;box-shadow:0 18px 36px #0003}.clock-panel-header,.clock-summary,.clock-footer{display:flex;align-items:center;justify-content:space-between;gap:8px}.clock-panel-title{font-size:.95rem;font-weight:600}.clock-summary{justify-content:center;font-size:1.1rem}.clock-step{min-width:52px;font-weight:600}.clock-step.active{background:#1976d21f}.clock-face{position:relative;align-self:center;width:min(100%,280px);aspect-ratio:1;border-radius:50%;overflow:hidden;background:radial-gradient(circle at center,rgba(25,118,210,.08) 0 16%,transparent 16% 100%),radial-gradient(circle at center,transparent 0 61%,rgba(25,118,210,.08) 61% 62%,transparent 62% 100%),radial-gradient(circle at center,#0000000a 0 100%)}.clock-face.clickable-face{cursor:crosshair}.clock-hand{position:absolute;top:50%;left:50%;width:2px;transform-origin:center bottom;background:#1976d2;border-radius:999px;z-index:1}.clock-hour-hand{background:#1976d2b8;width:4px}.clock-minute-hand{background:#1976d2;width:2px}.clock-hour-label{position:absolute;transform:translate(-50%,-50%);border:0;padding:0;margin:0;min-width:0;width:auto;height:auto;font-size:.72rem;line-height:1;background:transparent;box-shadow:none;color:#000000d1;cursor:pointer}.clock-hour-label.inner-ring{font-size:.68rem}.clock-hour-label.selected{color:#1976d2;font-weight:700}.clock-ticks-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.clock-tick-line{stroke:#00000057;stroke-width:1.5;stroke-linecap:round;cursor:pointer}.clock-tick-line.selected{stroke:#1976d2;stroke-width:2.5}.clock-tick-label{position:absolute;transform:translate(-50%,-50%);font-size:.68rem;line-height:1;color:#000000b8}.clock-tick-label.selected{color:#1976d2;font-weight:700}.clock-center-dot{position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%);background:#1976d2;z-index:2}.hour-face .clock-hour-label:hover,.hour-face .clock-hour-label:focus-visible{color:#1976d2;outline:none}.clock-help,.clock-footer{font-size:.78rem;color:#000000ad}@media(min-width:720px){.time-row{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:960px){.datetime-wrapper.datetime-mode{display:grid;align-items:start;gap:8px;grid-template-columns:minmax(240px,2fr) auto repeat(2,minmax(84px,96px))}.datetime-wrapper.datetime-mode.has-seconds{grid-template-columns:minmax(240px,2fr) auto repeat(3,minmax(84px,96px))}.datetime-wrapper.datetime-mode .date-field{margin-bottom:0}.datetime-wrapper.datetime-mode .middle-actions{align-self:start;padding-top:4px}.datetime-wrapper.datetime-mode .time-row{display:contents}.datetime-wrapper.datetime-mode .clock-panel{grid-column:1/-1}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.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$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField$1, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel$1, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: 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"] }] }); }
4096
+ ], ngImport: i0, template: "<div class=\"datetime-wrapper\" [class.datetime-mode]=\"isDateTime\" [class.has-seconds]=\"showSeconds\">\n <mat-form-field class=\"date-field\">\n @if (display) {\n <mat-label>{{ display }}</mat-label>\n }\n <input\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeHolder\"\n [formControl]=\"dateControl\"\n [disabled]=\"isDisabled\"\n (dateChange)=\"markTouched()\"\n (blur)=\"markTouched()\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n @if (isDateTime) {\n <div class=\"middle-actions\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Clear date and time\"\n aria-label=\"Clear date and time\"\n (click)=\"clear()\">\n <i class=\"fal fa-eraser\"></i>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Open time clock\"\n aria-label=\"Open time clock\"\n (click)=\"openClock()\">\n <i class=\"fal fa-clock\"></i>\n </button>\n </div>\n\n <div class=\"time-row\">\n <mat-form-field class=\"time-field\">\n <mat-label>HH</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"23\"\n inputmode=\"numeric\"\n [formControl]=\"hourControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('hour')\"\n (blur)=\"onTimePartBlur('hour')\">\n </mat-form-field>\n\n <mat-form-field class=\"time-field\">\n <mat-label>MM</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"minuteControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('minute')\"\n (blur)=\"onTimePartBlur('minute')\">\n </mat-form-field>\n\n @if (showSeconds) {\n <mat-form-field class=\"time-field\">\n <mat-label>SS</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"secondControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('second')\"\n (blur)=\"onTimePartBlur('second')\">\n </mat-form-field>\n }\n </div>\n\n @if (isClockOpen) {\n <div class=\"clock-backdrop\" (click)=\"closeClock()\"></div>\n\n <div class=\"clock-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"clock-panel\">\n <div class=\"clock-panel-header\">\n <div class=\"clock-panel-title\">{{ clockTitle }}</div>\n <button\n mat-button\n type=\"button\"\n class=\"clock-close\"\n [disabled]=\"isDisabled\"\n (click)=\"closeClock()\">\n Close\n </button>\n </div>\n\n <div class=\"clock-summary\">\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'hour'\" (click)=\"goToClockStep('hour')\">\n {{ hourControl.value || '00' }}\n </button>\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'minute'\" (click)=\"goToClockStep('minute')\">\n {{ minuteControl.value || '00' }}\n </button>\n @if (showSeconds) {\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'second'\" (click)=\"goToClockStep('second')\">\n {{ secondControl.value || '00' }}\n </button>\n }\n </div>\n\n <div class=\"clock-face\" [class.clickable-face]=\"clockStep !== 'hour'\" [class.hour-face]=\"clockStep === 'hour'\" (click)=\"onClockFaceClick($event)\">\n <div class=\"clock-hand clock-hour-hand\" [style.transform]=\"hourHandTransform\" [style.height]=\"hourHandHeight\"></div>\n <div class=\"clock-hand clock-minute-hand\" [style.transform]=\"minuteHandTransform\" [style.height]=\"minuteHandHeight\"></div>\n\n @if (clockStep === 'hour') {\n @for (marker of hourMarkers; track marker.value) {\n <button\n type=\"button\"\n class=\"clock-hour-label\"\n [class.selected]=\"isHourSelected(marker.value)\"\n [class.inner-ring]=\"marker.value >= 12\"\n [style.left]=\"marker.left\"\n [style.top]=\"marker.top\"\n (click)=\"selectClockHour(marker.value, $event)\">\n {{ marker.label }}\n </button>\n }\n }\n\n @if (clockStep !== 'hour') {\n <div\n class=\"clock-hour-indicator\"\n [class.inner-ring]=\"selectedHourMarker.value >= 12\"\n [style.left]=\"selectedHourMarker.left\"\n [style.top]=\"selectedHourMarker.top\">\n {{ selectedHourMarker.label }}\n </div>\n }\n\n @if (clockStep === 'minute') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of minuteTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of minuteTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n @if (clockStep === 'second') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of secondTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of secondTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n <div class=\"clock-center-dot\"></div>\n </div>\n\n <div class=\"clock-help\">\n @if (clockStep === 'hour') {\n <span>Outer ring 00-11, inner ring 12-23.</span>\n }\n @if (clockStep === 'minute') {\n <span>Click the dial. The nearest minute will be selected.</span>\n }\n @if (clockStep === 'second') {\n <span>Click the dial. The nearest second will be selected.</span>\n }\n </div>\n\n <div class=\"clock-footer\">\n <span>{{ timeSummary }}</span>\n </div>\n </div>\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%;container-type:inline-size}.datetime-wrapper{display:flex;flex-direction:column;gap:8px;width:100%}.date-field,.time-field{width:100%}.middle-actions{display:flex;align-items:center;gap:4px;justify-content:flex-start}.icon-action{flex:0 0 auto}.icon-action i{font-size:1rem;line-height:1}.time-row{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}.clock-backdrop{position:fixed;inset:0;z-index:1000;background:#0000002e}.clock-dialog{position:fixed;z-index:1001;top:50%;left:50%;width:min(92vw,360px);transform:translate(-50%,-50%)}.clock-panel{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid rgba(0,0,0,.12);border-radius:16px;background:#fff;box-shadow:0 18px 36px #0003}.clock-panel-header,.clock-summary,.clock-footer{display:flex;align-items:center;justify-content:space-between;gap:8px}.clock-panel-title{font-size:.95rem;font-weight:600}.clock-summary{justify-content:center;font-size:1.1rem}.clock-step{min-width:52px;font-weight:600}.clock-step.active{background:#1976d21f}.clock-face{position:relative;align-self:center;width:min(100%,280px);aspect-ratio:1;border-radius:50%;overflow:hidden;background:radial-gradient(circle at center,rgba(25,118,210,.08) 0 16%,transparent 16% 100%),radial-gradient(circle at center,transparent 0 61%,rgba(25,118,210,.08) 61% 62%,transparent 62% 100%),radial-gradient(circle at center,#0000000a 0 100%)}.clock-face.clickable-face{cursor:crosshair}.clock-hand{position:absolute;top:50%;left:50%;width:2px;transform-origin:center bottom;background:#1976d2;border-radius:999px;z-index:1}.clock-hour-hand{background:#1976d2b8;width:4px}.clock-minute-hand{background:#1976d2;width:2px}.clock-hour-label{position:absolute;transform:translate(-50%,-50%);border:0;padding:0;margin:0;min-width:0;width:auto;height:auto;font-size:.72rem;line-height:1;background:transparent;box-shadow:none;color:#000000d1;cursor:pointer}.clock-hour-label.inner-ring{font-size:.68rem}.clock-hour-label.selected{color:#1976d2;font-weight:700}.clock-hour-indicator{position:absolute;transform:translate(-50%,-50%);font-size:.76rem;line-height:1;font-weight:800;color:#1976d2;z-index:2}.clock-hour-indicator.inner-ring{font-size:.7rem}.clock-ticks-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.clock-tick-line{stroke:#00000057;stroke-width:1.5;stroke-linecap:round;cursor:pointer}.clock-tick-line.selected{stroke:#1976d2;stroke-width:2.5}.clock-tick-label{position:absolute;transform:translate(-50%,-50%);font-size:.68rem;line-height:1;color:#000000b8}.clock-tick-label.selected{color:#1976d2;font-weight:700}.clock-center-dot{position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%);background:#1976d2;z-index:2}.hour-face .clock-hour-label:hover,.hour-face .clock-hour-label:focus-visible{color:#1976d2;outline:none}.clock-help,.clock-footer{font-size:.78rem;color:#000000ad}@container (min-width: 420px){.time-row{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 760px){.datetime-wrapper.datetime-mode{display:grid;align-items:start;gap:8px;grid-template-columns:minmax(220px,2fr) auto repeat(2,minmax(74px,88px))}.datetime-wrapper.datetime-mode.has-seconds{grid-template-columns:minmax(220px,2fr) auto repeat(3,minmax(74px,88px))}.datetime-wrapper.datetime-mode .date-field{margin-bottom:0}.datetime-wrapper.datetime-mode .middle-actions{align-self:start;padding-top:4px}.datetime-wrapper.datetime-mode .time-row{display:contents}.datetime-wrapper.datetime-mode .clock-panel{grid-column:1/-1}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.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$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField$1, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel$1, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: 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"] }] }); }
3963
4097
  }
3964
4098
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DatetimeComponent, decorators: [{
3965
4099
  type: Component,
@@ -3969,7 +4103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
3969
4103
  multi: true,
3970
4104
  useExisting: forwardRef(() => DatetimeComponent)
3971
4105
  }
3972
- ], imports: [ReactiveFormsModule, MatFormField$1, MatLabel$1, MatInput, MatDatepickerInput, MatDatepickerToggle, MatDatepicker, MatSuffix, MatButton], template: "<div class=\"datetime-wrapper\" [class.datetime-mode]=\"isDateTime\" [class.has-seconds]=\"showSeconds\">\n <mat-form-field class=\"date-field\">\n @if (display) {\n <mat-label>{{ display }}</mat-label>\n }\n <input\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeHolder\"\n [formControl]=\"dateControl\"\n [disabled]=\"isDisabled\"\n (dateChange)=\"markTouched()\"\n (blur)=\"markTouched()\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n @if (isDateTime) {\n <div class=\"middle-actions\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Clear date and time\"\n aria-label=\"Clear date and time\"\n (click)=\"clear()\">\n <i class=\"fal fa-eraser\"></i>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Open time clock\"\n aria-label=\"Open time clock\"\n (click)=\"openClock()\">\n <i class=\"fal fa-clock\"></i>\n </button>\n </div>\n\n <div class=\"time-row\">\n <mat-form-field class=\"time-field\">\n <mat-label>HH</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"23\"\n inputmode=\"numeric\"\n [formControl]=\"hourControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('hour')\"\n (blur)=\"onTimePartBlur('hour')\">\n </mat-form-field>\n\n <mat-form-field class=\"time-field\">\n <mat-label>MM</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"minuteControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('minute')\"\n (blur)=\"onTimePartBlur('minute')\">\n </mat-form-field>\n\n @if (showSeconds) {\n <mat-form-field class=\"time-field\">\n <mat-label>SS</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"secondControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('second')\"\n (blur)=\"onTimePartBlur('second')\">\n </mat-form-field>\n }\n </div>\n\n @if (isClockOpen) {\n <div class=\"clock-backdrop\" (click)=\"closeClock()\"></div>\n\n <div class=\"clock-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"clock-panel\">\n <div class=\"clock-panel-header\">\n <div class=\"clock-panel-title\">{{ clockTitle }}</div>\n <button\n mat-button\n type=\"button\"\n class=\"clock-close\"\n [disabled]=\"isDisabled\"\n (click)=\"closeClock()\">\n Close\n </button>\n </div>\n\n <div class=\"clock-summary\">\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'hour'\" (click)=\"goToClockStep('hour')\">\n {{ hourControl.value || '00' }}\n </button>\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'minute'\" (click)=\"goToClockStep('minute')\">\n {{ minuteControl.value || '00' }}\n </button>\n @if (showSeconds) {\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'second'\" (click)=\"goToClockStep('second')\">\n {{ secondControl.value || '00' }}\n </button>\n }\n </div>\n\n <div class=\"clock-face\" [class.clickable-face]=\"clockStep !== 'hour'\" [class.hour-face]=\"clockStep === 'hour'\" (click)=\"onClockFaceClick($event)\">\n <div class=\"clock-hand clock-hour-hand\" [style.transform]=\"hourHandTransform\" [style.height]=\"hourHandHeight\"></div>\n <div class=\"clock-hand clock-minute-hand\" [style.transform]=\"minuteHandTransform\" [style.height]=\"minuteHandHeight\"></div>\n\n @if (clockStep === 'hour') {\n @for (marker of hourMarkers; track marker.value) {\n <button\n type=\"button\"\n class=\"clock-hour-label\"\n [class.selected]=\"isHourSelected(marker.value)\"\n [class.inner-ring]=\"marker.value >= 12\"\n [style.left]=\"marker.left\"\n [style.top]=\"marker.top\"\n (click)=\"selectClockHour(marker.value, $event)\">\n {{ marker.label }}\n </button>\n }\n }\n\n @if (clockStep === 'minute') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of minuteTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of minuteTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n @if (clockStep === 'second') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of secondTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of secondTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n <div class=\"clock-center-dot\"></div>\n </div>\n\n <div class=\"clock-help\">\n @if (clockStep === 'hour') {\n <span>Outer ring 00-11, inner ring 12-23.</span>\n }\n @if (clockStep === 'minute') {\n <span>Click the dial. The nearest minute will be selected.</span>\n }\n @if (clockStep === 'second') {\n <span>Click the dial. The nearest second will be selected.</span>\n }\n </div>\n\n <div class=\"clock-footer\">\n <span>{{ timeSummary }}</span>\n </div>\n </div>\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%}.datetime-wrapper{display:flex;flex-direction:column;gap:8px;width:100%}.date-field,.time-field{width:100%}.middle-actions{display:flex;align-items:center;gap:4px;justify-content:flex-start}.icon-action{flex:0 0 auto}.icon-action i{font-size:1rem;line-height:1}.time-row{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}.clock-backdrop{position:fixed;inset:0;z-index:1000;background:#0000002e}.clock-dialog{position:fixed;z-index:1001;top:50%;left:50%;width:min(92vw,360px);transform:translate(-50%,-50%)}.clock-panel{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid rgba(0,0,0,.12);border-radius:16px;background:#fff;box-shadow:0 18px 36px #0003}.clock-panel-header,.clock-summary,.clock-footer{display:flex;align-items:center;justify-content:space-between;gap:8px}.clock-panel-title{font-size:.95rem;font-weight:600}.clock-summary{justify-content:center;font-size:1.1rem}.clock-step{min-width:52px;font-weight:600}.clock-step.active{background:#1976d21f}.clock-face{position:relative;align-self:center;width:min(100%,280px);aspect-ratio:1;border-radius:50%;overflow:hidden;background:radial-gradient(circle at center,rgba(25,118,210,.08) 0 16%,transparent 16% 100%),radial-gradient(circle at center,transparent 0 61%,rgba(25,118,210,.08) 61% 62%,transparent 62% 100%),radial-gradient(circle at center,#0000000a 0 100%)}.clock-face.clickable-face{cursor:crosshair}.clock-hand{position:absolute;top:50%;left:50%;width:2px;transform-origin:center bottom;background:#1976d2;border-radius:999px;z-index:1}.clock-hour-hand{background:#1976d2b8;width:4px}.clock-minute-hand{background:#1976d2;width:2px}.clock-hour-label{position:absolute;transform:translate(-50%,-50%);border:0;padding:0;margin:0;min-width:0;width:auto;height:auto;font-size:.72rem;line-height:1;background:transparent;box-shadow:none;color:#000000d1;cursor:pointer}.clock-hour-label.inner-ring{font-size:.68rem}.clock-hour-label.selected{color:#1976d2;font-weight:700}.clock-ticks-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.clock-tick-line{stroke:#00000057;stroke-width:1.5;stroke-linecap:round;cursor:pointer}.clock-tick-line.selected{stroke:#1976d2;stroke-width:2.5}.clock-tick-label{position:absolute;transform:translate(-50%,-50%);font-size:.68rem;line-height:1;color:#000000b8}.clock-tick-label.selected{color:#1976d2;font-weight:700}.clock-center-dot{position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%);background:#1976d2;z-index:2}.hour-face .clock-hour-label:hover,.hour-face .clock-hour-label:focus-visible{color:#1976d2;outline:none}.clock-help,.clock-footer{font-size:.78rem;color:#000000ad}@media(min-width:720px){.time-row{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:960px){.datetime-wrapper.datetime-mode{display:grid;align-items:start;gap:8px;grid-template-columns:minmax(240px,2fr) auto repeat(2,minmax(84px,96px))}.datetime-wrapper.datetime-mode.has-seconds{grid-template-columns:minmax(240px,2fr) auto repeat(3,minmax(84px,96px))}.datetime-wrapper.datetime-mode .date-field{margin-bottom:0}.datetime-wrapper.datetime-mode .middle-actions{align-self:start;padding-top:4px}.datetime-wrapper.datetime-mode .time-row{display:contents}.datetime-wrapper.datetime-mode .clock-panel{grid-column:1/-1}}\n"] }]
4106
+ ], imports: [ReactiveFormsModule, MatFormField$1, MatLabel$1, MatInput, MatDatepickerInput, MatDatepickerToggle, MatDatepicker, MatSuffix, MatButton], template: "<div class=\"datetime-wrapper\" [class.datetime-mode]=\"isDateTime\" [class.has-seconds]=\"showSeconds\">\n <mat-form-field class=\"date-field\">\n @if (display) {\n <mat-label>{{ display }}</mat-label>\n }\n <input\n matInput\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeHolder\"\n [formControl]=\"dateControl\"\n [disabled]=\"isDisabled\"\n (dateChange)=\"markTouched()\"\n (blur)=\"markTouched()\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n\n @if (isDateTime) {\n <div class=\"middle-actions\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Clear date and time\"\n aria-label=\"Clear date and time\"\n (click)=\"clear()\">\n <i class=\"fal fa-eraser\"></i>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n class=\"icon-action\"\n [disabled]=\"isDisabled\"\n title=\"Open time clock\"\n aria-label=\"Open time clock\"\n (click)=\"openClock()\">\n <i class=\"fal fa-clock\"></i>\n </button>\n </div>\n\n <div class=\"time-row\">\n <mat-form-field class=\"time-field\">\n <mat-label>HH</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"23\"\n inputmode=\"numeric\"\n [formControl]=\"hourControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('hour')\"\n (blur)=\"onTimePartBlur('hour')\">\n </mat-form-field>\n\n <mat-form-field class=\"time-field\">\n <mat-label>MM</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"minuteControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('minute')\"\n (blur)=\"onTimePartBlur('minute')\">\n </mat-form-field>\n\n @if (showSeconds) {\n <mat-form-field class=\"time-field\">\n <mat-label>SS</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n max=\"59\"\n inputmode=\"numeric\"\n [formControl]=\"secondControl\"\n [disabled]=\"isDisabled\"\n (input)=\"onTimePartInput('second')\"\n (blur)=\"onTimePartBlur('second')\">\n </mat-form-field>\n }\n </div>\n\n @if (isClockOpen) {\n <div class=\"clock-backdrop\" (click)=\"closeClock()\"></div>\n\n <div class=\"clock-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"clock-panel\">\n <div class=\"clock-panel-header\">\n <div class=\"clock-panel-title\">{{ clockTitle }}</div>\n <button\n mat-button\n type=\"button\"\n class=\"clock-close\"\n [disabled]=\"isDisabled\"\n (click)=\"closeClock()\">\n Close\n </button>\n </div>\n\n <div class=\"clock-summary\">\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'hour'\" (click)=\"goToClockStep('hour')\">\n {{ hourControl.value || '00' }}\n </button>\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'minute'\" (click)=\"goToClockStep('minute')\">\n {{ minuteControl.value || '00' }}\n </button>\n @if (showSeconds) {\n <span>:</span>\n <button mat-button type=\"button\" class=\"clock-step\" [class.active]=\"clockStep === 'second'\" (click)=\"goToClockStep('second')\">\n {{ secondControl.value || '00' }}\n </button>\n }\n </div>\n\n <div class=\"clock-face\" [class.clickable-face]=\"clockStep !== 'hour'\" [class.hour-face]=\"clockStep === 'hour'\" (click)=\"onClockFaceClick($event)\">\n <div class=\"clock-hand clock-hour-hand\" [style.transform]=\"hourHandTransform\" [style.height]=\"hourHandHeight\"></div>\n <div class=\"clock-hand clock-minute-hand\" [style.transform]=\"minuteHandTransform\" [style.height]=\"minuteHandHeight\"></div>\n\n @if (clockStep === 'hour') {\n @for (marker of hourMarkers; track marker.value) {\n <button\n type=\"button\"\n class=\"clock-hour-label\"\n [class.selected]=\"isHourSelected(marker.value)\"\n [class.inner-ring]=\"marker.value >= 12\"\n [style.left]=\"marker.left\"\n [style.top]=\"marker.top\"\n (click)=\"selectClockHour(marker.value, $event)\">\n {{ marker.label }}\n </button>\n }\n }\n\n @if (clockStep !== 'hour') {\n <div\n class=\"clock-hour-indicator\"\n [class.inner-ring]=\"selectedHourMarker.value >= 12\"\n [style.left]=\"selectedHourMarker.left\"\n [style.top]=\"selectedHourMarker.top\">\n {{ selectedHourMarker.label }}\n </div>\n }\n\n @if (clockStep === 'minute') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of minuteTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of minuteTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isMinuteSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n @if (clockStep === 'second') {\n <svg class=\"clock-ticks-svg\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n @for (tick of secondTicks; track tick.value) {\n <line\n class=\"clock-tick-line\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n (click)=\"selectClockTick(tick.value, $event)\"></line>\n }\n </svg>\n @for (tick of secondTicks; track tick.value) {\n <div\n class=\"clock-tick-label\"\n [class.selected]=\"isSecondSelected(tick.value)\"\n [style.left]=\"tick.labelLeft\"\n [style.top]=\"tick.labelTop\"\n (click)=\"selectClockTick(tick.value, $event)\">\n {{ tick.label }}\n </div>\n }\n }\n\n <div class=\"clock-center-dot\"></div>\n </div>\n\n <div class=\"clock-help\">\n @if (clockStep === 'hour') {\n <span>Outer ring 00-11, inner ring 12-23.</span>\n }\n @if (clockStep === 'minute') {\n <span>Click the dial. The nearest minute will be selected.</span>\n }\n @if (clockStep === 'second') {\n <span>Click the dial. The nearest second will be selected.</span>\n }\n </div>\n\n <div class=\"clock-footer\">\n <span>{{ timeSummary }}</span>\n </div>\n </div>\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%;container-type:inline-size}.datetime-wrapper{display:flex;flex-direction:column;gap:8px;width:100%}.date-field,.time-field{width:100%}.middle-actions{display:flex;align-items:center;gap:4px;justify-content:flex-start}.icon-action{flex:0 0 auto}.icon-action i{font-size:1rem;line-height:1}.time-row{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}.clock-backdrop{position:fixed;inset:0;z-index:1000;background:#0000002e}.clock-dialog{position:fixed;z-index:1001;top:50%;left:50%;width:min(92vw,360px);transform:translate(-50%,-50%)}.clock-panel{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid rgba(0,0,0,.12);border-radius:16px;background:#fff;box-shadow:0 18px 36px #0003}.clock-panel-header,.clock-summary,.clock-footer{display:flex;align-items:center;justify-content:space-between;gap:8px}.clock-panel-title{font-size:.95rem;font-weight:600}.clock-summary{justify-content:center;font-size:1.1rem}.clock-step{min-width:52px;font-weight:600}.clock-step.active{background:#1976d21f}.clock-face{position:relative;align-self:center;width:min(100%,280px);aspect-ratio:1;border-radius:50%;overflow:hidden;background:radial-gradient(circle at center,rgba(25,118,210,.08) 0 16%,transparent 16% 100%),radial-gradient(circle at center,transparent 0 61%,rgba(25,118,210,.08) 61% 62%,transparent 62% 100%),radial-gradient(circle at center,#0000000a 0 100%)}.clock-face.clickable-face{cursor:crosshair}.clock-hand{position:absolute;top:50%;left:50%;width:2px;transform-origin:center bottom;background:#1976d2;border-radius:999px;z-index:1}.clock-hour-hand{background:#1976d2b8;width:4px}.clock-minute-hand{background:#1976d2;width:2px}.clock-hour-label{position:absolute;transform:translate(-50%,-50%);border:0;padding:0;margin:0;min-width:0;width:auto;height:auto;font-size:.72rem;line-height:1;background:transparent;box-shadow:none;color:#000000d1;cursor:pointer}.clock-hour-label.inner-ring{font-size:.68rem}.clock-hour-label.selected{color:#1976d2;font-weight:700}.clock-hour-indicator{position:absolute;transform:translate(-50%,-50%);font-size:.76rem;line-height:1;font-weight:800;color:#1976d2;z-index:2}.clock-hour-indicator.inner-ring{font-size:.7rem}.clock-ticks-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.clock-tick-line{stroke:#00000057;stroke-width:1.5;stroke-linecap:round;cursor:pointer}.clock-tick-line.selected{stroke:#1976d2;stroke-width:2.5}.clock-tick-label{position:absolute;transform:translate(-50%,-50%);font-size:.68rem;line-height:1;color:#000000b8}.clock-tick-label.selected{color:#1976d2;font-weight:700}.clock-center-dot{position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%);background:#1976d2;z-index:2}.hour-face .clock-hour-label:hover,.hour-face .clock-hour-label:focus-visible{color:#1976d2;outline:none}.clock-help,.clock-footer{font-size:.78rem;color:#000000ad}@container (min-width: 420px){.time-row{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 760px){.datetime-wrapper.datetime-mode{display:grid;align-items:start;gap:8px;grid-template-columns:minmax(220px,2fr) auto repeat(2,minmax(74px,88px))}.datetime-wrapper.datetime-mode.has-seconds{grid-template-columns:minmax(220px,2fr) auto repeat(3,minmax(74px,88px))}.datetime-wrapper.datetime-mode .date-field{margin-bottom:0}.datetime-wrapper.datetime-mode .middle-actions{align-self:start;padding-top:4px}.datetime-wrapper.datetime-mode .time-row{display:contents}.datetime-wrapper.datetime-mode .clock-panel{grid-column:1/-1}}\n"] }]
3973
4107
  }], ctorParameters: () => [{ type: undefined, decorators: [{
3974
4108
  type: Optional
3975
4109
  }, {
@@ -4037,6 +4171,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
4037
4171
  type: Injectable
4038
4172
  }], ctorParameters: () => [{ type: GlowwI18nService }] });
4039
4173
 
4174
+ class AssignedUserTasksComponent {
4175
+ constructor(glowwService, authenticationService, i18n, router) {
4176
+ this.glowwService = glowwService;
4177
+ this.authenticationService = authenticationService;
4178
+ this.i18n = i18n;
4179
+ this.router = router;
4180
+ this.displayedColumns = ['action', 'task', 'definition', 'execution', 'status', 'message', 'assignment'];
4181
+ this.dataSource = new MatTableDataSource([]);
4182
+ this.loading = false;
4183
+ this.errorMessage = '';
4184
+ }
4185
+ ngOnInit() {
4186
+ this.dataSource.sortingDataAccessor = (item, property) => this.getSortValue(item, property);
4187
+ this.dataSource.sort = this.sort;
4188
+ this.loadAssignments();
4189
+ }
4190
+ ngAfterViewInit() {
4191
+ this.dataSource.paginator = this.paginator;
4192
+ }
4193
+ t(key, fallback) {
4194
+ return this.i18n.instant(key, fallback);
4195
+ }
4196
+ loadAssignments() {
4197
+ const query = this.buildQuery();
4198
+ this.loading = true;
4199
+ this.errorMessage = '';
4200
+ this.glowwService.searchBPMN2_UserTask_Assignment(query).pipe(catchError(error => {
4201
+ this.errorMessage = error?.error?.message || error?.message || `${error}`;
4202
+ return of([]);
4203
+ }), finalize(() => {
4204
+ this.loading = false;
4205
+ })).subscribe((items) => {
4206
+ this.dataSource.data = items ?? [];
4207
+ if (this.paginator) {
4208
+ this.dataSource.paginator = this.paginator;
4209
+ }
4210
+ });
4211
+ }
4212
+ openExecution(taskAssignment) {
4213
+ const executionId = taskAssignment.IsCandidate?.HasAsExecutionStep?.ExecutionID;
4214
+ if (!executionId) {
4215
+ return;
4216
+ }
4217
+ this.router.navigate(['/execution', executionId]);
4218
+ }
4219
+ openExecutionSteps(taskAssignment) {
4220
+ const executionId = taskAssignment.IsCandidate?.HasAsExecutionStep?.ExecutionID;
4221
+ if (!executionId) {
4222
+ return;
4223
+ }
4224
+ this.router.navigate(['/executionsteps', executionId]);
4225
+ }
4226
+ hasExecution(taskAssignment) {
4227
+ return !!taskAssignment.IsCandidate?.HasAsExecutionStep?.ExecutionID;
4228
+ }
4229
+ getTaskLabel(taskAssignment) {
4230
+ return taskAssignment.IsCandidate?.Title
4231
+ || taskAssignment.IsCandidate?.DialogTitle
4232
+ || `${this.t('GLOWW.USER_TASK', 'User task')} #${taskAssignment.UserTaskId ?? taskAssignment.AssignmentID}`;
4233
+ }
4234
+ getDefinitionLabel(taskAssignment) {
4235
+ const execution = taskAssignment.IsCandidate?.HasAsExecutionStep?.HasAsExecution;
4236
+ if (!execution?.DefinitionID) {
4237
+ return '';
4238
+ }
4239
+ return execution.ProcessID
4240
+ ? `${execution.DefinitionID} (${execution.ProcessID})`
4241
+ : execution.DefinitionID;
4242
+ }
4243
+ getExecutionLabel(taskAssignment) {
4244
+ const step = taskAssignment.IsCandidate?.HasAsExecutionStep;
4245
+ if (!step?.ExecutionID) {
4246
+ return '';
4247
+ }
4248
+ const processStepId = step.ProcessStepID ?? taskAssignment.IsCandidate?.ProcessStepID;
4249
+ return processStepId
4250
+ ? `${step.ExecutionID} / ${processStepId}`
4251
+ : `${step.ExecutionID}`;
4252
+ }
4253
+ getStatusLabel(taskAssignment) {
4254
+ return taskAssignment.IsCandidate?.Statut
4255
+ || taskAssignment.STATUT
4256
+ || '';
4257
+ }
4258
+ getAssignmentLabel(taskAssignment) {
4259
+ const type = taskAssignment.Responsible
4260
+ ? this.t('GLOWW.RESPONSIBLE', 'Responsible')
4261
+ : this.t('GLOWW.CANDIDATE', 'Candidate');
4262
+ return `${taskAssignment.Domain ? `${taskAssignment.Domain}\\` : ''}${taskAssignment.Username ?? ''} (${type})`;
4263
+ }
4264
+ buildQuery() {
4265
+ const currentUser = this.authenticationService.currentUserValue;
4266
+ const query = {};
4267
+ if (currentUser?.username) {
4268
+ query.Username = currentUser.username;
4269
+ }
4270
+ if (currentUser?.domain) {
4271
+ query.Domain = currentUser.domain;
4272
+ }
4273
+ return query;
4274
+ }
4275
+ getSortValue(item, property) {
4276
+ switch (property) {
4277
+ case 'task':
4278
+ return this.getTaskLabel(item).toLowerCase();
4279
+ case 'definition':
4280
+ return this.getDefinitionLabel(item).toLowerCase();
4281
+ case 'execution':
4282
+ return item.IsCandidate?.HasAsExecutionStep?.ExecutionID ?? 0;
4283
+ case 'status':
4284
+ return this.getStatusLabel(item).toLowerCase();
4285
+ case 'message':
4286
+ return (item.IsCandidate?.MESSAGE ?? '').toLowerCase();
4287
+ case 'assignment':
4288
+ return this.getAssignmentLabel(item).toLowerCase();
4289
+ default:
4290
+ return item.AssignmentID ?? 0;
4291
+ }
4292
+ }
4293
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssignedUserTasksComponent, deps: [{ token: 'glowwService' }, { token: AuthenticationService }, { token: GlowwI18nService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
4294
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AssignedUserTasksComponent, isStandalone: true, selector: "glw-assigned-user-tasks", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], ngImport: i0, template: "<mat-card class=\"assigned-user-tasks-card\" appearance=\"outlined\">\n <mat-card-header class=\"assigned-user-tasks-header\">\n <mat-card-title>{{ t('GLOWW.MY_ASSIGNED_TASKS', 'My assigned tasks') }}</mat-card-title>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"loadAssignments()\">\n <mat-icon>refresh</mat-icon>\n {{ t('COMMON.REFRESH', 'Refresh') }}\n </button>\n </mat-card-header>\n\n <mat-card-content>\n @if (errorMessage) {\n <div class=\"assigned-user-tasks-error\">\n {{ t('GLOWW.UNABLE_TO_QUERY', 'Unable to query') }}: {{ errorMessage }}\n </div>\n }\n\n @if (loading) {\n <div class=\"assigned-user-tasks-loading\">\n <mat-spinner diameter=\"36\"></mat-spinner>\n </div>\n }\n\n @if (!loading) {\n <div class=\"assigned-user-tasks-table-wrapper\">\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let obj\">\n <button mat-icon-button type=\"button\" (click)=\"openExecution(obj)\" [disabled]=\"!hasExecution(obj)\" [attr.aria-label]=\"t('LISTS.DISPLAY', 'Display')\">\n <i class=\"fal fa-eye\"></i>\n </button>\n <button mat-icon-button type=\"button\" (click)=\"openExecutionSteps(obj)\" [disabled]=\"!hasExecution(obj)\" [attr.aria-label]=\"t('LISTS.STEPS', 'Steps')\">\n <i class=\"fal fa-list-check\"></i>\n </button>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"task\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"task\">{{ t('LISTS.TASK', 'Task') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getTaskLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"definition\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"definition\">{{ t('LISTS.DEFINITION_ID', 'Definition ID') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getDefinitionLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"execution\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"execution\">{{ t('LISTS.EXECUTION', 'Execution') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getExecutionLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"status\">{{ t('LISTS.STATUS', 'Status') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getStatusLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"message\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"message\">{{ t('LISTS.MESSAGE', 'Message') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ obj.IsCandidate?.MESSAGE }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"assignment\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"assignment\">{{ t('LISTS.ASSIGNED_TO', 'Assigned to') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getAssignmentLabel(obj) }}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n </div>\n\n @if (!dataSource.data.length) {\n <div class=\"assigned-user-tasks-empty\">\n {{ t('GLOWW.NO_ASSIGNED_TASKS', 'No task is currently assigned to you.') }}\n </div>\n }\n }\n </mat-card-content>\n\n <mat-card-actions>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </mat-card-actions>\n</mat-card>\n", styles: [":host{display:block}.assigned-user-tasks-card{margin:16px}.assigned-user-tasks-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:12px}.assigned-user-tasks-loading,.assigned-user-tasks-empty,.assigned-user-tasks-error{padding:16px 0}.assigned-user-tasks-table-wrapper{overflow:auto}table{width:100%}th:first-child,td:first-child{width:88px;white-space:nowrap}button[mat-icon-button]{margin-right:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4$1.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: i4$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i5$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i5$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i5$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i7.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i9.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i9.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i10.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i10.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i10.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i10.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i10.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i10.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i10.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i10.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i10.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i10.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }] }); }
4295
+ }
4296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssignedUserTasksComponent, decorators: [{
4297
+ type: Component,
4298
+ args: [{ selector: 'glw-assigned-user-tasks', imports: [
4299
+ RouterLink,
4300
+ DatePipe,
4301
+ MatButtonModule,
4302
+ MatCardModule,
4303
+ MatIconModule,
4304
+ MatPaginatorModule,
4305
+ MatProgressSpinnerModule,
4306
+ MatSortModule,
4307
+ MatTableModule
4308
+ ], template: "<mat-card class=\"assigned-user-tasks-card\" appearance=\"outlined\">\n <mat-card-header class=\"assigned-user-tasks-header\">\n <mat-card-title>{{ t('GLOWW.MY_ASSIGNED_TASKS', 'My assigned tasks') }}</mat-card-title>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"loadAssignments()\">\n <mat-icon>refresh</mat-icon>\n {{ t('COMMON.REFRESH', 'Refresh') }}\n </button>\n </mat-card-header>\n\n <mat-card-content>\n @if (errorMessage) {\n <div class=\"assigned-user-tasks-error\">\n {{ t('GLOWW.UNABLE_TO_QUERY', 'Unable to query') }}: {{ errorMessage }}\n </div>\n }\n\n @if (loading) {\n <div class=\"assigned-user-tasks-loading\">\n <mat-spinner diameter=\"36\"></mat-spinner>\n </div>\n }\n\n @if (!loading) {\n <div class=\"assigned-user-tasks-table-wrapper\">\n <table mat-table [dataSource]=\"dataSource\" matSort>\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let obj\">\n <button mat-icon-button type=\"button\" (click)=\"openExecution(obj)\" [disabled]=\"!hasExecution(obj)\" [attr.aria-label]=\"t('LISTS.DISPLAY', 'Display')\">\n <i class=\"fal fa-eye\"></i>\n </button>\n <button mat-icon-button type=\"button\" (click)=\"openExecutionSteps(obj)\" [disabled]=\"!hasExecution(obj)\" [attr.aria-label]=\"t('LISTS.STEPS', 'Steps')\">\n <i class=\"fal fa-list-check\"></i>\n </button>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"task\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"task\">{{ t('LISTS.TASK', 'Task') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getTaskLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"definition\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"definition\">{{ t('LISTS.DEFINITION_ID', 'Definition ID') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getDefinitionLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"execution\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"execution\">{{ t('LISTS.EXECUTION', 'Execution') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getExecutionLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"status\">{{ t('LISTS.STATUS', 'Status') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getStatusLabel(obj) }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"message\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"message\">{{ t('LISTS.MESSAGE', 'Message') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ obj.IsCandidate?.MESSAGE }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"assignment\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header=\"assignment\">{{ t('LISTS.ASSIGNED_TO', 'Assigned to') }}</th>\n <td mat-cell *matCellDef=\"let obj\">{{ getAssignmentLabel(obj) }}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n </div>\n\n @if (!dataSource.data.length) {\n <div class=\"assigned-user-tasks-empty\">\n {{ t('GLOWW.NO_ASSIGNED_TASKS', 'No task is currently assigned to you.') }}\n </div>\n }\n }\n </mat-card-content>\n\n <mat-card-actions>\n <mat-paginator [pageSize]=\"10\" [pageSizeOptions]=\"[10, 20, 50, 100]\" [showFirstLastButtons]=\"true\"></mat-paginator>\n </mat-card-actions>\n</mat-card>\n", styles: [":host{display:block}.assigned-user-tasks-card{margin:16px}.assigned-user-tasks-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:12px}.assigned-user-tasks-loading,.assigned-user-tasks-empty,.assigned-user-tasks-error{padding:16px 0}.assigned-user-tasks-table-wrapper{overflow:auto}table{width:100%}th:first-child,td:first-child{width:88px;white-space:nowrap}button[mat-icon-button]{margin-right:4px}\n"] }]
4309
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
4310
+ type: Inject,
4311
+ args: ['glowwService']
4312
+ }] }, { type: AuthenticationService }, { type: GlowwI18nService }, { type: i2.Router }], propDecorators: { sort: [{
4313
+ type: ViewChild,
4314
+ args: [MatSort, { static: true }]
4315
+ }], paginator: [{
4316
+ type: ViewChild,
4317
+ args: [MatPaginator]
4318
+ }] } });
4319
+
4040
4320
  class BaseCollectionComponent {
4041
4321
  constructor(_formBuilder) {
4042
4322
  this._formBuilder = _formBuilder;
@@ -4103,6 +4383,7 @@ const GLOWW_STANDALONE_DECLARATIONS = [
4103
4383
  SelectComponent,
4104
4384
  AutoCompleteComponent,
4105
4385
  DatetimeComponent,
4386
+ AssignedUserTasksComponent,
4106
4387
  RouteDirective,
4107
4388
  CallbackDirective,
4108
4389
  FilterFormComponent
@@ -4187,6 +4468,7 @@ class GlowwModule {
4187
4468
  SelectComponent,
4188
4469
  AutoCompleteComponent,
4189
4470
  DatetimeComponent,
4471
+ AssignedUserTasksComponent,
4190
4472
  RouteDirective,
4191
4473
  CallbackDirective,
4192
4474
  FilterFormComponent], exports: [UploadDocComponent,
@@ -4213,6 +4495,7 @@ class GlowwModule {
4213
4495
  SelectComponent,
4214
4496
  AutoCompleteComponent,
4215
4497
  DatetimeComponent,
4498
+ AssignedUserTasksComponent,
4216
4499
  RouteDirective,
4217
4500
  CallbackDirective,
4218
4501
  FilterFormComponent, MatDatepickerModule,
@@ -4258,6 +4541,7 @@ class GlowwModule {
4258
4541
  SelectComponent,
4259
4542
  AutoCompleteComponent,
4260
4543
  DatetimeComponent,
4544
+ AssignedUserTasksComponent,
4261
4545
  FilterFormComponent, MatDatepickerModule,
4262
4546
  NgxMatDatetimePickerModule,
4263
4547
  NgxMatNativeDateModule] }); }
@@ -4435,5 +4719,5 @@ class GlowwValidators {
4435
4719
  * Generated bundle index. Do not edit.
4436
4720
  */
4437
4721
 
4438
- export { API_SERVER_URL, AdministratorGuard, AuthGuard, AuthenticationService, AuthenticationServiceConfig, AutoCompleteComponent, BaseCollectionComponent, CallbackDirective, ChangePasswordDlgComponent, CodeEditorComponent, ConfirmationComponent, ConfirmationModel, DatetimeComponent, DialogService, DisplayObjectsComponent, DownloadProgressComponent, DummyComponent, ErrorInterceptor, FileEditComponent, FileSinkDirective, FilterFormComponent, FolderService, FolderServiceConfig, FoldersComponent, GLOWW_APPLI, GLOWW_MODULE_EXPORTS, GLOWW_SECURITY_STANDALONE_DECLARATIONS, GLOWW_STANDALONE_DECLARATIONS, GlowwModule, GlowwSecurityModule, GlowwSecurityService, GlowwService, GlowwValidators, HasUnsavedDataGuard, HeaderComponent, HtmlEditorComponent, HtmlFormatPipe, JwtInterceptor, LoginComponent, MenuListItemComponent, NavService, PromptComponent, PromptModel, ResultTableComponent, RouteDirective, SafeHtmlPipe, SearchFormComponent, SecureAComponent, SecureImgComponent, SecurePipe, SelectComponent, SocialNetworkComponent, SocialNetworkDlgComponent, StagingInterceptor, UploadDocComponent, UploadFileComponent, UserMenuComponent, VersionCheckService, VoiceRecognitionService, provideGloww, provideGlowwSecurity };
4722
+ export { API_SERVER_URL, AdministratorGuard, AssignedUserTasksComponent, AuthGuard, AuthenticationService, AuthenticationServiceConfig, AutoCompleteComponent, BaseCollectionComponent, CallbackDirective, ChangePasswordDlgComponent, CodeEditorComponent, ConfirmationComponent, ConfirmationModel, DatetimeComponent, DialogService, DisplayObjectsComponent, DownloadProgressComponent, DummyComponent, ErrorInterceptor, FileEditComponent, FileSinkDirective, FilterFormComponent, FolderService, FolderServiceConfig, FoldersComponent, GLOWW_APPLI, GLOWW_MODULE_EXPORTS, GLOWW_SECURITY_STANDALONE_DECLARATIONS, GLOWW_STANDALONE_DECLARATIONS, GlowwModule, GlowwSecurityModule, GlowwSecurityService, GlowwService, GlowwValidators, HasUnsavedDataGuard, HeaderComponent, HtmlEditorComponent, HtmlFormatPipe, JwtInterceptor, LoginComponent, MenuListItemComponent, NavService, PromptComponent, PromptModel, ResultTableComponent, RouteDirective, SafeHtmlPipe, SearchFormComponent, SecureAComponent, SecureImgComponent, SecurePipe, SelectComponent, SocialNetworkComponent, SocialNetworkDlgComponent, StagingInterceptor, UploadDocComponent, UploadFileComponent, UserMenuComponent, VersionCheckService, VoiceRecognitionService, provideGloww, provideGlowwSecurity };
4439
4723
  //# sourceMappingURL=gloww-gloww.mjs.map