@sumaris-net/ngx-components 18.3.29 → 18.3.30-alpha1

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,12 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Directive, Pipe, Injectable, EventEmitter, Output, Optional, Inject, inject, NgModule, forwardRef, Component, ChangeDetectionStrategy, Input, ViewChildren, HostBinding, HostListener, ElementRef, numberAttribute, booleanAttribute, ViewChild, ANIMATION_MODULE_TYPE, RendererStyleFlags2, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation, APP_INITIALIZER, ChangeDetectorRef } from '@angular/core';
3
- import { firstValueFrom, shareReplay, tap, of, timer, Subject, merge, delay, isObservable, from, Subscription, BehaviorSubject, fromEvent, noop as noop$a, Observable, forkJoin, defer, timeout, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, fromEventPattern, interval, combineLatest, EMPTY, switchMap as switchMap$1 } from 'rxjs';
2
+ import { InjectionToken, Directive, Pipe, Injectable, EventEmitter, Output, Optional, Inject, inject, NgModule, forwardRef, Component, ChangeDetectionStrategy, Input, ViewChildren, HostBinding, HostListener, ElementRef, numberAttribute, booleanAttribute, ViewChild, ANIMATION_MODULE_TYPE, RendererStyleFlags2, CUSTOM_ELEMENTS_SCHEMA, Self, ViewEncapsulation, APP_INITIALIZER, ChangeDetectorRef, viewChild, signal, input, model, computed, effect, untracked } from '@angular/core';
3
+ import { firstValueFrom, shareReplay, tap, of, timer, Subject, merge, delay, isObservable, from, Subscription, BehaviorSubject, fromEvent, noop as noop$9, Observable, forkJoin, defer, timeout, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, fromEventPattern, interval, combineLatest, EMPTY, switchMap as switchMap$1 } from 'rxjs';
4
4
  import { catchError, map, filter, takeUntil, first, switchMap, tap as tap$1, throttleTime, debounceTime, startWith, distinctUntilChanged, mergeMap, skip, finalize, bufferWhen, distinctUntilKeyChanged, take } from 'rxjs/operators';
5
5
  import * as i3 from '@angular/common';
6
- import { CommonModule, DOCUMENT, Location } from '@angular/common';
6
+ import { CommonModule, DOCUMENT, Location, AsyncPipe, JsonPipe } from '@angular/common';
7
7
  import { CdkTableModule } from '@angular/cdk/table';
8
8
  import * as i1$4 from '@angular/cdk/a11y';
9
- import { A11yModule } from '@angular/cdk/a11y';
9
+ import { A11yModule, FocusMonitor } from '@angular/cdk/a11y';
10
10
  import { OverlayModule, OverlayContainer, FullscreenOverlayContainer, Overlay } from '@angular/cdk/overlay';
11
11
  import { ScrollingModule } from '@angular/cdk/scrolling';
12
12
  import * as i2 from '@angular/material/core';
@@ -34,12 +34,12 @@ import * as i1 from '@angular/material-moment-adapter';
34
34
  import { MatMomentDateModule } from '@angular/material-moment-adapter';
35
35
  import { isMoment as isMoment$1 } from 'moment/moment';
36
36
  import * as i1$3 from '@angular/forms';
37
- import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, Validators, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormControl, FormGroup, FormsModule } from '@angular/forms';
38
- import { maskitoWithPlaceholder, maskitoEventHandler, maskitoNumberOptionsGenerator, maskitoDateOptionsGenerator, maskitoTimeOptionsGenerator } from '@maskito/kit';
37
+ import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, Validators, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormBuilder, FormControl, FormGroup, FormsModule, NgControl } from '@angular/forms';
38
+ import { maskitoWithPlaceholder, maskitoEventHandler, maskitoDateOptionsGenerator, maskitoTimeOptionsGenerator, maskitoNumberOptionsGenerator } from '@maskito/kit';
39
39
  import * as i1$2 from '@angular/platform-browser';
40
40
  import { HammerGestureConfig, HammerModule } from '@angular/platform-browser';
41
41
  import * as i6 from '@angular/material/form-field';
42
- import { MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
42
+ import { MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS, MAT_FORM_FIELD, MatFormFieldControl } from '@angular/material/form-field';
43
43
  import * as i4 from '@angular/material/input';
44
44
  import { MatInputModule } from '@angular/material/input';
45
45
  import * as i11 from '@maskito/angular';
@@ -63,7 +63,7 @@ import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
63
63
  import * as i8$2 from '@angular/material/menu';
64
64
  import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
65
65
  import * as i12 from '@angular/material/select';
66
- import { MatSelectModule, MatSelect, MAT_SELECT_SCROLL_STRATEGY } from '@angular/material/select';
66
+ import { MatSelectModule, MAT_SELECT_SCROLL_STRATEGY } from '@angular/material/select';
67
67
  import { MatCardModule } from '@angular/material/card';
68
68
  import * as i7 from '@angular/material/tabs';
69
69
  import { MatTabsModule } from '@angular/material/tabs';
@@ -100,6 +100,7 @@ import * as LocalForage from 'localforage';
100
100
  import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
101
101
  import * as i2$2 from '@ionic/storage-angular';
102
102
  import { IonicStorageModule } from '@ionic/storage-angular';
103
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
103
104
  import * as i5$3 from 'ngx-color-picker';
104
105
  import { ColorPickerModule } from 'ngx-color-picker';
105
106
  import * as i2$3 from '@ionic-native/audio-management/ngx';
@@ -153,6 +154,7 @@ import { Geolocation } from '@capacitor/geolocation';
153
154
  import * as i1$7 from '@e-is/ngx-material-table';
154
155
  import { ValidatorService, TableDataSource, AsyncTableDataSource } from '@e-is/ngx-material-table';
155
156
  import 'moment-timezone';
157
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
156
158
 
157
159
  const ENVIRONMENT = new InjectionToken('ENV');
158
160
  class Environment {
@@ -1575,6 +1577,9 @@ const DEFAULT_LONGITUDE_OPTIONS = {
1575
1577
  ...DEFAULT_OPTIONS,
1576
1578
  longitude: true,
1577
1579
  };
1580
+ function computeDecimalPart(value, nbOfDecimals) {
1581
+ return value * 10 ** (nbOfDecimals * -1);
1582
+ }
1578
1583
  function formatLatLong(value, type, opts) {
1579
1584
  switch (type) {
1580
1585
  case 'latitude':
@@ -3739,6 +3744,7 @@ function disableControl(control, opts) {
3739
3744
  }
3740
3745
  function disableAndClearControl(control, opts) {
3741
3746
  const wasDisabled = control.disabled;
3747
+ // Apply disable
3742
3748
  setControlEnabled(control, false, { required: false, ...opts });
3743
3749
  // Important, should not use reset() to mark the control as dirty.
3744
3750
  // Otherwise, optimization using dirty (.e.g MeasurementForm) will not be notified by this changed
@@ -5474,7 +5480,7 @@ const DEFAULT_VALUE_ACCESSOR$5 = {
5474
5480
  };
5475
5481
  const HOUR_TIME_PATTERN = /[0-9]\d\d:[0-5]\d/;
5476
5482
  const DURATION_MASK = [/\d/, /\d/, /\d/, ':', /[0-5]/, /\d/];
5477
- const noop$9 = () => { };
5483
+ const noop$8 = () => { };
5478
5484
  class MatDuration {
5479
5485
  dateAdapter;
5480
5486
  translate;
@@ -5482,8 +5488,8 @@ class MatDuration {
5482
5488
  cd;
5483
5489
  formGroupDir;
5484
5490
  _subscription = new Subscription();
5485
- _onChangeCallback = noop$9;
5486
- _onTouchedCallback = noop$9;
5491
+ _onChangeCallback = noop$8;
5492
+ _onTouchedCallback = noop$8;
5487
5493
  writing = true;
5488
5494
  disabling = false;
5489
5495
  _tabindex;
@@ -6065,13 +6071,13 @@ const DEFAULT_VALUE_ACCESSOR$4 = {
6065
6071
  useExisting: forwardRef(() => MatBooleanField),
6066
6072
  multi: true,
6067
6073
  };
6068
- const noop$8 = () => { };
6074
+ const noop$7 = () => { };
6069
6075
  class MatBooleanField {
6070
6076
  cd;
6071
6077
  el;
6072
6078
  formGroupDir;
6073
- _onChangeCallback = noop$8;
6074
- _onTouchedCallback = noop$8;
6079
+ _onChangeCallback = noop$7;
6080
+ _onTouchedCallback = noop$7;
6075
6081
  _subscription = new Subscription();
6076
6082
  _writing = false;
6077
6083
  _value;
@@ -7684,7 +7690,7 @@ class MatAutocompleteFieldUtils {
7684
7690
  }
7685
7691
  }
7686
7692
 
7687
- const noop$7 = () => { };
7693
+ const noop$6 = () => { };
7688
7694
  class MatAutocompleteField {
7689
7695
  injector;
7690
7696
  el;
@@ -7692,8 +7698,8 @@ class MatAutocompleteField {
7692
7698
  modalController;
7693
7699
  renderer;
7694
7700
  formGroupDir;
7695
- _onChangeCallback = noop$7;
7696
- _onTouchedCallback = noop$7;
7701
+ _onChangeCallback = noop$6;
7702
+ _onTouchedCallback = noop$6;
7697
7703
  _onFetchMoreCallback;
7698
7704
  _implicitValue;
7699
7705
  _subscription = new Subscription();
@@ -8942,630 +8948,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
8942
8948
  const MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING = 'fixed';
8943
8949
  const MAT_FORM_FIELD_DEFAULT_APPEARANCE = 'fill';
8944
8950
 
8945
- const noop$6 = () => { };
8946
- class MatLatLongField {
8947
- cd;
8948
- formGroupDir;
8949
- _onChangeCallback = noop$6;
8950
- _onTouchedCallback = noop$6;
8951
- _subscription = new Subscription();
8952
- _disabling = false;
8953
- _writing = false;
8954
- _appearance = null;
8955
- _subscriptSizing = null;
8956
- _readonly = false;
8957
- _tabindex;
8958
- _defaultAppearance;
8959
- _defaultSubscriptSizing;
8960
- _focused = false;
8961
- _touched = false;
8962
- degreesControl;
8963
- minutesControl;
8964
- secondsControl;
8965
- signControl;
8966
- showMinutes = false;
8967
- showSeconds = false;
8968
- showSignControl;
8969
- degreesPlaceholder;
8970
- minutesPlaceholder;
8971
- secondsPlaceholder;
8972
- degreesMask;
8973
- minutesMask;
8974
- secondsMask;
8975
- patternMaxDecimals = LAT_LONG_PATTERN_MAX_DECIMALS;
8976
- i18nErrorKeys = SharedValidators.I18N_ERROR_KEYS;
8977
- formControl;
8978
- formControlName;
8979
- type;
8980
- pattern;
8981
- maxDecimals = LAT_LONG_VALUE_MAX_DECIMALS;
8982
- required = false;
8983
- floatLabel = 'auto';
8984
- placeholder;
8985
- defaultSign;
8986
- autofocus = false;
8987
- mobile;
8988
- degreesSymbolUnit = '°';
8989
- minutesSymbolUnit = "'";
8990
- secondsSymbolUnit = '"';
8991
- clearable = false;
8992
- classList;
8993
- set tabindex(value) {
8994
- if (this._tabindex !== value) {
8995
- this._tabindex = value;
8996
- setTimeout(() => this.updateTabIndex());
8997
- }
8998
- }
8999
- get tabindex() {
9000
- return this._tabindex;
9001
- }
9002
- set appearance(value) {
9003
- this._appearance = value;
9004
- }
9005
- get appearance() {
9006
- return this._appearance || this._defaultAppearance;
9007
- }
9008
- set readonly(value) {
9009
- this._readonly = value;
9010
- this.markForCheck();
9011
- }
9012
- get readonly() {
9013
- return this._readonly;
9014
- }
9015
- set subscriptSizing(value) {
9016
- this._subscriptSizing = value;
9017
- }
9018
- get subscriptSizing() {
9019
- return this._subscriptSizing || this._defaultSubscriptSizing;
9020
- }
9021
- get showFields() {
9022
- return isNotNilOrNaN(this.formControl.value) || this._focused;
9023
- }
9024
- get disabled() {
9025
- return this.readonly || this.formControl.disabled;
9026
- }
9027
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix,@angular-eslint/no-output-rename
9028
- keyupEnter = new EventEmitter();
9029
- // eslint-disable-next-line @angular-eslint/no-output-rename
9030
- blurred = new EventEmitter();
9031
- // eslint-disable-next-line @angular-eslint/no-output-rename
9032
- focused = new EventEmitter();
9033
- formField;
9034
- fakeInput;
9035
- inputDegrees;
9036
- inputMinutes;
9037
- inputSeconds;
9038
- inputSign;
9039
- inputSignSelect;
9040
- constructor(cd, formGroupDir, defaultOptions) {
9041
- this.cd = cd;
9042
- this.formGroupDir = formGroupDir;
9043
- this._defaultSubscriptSizing = defaultOptions?.subscriptSizing || MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING;
9044
- this._defaultAppearance = defaultOptions?.appearance || MAT_FORM_FIELD_DEFAULT_APPEARANCE;
9045
- }
9046
- ngOnInit() {
9047
- this.mobile = this.mobile ?? isMobile(window);
9048
- this.type = this.type || 'latitude';
9049
- this.pattern = this.pattern || 'DDMM';
9050
- this.showSignControl = this.pattern !== 'DD';
9051
- switch (this.pattern) {
9052
- case 'DD':
9053
- this.patternMaxDecimals = 7;
9054
- this.degreesPlaceholder =
9055
- this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD_PLACEHOLDER' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD_PLACEHOLDER';
9056
- this.degreesMask = maskitoNumberOptionsGenerator({
9057
- precision: this.patternMaxDecimals,
9058
- min: this.type === 'latitude' ? -90 : -180,
9059
- max: this.type === 'latitude' ? 90 : 180,
9060
- minusSign: '-',
9061
- });
9062
- break;
9063
- case 'DDMM':
9064
- this.patternMaxDecimals = 3;
9065
- this.showMinutes = true;
9066
- this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
9067
- this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
9068
- this.degreesMask = maskitoNumberOptionsGenerator({
9069
- precision: 0,
9070
- min: 0,
9071
- max: this.type === 'latitude' ? 90 : 180,
9072
- });
9073
- this.minutesMask = maskitoNumberOptionsGenerator({
9074
- precision: this.patternMaxDecimals,
9075
- min: 0,
9076
- max: 60 - this.computeDecimalPart(1, this.patternMaxDecimals),
9077
- });
9078
- break;
9079
- default: // Default is DDMMSS
9080
- this.patternMaxDecimals = 2;
9081
- this.showMinutes = true;
9082
- this.showSeconds = true;
9083
- this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
9084
- this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
9085
- this.secondsPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.SS_SS';
9086
- this.degreesMask = maskitoNumberOptionsGenerator({
9087
- precision: 0,
9088
- min: 0,
9089
- max: this.type === 'latitude' ? 90 : 180,
9090
- });
9091
- this.minutesMask = maskitoNumberOptionsGenerator({
9092
- precision: 0,
9093
- min: 0,
9094
- max: 59,
9095
- });
9096
- this.secondsMask = maskitoNumberOptionsGenerator({
9097
- precision: this.patternMaxDecimals,
9098
- min: 0,
9099
- max: 60 - this.computeDecimalPart(1, this.patternMaxDecimals),
9100
- });
9101
- break;
9102
- }
9103
- this.formControl =
9104
- this.formControl || (this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName));
9105
- if (!this.formControl)
9106
- throw new Error("Missing mandatory attribute 'formControl' or 'formControlName' in <mat-latlong-field>.");
9107
- this.degreesControl = new FormControl(null);
9108
- this.minutesControl = new FormControl(null);
9109
- this.secondsControl = new FormControl(null);
9110
- this.signControl = new FormControl(null);
9111
- this._subscription.add(merge(this.degreesControl.valueChanges, this.minutesControl.valueChanges, this.secondsControl.valueChanges, this.signControl.valueChanges).subscribe(() => this.onFormChange()));
9112
- // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
9113
- this._subscription.add(this.formControl.statusChanges
9114
- .pipe(filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
9115
- )
9116
- .subscribe(() => this.markForCheck()));
9117
- }
9118
- ngOnDestroy() {
9119
- this._subscription.unsubscribe();
9120
- }
9121
- registerOnChange(fn) {
9122
- this._onChangeCallback = fn;
9123
- }
9124
- registerOnTouched(fn) {
9125
- this._onTouchedCallback = fn;
9126
- }
9127
- writeValue(value) {
9128
- if (this._writing)
9129
- return;
9130
- this._writing = true;
9131
- if (value !== this.formControl.value) {
9132
- this.formControl.patchValue(value, { emitEvent: false });
9133
- this._onChangeCallback(value);
9134
- }
9135
- const result = this.computeLatLongFormGroupValue(value);
9136
- // DEBUG
9137
- // console.debug('[mat-latlong-field] Changing value of inputs:', value, result);
9138
- this.patchValue(result, { emitEvent: false });
9139
- this._writing = false;
9140
- this.markForCheck();
9141
- setTimeout(() => {
9142
- this.updateFakeInput();
9143
- this.updateTabIndex();
9144
- });
9145
- }
9146
- setDisabledState(isDisabled) {
9147
- if (this._disabling)
9148
- return;
9149
- this._disabling = true;
9150
- if (isDisabled) {
9151
- this.degreesControl.disable();
9152
- this.minutesControl.disable();
9153
- this.secondsControl.disable();
9154
- this.signControl.disable();
9155
- }
9156
- else {
9157
- this.degreesControl.enable();
9158
- this.minutesControl.enable();
9159
- this.secondsControl.enable();
9160
- this.signControl.enable();
9161
- }
9162
- this._disabling = false;
9163
- this.markForCheck();
9164
- }
9165
- clearValue(event) {
9166
- event?.stopPropagation();
9167
- this.writeValue(null);
9168
- }
9169
- get internalElements() {
9170
- return (this.inputDegrees ? [this.inputDegrees.nativeElement] : [])
9171
- .concat(this.inputMinutes ? [this.inputMinutes.nativeElement] : [])
9172
- .concat(this.inputSeconds ? [this.inputSeconds.nativeElement] : [])
9173
- .concat(this.inputSign ? [this.inputSign.nativeElement] : [])
9174
- .concat(this.fakeInput ? [this.fakeInput.nativeElement] : []);
9175
- }
9176
- onFocusFakeInput(event) {
9177
- if (!this.showFields) {
9178
- event.preventDefault();
9179
- // Hide the fake input
9180
- this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
9181
- }
9182
- this._touched = this.formControl.touched;
9183
- // Focus on first input
9184
- this.focus();
9185
- }
9186
- onBlurFakeInput(event) {
9187
- const internalEvent = this.internalElements.some((el) => el === event.relatedTarget);
9188
- if (internalEvent && !this._touched) {
9189
- // Workaround to remove touched on the fakeInput
9190
- this.formControl.markAsUntouched();
9191
- }
9192
- }
9193
- _onFocusInput(event) {
9194
- const internalEvent = this.internalElements.some((el) => el === event.target);
9195
- if (internalEvent) {
9196
- if (event.target === this.inputSign?.nativeElement) {
9197
- this.inputSignSelect?.open();
9198
- }
9199
- else {
9200
- selectInputContent(event.target);
9201
- }
9202
- }
9203
- this.focus(event.target);
9204
- }
9205
- _onBlurInput(event) {
9206
- const internalEvent = this.internalElements.some((el) => el === event.relatedTarget);
9207
- if (!internalEvent) {
9208
- this._focused = false;
9209
- if (this.appearance == 'fill') {
9210
- this.formField._lineRipple.deactivate();
9211
- }
9212
- this.blurred.emit(event);
9213
- this.updateFakeInput();
9214
- this.updateTabIndex();
9215
- this._touched = true;
9216
- this.formControl.markAsTouched();
9217
- this._checkIfTouched();
9218
- }
9219
- }
9220
- _onClickInput(event) {
9221
- const internalEvent = this.internalElements.some((el) => el === event.target);
9222
- if (internalEvent) {
9223
- selectInputContent(event.target);
9224
- }
9225
- // Avoid mat-form-field to give focus to fake input
9226
- event.stopPropagation();
9227
- }
9228
- focus(target) {
9229
- if (this._focused)
9230
- return true; // Already focused
9231
- const showFields = this.showFields;
9232
- this._focused = true;
9233
- this.markForCheck();
9234
- setTimeout(() => {
9235
- if (!this._focused)
9236
- return; // Focus was lost: skip
9237
- if (!showFields) {
9238
- this.inputDegrees.nativeElement.focus();
9239
- selectInputContent(this.inputDegrees.nativeElement);
9240
- }
9241
- else if (target) {
9242
- target.focus();
9243
- selectInputContent(target);
9244
- }
9245
- if (this.appearance == 'fill') {
9246
- this.formField._lineRipple.activate();
9247
- }
9248
- this.updateFakeInput();
9249
- this.updateTabIndex();
9250
- }, 50);
9251
- }
9252
- format(rawValue) {
9253
- const values = this.computeLatLongFormGroupValue(rawValue);
9254
- if (values.degrees === null)
9255
- return '';
9256
- let result = `${values.degrees}° `;
9257
- if (values.minutes !== null)
9258
- result += `${values.minutes}' `;
9259
- if (values.seconds !== null)
9260
- result += `${values.seconds}" `;
9261
- if (this.type === 'latitude') {
9262
- result += values.sign === 1 ? 'N' : 'S';
9263
- }
9264
- else {
9265
- result += values.sign === 1 ? 'E' : 'W';
9266
- }
9267
- return result;
9268
- }
9269
- computeDecimalPart(value, nbOfDecimals) {
9270
- return value * 10 ** (nbOfDecimals * -1);
9271
- }
9272
- computeLatLongFormGroupValue(rawValue) {
9273
- const isLongitude = this.type === 'longitude';
9274
- const value = typeof rawValue === 'string' ? parseFloat(rawValue.replace(/,/g, '.')) : rawValue;
9275
- const result = {
9276
- degrees: null,
9277
- minutes: null,
9278
- seconds: null,
9279
- sign: isNotNil(value)
9280
- ? value < 0
9281
- ? -1
9282
- : 1
9283
- : // Use default sign, if any
9284
- this.defaultSign && this.defaultSign === '-'
9285
- ? -1
9286
- : 1,
9287
- };
9288
- if (value === 0) {
9289
- result.degrees = 0;
9290
- }
9291
- else if (isNotNil(value)) {
9292
- if (this.pattern === 'DD') {
9293
- const splitValue = splitNumberToFieldsDD(value, {
9294
- longitude: isLongitude,
9295
- pattern: this.pattern,
9296
- maxDecimals: this.patternMaxDecimals,
9297
- fixLatLong: true,
9298
- }).slice(1); // remove sign;
9299
- result.degrees = (splitValue[0] + this.computeDecimalPart(splitValue[1] ?? 0, this.patternMaxDecimals)) * (result.sign || 1) || null;
9300
- }
9301
- else if (this.pattern === 'DDMM') {
9302
- const splitValue = splitNumberToFieldsDDMM(value, {
9303
- longitude: isLongitude,
9304
- pattern: this.pattern,
9305
- maxDecimals: this.patternMaxDecimals,
9306
- fixLatLong: true,
9307
- });
9308
- result['minutes'] = Math.abs((splitValue[1] ?? 0) + this.computeDecimalPart(splitValue[2] ?? 0, this.patternMaxDecimals)) || null;
9309
- result['degrees'] = Math.abs(!result['minutes'] && isNilOrBlank(splitValue[0]) ? null : (splitValue[0] ?? 0));
9310
- }
9311
- else {
9312
- // Default // DDMMSS
9313
- const splitValue = splitNumberToFieldsDDMMSS(value, {
9314
- longitude: isLongitude,
9315
- pattern: this.pattern,
9316
- maxDecimals: this.patternMaxDecimals,
9317
- fixLatLong: true,
9318
- });
9319
- result['seconds'] = Math.abs((splitValue[2] ?? 0) + this.computeDecimalPart(splitValue[3] ?? 0, this.patternMaxDecimals)) || null;
9320
- result['minutes'] = !result['seconds'] && !splitValue[1] ? null : Math.abs(splitValue[1] ?? 0);
9321
- result['degrees'] = !result['seconds'] && !result['minutes'] && isNilOrBlank(splitValue[0]) ? null : Math.abs(splitValue[0] ?? 0);
9322
- }
9323
- }
9324
- return result;
9325
- }
9326
- markAsTouched() {
9327
- this.formControl.markAsTouched();
9328
- this.degreesControl.markAsTouched();
9329
- this.minutesControl.markAsTouched();
9330
- this.secondsControl.markAsTouched();
9331
- this.signControl.markAsTouched();
9332
- this._onTouchedCallback();
9333
- }
9334
- /* -- private method -- */
9335
- patchValue(values, opts) {
9336
- this.degreesControl.patchValue(values.degrees?.toString(), opts);
9337
- this.minutesControl.patchValue(values.minutes?.toString(), opts);
9338
- this.secondsControl.patchValue(values.seconds?.toString(), opts);
9339
- this.signControl.patchValue(values.sign, opts);
9340
- }
9341
- onFormChange() {
9342
- if (this._writing)
9343
- return; // Skip if call by self
9344
- this._writing = true;
9345
- const degrees = isNotNilOrBlank(this.degreesControl.value) ? parseFloat(this.degreesControl.value) : undefined;
9346
- const minutes = isNotNilOrBlank(this.minutesControl.value) ? parseFloat(this.minutesControl.value) : undefined;
9347
- const seconds = isNotNilOrBlank(this.secondsControl.value) ? parseFloat(this.secondsControl.value) : undefined;
9348
- const sign = this.signControl.value;
9349
- const incompleteValue = isNil(degrees) && (isNotNil(minutes) || isNotNil(seconds));
9350
- const invalid = incompleteValue || this.degreesControl.invalid || this.minutesControl.invalid || this.secondsControl.invalid || this.signControl.invalid;
9351
- if (invalid) {
9352
- this.formControl.markAsPending({ onlySelf: true });
9353
- this.formControl.setErrors({
9354
- invalid: incompleteValue,
9355
- ...this.degreesControl.errors,
9356
- ...this.minutesControl.errors,
9357
- ...this.secondsControl.errors,
9358
- ...this.signControl.errors,
9359
- });
9360
- if (this.degreesControl.dirty || this.minutesControl.dirty || this.secondsControl.dirty || this.signControl.dirty) {
9361
- this.formControl.markAsDirty();
9362
- }
9363
- this._writing = false;
9364
- return;
9365
- }
9366
- // Compute decimal values
9367
- const value = isNil(degrees) || this.pattern === 'DD' ? degrees : computeDecimalDegrees(degrees, minutes, seconds, sign, this.maxDecimals);
9368
- // Set model value
9369
- this.emitChange(value);
9370
- this._writing = false;
9371
- this.markForCheck();
9372
- }
9373
- emitChange(value) {
9374
- if (this.formControl.value !== value) {
9375
- this.formControl.setValue(value, { emitEvent: false });
9376
- // Changes comes from inside function: use the callback
9377
- this._onChangeCallback(value);
9378
- // Check if need to update controls
9379
- this._checkIfTouched();
9380
- }
9381
- }
9382
- _checkIfTouched() {
9383
- if (this.formControl.touched) {
9384
- this._onTouchedCallback();
9385
- this.markForCheck();
9386
- this._touched = true;
9387
- }
9388
- else {
9389
- this._touched = false;
9390
- }
9391
- }
9392
- markForCheck() {
9393
- this.cd.markForCheck();
9394
- }
9395
- /**
9396
- * Show/Hide the fake input
9397
- */
9398
- updateFakeInput() {
9399
- if (this.showFields) {
9400
- this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
9401
- }
9402
- else {
9403
- this.fakeInput?.nativeElement.classList.remove('cdk-visually-hidden');
9404
- }
9405
- // TODO: check if need
9406
- this.markForCheck();
9407
- }
9408
- /**
9409
- * This is a special case, because, this component has a temporary component displayed before the first focus event
9410
- */
9411
- updateTabIndex() {
9412
- if (isNil(this._tabindex))
9413
- return;
9414
- if (this.fakeInput) {
9415
- this.fakeInput.nativeElement.tabIndex = this._tabindex;
9416
- }
9417
- this.markForCheck();
9418
- }
9419
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$3.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
9420
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField, selector: "mat-latlong-field", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], maxDecimals: "maxDecimals", required: "required", floatLabel: "floatLabel", placeholder: "placeholder", defaultSign: "defaultSign", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", clearable: ["clearable", "clearable", booleanAttribute], classList: ["class", "classList"], tabindex: ["tabindex", "tabindex", numberAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, outputs: { keyupEnter: "keyup.enter", blurred: "blur", focused: "focus" }, providers: [
9421
- {
9422
- provide: NG_VALUE_ACCESSOR,
9423
- multi: true,
9424
- useExisting: forwardRef(() => MatLatLongField),
9425
- },
9426
- ], viewQueries: [{ propertyName: "formField", first: true, predicate: ["formField"], descendants: true }, { propertyName: "fakeInput", first: true, predicate: ["fakeInput"], descendants: true }, { propertyName: "inputDegrees", first: true, predicate: ["inputDegrees"], descendants: true }, { propertyName: "inputMinutes", first: true, predicate: ["inputMinutes"], descendants: true }, { propertyName: "inputSeconds", first: true, predicate: ["inputSeconds"], descendants: true }, { propertyName: "inputSign", first: true, predicate: ["inputSign"], descendants: true, read: ElementRef }, { propertyName: "inputSignSelect", first: true, predicate: ["inputSign"], descendants: true, read: MatSelect }], ngImport: i0, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: patternMaxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <mat-form-field\n #formField\n [floatLabel]=\"showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [class.degrees]=\"pattern !== 'DD'\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [maskito]=\"degreesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"minutesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n class=\"seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"secondsMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span [class.cdk-visually-hidden]=\"!showFields\" class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSignControl) {\n <span class=\"flex-spacer\"></span>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n [tabindex]=\"tabindex\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n class=\"sign\"\n >\n <mat-option [value]=\"1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0;--mdc-filled-text-field-input-text-placeholder-color: var(--mdc-filled-text-field-input-text-placeholder-color, var(--app-form-field-label-color));--mdc-outlined-text-field-input-text-placeholder-color: var(--mdc-outlined-text-field-input-text-placeholder-color, var(--app-form-field-label-color))}input{text-align:right}input::placeholder{letter-spacing:-.05em}input.degrees{width:2em}input.minutes{width:1.7em}input.minutes-seconds{width:3.55em}input.seconds{width:3em}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mat-latlong-field-latitude input.degrees{width:1.3em!important}.symbol-unit{max-height:24px;display:inline-block;text-align:center;font-weight:700;font-size:1.3em}.mat-form-field-appearance-fill .symbol-unit{color:var(--mdc-filled-text-field-input-text-placeholder-color)!important}.mat-form-field-appearance-outline .symbol-unit{color:var(--mdc-outlined-text-field-input-text-placeholder-color)!important}\n"], dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i11.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "pipe", type: LatLongFormatPipe, name: "latLongFormat" }, { kind: "pipe", type: ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: MapGetPipe, name: "mapGet" }, { kind: "pipe", type: MapKeysPipe, name: "mapKeys" }, { kind: "pipe", type: IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: IsNilPipe, name: "isNil" }, { kind: "pipe", type: AsFloatLabelTypePipe, name: "asFloatLabelType" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9427
- }
9428
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, decorators: [{
9429
- type: Component,
9430
- args: [{ selector: 'mat-latlong-field', providers: [
9431
- {
9432
- provide: NG_VALUE_ACCESSOR,
9433
- multi: true,
9434
- useExisting: forwardRef(() => MatLatLongField),
9435
- },
9436
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: patternMaxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <mat-form-field\n #formField\n [floatLabel]=\"showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [class.degrees]=\"pattern !== 'DD'\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [maskito]=\"degreesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"minutesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n class=\"seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"secondsMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span [class.cdk-visually-hidden]=\"!showFields\" class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSignControl) {\n <span class=\"flex-spacer\"></span>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n [tabindex]=\"tabindex\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n class=\"sign\"\n >\n <mat-option [value]=\"1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0;--mdc-filled-text-field-input-text-placeholder-color: var(--mdc-filled-text-field-input-text-placeholder-color, var(--app-form-field-label-color));--mdc-outlined-text-field-input-text-placeholder-color: var(--mdc-outlined-text-field-input-text-placeholder-color, var(--app-form-field-label-color))}input{text-align:right}input::placeholder{letter-spacing:-.05em}input.degrees{width:2em}input.minutes{width:1.7em}input.minutes-seconds{width:3.55em}input.seconds{width:3em}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mat-latlong-field-latitude input.degrees{width:1.3em!important}.symbol-unit{max-height:24px;display:inline-block;text-align:center;font-weight:700;font-size:1.3em}.mat-form-field-appearance-fill .symbol-unit{color:var(--mdc-filled-text-field-input-text-placeholder-color)!important}.mat-form-field-appearance-outline .symbol-unit{color:var(--mdc-outlined-text-field-input-text-placeholder-color)!important}\n"] }]
9437
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$3.FormGroupDirective, decorators: [{
9438
- type: Optional
9439
- }] }, { type: undefined, decorators: [{
9440
- type: Inject,
9441
- args: [MAT_FORM_FIELD_DEFAULT_OPTIONS]
9442
- }] }], propDecorators: { formControl: [{
9443
- type: Input
9444
- }], formControlName: [{
9445
- type: Input
9446
- }], type: [{
9447
- type: Input
9448
- }], pattern: [{
9449
- type: Input,
9450
- args: ['latLongPattern']
9451
- }], maxDecimals: [{
9452
- type: Input
9453
- }], required: [{
9454
- type: Input
9455
- }], floatLabel: [{
9456
- type: Input
9457
- }], placeholder: [{
9458
- type: Input
9459
- }], defaultSign: [{
9460
- type: Input
9461
- }], autofocus: [{
9462
- type: Input
9463
- }], mobile: [{
9464
- type: Input,
9465
- args: [{ transform: booleanAttribute }]
9466
- }], degreesSymbolUnit: [{
9467
- type: Input
9468
- }], minutesSymbolUnit: [{
9469
- type: Input
9470
- }], secondsSymbolUnit: [{
9471
- type: Input
9472
- }], clearable: [{
9473
- type: Input,
9474
- args: [{ transform: booleanAttribute }]
9475
- }], classList: [{
9476
- type: Input,
9477
- args: ['class']
9478
- }], tabindex: [{
9479
- type: Input,
9480
- args: [{ transform: numberAttribute }]
9481
- }], appearance: [{
9482
- type: Input
9483
- }], readonly: [{
9484
- type: Input
9485
- }], subscriptSizing: [{
9486
- type: Input
9487
- }], keyupEnter: [{
9488
- type: Output,
9489
- args: ['keyup.enter']
9490
- }], blurred: [{
9491
- type: Output,
9492
- args: ['blur']
9493
- }], focused: [{
9494
- type: Output,
9495
- args: ['focus']
9496
- }], formField: [{
9497
- type: ViewChild,
9498
- args: ['formField']
9499
- }], fakeInput: [{
9500
- type: ViewChild,
9501
- args: ['fakeInput']
9502
- }], inputDegrees: [{
9503
- type: ViewChild,
9504
- args: ['inputDegrees']
9505
- }], inputMinutes: [{
9506
- type: ViewChild,
9507
- args: ['inputMinutes']
9508
- }], inputSeconds: [{
9509
- type: ViewChild,
9510
- args: ['inputSeconds']
9511
- }], inputSign: [{
9512
- type: ViewChild,
9513
- args: ['inputSign', { read: ElementRef }]
9514
- }], inputSignSelect: [{
9515
- type: ViewChild,
9516
- args: ['inputSign', { read: MatSelect }]
9517
- }] } });
9518
-
9519
- class SharedMatLatLongModule {
9520
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
9521
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, declarations: [MatLatLongField], imports: [CommonModule,
9522
- IonicModule,
9523
- ReactiveFormsModule,
9524
- SharedDirectivesModule,
9525
- SharedPipesModule,
9526
- MatCommonModule,
9527
- MatFormFieldModule,
9528
- MatInputModule,
9529
- MatButtonModule,
9530
- MaskitoDirective,
9531
- MatIconModule,
9532
- MatSelectModule, i1$1.TranslateModule], exports: [MatLatLongField] });
9533
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, imports: [CommonModule,
9534
- IonicModule,
9535
- ReactiveFormsModule,
9536
- SharedDirectivesModule,
9537
- SharedPipesModule,
9538
- MatCommonModule,
9539
- MatFormFieldModule,
9540
- MatInputModule,
9541
- MatButtonModule,
9542
- MatIconModule,
9543
- MatSelectModule,
9544
- TranslateModule.forChild()] });
9545
- }
9546
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, decorators: [{
9547
- type: NgModule,
9548
- args: [{
9549
- imports: [
9550
- CommonModule,
9551
- IonicModule,
9552
- ReactiveFormsModule,
9553
- SharedDirectivesModule,
9554
- SharedPipesModule,
9555
- MatCommonModule,
9556
- MatFormFieldModule,
9557
- MatInputModule,
9558
- MatButtonModule,
9559
- MaskitoDirective,
9560
- MatIconModule,
9561
- MatSelectModule,
9562
- TranslateModule.forChild(),
9563
- ],
9564
- exports: [MatLatLongField],
9565
- declarations: [MatLatLongField],
9566
- }]
9567
- }] });
9568
-
9569
8951
  const DEFAULT_VALUE_ACCESSOR$3 = {
9570
8952
  provide: NG_VALUE_ACCESSOR,
9571
8953
  useExisting: forwardRef(() => MatDate),
@@ -11144,8 +10526,8 @@ const DEFAULT_VALUE_ACCESSOR = {
11144
10526
  class MatSwipeField {
11145
10527
  cd;
11146
10528
  formGroupDir;
11147
- _onChangeCallback = noop$a;
11148
- _onTouchedCallback = noop$a;
10529
+ _onChangeCallback = noop$9;
10530
+ _onTouchedCallback = noop$9;
11149
10531
  _value;
11150
10532
  _subscription = new Subscription();
11151
10533
  _itemsSubscription;
@@ -13889,6 +13271,690 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
13889
13271
  }]
13890
13272
  }] });
13891
13273
 
13274
+ class MatLatLongFieldInput {
13275
+ _elementRef;
13276
+ _formField;
13277
+ ngControl;
13278
+ static nextId = 0;
13279
+ degreesInput;
13280
+ minutesInput;
13281
+ secondsInput;
13282
+ signInput;
13283
+ parts = inject(FormBuilder).group({
13284
+ degrees: ['', [Validators.required]],
13285
+ minutes: [''],
13286
+ seconds: [''],
13287
+ sign: [null, [Validators.required]],
13288
+ });
13289
+ stateChanges = new Subject();
13290
+ focused = false;
13291
+ touched = false;
13292
+ controlType = 'mat-latlong-input';
13293
+ id = `mat-latlong-input-${MatLatLongFieldInput.nextId++}`;
13294
+ onChange = (_) => { };
13295
+ onTouched = () => { };
13296
+ get empty() {
13297
+ const { value: { degrees, minutes, seconds }, } = this.parts;
13298
+ return !degrees && !minutes && !seconds;
13299
+ }
13300
+ get shouldLabelFloat() {
13301
+ return this.focused || !this.empty;
13302
+ }
13303
+ userAriaDescribedBy;
13304
+ placeholder; // Not used
13305
+ get required() {
13306
+ return this._required;
13307
+ }
13308
+ set required(value) {
13309
+ this._required = coerceBooleanProperty(value);
13310
+ this.stateChanges.next();
13311
+ }
13312
+ _required = false;
13313
+ get disabled() {
13314
+ return this._disabled;
13315
+ }
13316
+ set disabled(value) {
13317
+ this._disabled = coerceBooleanProperty(value);
13318
+ if (this._disabled) {
13319
+ this.parts.disable();
13320
+ }
13321
+ else {
13322
+ this.parts.enable();
13323
+ }
13324
+ this.stateChanges.next();
13325
+ }
13326
+ _disabled = false;
13327
+ get value() {
13328
+ if (this.parts.valid) {
13329
+ const degrees = parseFloat(this.parts.value.degrees);
13330
+ const minutes = parseFloat(this.parts.value.minutes);
13331
+ const seconds = parseFloat(this.parts.value.seconds);
13332
+ const sign = this.parts.value.sign;
13333
+ return this.parts.valid
13334
+ ? isNil(degrees) || this.pattern === 'DD'
13335
+ ? degrees
13336
+ : computeDecimalDegrees(degrees, minutes, seconds, sign, this.maxDecimals)
13337
+ : null;
13338
+ }
13339
+ return null;
13340
+ }
13341
+ set value(value) {
13342
+ const result = this.computeLatLongFormGroupValue(value);
13343
+ console.debug(`${this.logPrefix} Setting value`, value, result);
13344
+ this.parts.setValue({
13345
+ degrees: result.degrees?.toString() || null,
13346
+ minutes: result.minutes?.toString() || null,
13347
+ seconds: result.seconds?.toString() || null,
13348
+ sign: result.sign,
13349
+ });
13350
+ this.stateChanges.next();
13351
+ }
13352
+ get errorState() {
13353
+ return this.parts.invalid && this.touched;
13354
+ }
13355
+ type;
13356
+ pattern;
13357
+ degreesSymbolUnit;
13358
+ minutesSymbolUnit;
13359
+ secondsSymbolUnit;
13360
+ defaultSign;
13361
+ maxDecimals;
13362
+ showMinutes;
13363
+ showSeconds;
13364
+ showSign;
13365
+ degreesMask;
13366
+ minutesMask;
13367
+ secondsMask;
13368
+ degreesPlaceholder;
13369
+ minutesPlaceholder;
13370
+ secondsPlaceholder;
13371
+ lastInputMaxDecimals;
13372
+ logPrefix = '[mat-latlong-input]';
13373
+ constructor(_elementRef, _formField, ngControl) {
13374
+ this._elementRef = _elementRef;
13375
+ this._formField = _formField;
13376
+ this.ngControl = ngControl;
13377
+ if (this.ngControl != null) {
13378
+ this.ngControl.valueAccessor = this;
13379
+ }
13380
+ }
13381
+ ngOnInit() {
13382
+ if (this.showMinutes) {
13383
+ this.parts.controls.minutes.addValidators(Validators.required);
13384
+ }
13385
+ if (this.showSeconds) {
13386
+ this.parts.controls.seconds.addValidators(Validators.required);
13387
+ }
13388
+ }
13389
+ ngOnDestroy() {
13390
+ this.stateChanges.complete();
13391
+ }
13392
+ onFocusIn(event) {
13393
+ if (!this.focused) {
13394
+ this.focused = true;
13395
+ this.stateChanges.next();
13396
+ }
13397
+ }
13398
+ onFocusOut(event) {
13399
+ if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
13400
+ this.touched = true;
13401
+ this.focused = false;
13402
+ this.onTouched();
13403
+ this.stateChanges.next();
13404
+ }
13405
+ }
13406
+ handleInput(controlName, nextControlName) {
13407
+ // Can autofocus next control ?
13408
+ let focusNext = false;
13409
+ switch (controlName) {
13410
+ case 'degrees': {
13411
+ const degrees = parseFloat(this.parts.value.degrees);
13412
+ if (this.type === 'latitude' && (degrees === 0 || degrees > 9)) {
13413
+ focusNext = true;
13414
+ }
13415
+ else if (this.type === 'longitude' && (degrees === 0 || degrees > 18)) {
13416
+ focusNext = true;
13417
+ }
13418
+ break;
13419
+ }
13420
+ case 'minutes': {
13421
+ const minutes = parseFloat(this.parts.value.minutes);
13422
+ if (minutes === 0 || minutes > 6) {
13423
+ focusNext = true;
13424
+ }
13425
+ break;
13426
+ }
13427
+ case 'seconds': {
13428
+ // focusNext = true;
13429
+ break;
13430
+ }
13431
+ }
13432
+ if (focusNext) {
13433
+ this.autoFocusNext(controlName, nextControlName);
13434
+ }
13435
+ this.onChange(this.value);
13436
+ }
13437
+ autoFocusNext(controlName, nextControlName) {
13438
+ if (!this.parts.controls[controlName].errors && nextControlName) {
13439
+ this.getElementByName(nextControlName).focus();
13440
+ }
13441
+ }
13442
+ autoFocusPrev(controlName, prevControlName) {
13443
+ if (isNilOrBlank(this.parts.controls[controlName].value)) {
13444
+ this.getElementByName(prevControlName).focus();
13445
+ }
13446
+ }
13447
+ getElementByName(name) {
13448
+ switch (name) {
13449
+ case 'degrees':
13450
+ return this.degreesInput.nativeElement;
13451
+ case 'minutes':
13452
+ return this.minutesInput.nativeElement;
13453
+ case 'seconds':
13454
+ return this.secondsInput.nativeElement;
13455
+ case 'sign':
13456
+ return this.signInput.nativeElement;
13457
+ default:
13458
+ throw new Error(`${this.logPrefix} No HTMLElement with name '${name}'`);
13459
+ }
13460
+ }
13461
+ setDescribedByIds(ids) {
13462
+ const controlElement = this._elementRef.nativeElement.querySelector('.mat-latlong-input-container');
13463
+ controlElement.setAttribute('aria-describedby', ids.join(' '));
13464
+ }
13465
+ onContainerClick() {
13466
+ console.debug(`${this.logPrefix} DEBUG onContainerClick`);
13467
+ if (this.empty) {
13468
+ this.degreesInput.nativeElement.focus();
13469
+ }
13470
+ else if (isNilOrBlank(this.parts.value.minutes)) {
13471
+ this.minutesInput.nativeElement.focus();
13472
+ }
13473
+ else if (isNilOrBlank(this.parts.value.seconds)) {
13474
+ this.secondsInput.nativeElement.focus();
13475
+ }
13476
+ else if (isNil(this.parts.value.sign)) {
13477
+ this.signInput.nativeElement.focus();
13478
+ }
13479
+ }
13480
+ writeValue(value) {
13481
+ this.value = value;
13482
+ }
13483
+ registerOnChange(fn) {
13484
+ this.onChange = fn;
13485
+ }
13486
+ registerOnTouched(fn) {
13487
+ this.onTouched = fn;
13488
+ }
13489
+ setDisabledState(isDisabled) {
13490
+ this.disabled = isDisabled;
13491
+ }
13492
+ computeLatLongFormGroupValue(rawValue) {
13493
+ const isLongitude = this.type === 'longitude';
13494
+ const value = typeof rawValue === 'string' ? parseFloat(rawValue.replace(/,/g, '.')) : rawValue;
13495
+ const result = {
13496
+ degrees: null,
13497
+ minutes: null,
13498
+ seconds: null,
13499
+ sign: isNotNil(value)
13500
+ ? value < 0
13501
+ ? -1
13502
+ : 1
13503
+ : // Use default sign, if any
13504
+ this.defaultSign
13505
+ ? this.defaultSign === '-'
13506
+ ? -1
13507
+ : 1
13508
+ : null,
13509
+ };
13510
+ if (value === 0) {
13511
+ result.degrees = 0;
13512
+ }
13513
+ else if (isNotNil(value)) {
13514
+ // Parse options
13515
+ const parseOptions = {
13516
+ longitude: isLongitude,
13517
+ pattern: this.pattern,
13518
+ maxDecimals: this.lastInputMaxDecimals,
13519
+ fixLatLong: true,
13520
+ };
13521
+ if (this.pattern === 'DD') {
13522
+ const splitValue = splitNumberToFieldsDD(value, parseOptions).slice(1); // remove sign;
13523
+ result.seconds = 0;
13524
+ result.minutes = 0;
13525
+ result.degrees = (splitValue[0] + computeDecimalPart(splitValue[1] ?? 0, this.lastInputMaxDecimals)) * (result.sign || 1);
13526
+ }
13527
+ else if (this.pattern === 'DDMM') {
13528
+ const splitValue = splitNumberToFieldsDDMM(value, parseOptions);
13529
+ result.seconds = 0;
13530
+ result.minutes = Math.abs((splitValue[1] ?? 0) + computeDecimalPart(splitValue[2] ?? 0, this.lastInputMaxDecimals));
13531
+ result.degrees = Math.abs(!result.minutes && isNilOrBlank(splitValue[0]) ? 0 : (splitValue[0] ?? 0));
13532
+ }
13533
+ else {
13534
+ // Default // DDMMSS
13535
+ const splitValue = splitNumberToFieldsDDMMSS(value, parseOptions);
13536
+ result.seconds = Math.abs((splitValue[2] ?? 0) + computeDecimalPart(splitValue[3] ?? 0, this.lastInputMaxDecimals));
13537
+ result.minutes = !result.seconds && !splitValue[1] ? 0 : Math.abs(splitValue[1] ?? 0);
13538
+ result.degrees = !result.seconds && !result.minutes && isNilOrBlank(splitValue[0]) ? 0 : Math.abs(splitValue[0] ?? 0);
13539
+ }
13540
+ }
13541
+ return result;
13542
+ }
13543
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongFieldInput, deps: [{ token: i0.ElementRef }, { token: MAT_FORM_FIELD, optional: true }, { token: i1$3.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
13544
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongFieldInput, selector: "mat-latlong-input", inputs: { userAriaDescribedBy: ["aria-describedby", "userAriaDescribedBy"], required: "required", disabled: "disabled", value: "value", type: "type", pattern: ["latLongPattern", "pattern"], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", defaultSign: "defaultSign", maxDecimals: "maxDecimals", showMinutes: "showMinutes", showSeconds: "showSeconds", showSign: "showSign", degreesMask: "degreesMask", minutesMask: "minutesMask", secondsMask: "secondsMask", degreesPlaceholder: "degreesPlaceholder", minutesPlaceholder: "minutesPlaceholder", secondsPlaceholder: "secondsPlaceholder", lastInputMaxDecimals: "lastInputMaxDecimals" }, host: { properties: { "class.label-floating": "shouldLabelFloat", "id": "id" } }, providers: [{ provide: MatFormFieldControl, useExisting: MatLatLongFieldInput }], viewQueries: [{ propertyName: "degreesInput", first: true, predicate: ["degrees"], descendants: true, read: ElementRef }, { propertyName: "minutesInput", first: true, predicate: ["minutes"], descendants: true, read: ElementRef }, { propertyName: "secondsInput", first: true, predicate: ["seconds"], descendants: true, read: ElementRef }, { propertyName: "signInput", first: true, predicate: ["sign"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n role=\"group\"\n class=\"mat-latlong-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n #degrees\n aria-label=\"Degrees\"\n [class.degrees]=\"pattern !== 'DD'\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n formControlName=\"degrees\"\n [maskito]=\"degreesMask\"\n (input)=\"handleInput('degrees', 'minutes')\"\n />\n <span class=\"symbol-unit\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n #minutes\n aria-label=\"Minutes\"\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n formControlName=\"minutes\"\n [maskito]=\"minutesMask\"\n (input)=\"handleInput('minutes', 'seconds')\"\n (keyup.backspace)=\"autoFocusPrev('minutes', 'degrees')\"\n />\n <span class=\"symbol-unit\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n #seconds\n aria-label=\"Seconds\"\n class=\"seconds\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n formControlName=\"seconds\"\n [maskito]=\"secondsMask\"\n (input)=\"handleInput('seconds', 'sign')\"\n (keyup.backspace)=\"autoFocusPrev('seconds', 'minutes')\"\n />\n <span class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSign) {\n <span class=\"sign-spacer\"></span>\n <mat-select\n #sign\n aria-label=\"Sign\"\n class=\"sign\"\n formControlName=\"sign\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n (focusin)=\"sign.open()\"\n (selectionChange)=\"handleInput('sign')\"\n >\n <mat-option [value]=\"1\" (click)=\"sign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"sign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n</div>\n", styles: [".mat-latlong-input-container{display:inline-flex;opacity:0;transition:opacity .2s;pointer-events:none;--mat-select-arrow-transform: translateY(0)}input{border:none;background:none;padding:0;outline:none;font:inherit;text-align:right}input::placeholder{letter-spacing:-.075em;font-size:smaller}input.degrees{width:2em}input.minutes{width:1.5em}input.minutes-seconds{width:3.5em}input.seconds{width:3em}.symbol-unit{font-weight:700}.sign-spacer{width:.25em}.sign{max-width:2.5em;color:inherit}:host.label-floating .mat-latlong-input-container{opacity:1;pointer-events:revert}\n"], dependencies: [{ 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: "directive", type: i11.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13545
+ }
13546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongFieldInput, decorators: [{
13547
+ type: Component,
13548
+ args: [{ selector: 'mat-latlong-input', providers: [{ provide: MatFormFieldControl, useExisting: MatLatLongFieldInput }], host: {
13549
+ '[class.label-floating]': 'shouldLabelFloat',
13550
+ '[id]': 'id',
13551
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n role=\"group\"\n class=\"mat-latlong-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n #degrees\n aria-label=\"Degrees\"\n [class.degrees]=\"pattern !== 'DD'\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n formControlName=\"degrees\"\n [maskito]=\"degreesMask\"\n (input)=\"handleInput('degrees', 'minutes')\"\n />\n <span class=\"symbol-unit\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n #minutes\n aria-label=\"Minutes\"\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n formControlName=\"minutes\"\n [maskito]=\"minutesMask\"\n (input)=\"handleInput('minutes', 'seconds')\"\n (keyup.backspace)=\"autoFocusPrev('minutes', 'degrees')\"\n />\n <span class=\"symbol-unit\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n #seconds\n aria-label=\"Seconds\"\n class=\"seconds\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n formControlName=\"seconds\"\n [maskito]=\"secondsMask\"\n (input)=\"handleInput('seconds', 'sign')\"\n (keyup.backspace)=\"autoFocusPrev('seconds', 'minutes')\"\n />\n <span class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSign) {\n <span class=\"sign-spacer\"></span>\n <mat-select\n #sign\n aria-label=\"Sign\"\n class=\"sign\"\n formControlName=\"sign\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n (focusin)=\"sign.open()\"\n (selectionChange)=\"handleInput('sign')\"\n >\n <mat-option [value]=\"1\" (click)=\"sign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"sign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n</div>\n", styles: [".mat-latlong-input-container{display:inline-flex;opacity:0;transition:opacity .2s;pointer-events:none;--mat-select-arrow-transform: translateY(0)}input{border:none;background:none;padding:0;outline:none;font:inherit;text-align:right}input::placeholder{letter-spacing:-.075em;font-size:smaller}input.degrees{width:2em}input.minutes{width:1.5em}input.minutes-seconds{width:3.5em}input.seconds{width:3em}.symbol-unit{font-weight:700}.sign-spacer{width:.25em}.sign{max-width:2.5em;color:inherit}:host.label-floating .mat-latlong-input-container{opacity:1;pointer-events:revert}\n"] }]
13552
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i6.MatFormField, decorators: [{
13553
+ type: Optional
13554
+ }, {
13555
+ type: Inject,
13556
+ args: [MAT_FORM_FIELD]
13557
+ }] }, { type: i1$3.NgControl, decorators: [{
13558
+ type: Optional
13559
+ }, {
13560
+ type: Self
13561
+ }] }], propDecorators: { degreesInput: [{
13562
+ type: ViewChild,
13563
+ args: ['degrees', { read: ElementRef }]
13564
+ }], minutesInput: [{
13565
+ type: ViewChild,
13566
+ args: ['minutes', { read: ElementRef }]
13567
+ }], secondsInput: [{
13568
+ type: ViewChild,
13569
+ args: ['seconds', { read: ElementRef }]
13570
+ }], signInput: [{
13571
+ type: ViewChild,
13572
+ args: ['sign', { read: ElementRef }]
13573
+ }], userAriaDescribedBy: [{
13574
+ type: Input,
13575
+ args: ['aria-describedby']
13576
+ }], required: [{
13577
+ type: Input
13578
+ }], disabled: [{
13579
+ type: Input
13580
+ }], value: [{
13581
+ type: Input
13582
+ }], type: [{
13583
+ type: Input
13584
+ }], pattern: [{
13585
+ type: Input,
13586
+ args: ['latLongPattern']
13587
+ }], degreesSymbolUnit: [{
13588
+ type: Input
13589
+ }], minutesSymbolUnit: [{
13590
+ type: Input
13591
+ }], secondsSymbolUnit: [{
13592
+ type: Input
13593
+ }], defaultSign: [{
13594
+ type: Input
13595
+ }], maxDecimals: [{
13596
+ type: Input
13597
+ }], showMinutes: [{
13598
+ type: Input
13599
+ }], showSeconds: [{
13600
+ type: Input
13601
+ }], showSign: [{
13602
+ type: Input
13603
+ }], degreesMask: [{
13604
+ type: Input
13605
+ }], minutesMask: [{
13606
+ type: Input
13607
+ }], secondsMask: [{
13608
+ type: Input
13609
+ }], degreesPlaceholder: [{
13610
+ type: Input
13611
+ }], minutesPlaceholder: [{
13612
+ type: Input
13613
+ }], secondsPlaceholder: [{
13614
+ type: Input
13615
+ }], lastInputMaxDecimals: [{
13616
+ type: Input
13617
+ }] } });
13618
+
13619
+ class MatLatLongField {
13620
+ cd;
13621
+ formGroupDir;
13622
+ _subscription = new Subscription();
13623
+ _appearance = null;
13624
+ _subscriptSizing = null;
13625
+ _readonly = false;
13626
+ _tabindex;
13627
+ _defaultAppearance;
13628
+ _defaultSubscriptSizing;
13629
+ showMinutes = false;
13630
+ showSeconds = false;
13631
+ showSign;
13632
+ degreesPlaceholder;
13633
+ minutesPlaceholder;
13634
+ secondsPlaceholder;
13635
+ degreesMask;
13636
+ minutesMask;
13637
+ secondsMask;
13638
+ lastInputMaxDecimals = LAT_LONG_PATTERN_MAX_DECIMALS;
13639
+ i18nErrorKeys = SharedValidators.I18N_ERROR_KEYS;
13640
+ formControl;
13641
+ formControlName;
13642
+ type;
13643
+ pattern;
13644
+ maxDecimals = LAT_LONG_VALUE_MAX_DECIMALS;
13645
+ required = false;
13646
+ floatLabel = 'auto';
13647
+ placeholder;
13648
+ defaultSign;
13649
+ autofocus = false;
13650
+ mobile;
13651
+ degreesSymbolUnit = '°';
13652
+ minutesSymbolUnit = "'";
13653
+ secondsSymbolUnit = '"';
13654
+ clearable = false;
13655
+ classList;
13656
+ set tabindex(value) {
13657
+ if (this._tabindex !== value) {
13658
+ this._tabindex = value;
13659
+ }
13660
+ }
13661
+ get tabindex() {
13662
+ return this._tabindex;
13663
+ }
13664
+ set appearance(value) {
13665
+ this._appearance = value;
13666
+ }
13667
+ get appearance() {
13668
+ return this._appearance || this._defaultAppearance;
13669
+ }
13670
+ set readonly(value) {
13671
+ this._readonly = value;
13672
+ this.markForCheck();
13673
+ }
13674
+ get readonly() {
13675
+ return this._readonly;
13676
+ }
13677
+ set subscriptSizing(value) {
13678
+ this._subscriptSizing = value;
13679
+ }
13680
+ get subscriptSizing() {
13681
+ return this._subscriptSizing || this._defaultSubscriptSizing;
13682
+ }
13683
+ get disabled() {
13684
+ return this.readonly || this.formControl.disabled;
13685
+ }
13686
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix,@angular-eslint/no-output-rename
13687
+ // @Output('keyup.enter') keyupEnter = new EventEmitter<any>();
13688
+ // eslint-disable-next-line @angular-eslint/no-output-rename
13689
+ // @Output('blur') blurred = new EventEmitter<FocusEvent>();
13690
+ // eslint-disable-next-line @angular-eslint/no-output-rename
13691
+ // @Output('focus') focused = new EventEmitter<FocusEvent>();
13692
+ input;
13693
+ pendingValue;
13694
+ pendingValueSet = false;
13695
+ pendingDisabledState;
13696
+ pendingOnChange;
13697
+ pendingOnTouched;
13698
+ constructor(cd, formGroupDir, defaultOptions) {
13699
+ this.cd = cd;
13700
+ this.formGroupDir = formGroupDir;
13701
+ this._defaultSubscriptSizing = defaultOptions?.subscriptSizing || MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING;
13702
+ this._defaultAppearance = defaultOptions?.appearance || MAT_FORM_FIELD_DEFAULT_APPEARANCE;
13703
+ }
13704
+ // Delegate control vale accessor
13705
+ writeValue(value) {
13706
+ if (this.input) {
13707
+ this.input.writeValue(value);
13708
+ }
13709
+ else {
13710
+ this.pendingValue = value;
13711
+ this.pendingValueSet = true;
13712
+ }
13713
+ }
13714
+ registerOnChange(fn) {
13715
+ if (this.input) {
13716
+ this.input.registerOnChange(fn);
13717
+ }
13718
+ else {
13719
+ this.pendingOnChange = fn;
13720
+ }
13721
+ }
13722
+ registerOnTouched(fn) {
13723
+ if (this.input) {
13724
+ this.input.registerOnTouched(fn);
13725
+ }
13726
+ else {
13727
+ this.pendingOnTouched = fn;
13728
+ }
13729
+ }
13730
+ setDisabledState(isDisabled) {
13731
+ if (this.input) {
13732
+ this.input.setDisabledState(isDisabled);
13733
+ }
13734
+ else {
13735
+ this.pendingDisabledState = isDisabled;
13736
+ }
13737
+ }
13738
+ ngOnInit() {
13739
+ this.formControl =
13740
+ this.formControl || (this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName));
13741
+ if (!this.formControl)
13742
+ throw new Error("Missing mandatory attribute 'formControl' or 'formControlName' in <mat-latlong-field>.");
13743
+ this.mobile = this.mobile ?? isMobile(window);
13744
+ this.type = this.type || 'latitude';
13745
+ this.pattern = this.pattern || 'DDMM';
13746
+ this.showSign = this.pattern !== 'DD';
13747
+ switch (this.pattern) {
13748
+ case 'DD':
13749
+ this.lastInputMaxDecimals = 7;
13750
+ this.degreesPlaceholder =
13751
+ this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD_PLACEHOLDER' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD_PLACEHOLDER';
13752
+ this.degreesMask = maskitoNumberOptionsGenerator({
13753
+ precision: this.lastInputMaxDecimals,
13754
+ min: this.type === 'latitude' ? -90 : -180,
13755
+ max: this.type === 'latitude' ? 90 : 180,
13756
+ minusSign: '-',
13757
+ });
13758
+ break;
13759
+ case 'DDMM':
13760
+ this.lastInputMaxDecimals = 3;
13761
+ this.showMinutes = true;
13762
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
13763
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM_MMM';
13764
+ this.degreesMask = maskitoNumberOptionsGenerator({
13765
+ precision: 0,
13766
+ min: 0,
13767
+ max: this.type === 'latitude' ? 90 : 180,
13768
+ });
13769
+ this.minutesMask = maskitoNumberOptionsGenerator({
13770
+ precision: this.lastInputMaxDecimals,
13771
+ min: 0,
13772
+ max: 60 - computeDecimalPart(1, this.lastInputMaxDecimals),
13773
+ });
13774
+ break;
13775
+ default: // Default is DDMMSS
13776
+ this.lastInputMaxDecimals = 2;
13777
+ this.showMinutes = true;
13778
+ this.showSeconds = true;
13779
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
13780
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
13781
+ this.secondsPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.SS_SS';
13782
+ this.degreesMask = maskitoNumberOptionsGenerator({
13783
+ precision: 0,
13784
+ min: 0,
13785
+ max: this.type === 'latitude' ? 90 : 180,
13786
+ });
13787
+ this.minutesMask = maskitoNumberOptionsGenerator({
13788
+ precision: 0,
13789
+ min: 0,
13790
+ max: 59,
13791
+ });
13792
+ this.secondsMask = maskitoNumberOptionsGenerator({
13793
+ precision: this.lastInputMaxDecimals,
13794
+ min: 0,
13795
+ max: 60 - computeDecimalPart(1, this.lastInputMaxDecimals),
13796
+ });
13797
+ break;
13798
+ }
13799
+ // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
13800
+ // this._subscription.add(
13801
+ // this.formControl.statusChanges
13802
+ // .pipe(
13803
+ // filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
13804
+ // )
13805
+ // .subscribe(() => this.markForCheck())
13806
+ // );
13807
+ }
13808
+ ngAfterViewInit() {
13809
+ if (!this.readonly) {
13810
+ if (this.pendingOnChange) {
13811
+ this.input.registerOnChange(this.pendingOnChange);
13812
+ }
13813
+ if (this.pendingOnTouched) {
13814
+ this.input.registerOnTouched(this.pendingOnTouched);
13815
+ }
13816
+ if (isNotNil(this.pendingDisabledState)) {
13817
+ this.input.setDisabledState(this.pendingDisabledState);
13818
+ }
13819
+ if (this.pendingValueSet) {
13820
+ this.input.writeValue(this.pendingValue);
13821
+ }
13822
+ }
13823
+ }
13824
+ ngOnDestroy() {
13825
+ this._subscription.unsubscribe();
13826
+ }
13827
+ clearValue(event) {
13828
+ event?.stopPropagation();
13829
+ this.formControl.setValue(null);
13830
+ }
13831
+ /* -- private method -- */
13832
+ markForCheck() {
13833
+ this.cd.markForCheck();
13834
+ }
13835
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$3.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
13836
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField, selector: "mat-latlong-field", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], maxDecimals: "maxDecimals", required: "required", floatLabel: "floatLabel", placeholder: "placeholder", defaultSign: "defaultSign", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", clearable: ["clearable", "clearable", booleanAttribute], classList: ["class", "classList"], tabindex: ["tabindex", "tabindex", numberAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, providers: [
13837
+ {
13838
+ provide: NG_VALUE_ACCESSOR,
13839
+ multi: true,
13840
+ useExisting: forwardRef(() => MatLatLongField),
13841
+ },
13842
+ ], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: lastInputMaxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <mat-form-field\n #formField\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && formControl.invalid\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <mat-latlong-input\n #input\n [formControl]=\"formControl\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [type]=\"type\"\n [latLongPattern]=\"pattern\"\n [defaultSign]=\"defaultSign\"\n [maxDecimals]=\"maxDecimals\"\n [lastInputMaxDecimals]=\"lastInputMaxDecimals\"\n [showMinutes]=\"showMinutes\"\n [showSeconds]=\"showSeconds\"\n [showSign]=\"showSign\"\n [degreesMask]=\"degreesMask\"\n [minutesMask]=\"minutesMask\"\n [secondsMask]=\"secondsMask\"\n [degreesPlaceholder]=\"degreesPlaceholder\"\n [minutesPlaceholder]=\"minutesPlaceholder\"\n [secondsPlaceholder]=\"secondsPlaceholder\"\n [degreesSymbolUnit]=\"degreesSymbolUnit\"\n [minutesSymbolUnit]=\"minutesSymbolUnit\"\n [secondsSymbolUnit]=\"secondsSymbolUnit\"\n ></mat-latlong-input>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative}.mat-latlong-field-latitude input.degrees{width:1.3em!important}\n"], dependencies: [{ kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatLatLongFieldInput, selector: "mat-latlong-input", inputs: ["aria-describedby", "required", "disabled", "value", "type", "latLongPattern", "degreesSymbolUnit", "minutesSymbolUnit", "secondsSymbolUnit", "defaultSign", "maxDecimals", "showMinutes", "showSeconds", "showSign", "degreesMask", "minutesMask", "secondsMask", "degreesPlaceholder", "minutesPlaceholder", "secondsPlaceholder", "lastInputMaxDecimals"] }, { kind: "pipe", type: LatLongFormatPipe, name: "latLongFormat" }, { kind: "pipe", type: ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: MapGetPipe, name: "mapGet" }, { kind: "pipe", type: MapKeysPipe, name: "mapKeys" }, { kind: "pipe", type: IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: IsNilPipe, name: "isNil" }, { kind: "pipe", type: AsFloatLabelTypePipe, name: "asFloatLabelType" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13843
+ }
13844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, decorators: [{
13845
+ type: Component,
13846
+ args: [{ selector: 'mat-latlong-field', providers: [
13847
+ {
13848
+ provide: NG_VALUE_ACCESSOR,
13849
+ multi: true,
13850
+ useExisting: forwardRef(() => MatLatLongField),
13851
+ },
13852
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: lastInputMaxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <mat-form-field\n #formField\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && formControl.invalid\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <mat-latlong-input\n #input\n [formControl]=\"formControl\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [type]=\"type\"\n [latLongPattern]=\"pattern\"\n [defaultSign]=\"defaultSign\"\n [maxDecimals]=\"maxDecimals\"\n [lastInputMaxDecimals]=\"lastInputMaxDecimals\"\n [showMinutes]=\"showMinutes\"\n [showSeconds]=\"showSeconds\"\n [showSign]=\"showSign\"\n [degreesMask]=\"degreesMask\"\n [minutesMask]=\"minutesMask\"\n [secondsMask]=\"secondsMask\"\n [degreesPlaceholder]=\"degreesPlaceholder\"\n [minutesPlaceholder]=\"minutesPlaceholder\"\n [secondsPlaceholder]=\"secondsPlaceholder\"\n [degreesSymbolUnit]=\"degreesSymbolUnit\"\n [minutesSymbolUnit]=\"minutesSymbolUnit\"\n [secondsSymbolUnit]=\"secondsSymbolUnit\"\n ></mat-latlong-input>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative}.mat-latlong-field-latitude input.degrees{width:1.3em!important}\n"] }]
13853
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$3.FormGroupDirective, decorators: [{
13854
+ type: Optional
13855
+ }] }, { type: undefined, decorators: [{
13856
+ type: Inject,
13857
+ args: [MAT_FORM_FIELD_DEFAULT_OPTIONS]
13858
+ }] }], propDecorators: { formControl: [{
13859
+ type: Input
13860
+ }], formControlName: [{
13861
+ type: Input
13862
+ }], type: [{
13863
+ type: Input
13864
+ }], pattern: [{
13865
+ type: Input,
13866
+ args: ['latLongPattern']
13867
+ }], maxDecimals: [{
13868
+ type: Input
13869
+ }], required: [{
13870
+ type: Input
13871
+ }], floatLabel: [{
13872
+ type: Input
13873
+ }], placeholder: [{
13874
+ type: Input
13875
+ }], defaultSign: [{
13876
+ type: Input
13877
+ }], autofocus: [{
13878
+ type: Input
13879
+ }], mobile: [{
13880
+ type: Input,
13881
+ args: [{ transform: booleanAttribute }]
13882
+ }], degreesSymbolUnit: [{
13883
+ type: Input
13884
+ }], minutesSymbolUnit: [{
13885
+ type: Input
13886
+ }], secondsSymbolUnit: [{
13887
+ type: Input
13888
+ }], clearable: [{
13889
+ type: Input,
13890
+ args: [{ transform: booleanAttribute }]
13891
+ }], classList: [{
13892
+ type: Input,
13893
+ args: ['class']
13894
+ }], tabindex: [{
13895
+ type: Input,
13896
+ args: [{ transform: numberAttribute }]
13897
+ }], appearance: [{
13898
+ type: Input
13899
+ }], readonly: [{
13900
+ type: Input
13901
+ }], subscriptSizing: [{
13902
+ type: Input
13903
+ }], input: [{
13904
+ type: ViewChild,
13905
+ args: ['input']
13906
+ }] } });
13907
+
13908
+ class SharedMatLatLongModule {
13909
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
13910
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, declarations: [MatLatLongField, MatLatLongFieldInput], imports: [CommonModule,
13911
+ IonicModule,
13912
+ ReactiveFormsModule,
13913
+ SharedDirectivesModule,
13914
+ SharedPipesModule,
13915
+ MatCommonModule,
13916
+ MatFormFieldModule,
13917
+ MatInputModule,
13918
+ MatButtonModule,
13919
+ MaskitoDirective,
13920
+ MatIconModule,
13921
+ MatSelectModule, i1$1.TranslateModule], exports: [MatLatLongField, MatLatLongFieldInput] });
13922
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, imports: [CommonModule,
13923
+ IonicModule,
13924
+ ReactiveFormsModule,
13925
+ SharedDirectivesModule,
13926
+ SharedPipesModule,
13927
+ MatCommonModule,
13928
+ MatFormFieldModule,
13929
+ MatInputModule,
13930
+ MatButtonModule,
13931
+ MatIconModule,
13932
+ MatSelectModule,
13933
+ TranslateModule.forChild()] });
13934
+ }
13935
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: SharedMatLatLongModule, decorators: [{
13936
+ type: NgModule,
13937
+ args: [{
13938
+ imports: [
13939
+ CommonModule,
13940
+ IonicModule,
13941
+ ReactiveFormsModule,
13942
+ SharedDirectivesModule,
13943
+ SharedPipesModule,
13944
+ MatCommonModule,
13945
+ MatFormFieldModule,
13946
+ MatInputModule,
13947
+ MatButtonModule,
13948
+ MaskitoDirective,
13949
+ MatIconModule,
13950
+ MatSelectModule,
13951
+ TranslateModule.forChild(),
13952
+ ],
13953
+ declarations: [MatLatLongField, MatLatLongFieldInput],
13954
+ exports: [MatLatLongField, MatLatLongFieldInput],
13955
+ }]
13956
+ }] });
13957
+
13892
13958
  //import {SharedMatNumpadModule} from './numpad/numpad.module';
13893
13959
  const modules = [
13894
13960
  // Angular material components
@@ -42494,7 +42560,7 @@ class LatLongTestPage {
42494
42560
  }
42495
42561
  stringify = JSON.stringify;
42496
42562
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: LatLongTestPage, deps: [{ token: i1$3.UntypedFormBuilder }, { token: PlatformService }], target: i0.ɵɵFactoryTarget.Component });
42497
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: LatLongTestPage, selector: "app-latlong-test", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Lat/Long field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <!-- Tab nav - desktop mode -->\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <a mat-tab-link [active]=\"mode === 'mobile'\" (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'desktop'\" (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'dev'\" (click)=\"toggleMode('dev')\">\n <mat-label>Dev</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'temp'\" (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form #tabPanel class=\"form-container ion-padding\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n @if (mode === 'mobile') {\n <ng-container *ngTemplateOutlet=\"mainTest; context: { mobile: true }\"></ng-container>\n } @else if (mode === 'desktop') {\n <ng-container *ngTemplateOutlet=\"mainTest; context: { mobile: false }\"></ng-container>\n } @else if (mode === 'dev') {\n <ion-grid>\n <ion-row>\n <ion-col>\n <mat-checkbox (change)=\"toggleAppearance($event)\">Change apparence</mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-form-field [appearance]=\"appearance\" [subscriptSizing]=\"'dynamic'\">\n <mat-label>LatLongFormat</mat-label>\n <mat-select #selectLatLongFormat [(value)]=\"selectedFormat\">\n <mat-option value=\"DDMM\" selected>DDMM</mat-option>\n <mat-option value=\"DDMMSS\">DDMMSS</mat-option>\n <mat-option value=\"DD\">DD</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @switch (selectedFormat) {\n @case ('DDMM') {\n <ion-row>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DDMM', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DDMM', required: true }\n \"\n ></ng-container>\n </ion-col>\n <!-- <ion-col> -->\n <!-- <ng-container -->\n <!-- *ngTemplateOutlet=\"testV2; context: { formGroup: 'disable', latLongPattern: 'DDMM', required: true }\" -->\n <!-- ></ng-container> -->\n <!-- </ion-col> -->\n </ion-row>\n }\n @case ('DDMMSS') {\n <ion-row>\n <!-- DDMMSS -->\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DDMMSS', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DDMMSS', required: true }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'disable', latLongPattern: 'DDMMSS', required: true }\n \"\n ></ng-container>\n </ion-col>\n </ion-row>\n }\n @case ('DD') {\n <ion-row>\n <!-- DDMMSS -->\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DD', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DD', required: true }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'disable', latLongPattern: 'DD', required: true }\n \"\n ></ng-container>\n </ion-col>\n </ion-row>\n }\n }\n </ion-grid>\n } @else {\n <!-- Temporay TAB (for DEV) -->\n <form *ngIf=\"form | formGetGroup: 'enable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, defaultSign '-'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ formGroup.value | json }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"-\"\n [required]=\"true\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </form>\n }\n </form>\n</ion-content>\n\n<ng-template #mainTest let-mobile=\"mobile\">\n <!-- Empty value -->\n <form *ngIf=\"form | formGetGroup: 'empty' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <mat-checkbox (change)=\"toggleAppearance($event)\">Change apparence</mat-checkbox>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <ion-text><h4>Empty, with defaults</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, defaultSign '-'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMM Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM, defaultSign '+'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n defaultSign=\"+\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n defaultSign=\"+\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMMSS, defaultSign '+'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"+\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"+\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <!-- Empty value -->\n <form *ngIf=\"form | formGetGroup: 'emptyRequired' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text><h4>Empty, required (no defaults)</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, required</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMM -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM, required</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <form *ngIf=\"form | formGetGroup: 'enable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <!-- With value -->\n <ion-row>\n <ion-col>\n <ion-text><h4>With value</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMMSS</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <!-- Disable -->\n <form *ngIf=\"form | formGetGroup: 'disable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text><h4>Disabled control</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Disabled control</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <mat-icon matSuffix>gps_fixed</mat-icon>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Readonly (control is enable)</ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-checkbox\n (change)=\"readonlyField.readonly = $event.checked\"\n [checked]=\"readonlyField.readonly\"\n ></mat-checkbox>\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n #readonlyField\n [formControl]=\"form | formGetControl: 'enable.latitude'\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [readonly]=\"true\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <mat-icon matSuffix>gps_fixed</mat-icon>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">With hint</ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-latlong-field\n #readonlyField\n [formControl]=\"form | formGetControl: 'enable.latitude'\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-hint align=\"end\">This is a long long hint</mat-hint>\n </mat-latlong-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ng-template>\n\n<ng-template #newComponent let-formGroupName=\"formGroup\" let-pattern=\"latLongPattern\" let-required=\"required\">\n <form *ngIf=\"form | formGetGroup: formGroupName as formGroup\" [formGroup]=\"formGroup\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">{{ formGroupName }}</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-text color=\"medium\">\n <small>\n <pre>{{ formGroup.value | json }}</pre>\n <pre>invalid ? : {{ (formGroup | formGetControl: 'latitude').invalid }}</pre>\n <pre>touched ? : {{ (formGroup | formGetControl: 'latitude').touched }}</pre>\n <pre>errors : {{ formGroup | formGetGroup: 'latitude' | formError }}</pre>\n </small>\n </ion-text>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n [readonly]=\"true\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n [readonly]=\"true\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [required]=\"required\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [required]=\"required\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </form>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2$1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2$1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2$1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonBackButton, selector: "ion-back-button" }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i7.MatTabNav, selector: "[mat-tab-nav-bar]", inputs: ["fitInkBarToContent", "mat-stretch-tabs", "animationDuration", "backgroundColor", "disableRipple", "color", "tabPanel"], exportAs: ["matTabNavBar", "matTabNav"] }, { kind: "component", type: i7.MatTabLink, selector: "[mat-tab-link], [matTabLink]", inputs: ["active", "disabled", "disableRipple", "tabIndex", "id"], exportAs: ["matTabLink"] }, { kind: "component", type: MatLatLongField, selector: "mat-latlong-field", inputs: ["formControl", "formControlName", "type", "latLongPattern", "maxDecimals", "required", "floatLabel", "placeholder", "defaultSign", "autofocus", "mobile", "degreesSymbolUnit", "minutesSymbolUnit", "secondsSymbolUnit", "clearable", "class", "tabindex", "appearance", "readonly", "subscriptSizing"], outputs: ["keyup.enter", "blur", "focus"] }, { kind: "pipe", type: i3.JsonPipe, name: "json" }, { kind: "pipe", type: FormErrorPipe, name: "formError" }, { kind: "pipe", type: FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: FormGetGroupPipe, name: "formGetGroup" }] });
42563
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: LatLongTestPage, selector: "app-latlong-test", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Lat/Long field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <!-- Tab nav - desktop mode -->\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <a mat-tab-link [active]=\"mode === 'mobile'\" (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'desktop'\" (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'dev'\" (click)=\"toggleMode('dev')\">\n <mat-label>Dev</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode === 'temp'\" (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form #tabPanel class=\"form-container ion-padding\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n @if (mode === 'mobile') {\n <ng-container *ngTemplateOutlet=\"mainTest; context: { mobile: true }\"></ng-container>\n } @else if (mode === 'desktop') {\n <ng-container *ngTemplateOutlet=\"mainTest; context: { mobile: false }\"></ng-container>\n } @else if (mode === 'dev') {\n <ion-grid>\n <ion-row>\n <ion-col>\n <mat-checkbox (change)=\"toggleAppearance($event)\">Change apparence</mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-form-field [appearance]=\"appearance\" [subscriptSizing]=\"'dynamic'\">\n <mat-label>LatLongFormat</mat-label>\n <mat-select #selectLatLongFormat [(value)]=\"selectedFormat\">\n <mat-option value=\"DDMM\" selected>DDMM</mat-option>\n <mat-option value=\"DDMMSS\">DDMMSS</mat-option>\n <mat-option value=\"DD\">DD</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @switch (selectedFormat) {\n @case ('DDMM') {\n <ion-row>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DDMM', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DDMM', required: true }\n \"\n ></ng-container>\n </ion-col>\n <!-- <ion-col> -->\n <!-- <ng-container -->\n <!-- *ngTemplateOutlet=\"testV2; context: { formGroup: 'disable', latLongPattern: 'DDMM', required: true }\" -->\n <!-- ></ng-container> -->\n <!-- </ion-col> -->\n </ion-row>\n }\n @case ('DDMMSS') {\n <ion-row>\n <!-- DDMMSS -->\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DDMMSS', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DDMMSS', required: true }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'disable', latLongPattern: 'DDMMSS', required: true }\n \"\n ></ng-container>\n </ion-col>\n </ion-row>\n }\n @case ('DD') {\n <ion-row>\n <!-- DDMMSS -->\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'empty', latLongPattern: 'DD', required: false }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'enable', latLongPattern: 'DD', required: true }\n \"\n ></ng-container>\n </ion-col>\n <ion-col>\n <ng-container\n *ngTemplateOutlet=\"\n newComponent;\n context: { formGroup: 'disable', latLongPattern: 'DD', required: true }\n \"\n ></ng-container>\n </ion-col>\n </ion-row>\n }\n }\n </ion-grid>\n } @else {\n <!-- Temporay TAB (for DEV) -->\n <form *ngIf=\"form | formGetGroup: 'enable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, defaultSign '-'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ formGroup.value | json }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"-\"\n [required]=\"true\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </form>\n }\n </form>\n</ion-content>\n\n<ng-template #mainTest let-mobile=\"mobile\">\n <!-- Empty value -->\n <form *ngIf=\"form | formGetGroup: 'empty' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <mat-checkbox (change)=\"toggleAppearance($event)\">Change apparence</mat-checkbox>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <ion-text><h4>Empty, with defaults</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, defaultSign '-'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMM Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM, defaultSign '+'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n defaultSign=\"+\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n defaultSign=\"+\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS Default sign -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMMSS, defaultSign '+'</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"+\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n defaultSign=\"+\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <!-- Empty value -->\n <form *ngIf=\"form | formGetGroup: 'emptyRequired' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text><h4>Empty, required (no defaults)</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD, required</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMM -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM, required</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <form *ngIf=\"form | formGetGroup: 'enable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <!-- With value -->\n <ion-row>\n <ion-col>\n <ion-text><h4>With value</h4></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- DD -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DD</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DD\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DD\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMM</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- DDMMSS -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Format DDMMSS</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMMSS\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMMSS\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <!-- Disable -->\n <form *ngIf=\"form | formGetGroup: 'disable' as formGroup\" [formGroup]=\"formGroup\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text><h4>Disabled control</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Disabled control</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>{{ stringify(formGroup.value) }}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <mat-icon matSuffix>gps_fixed</mat-icon>\n </mat-latlong-field>\n </ion-col>\n <ion-col>\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button type=\"button\" mat-icon-button matSuffix (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Readonly (control is enable)</ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-checkbox\n (change)=\"readonlyField.readonly = $event.checked\"\n [checked]=\"readonlyField.readonly\"\n ></mat-checkbox>\n\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-latlong-field\n #readonlyField\n [formControl]=\"form | formGetControl: 'enable.latitude'\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [readonly]=\"true\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <mat-icon matSuffix>gps_fixed</mat-icon>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">With hint</ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-latlong-field\n #readonlyField\n [formControl]=\"form | formGetControl: 'enable.latitude'\"\n type=\"latitude\"\n latLongPattern=\"DDMM\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [mobile]=\"mobile\"\n >\n <mat-hint align=\"end\">This is a long long hint</mat-hint>\n </mat-latlong-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ng-template>\n\n<ng-template #newComponent let-formGroupName=\"formGroup\" let-pattern=\"latLongPattern\" let-required=\"required\">\n <form *ngIf=\"form | formGetGroup: formGroupName as formGroup\" [formGroup]=\"formGroup\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">{{ formGroupName }}</ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-text color=\"medium\">\n <small>\n <pre>{{ formGroup.value | json }}</pre>\n <pre>invalid ? : {{ (formGroup | formGetControl: 'latitude').invalid }}</pre>\n <pre>touched ? : {{ (formGroup | formGetControl: 'latitude').touched }}</pre>\n <pre>errors : {{ formGroup | formGetGroup: 'latitude' | formError }}</pre>\n </small>\n </ion-text>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n [readonly]=\"true\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n ></mat-latlong-field>\n </ion-col>\n <ion-col sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n [readonly]=\"true\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n ></mat-latlong-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"latitude\"\n type=\"latitude\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Latitude\"\n [appearance]=\"appearance\"\n [required]=\"required\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n <ion-col class=\"ion-no-padding\" sizeLg=\"6\">\n <mat-latlong-field\n formControlName=\"longitude\"\n type=\"longitude\"\n [latLongPattern]=\"pattern\"\n defaultSign=\"-\"\n placeholder=\"Longitude\"\n [appearance]=\"appearance\"\n [required]=\"required\"\n >\n <mat-icon matPrefix>room</mat-icon>\n <button matSuffix mat-icon-button (click)=\"geoPosition($event)\">\n <mat-icon>gps_fixed</mat-icon>\n </button>\n </mat-latlong-field>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"geoPositionMessage\">\n <ion-col>{{ geoPositionMessage }}</ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </form>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2$1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2$1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2$1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonBackButton, selector: "ion-back-button" }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i7.MatTabNav, selector: "[mat-tab-nav-bar]", inputs: ["fitInkBarToContent", "mat-stretch-tabs", "animationDuration", "backgroundColor", "disableRipple", "color", "tabPanel"], exportAs: ["matTabNavBar", "matTabNav"] }, { kind: "component", type: i7.MatTabLink, selector: "[mat-tab-link], [matTabLink]", inputs: ["active", "disabled", "disableRipple", "tabIndex", "id"], exportAs: ["matTabLink"] }, { kind: "component", type: MatLatLongField, selector: "mat-latlong-field", inputs: ["formControl", "formControlName", "type", "latLongPattern", "maxDecimals", "required", "floatLabel", "placeholder", "defaultSign", "autofocus", "mobile", "degreesSymbolUnit", "minutesSymbolUnit", "secondsSymbolUnit", "clearable", "class", "tabindex", "appearance", "readonly", "subscriptSizing"] }, { kind: "pipe", type: i3.JsonPipe, name: "json" }, { kind: "pipe", type: FormErrorPipe, name: "formError" }, { kind: "pipe", type: FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: FormGetGroupPipe, name: "formGetGroup" }] });
42498
42564
  }
42499
42565
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: LatLongTestPage, decorators: [{
42500
42566
  type: Component,
@@ -42992,6 +43058,234 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
42992
43058
  args: [{ selector: 'app-maskito-test', template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Maskito test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <form [formGroup]=\"form\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">Test Strategy Pattern</ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-form-field>\n <input\n matInput\n #strategyInput\n formControlName=\"strategy\"\n autocomplete=\"off\"\n type=\"text\"\n [maskito]=\"'__ _______ ___' | maskitoPlaceholder: labelMask\"\n placeholder=\"Strategy field\"\n />\n </mat-form-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n" }]
42993
43059
  }], ctorParameters: () => [{ type: i1$3.UntypedFormBuilder }] });
42994
43060
 
43061
+ /** @title Form field with custom telephone number input control. */
43062
+ class FormFieldCustomControlExample {
43063
+ form = new FormGroup({
43064
+ tel: new FormControl(null),
43065
+ });
43066
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: FormFieldCustomControlExample, deps: [], target: i0.ɵɵFactoryTarget.Component });
43067
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.11", type: FormFieldCustomControlExample, isStandalone: true, selector: "form-field-custom-control-example", ngImport: i0, template: `
43068
+ <div [formGroup]="form">
43069
+ <mat-form-field>
43070
+ <mat-label>Phone number</mat-label>
43071
+ <example-tel-input formControlName="tel" required></example-tel-input>
43072
+ <mat-icon matSuffix>phone</mat-icon>
43073
+ <mat-hint>Include area code</mat-hint>
43074
+ </mat-form-field>
43075
+ <p>Entered value: {{ form.valueChanges | async | json }}</p>
43076
+ </div>
43077
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: i0.forwardRef(() => FormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1$3.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1$3.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i1$3.RequiredValidator), selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1$3.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1$3.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatFormFieldModule) }, { kind: "component", type: i0.forwardRef(() => i6.MatFormField), selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i0.forwardRef(() => i6.MatLabel), selector: "mat-label" }, { kind: "directive", type: i0.forwardRef(() => i6.MatHint), selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i0.forwardRef(() => i6.MatSuffix), selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i0.forwardRef(() => MyTelInput), selector: "example-tel-input", inputs: ["aria-describedby", "placeholder", "required", "disabled", "value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatIconModule) }, { kind: "component", type: i0.forwardRef(() => i8.MatIcon), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i0.forwardRef(() => AsyncPipe), name: "async" }, { kind: "pipe", type: i0.forwardRef(() => JsonPipe), name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
43078
+ }
43079
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: FormFieldCustomControlExample, decorators: [{
43080
+ type: Component,
43081
+ args: [{
43082
+ selector: 'form-field-custom-control-example',
43083
+ template: `
43084
+ <div [formGroup]="form">
43085
+ <mat-form-field>
43086
+ <mat-label>Phone number</mat-label>
43087
+ <example-tel-input formControlName="tel" required></example-tel-input>
43088
+ <mat-icon matSuffix>phone</mat-icon>
43089
+ <mat-hint>Include area code</mat-hint>
43090
+ </mat-form-field>
43091
+ <p>Entered value: {{ form.valueChanges | async | json }}</p>
43092
+ </div>
43093
+ `,
43094
+ standalone: true,
43095
+ imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, forwardRef(() => MyTelInput), MatIconModule, AsyncPipe, JsonPipe],
43096
+ changeDetection: ChangeDetectionStrategy.OnPush,
43097
+ }]
43098
+ }] });
43099
+ /** Data structure for holding telephone number. */
43100
+ class MyTel {
43101
+ area;
43102
+ exchange;
43103
+ subscriber;
43104
+ constructor(area, exchange, subscriber) {
43105
+ this.area = area;
43106
+ this.exchange = exchange;
43107
+ this.subscriber = subscriber;
43108
+ }
43109
+ }
43110
+ /** Custom `MatFormFieldControl` for telephone number input. */
43111
+ class MyTelInput {
43112
+ static nextId = 0;
43113
+ areaInput = viewChild.required('area');
43114
+ exchangeInput = viewChild.required('exchange');
43115
+ subscriberInput = viewChild.required('subscriber');
43116
+ ngControl = inject(NgControl, { optional: true, self: true });
43117
+ parts;
43118
+ stateChanges = new Subject();
43119
+ touched = signal(false);
43120
+ controlType = 'example-tel-input';
43121
+ id = `example-tel-input-${MyTelInput.nextId++}`;
43122
+ _userAriaDescribedBy = input('', { alias: 'aria-describedby' });
43123
+ _placeholder = input('', { alias: 'placeholder' });
43124
+ _required = input(false, {
43125
+ alias: 'required',
43126
+ transform: booleanAttribute,
43127
+ });
43128
+ _disabledByInput = input(false, {
43129
+ alias: 'disabled',
43130
+ transform: booleanAttribute,
43131
+ });
43132
+ _value = model(null, { alias: 'value' });
43133
+ onChange = (_) => { };
43134
+ onTouched = () => { };
43135
+ _formField = inject(MAT_FORM_FIELD, {
43136
+ optional: true,
43137
+ });
43138
+ _focused = signal(false);
43139
+ _disabledByCva = signal(false);
43140
+ _disabled = computed(() => this._disabledByInput() || this._disabledByCva());
43141
+ _focusMonitor = inject(FocusMonitor);
43142
+ _elementRef = inject(ElementRef);
43143
+ get focused() {
43144
+ return this._focused();
43145
+ }
43146
+ get empty() {
43147
+ const { value: { area, exchange, subscriber }, } = this.parts;
43148
+ return !area && !exchange && !subscriber;
43149
+ }
43150
+ get shouldLabelFloat() {
43151
+ return this.focused || !this.empty;
43152
+ }
43153
+ get userAriaDescribedBy() {
43154
+ return this._userAriaDescribedBy();
43155
+ }
43156
+ get placeholder() {
43157
+ return this._placeholder();
43158
+ }
43159
+ get required() {
43160
+ return this._required();
43161
+ }
43162
+ get disabled() {
43163
+ return this._disabled();
43164
+ }
43165
+ get value() {
43166
+ return this._value();
43167
+ }
43168
+ get errorState() {
43169
+ return this.parts.invalid && this.touched();
43170
+ }
43171
+ constructor() {
43172
+ if (this.ngControl != null) {
43173
+ this.ngControl.valueAccessor = this;
43174
+ }
43175
+ this.parts = inject(FormBuilder).group({
43176
+ area: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(3)]],
43177
+ exchange: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(3)]],
43178
+ subscriber: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(4)]],
43179
+ });
43180
+ effect(() => {
43181
+ // Read signals to trigger effect.
43182
+ this._placeholder();
43183
+ this._required();
43184
+ this._disabled();
43185
+ this._focused();
43186
+ // Propagate state changes.
43187
+ untracked(() => this.stateChanges.next());
43188
+ });
43189
+ effect(() => {
43190
+ if (this._disabled()) {
43191
+ untracked(() => this.parts.disable());
43192
+ }
43193
+ else {
43194
+ untracked(() => this.parts.enable());
43195
+ }
43196
+ });
43197
+ effect(() => {
43198
+ const value = this._value() || new MyTel('', '', '');
43199
+ untracked(() => this.parts.setValue(value));
43200
+ });
43201
+ this.parts.statusChanges.pipe(takeUntilDestroyed()).subscribe(() => {
43202
+ this.stateChanges.next();
43203
+ });
43204
+ this.parts.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
43205
+ const tel = this.parts.valid
43206
+ ? new MyTel(this.parts.value.area || '', this.parts.value.exchange || '', this.parts.value.subscriber || '')
43207
+ : null;
43208
+ this._updateValue(tel);
43209
+ });
43210
+ }
43211
+ ngOnDestroy() {
43212
+ this.stateChanges.complete();
43213
+ this._focusMonitor.stopMonitoring(this._elementRef);
43214
+ }
43215
+ onFocusIn() {
43216
+ if (!this._focused()) {
43217
+ this._focused.set(true);
43218
+ }
43219
+ }
43220
+ onFocusOut(event) {
43221
+ if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
43222
+ this.touched.set(true);
43223
+ this._focused.set(false);
43224
+ this.onTouched();
43225
+ }
43226
+ }
43227
+ autoFocusNext(control, nextElement) {
43228
+ if (!control.errors && nextElement) {
43229
+ this._focusMonitor.focusVia(nextElement, 'program');
43230
+ }
43231
+ }
43232
+ autoFocusPrev(control, prevElement) {
43233
+ if (control.value.length < 1) {
43234
+ this._focusMonitor.focusVia(prevElement, 'program');
43235
+ }
43236
+ }
43237
+ setDescribedByIds(ids) {
43238
+ const controlElement = this._elementRef.nativeElement.querySelector('.example-tel-input-container');
43239
+ controlElement.setAttribute('aria-describedby', ids.join(' '));
43240
+ }
43241
+ onContainerClick() {
43242
+ if (this.parts.controls.subscriber.valid) {
43243
+ this._focusMonitor.focusVia(this.subscriberInput(), 'program');
43244
+ }
43245
+ else if (this.parts.controls.exchange.valid) {
43246
+ this._focusMonitor.focusVia(this.subscriberInput(), 'program');
43247
+ }
43248
+ else if (this.parts.controls.area.valid) {
43249
+ this._focusMonitor.focusVia(this.exchangeInput(), 'program');
43250
+ }
43251
+ else {
43252
+ this._focusMonitor.focusVia(this.areaInput(), 'program');
43253
+ }
43254
+ }
43255
+ writeValue(tel) {
43256
+ this._updateValue(tel);
43257
+ }
43258
+ registerOnChange(fn) {
43259
+ this.onChange = fn;
43260
+ }
43261
+ registerOnTouched(fn) {
43262
+ this.onTouched = fn;
43263
+ }
43264
+ setDisabledState(isDisabled) {
43265
+ this._disabledByCva.set(isDisabled);
43266
+ }
43267
+ _handleInput(control, nextElement) {
43268
+ this.autoFocusNext(control, nextElement);
43269
+ this.onChange(this.value);
43270
+ }
43271
+ _updateValue(tel) {
43272
+ const current = this._value();
43273
+ if (tel === current || (tel?.area === current?.area && tel?.exchange === current?.exchange && tel?.subscriber === current?.subscriber)) {
43274
+ return;
43275
+ }
43276
+ this._value.set(tel);
43277
+ }
43278
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MyTelInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
43279
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.11", type: MyTelInput, isStandalone: true, selector: "example-tel-input", inputs: { _userAriaDescribedBy: { classPropertyName: "_userAriaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, _placeholder: { classPropertyName: "_placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, _required: { classPropertyName: "_required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, _disabledByInput: { classPropertyName: "_disabledByInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, _value: { classPropertyName: "_value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { _value: "valueChange" }, host: { properties: { "class.example-floating": "shouldLabelFloat", "id": "id" } }, providers: [{ provide: MatFormFieldControl, useExisting: MyTelInput }], viewQueries: [{ propertyName: "areaInput", first: true, predicate: ["area"], descendants: true, isSignal: true }, { propertyName: "exchangeInput", first: true, predicate: ["exchange"], descendants: true, isSignal: true }, { propertyName: "subscriberInput", first: true, predicate: ["subscriber"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n role=\"group\"\n class=\"example-tel-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"area\"\n size=\"3\"\n maxLength=\"3\"\n aria-label=\"Area code\"\n (input)=\"_handleInput(parts.controls.area, exchange)\"\n #area\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"exchange\"\n maxLength=\"3\"\n size=\"3\"\n aria-label=\"Exchange code\"\n (input)=\"_handleInput(parts.controls.exchange, subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.exchange, area)\"\n #exchange\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"subscriber\"\n maxLength=\"4\"\n size=\"4\"\n aria-label=\"Subscriber number\"\n (input)=\"_handleInput(parts.controls.subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.subscriber, exchange)\"\n #subscriber\n />\n</div>\n", styles: [".example-tel-input-container{display:flex}.example-tel-input-element{border:none;background:none;padding:0;outline:none;font:inherit;text-align:center;color:currentcolor}.example-tel-input-spacer{opacity:0;transition:opacity .2s}:host.example-floating .example-tel-input-spacer{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
43280
+ }
43281
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MyTelInput, decorators: [{
43282
+ type: Component,
43283
+ args: [{ selector: 'example-tel-input', providers: [{ provide: MatFormFieldControl, useExisting: MyTelInput }], host: {
43284
+ '[class.example-floating]': 'shouldLabelFloat',
43285
+ '[id]': 'id',
43286
+ }, standalone: true, imports: [FormsModule, ReactiveFormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n role=\"group\"\n class=\"example-tel-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"area\"\n size=\"3\"\n maxLength=\"3\"\n aria-label=\"Area code\"\n (input)=\"_handleInput(parts.controls.area, exchange)\"\n #area\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"exchange\"\n maxLength=\"3\"\n size=\"3\"\n aria-label=\"Exchange code\"\n (input)=\"_handleInput(parts.controls.exchange, subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.exchange, area)\"\n #exchange\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"subscriber\"\n maxLength=\"4\"\n size=\"4\"\n aria-label=\"Subscriber number\"\n (input)=\"_handleInput(parts.controls.subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.subscriber, exchange)\"\n #subscriber\n />\n</div>\n", styles: [".example-tel-input-container{display:flex}.example-tel-input-element{border:none;background:none;padding:0;outline:none;font:inherit;text-align:center;color:currentcolor}.example-tel-input-spacer{opacity:0;transition:opacity .2s}:host.example-floating .example-tel-input-spacer{opacity:1}\n"] }]
43287
+ }], ctorParameters: () => [] });
43288
+
42995
43289
  const SHARED_MATERIAL_TESTING_PAGES = [
42996
43290
  { label: 'Shared Material components', divider: true },
42997
43291
  { label: 'Common field', page: '/testing/shared/common' },
@@ -43002,6 +43296,8 @@ const SHARED_MATERIAL_TESTING_PAGES = [
43002
43296
  { label: 'Autocomplete field', page: '/testing/shared/autocomplete' },
43003
43297
  { label: 'Boolean field', page: '/testing/shared/boolean' },
43004
43298
  { label: 'Lat/Long field', page: '/testing/shared/latlong' },
43299
+ { label: 'Lat/Long field 2', page: '/testing/shared/latlong2' },
43300
+ { label: 'TEST field', page: '/testing/shared/test' },
43005
43301
  //{ label: 'Numeric pad component', page: '/testing/shared/numpad' },
43006
43302
  { label: 'Text form', page: '/testing/shared/text-form' },
43007
43303
  { label: 'Swipe component', page: '/testing/shared/swipe' },
@@ -43059,6 +43355,16 @@ const routes$b = [
43059
43355
  component: LatLongTestPage,
43060
43356
  },
43061
43357
  // {
43358
+ // path: 'latlong2',
43359
+ // pathMatch: 'full',
43360
+ // component: LatLongTest2Page,
43361
+ // },
43362
+ {
43363
+ path: 'test',
43364
+ pathMatch: 'full',
43365
+ component: FormFieldCustomControlExample,
43366
+ },
43367
+ // {
43062
43368
  // path: 'numpad',
43063
43369
  // pathMatch: 'full',
43064
43370
  // component: NumpadTestPage
@@ -43104,6 +43410,7 @@ class MaterialTestingModule {
43104
43410
  AutocompleteTestPage,
43105
43411
  BooleanTestPage,
43106
43412
  LatLongTestPage,
43413
+ //LatLongTest2Page,
43107
43414
  //NumpadTestPage,
43108
43415
  TextFormTestingPage,
43109
43416
  SwipeTestPage,
@@ -43116,7 +43423,8 @@ class MaterialTestingModule {
43116
43423
  SharedMaterialModule, i1$1.TranslateModule, i1$5.RouterModule, SharedPipesModule,
43117
43424
  SharedBadgeModule,
43118
43425
  FormsModule,
43119
- MaskitoDirective], exports: [SharedMaterialModule,
43426
+ MaskitoDirective,
43427
+ SharedMatLatLongModule], exports: [SharedMaterialModule,
43120
43428
  RouterModule,
43121
43429
  MatCommonTestPage,
43122
43430
  DateTimeTestPage,
@@ -43126,6 +43434,7 @@ class MaterialTestingModule {
43126
43434
  AutocompleteTestPage,
43127
43435
  BooleanTestPage,
43128
43436
  LatLongTestPage,
43437
+ //LatLongTest2Page,
43129
43438
  //NumpadTestPage,
43130
43439
  TextFormTestingPage,
43131
43440
  SwipeTestPage,
@@ -43141,7 +43450,8 @@ class MaterialTestingModule {
43141
43450
  RouterModule.forChild(routes$b),
43142
43451
  SharedPipesModule,
43143
43452
  SharedBadgeModule,
43144
- FormsModule, SharedMaterialModule,
43453
+ FormsModule,
43454
+ SharedMatLatLongModule, SharedMaterialModule,
43145
43455
  RouterModule] });
43146
43456
  }
43147
43457
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MaterialTestingModule, decorators: [{
@@ -43158,6 +43468,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
43158
43468
  SharedBadgeModule,
43159
43469
  FormsModule,
43160
43470
  MaskitoDirective,
43471
+ SharedMatLatLongModule,
43161
43472
  ],
43162
43473
  declarations: [
43163
43474
  MatCommonTestPage,
@@ -43168,6 +43479,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
43168
43479
  AutocompleteTestPage,
43169
43480
  BooleanTestPage,
43170
43481
  LatLongTestPage,
43482
+ //LatLongTest2Page,
43171
43483
  //NumpadTestPage,
43172
43484
  TextFormTestingPage,
43173
43485
  SwipeTestPage,
@@ -43187,6 +43499,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
43187
43499
  AutocompleteTestPage,
43188
43500
  BooleanTestPage,
43189
43501
  LatLongTestPage,
43502
+ //LatLongTest2Page,
43190
43503
  //NumpadTestPage,
43191
43504
  TextFormTestingPage,
43192
43505
  SwipeTestPage,
@@ -44561,7 +44874,7 @@ class TableTestPage extends AppTable {
44561
44874
  provide: AppTable,
44562
44875
  useExisting: forwardRef(() => TableTestPage),
44563
44876
  },
44564
- ], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n color=\"primary\"\n [canGoBack]=\"true\"\n [hasValidate]=\"(loadingSubject | async) !== true && (dirtySubject | async) === true\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\"\n>\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n @if (selection | isEmptySelection) {\n <input matInput type=\"number\" step=\"1\" style=\"color: black; width: 50px\" [(ngModel)]=\"rowHeight\" />\n\n <!-- Add -->\n <button mat-icon-button *ngIf=\"canEdit && !mobile\" [title]=\"'COMMON.BTN_ADD' | translate\" (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\" [disabled]=\"(dirtySubject | async) !== true\" (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n } @else {\n <!-- if row selection -->\n <!-- delete -->\n <button\n mat-icon-button\n *ngIf=\"canEdit\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button\n mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: { equals: 1 }\"\n [title]=\"'COMMON.BTN_DUPLICATE' | translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\"\n >\n <mat-icon>file_copy</mat-icon>\n </button>\n }\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n [class.filter-panel-pinned]=\"!filterPanelFloating\"\n >\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{ 'TABLE.TESTING.SEARCH_TEXT' | translate }}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput formControlName=\"searchText\" autocomplete=\"off\" />\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '&#xbb;' : '&#xab;' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\"\n >\n <!-- group header cells -->\n <ng-container matColumnDef=\"top-start\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{ i18nColumnPrefix + 'GROUP_1' }}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"displayedColumns.length - 6\">\n <ion-label translate>{{ i18nColumnPrefix + 'GROUP_2' }}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" [stickyEnd]=\"stickyEnd\">\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n <ion-label></ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"sticky\" [class.mat-column-sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n @if (selection | isMultipleSelection) {\n <mat-checkbox\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n (change)=\"$event ? masterToggle() : null\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"toggleSelectRow($event, row)\"\n [checked]=\"selection | isSelected: row\"\n tabindex=\"-1\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"sticky\" [class.mat-column-sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'label'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL' | translate\"\n [appAutofocus]=\"focusColumn === 'label'\"\n [readonly]=\"!row.editing\"\n />\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'label' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'name'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator?.controls.name\"\n [placeholder]=\"'TABLE.TESTING.NAME' | translate\"\n [appAutofocus]=\"focusColumn === 'name'\"\n />\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'name' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'levelId'\">\n @if (row.editing) {\n <mat-autocomplete-field\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID' | translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"focusColumn === 'levelId'\"\n [required]=\"true\"\n ></mat-autocomplete-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'levelId' | referentialToString: autocompleteFields.level.attributes }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [class.mat-form-field-disabled]=\"!row.editing\"\n (click)=\"focusColumn = 'statusId'\"\n >\n <mat-form-field>\n <mat-select\n [formControl]=\"row.validator.controls['statusId']\"\n [placeholder]=\"i18nColumnPrefix + 'STATUS_ID' | translate\"\n >\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label | translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n <!-- <ng-container matColumnDef=\"values\">-->\n <!-- <th mat-header-cell *matHeaderCellDef>-->\n <!-- <span translate>Enums</span>-->\n <!-- </th>-->\n <!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n <!-- <app-form-field-->\n <!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n <!-- [definition]=\"columnDefinitions['values']\"-->\n <!-- ></app-form-field>-->\n <!-- </td>-->\n <!-- </ng-container>-->\n\n <!-- boolean (as checkbox) -->\n <ng-container matColumnDef=\"boolean\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n @if (!readOnly && row.editing) {\n <mat-boolean-field\n floatLabel=\"never\"\n [style]=\"'checkbox'\"\n placeholder=\"Oui/Non\"\n [formControl]=\"row.validator | formGetControl: 'properties.boolean'\"\n [compact]=\"true\"\n ></mat-boolean-field>\n } @else {\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'properties.boolean') ? '&#x2714;' : '&#x2718;' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- date -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\" class=\"mat-cell-date-time\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Date</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\" (click)=\"focusColumn = 'date'\">\n @if (!readOnly && row.editing) {\n <mat-date-time-field\n floatLabel=\"never\"\n [formControl]=\"row.validator | formGetControl: 'properties.date'\"\n [autofocus]=\"focusColumn === 'date'\"\n placeholder=\"Date/Time\"\n [compact]=\"true\"\n ></mat-date-time-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'properties.date' | dateFormat: { time: true } }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- latitude -->\n <ng-container matColumnDef=\"latitude\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Latitude</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'latitude'\">\n @if (!readOnly && row.editing) {\n <mat-latlong-field\n floatLabel=\"never\"\n [formControl]=\"row.validator | formGetControl: 'properties.latitude'\"\n placeholder=\"Latitude\"\n [latLongPattern]=\"'DDMM'\"\n [type]=\"'latitude'\"\n [autofocus]=\"focusColumn === 'latitude'\"\n ></mat-latlong-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'properties.latitude' | latitudeFormat: { pattern: 'DDMM', placeholderChar: '0' } }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id !== -1\">\n <small>\n {{ row.validator | formGetValue: 'creationDate' | dateFormat: { time: true } }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input\n type=\"text\"\n matInput\n [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS' | translate\"\n [readonly]=\"!row.editing\"\n />\n </mat-form-field>\n\n <ng-template #iconComment>\n <ion-icon\n [color]=\"row.validator?.controls.comments.value ? 'tertiary' : 'medium'\"\n name=\"chatbox\"\n slot=\"icon-only\"\n ></ion-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions column -->\n <app-nav-actions-column\n [stickyEnd]=\"stickyEnd\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n [cellTemplate]=\"cellInjection\"\n [showPending]=\"true\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n </app-nav-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-mdc-row-selected]=\"row.editing\"\n [class.mat-mdc-row-error]=\"row.invalid\"\n [class.mat-mdc-row-disabled]=\"!row.editing\"\n [class.mat-mdc-row-dirty]=\"row.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll\n *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\"\n position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\"\n >\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS' | translate\"\n ></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator\n *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\"\n showFirstLastButtons\n ></mat-paginator>\n\n <app-form-buttons-bar\n *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject | async) || !dirty\"\n >\n <!-- error -->\n <ion-item *ngIf=\"error$ | async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i2$1.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i2$1.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i2$1.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: "directive", type: i6$5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8$3.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9$3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13$3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13$3.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i8$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "label", "appearance", "subscriptSizing", "placeholder", "suggestFn", "required", "hideRequiredMarker", "mobile", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "reloadItemsOnFocus", "clearInvalidValueOnBlur", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "splitSearchText", "selectInputContentOnFocus", "selectInputContentOnFocusDelay", "previewImplicitValue", "class", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keydown.backspace", "keyup.enter", "selectionChange"] }, { kind: "component", type: MatLatLongField, selector: "mat-latlong-field", inputs: ["formControl", "formControlName", "type", "latLongPattern", "maxDecimals", "required", "floatLabel", "placeholder", "defaultSign", "autofocus", "mobile", "degreesSymbolUnit", "minutesSymbolUnit", "secondsSymbolUnit", "clearable", "class", "tabindex", "appearance", "readonly", "subscriptSizing"], outputs: ["keyup.enter", "blur", "focus"] }, { kind: "component", type: MatDateTime, selector: "mat-date-time-field", inputs: ["placeholder", "floatLabel", "mobile", "compact", "autofocus", "clearable", "startDate", "datePickerFilter", "allowNoTime", "appearance", "subscriptSizing", "formControl", "formControlName", "required", "readonly", "tabindex"] }, { kind: "component", type: MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: NavActionsColumnComponent, selector: "app-nav-actions-column", inputs: ["appTable", "matColumnDef", "style", "stickyEnd", "showPending", "dirtyIcon", "optionsTitle", "class", "cellTemplate", "throttleTime"], outputs: ["optionsClick"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ResizableComponent, selector: "th[resizable]", inputs: ["resizable"], outputs: ["sizeChanged"] }, { kind: "directive", type: ResizableDirective, selector: "[resizable]", outputs: ["resizable", "fit"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: LatitudeFormatPipe, name: "latitudeFormat" }, { kind: "pipe", type: NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: FormGetValuePipe, name: "formGetValue" }, { kind: "pipe", type: IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: IsMultipleSelectionPipe, name: "isMultipleSelection" }, { kind: "pipe", type: IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: IsNotAllSelectedPipe, name: "isNotAllSelected" }, { kind: "pipe", type: ReferentialToStringPipe, name: "referentialToString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
44877
+ ], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n color=\"primary\"\n [canGoBack]=\"true\"\n [hasValidate]=\"(loadingSubject | async) !== true && (dirtySubject | async) === true\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\"\n>\n <ion-title>Table (click to edit)</ion-title>\n <ion-buttons slot=\"end\">\n @if (selection | isEmptySelection) {\n <input matInput type=\"number\" step=\"1\" style=\"color: black; width: 50px\" [(ngModel)]=\"rowHeight\" />\n\n <!-- Add -->\n <button mat-icon-button *ngIf=\"canEdit && !mobile\" [title]=\"'COMMON.BTN_ADD' | translate\" (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\" [disabled]=\"(dirtySubject | async) !== true\" (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n\n <!-- start/stop timer to auto-load data -->\n <ion-button *ngIf=\"!timer\" (click)=\"startTimer()\">Start reload</ion-button>\n <ion-button *ngIf=\"timer\" (click)=\"stopTimer()\" color=\"accent\">Stop reload</ion-button>\n } @else {\n <!-- if row selection -->\n <!-- delete -->\n <button\n mat-icon-button\n *ngIf=\"canEdit\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button\n mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: { equals: 1 }\"\n [title]=\"'COMMON.BTN_DUPLICATE' | translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\"\n >\n <mat-icon>file_copy</mat-icon>\n </button>\n }\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n [class.filter-panel-pinned]=\"!filterPanelFloating\"\n >\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{ 'TABLE.TESTING.SEARCH_TEXT' | translate }}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput formControlName=\"searchText\" autocomplete=\"off\" />\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '&#xbb;' : '&#xab;' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\"\n >\n <!-- group header cells -->\n <ng-container matColumnDef=\"top-start\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\" [attr.colspan]=\"2\">\n <!-- start spacer -->\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-1\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"3\">\n <ion-label translate>{{ i18nColumnPrefix + 'GROUP_1' }}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"group-2\">\n <th mat-header-cell *matHeaderCellDef [attr.colspan]=\"displayedColumns.length - 6\">\n <ion-label translate>{{ i18nColumnPrefix + 'GROUP_2' }}</ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"top-end\" [stickyEnd]=\"stickyEnd\">\n <th mat-header-cell *matHeaderCellDef>\n <!-- end spacer -->\n <ion-label></ion-label>\n </th>\n </ng-container>\n\n <ng-container matColumnDef=\"select\" [sticky]=\"sticky\" [class.mat-column-sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n @if (selection | isMultipleSelection) {\n <mat-checkbox\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n (change)=\"$event ? masterToggle() : null\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"toggleSelectRow($event, row)\"\n [checked]=\"selection | isSelected: row\"\n tabindex=\"-1\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"sticky\" [class.mat-column-sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData?.id }}</td>\n </ng-container>\n\n <!-- Label column -->\n <ng-container matColumnDef=\"label\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LABEL</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'label'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n autocomplete=\"off\"\n [formControl]=\"row.validator.controls['label']\"\n [placeholder]=\"'TABLE.TESTING.LABEL' | translate\"\n [appAutofocus]=\"focusColumn === 'label'\"\n [readonly]=\"!row.editing\"\n />\n <mat-error *ngIf=\"row.validator.controls['label'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'label' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.NAME</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'name'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator?.controls.name\"\n [placeholder]=\"'TABLE.TESTING.NAME' | translate\"\n [appAutofocus]=\"focusColumn === 'name'\"\n />\n <mat-error *ngIf=\"row.validator?.controls.name.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'name' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.LEVEL_ID</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'levelId'\">\n @if (row.editing) {\n <mat-autocomplete-field\n [formControl]=\"row.validator.controls.levelId\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID' | translate\"\n floatLabel=\"never\"\n [config]=\"autocompleteFields.level\"\n [readonly]=\"!row.editing\"\n [autofocus]=\"focusColumn === 'levelId'\"\n [required]=\"true\"\n ></mat-autocomplete-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'levelId' | referentialToString: autocompleteFields.level.attributes }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"statusId\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [class.mat-form-field-disabled]=\"!row.editing\"\n (click)=\"focusColumn = 'statusId'\"\n >\n <mat-form-field>\n <mat-select\n [formControl]=\"row.validator.controls['statusId']\"\n [placeholder]=\"i18nColumnPrefix + 'STATUS_ID' | translate\"\n >\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <mat-icon><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-label>{{ item.label | translate }}</mat-label>\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Enum column -->\n <!-- NOTE : Never used in table -->\n <!-- <ng-container matColumnDef=\"values\">-->\n <!-- <th mat-header-cell *matHeaderCellDef>-->\n <!-- <span translate>Enums</span>-->\n <!-- </th>-->\n <!-- <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">-->\n <!-- <app-form-field-->\n <!-- [formControl]=\"row.validator|formGetControl:'properties.values'\"-->\n <!-- [definition]=\"columnDefinitions['values']\"-->\n <!-- ></app-form-field>-->\n <!-- </td>-->\n <!-- </ng-container>-->\n\n <!-- boolean (as checkbox) -->\n <ng-container matColumnDef=\"boolean\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n @if (!readOnly && row.editing) {\n <mat-boolean-field\n floatLabel=\"never\"\n [style]=\"'checkbox'\"\n placeholder=\"Oui/Non\"\n [formControl]=\"row.validator | formGetControl: 'properties.boolean'\"\n [compact]=\"true\"\n ></mat-boolean-field>\n } @else {\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'properties.boolean') ? '&#x2714;' : '&#x2718;' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- date -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\" class=\"mat-cell-date-time\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Date</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\" (click)=\"focusColumn = 'date'\">\n @if (!readOnly && row.editing) {\n <mat-date-time-field\n floatLabel=\"never\"\n [formControl]=\"row.validator | formGetControl: 'properties.date'\"\n [autofocus]=\"focusColumn === 'date'\"\n placeholder=\"Date/Time\"\n [compact]=\"true\"\n ></mat-date-time-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'properties.date' | dateFormat: { time: true } }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- latitude -->\n <ng-container matColumnDef=\"latitude\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"true\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Latitude</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'latitude'\">\n @if (!readOnly && row.editing) {\n <mat-latlong-field\n floatLabel=\"never\"\n [formControl]=\"row.validator | formGetControl: 'properties.latitude'\"\n placeholder=\"Latitude\"\n [latLongPattern]=\"'DDMM'\"\n [type]=\"'latitude'\"\n [autofocus]=\"focusColumn === 'latitude'\"\n ></mat-latlong-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'properties.latitude' | latitudeFormat: { pattern: 'DDMM', placeholderChar: '0' } }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>TABLE.TESTING.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text color=\"medium\" *ngIf=\"row.id !== -1\">\n <small>\n {{ row.validator | formGetValue: 'creationDate' | dateFormat: { time: true } }}\n </small>\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Comment column -->\n <ng-container matColumnDef=\"comments\">\n <th mat-header-cell *matHeaderCellDef>\n <ion-label translate>TABLE.TESTING.COMMENTS</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"row.editing; else iconComment\">\n <!--<textarea matInput [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS'|translate\"\n [readonly]=\"!row.editing\"></textarea>-->\n\n <input\n type=\"text\"\n matInput\n [formControl]=\"row.validator?.controls.comments\"\n [placeholder]=\"'TABLE.TESTING.COMMENTS' | translate\"\n [readonly]=\"!row.editing\"\n />\n </mat-form-field>\n\n <ng-template #iconComment>\n <ion-icon\n [color]=\"row.validator?.controls.comments.value ? 'tertiary' : 'medium'\"\n name=\"chatbox\"\n slot=\"icon-only\"\n ></ion-icon>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions column -->\n <app-nav-actions-column\n [stickyEnd]=\"stickyEnd\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n [cellTemplate]=\"cellInjection\"\n [showPending]=\"true\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n </app-nav-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"groupColumns\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-mdc-row-selected]=\"row.editing\"\n [class.mat-mdc-row-error]=\"row.invalid\"\n [class.mat-mdc-row-disabled]=\"!row.editing\"\n [class.mat-mdc-row-dirty]=\"row.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll\n *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\"\n position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\"\n >\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS' | translate\"\n ></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator\n *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\"\n showFirstLastButtons\n ></mat-paginator>\n\n <app-form-buttons-bar\n *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject | async) || !dirty\"\n >\n <!-- error -->\n <ion-item *ngIf=\"error$ | async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table{--mat-column-actions-min-width: 62px;--mat-column-actions-max-width: 62px}.table-container .mat-mdc-table .mat-row-selected{padding:3px}.table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i2$1.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i2$1.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i2$1.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: "directive", type: i6$5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8$3.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9$3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13$3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13$3.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i8$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "label", "appearance", "subscriptSizing", "placeholder", "suggestFn", "required", "hideRequiredMarker", "mobile", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "reloadItemsOnFocus", "clearInvalidValueOnBlur", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "splitSearchText", "selectInputContentOnFocus", "selectInputContentOnFocusDelay", "previewImplicitValue", "class", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keydown.backspace", "keyup.enter", "selectionChange"] }, { kind: "component", type: MatLatLongField, selector: "mat-latlong-field", inputs: ["formControl", "formControlName", "type", "latLongPattern", "maxDecimals", "required", "floatLabel", "placeholder", "defaultSign", "autofocus", "mobile", "degreesSymbolUnit", "minutesSymbolUnit", "secondsSymbolUnit", "clearable", "class", "tabindex", "appearance", "readonly", "subscriptSizing"] }, { kind: "component", type: MatDateTime, selector: "mat-date-time-field", inputs: ["placeholder", "floatLabel", "mobile", "compact", "autofocus", "clearable", "startDate", "datePickerFilter", "allowNoTime", "appearance", "subscriptSizing", "formControl", "formControlName", "required", "readonly", "tabindex"] }, { kind: "component", type: MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: NavActionsColumnComponent, selector: "app-nav-actions-column", inputs: ["appTable", "matColumnDef", "style", "stickyEnd", "showPending", "dirtyIcon", "optionsTitle", "class", "cellTemplate", "throttleTime"], outputs: ["optionsClick"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ResizableComponent, selector: "th[resizable]", inputs: ["resizable"], outputs: ["sizeChanged"] }, { kind: "directive", type: ResizableDirective, selector: "[resizable]", outputs: ["resizable", "fit"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: LatitudeFormatPipe, name: "latitudeFormat" }, { kind: "pipe", type: NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: FormGetValuePipe, name: "formGetValue" }, { kind: "pipe", type: IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: IsMultipleSelectionPipe, name: "isMultipleSelection" }, { kind: "pipe", type: IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: IsNotAllSelectedPipe, name: "isNotAllSelected" }, { kind: "pipe", type: ReferentialToStringPipe, name: "referentialToString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
44565
44878
  }
44566
44879
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: TableTestPage, decorators: [{
44567
44880
  type: Component,
@@ -45586,5 +45899,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
45586
45899
  * Generated bundle index. Do not edit.
45587
45900
  */
45588
45901
 
45589
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DisplayWithPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldDefinitionUtils, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, IsValidDatePipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_PATTERNS, LAT_LONG_PATTERN_MAX_DECIMALS, LAT_LONG_VALUE_MAX_DECIMALS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenForm, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegExpUtils, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, RxStateProperty, RxStateRegister, RxStateSelect, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ThrottledClickDirective, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, computeDecimalDegrees, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableAndClearControl, disableAndClearControls, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, enableRxStateProduction, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, getUserAgent, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isChrome, isControlHasInput, isEdge, isEmptyArray, isFirefox, isIOS, isInputElement, isInstanceOf, isInt, isIpad, isMacOS, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isPromise, isResponseEvent, isSafari, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputContentFromEvent, selectInputRange, setCalculatedValue, setControlEnabled, setControlsEnabled, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, splitNumberToFieldsDD, splitNumberToFieldsDDMM, splitNumberToFieldsDDMMSS, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
45902
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DisplayWithPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldDefinitionUtils, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, IsValidDatePipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_PATTERNS, LAT_LONG_PATTERN_MAX_DECIMALS, LAT_LONG_VALUE_MAX_DECIMALS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatLatLongFieldInput, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenForm, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegExpUtils, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, RxStateProperty, RxStateRegister, RxStateSelect, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ThrottledClickDirective, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, computeDecimalDegrees, computeDecimalPart, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableAndClearControl, disableAndClearControls, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, enableRxStateProduction, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, getUserAgent, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isChrome, isControlHasInput, isEdge, isEmptyArray, isFirefox, isIOS, isInputElement, isInstanceOf, isInt, isIpad, isMacOS, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isPromise, isResponseEvent, isSafari, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputContentFromEvent, selectInputRange, setCalculatedValue, setControlEnabled, setControlsEnabled, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, splitNumberToFieldsDD, splitNumberToFieldsDDMM, splitNumberToFieldsDDMMSS, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
45590
45903
  //# sourceMappingURL=sumaris-net.ngx-components.mjs.map