@sumaris-net/ngx-components 1.6.4 → 1.6.5

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Component, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Input, Output, ViewChild, HostBinding, Pipe, Injectable, Directive, Inject, NgModule, ElementRef, ViewChildren, HostListener, ComponentFactoryResolver, ApplicationRef, Injector, Renderer2, ViewEncapsulation } from '@angular/core';
2
+ import { InjectionToken, EventEmitter, Component, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Input, Output, ViewChild, Pipe, Injectable, Directive, Inject, NgModule, ElementRef, ViewChildren, HostListener, ComponentFactoryResolver, ApplicationRef, Injector, Renderer2, ViewEncapsulation } from '@angular/core';
3
3
  import * as i1$3 from '@angular/common';
4
4
  import { CommonModule, DOCUMENT, Location } from '@angular/common';
5
5
  import { CdkTableModule } from '@angular/cdk/table';
@@ -36,7 +36,7 @@ import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteModule, MAT_AUT
36
36
  import { __awaiter, __decorate } from 'tslib';
37
37
  import * as i1$6 from '@angular/forms';
38
38
  import { NG_VALUE_ACCESSOR, FormGroupDirective, AbstractControl, FormGroup, FormArray, FormControl, ReactiveFormsModule, Validators, FormBuilder } from '@angular/forms';
39
- import { timer, merge, fromEvent, BehaviorSubject, Subscription, Subject, isObservable, noop as noop$8, Observable, defer, of, from, combineLatest, EMPTY } from 'rxjs';
39
+ import { timer, merge, fromEvent, BehaviorSubject, Subscription, Subject, isObservable, noop as noop$9, Observable, defer, of, from, combineLatest, EMPTY } from 'rxjs';
40
40
  import { filter, first, map, takeUntil, switchMap, startWith, debounceTime, takeWhile, tap, distinctUntilChanged, mergeMap, catchError, throttleTime, skip } from 'rxjs/operators';
41
41
  import * as i1$1 from '@ngx-translate/core';
42
42
  import { TranslateService, TranslateModule } from '@ngx-translate/core';
@@ -976,10 +976,11 @@ class MatAutocompleteConfigHolder {
976
976
  const attributesOrFn = attributes.map((a, index) => typeof a === 'function' && options.attributes[index] || a);
977
977
  const filter = Object.assign({ searchAttribute: attributes.length === 1 ? attributes[0] : undefined, searchAttributes: attributes.length > 1 ? attributes : undefined }, options.filter);
978
978
  const displayWith = options.displayWith || ((obj) => obj && joinPropertiesPath(obj, attributes));
979
- const compareWith = options.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
979
+ const equals = options.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
980
980
  const config = Object.assign(Object.assign({}, options), { attributes: attributesOrFn, suggestFn,
981
981
  filter,
982
- displayWith, equals: compareWith });
982
+ displayWith,
983
+ equals });
983
984
  this.fields[fieldName] = config;
984
985
  return config;
985
986
  }
@@ -990,14 +991,14 @@ class MatAutocompleteConfigHolder {
990
991
  return this.fields[fieldName] || this.add(fieldName);
991
992
  }
992
993
  }
993
- const noop$7 = () => { };
994
- const ɵ0$a = noop$7;
994
+ const noop$8 = (_) => { };
995
+ const ɵ0$b = noop$8;
995
996
  class MatAutocompleteField {
996
997
  constructor(cd, formGroupDir) {
997
998
  this.cd = cd;
998
999
  this.formGroupDir = formGroupDir;
999
- this._onChangeCallback = noop$7;
1000
- this._onTouchedCallback = noop$7;
1000
+ this._onChangeCallback = noop$8;
1001
+ this._onTouchedCallback = noop$8;
1001
1002
  this.logPrefix = '[mat-autocomplete] ';
1002
1003
  this.formControlName = null;
1003
1004
  this.required = false;
@@ -1010,13 +1011,13 @@ class MatAutocompleteField {
1010
1011
  this.fetchMoreThreshold = '15%';
1011
1012
  this.suggestLengthThreshold = null;
1012
1013
  this.showLoadingSpinner = true;
1014
+ this.debug = false;
1013
1015
  this.clicked = new EventEmitter();
1014
1016
  this.blurred = new EventEmitter();
1015
1017
  this.focused = new EventEmitter();
1016
1018
  this.dropButtonClick = new EventEmitter(true);
1017
1019
  this.keydownEscape = new EventEmitter();
1018
1020
  this.keyupEnter = new EventEmitter();
1019
- this.animationsDisabled = true;
1020
1021
  this._readonly = false;
1021
1022
  this.$inputItems = new BehaviorSubject(undefined);
1022
1023
  this.$filteredItems = new BehaviorSubject(undefined);
@@ -1087,6 +1088,9 @@ class MatAutocompleteField {
1087
1088
  get enabled() {
1088
1089
  return !this._readonly && this.formControl.enabled;
1089
1090
  }
1091
+ get loading() {
1092
+ return isNil(this.$filteredItems.value);
1093
+ }
1090
1094
  ngOnInit() {
1091
1095
  var _a, _b;
1092
1096
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
@@ -1107,7 +1111,7 @@ class MatAutocompleteField {
1107
1111
  this.mobile = toBoolean(this.mobile, this.config.mobile);
1108
1112
  this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
1109
1113
  this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
1110
- this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus));
1114
+ this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
1111
1115
  this.classList = this.classList || this.config.class;
1112
1116
  this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
1113
1117
  this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
@@ -1185,15 +1189,15 @@ class MatAutocompleteField {
1185
1189
  // Filter if not enough character
1186
1190
  filter(value => value.length >= this.suggestLengthThreshold),
1187
1191
  // Wait a debounce time
1188
- debounceTime(this.debounceTime)
1192
+ debounceTime(this.debounceTime),
1189
1193
  // DEBUG
1190
- //tap((value) => console.debug(this.logPrefix + ' Search text changes:', value)),
1191
- ),
1194
+ tap((value) => console.debug(this.logPrefix + ' Search text changes:', value))),
1192
1195
  // Object set: use it (no distinctUntilChanged() pipe need)
1193
1196
  this.formControl.valueChanges
1194
1197
  .pipe(startWith(this.formControl.value), filter(value => (this.searchable && isNotNil(value) && typeof value === 'object')), tap(value => {
1195
1198
  // DEBUG
1196
- //console.debug(this.logPrefix + ' object changes:', value)
1199
+ if (this.debug)
1200
+ console.debug(this.logPrefix + ' object changes:', value);
1197
1201
  // Update the display value (if need)
1198
1202
  const displayValue = this.displayWith(value) || '';
1199
1203
  if (this.displayValue !== displayValue) {
@@ -1203,10 +1207,9 @@ class MatAutocompleteField {
1203
1207
  this.matInputText.nativeElement.value = this.displayValue;
1204
1208
  }
1205
1209
  }
1206
- })
1210
+ }),
1207
1211
  // DEBUG
1208
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
1209
- ),
1212
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
1210
1213
  // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
1211
1214
  this.dropButtonClick
1212
1215
  .pipe(filter(event => this.searchable && this.enabled && (!event || !event.defaultPrevented)), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
@@ -1216,20 +1219,23 @@ class MatAutocompleteField {
1216
1219
  merge(
1217
1220
  // Focus or click => Load all
1218
1221
  merge(this.focused, this.clicked)
1219
- .pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value)), merge(this.$inputItems, this._$filter)
1220
- .pipe(filter(_ => this.searchable && this.enabled), map(_ => this.formControl.value)))
1222
+ .pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
1223
+ // DEBUG
1224
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received focused or clicked event: ', value))), merge(this.$inputItems, this._$filter)
1225
+ .pipe(filter(_ => this.searchable && this.enabled), map(_ => this.formControl.value),
1226
+ // DEBUG
1227
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received $inputItems or filter event: ', value))))
1221
1228
  .pipe(
1222
- // Make enough characters
1229
+ // Make sure there is enough characters
1223
1230
  filter(thresholdFilterFn),
1224
1231
  // Distinguish changes
1225
- distinctUntilChanged(),
1226
- // DEBUG
1227
- tap(value => console.debug(this.logPrefix + ' Received update event: ', value))))
1232
+ // - do NOT filter if loading, to force update after a blur event
1233
+ distinctUntilChanged((v1, v2) => !this.loading && (v1 === v2 || this.equals(v1, v2)))))
1228
1234
  .pipe(
1229
1235
  // Suggest values
1230
1236
  mergeMap(value => this.suggest(value, this.filter)),
1231
1237
  // DEBUG
1232
- //tap(items => console.debug(this.logPrefix + ' Received from suggest: ', items)),
1238
+ tap(items => this.debug && console.debug(this.logPrefix + ' Received from suggest: ', items)),
1233
1239
  // Store implicit value (will use it onBlur if not other value selected)
1234
1240
  tap(items => this.updateImplicitValue(items)));
1235
1241
  // Fetch more events
@@ -1262,7 +1268,9 @@ class MatAutocompleteField {
1262
1268
  this._subscription.add(this.blurred
1263
1269
  .pipe(
1264
1270
  // Skip if not searchable
1265
- filter(_ => this.searchable), map(_ => this.formControl.value))
1271
+ filter(_ => this.searchable), map(_ => this.formControl.value),
1272
+ // DEBUG
1273
+ tap(value => console.debug(this.logPrefix + ' Received blurred event: ', value)))
1266
1274
  .subscribe(value => {
1267
1275
  // When leave component without object, use implicit value if :
1268
1276
  // - an explicit value
@@ -1348,7 +1356,7 @@ class MatAutocompleteField {
1348
1356
  }
1349
1357
  writeValue(value) {
1350
1358
  // DEBUG
1351
- // console.debug(this.logPrefix + " Writing value: ", value);
1359
+ // console.debug(this.logPrefix + ' Writing value: ', value);
1352
1360
  if (value !== this.formControl.value) {
1353
1361
  this.formControl.patchValue(value, { emitEvent: false });
1354
1362
  this._onChangeCallback(value);
@@ -1385,15 +1393,20 @@ class MatAutocompleteField {
1385
1393
  if (event.stopPropagation)
1386
1394
  event.stopPropagation();
1387
1395
  event.returnValue = false;
1388
- //DEBUG console.debug(this.logPrefix + ' Cancelling focus event');
1396
+ // DEBUG
1397
+ if (this.debug)
1398
+ console.debug(this.logPrefix + ' Cancelling focus event');
1389
1399
  return false;
1390
1400
  }
1391
- const hasContent = selectInputContent(event);
1401
+ if (this.debug)
1402
+ console.debug(this.logPrefix + ' Select input content');
1403
+ const hasContent = true; // selectInputContent(event);
1392
1404
  // If combo is empty, or if has content but should force to show panel on focus
1393
- if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
1405
+ if (!hasContent || this.showPanelOnFocus || this.showAllOnFocus) {
1394
1406
  // DEBUG
1395
- //console.debug(this.logPrefix + ' Emit focus event');
1396
- this.focused.emit(event);
1407
+ if (this.debug)
1408
+ console.debug(this.logPrefix + ' Emit focus event');
1409
+ this.focused.emit();
1397
1410
  return true;
1398
1411
  }
1399
1412
  return false;
@@ -1407,11 +1420,14 @@ class MatAutocompleteField {
1407
1420
  if (event.stopPropagation)
1408
1421
  event.stopPropagation();
1409
1422
  event.returnValue = false;
1410
- //DEBUG console.debug(this.logPrefix + " Cancelling blur event");
1423
+ // DEBUG
1424
+ if (this.debug)
1425
+ console.debug(this.logPrefix + " Cancelling blur event");
1411
1426
  return false;
1412
1427
  }
1413
1428
  //DEBUG
1414
- //console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1429
+ if (this.debug)
1430
+ console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1415
1431
  // Move caret to the beginning (fix issue IMAGINE-469)
1416
1432
  selectInputRange(event.target, 0, 0);
1417
1433
  this.blurred.emit(event);
@@ -1522,6 +1538,7 @@ class MatAutocompleteField {
1522
1538
  /* -- private method -- */
1523
1539
  suggest(value, filter) {
1524
1540
  return __awaiter(this, void 0, void 0, function* () {
1541
+ // Call suggestion function
1525
1542
  let res = yield this.suggestFn(value, filter);
1526
1543
  // DEBUG
1527
1544
  //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
@@ -1542,6 +1559,9 @@ class MatAutocompleteField {
1542
1559
  this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
1543
1560
  res = data;
1544
1561
  }
1562
+ // DEBUG
1563
+ if (this.debug)
1564
+ console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
1545
1565
  return res;
1546
1566
  });
1547
1567
  }
@@ -1613,7 +1633,7 @@ MatAutocompleteField.decorators = [
1613
1633
  { type: Component, args: [{
1614
1634
  // eslint-disable-next-line @angular-eslint/component-selector
1615
1635
  selector: 'mat-autocomplete-field',
1616
- template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- readonly -->\n <ng-container>\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [class.cdk-visually-hidden]=\"!searchable\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1636
+ template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- readonly -->\n <ng-container>\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1617
1637
  providers: [{
1618
1638
  provide: NG_VALUE_ACCESSOR,
1619
1639
  multi: true,
@@ -1658,6 +1678,7 @@ MatAutocompleteField.propDecorators = {
1658
1678
  fetchMoreThreshold: [{ type: Input }],
1659
1679
  suggestLengthThreshold: [{ type: Input }],
1660
1680
  showLoadingSpinner: [{ type: Input }],
1681
+ debug: [{ type: Input }],
1661
1682
  clicked: [{ type: Output, args: ['click',] }],
1662
1683
  blurred: [{ type: Output, args: ['blur',] }],
1663
1684
  focused: [{ type: Output, args: ['focus',] }],
@@ -1668,7 +1689,6 @@ MatAutocompleteField.propDecorators = {
1668
1689
  matInputText: [{ type: ViewChild, args: ['matInputText',] }],
1669
1690
  autocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
1670
1691
  autocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }],
1671
- animationsDisabled: [{ type: HostBinding, args: ['@.disabled',] }],
1672
1692
  filter: [{ type: Input }],
1673
1693
  readonly: [{ type: Input }],
1674
1694
  tabindex: [{ type: Input }],
@@ -4086,9 +4106,9 @@ const MASKS = {
4086
4106
  DD: [/[+-]/, /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, '°']
4087
4107
  }
4088
4108
  };
4089
- const noop$6 = () => {
4109
+ const noop$7 = () => {
4090
4110
  };
4091
- const ɵ0$9 = noop$6;
4111
+ const ɵ0$a = noop$7;
4092
4112
  class MatLatLongField {
4093
4113
  constructor(platform, translate, formBuilder, cd, formGroupDir) {
4094
4114
  this.platform = platform;
@@ -4096,8 +4116,8 @@ class MatLatLongField {
4096
4116
  this.formBuilder = formBuilder;
4097
4117
  this.cd = cd;
4098
4118
  this.formGroupDir = formGroupDir;
4099
- this._onChangeCallback = noop$6;
4100
- this._onTouchedCallback = noop$6;
4119
+ this._onChangeCallback = noop$7;
4120
+ this._onTouchedCallback = noop$7;
4101
4121
  this._subscription = new Subscription();
4102
4122
  this.disabling = false;
4103
4123
  this.writing = false;
@@ -4439,8 +4459,8 @@ const DEFAULT_VALUE_ACCESSOR$5 = {
4439
4459
  multi: true
4440
4460
  };
4441
4461
  const DAY_MASK$2 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
4442
- const noop$5 = () => { };
4443
- const ɵ0$8 = noop$5;
4462
+ const noop$6 = () => { };
4463
+ const ɵ0$9 = noop$6;
4444
4464
  class MatDate {
4445
4465
  constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
4446
4466
  this.dateAdapter = dateAdapter;
@@ -4449,8 +4469,8 @@ class MatDate {
4449
4469
  this.cd = cd;
4450
4470
  this.keyboard = keyboard;
4451
4471
  this.formGroupDir = formGroupDir;
4452
- this._onChangeCallback = noop$5;
4453
- this._onTouchedCallback = noop$5;
4472
+ this._onChangeCallback = noop$6;
4473
+ this._onTouchedCallback = noop$6;
4454
4474
  this._subscription = new Subscription();
4455
4475
  this.writing = true;
4456
4476
  this.disabling = false;
@@ -4732,9 +4752,9 @@ const DEFAULT_VALUE_ACCESSOR$4 = {
4732
4752
  const DAY_MASK$1 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
4733
4753
  const HOUR_REGEXP = /^[012][0-9][:][012345][0-9]$/;
4734
4754
  const HOUR_MASK$1 = [/[012]/, /\d/, ':', /[012345]/, /\d/];
4735
- const noop$4 = () => {
4755
+ const noop$5 = () => {
4736
4756
  };
4737
- const ɵ0$7 = noop$4;
4757
+ const ɵ0$8 = noop$5;
4738
4758
  class MatDateTime {
4739
4759
  constructor(platform, dateAdapter, translate, formBuilder, keyboard, cd, formGroupDir) {
4740
4760
  this.platform = platform;
@@ -4744,8 +4764,8 @@ class MatDateTime {
4744
4764
  this.keyboard = keyboard;
4745
4765
  this.cd = cd;
4746
4766
  this.formGroupDir = formGroupDir;
4747
- this._onChangeCallback = noop$4;
4748
- this._onTouchedCallback = noop$4;
4767
+ this._onChangeCallback = noop$5;
4768
+ this._onTouchedCallback = noop$5;
4749
4769
  this._subscription = new Subscription();
4750
4770
  this.writing = true;
4751
4771
  this.disabling = false;
@@ -5103,9 +5123,9 @@ const DEFAULT_VALUE_ACCESSOR$3 = {
5103
5123
  multi: true
5104
5124
  };
5105
5125
  const DAY_MASK = [/\d/, /\d/, /\d/, /\d/];
5106
- const noop$3 = () => {
5126
+ const noop$4 = () => {
5107
5127
  };
5108
- const ɵ0$6 = noop$3;
5128
+ const ɵ0$7 = noop$4;
5109
5129
  class MatDateShort {
5110
5130
  constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
5111
5131
  this.dateAdapter = dateAdapter;
@@ -5114,8 +5134,8 @@ class MatDateShort {
5114
5134
  this.cd = cd;
5115
5135
  this.keyboard = keyboard;
5116
5136
  this.formGroupDir = formGroupDir;
5117
- this._onChangeCallback = noop$3;
5118
- this._onTouchedCallback = noop$3;
5137
+ this._onChangeCallback = noop$4;
5138
+ this._onTouchedCallback = noop$4;
5119
5139
  this.writing = true;
5120
5140
  this.disabling = false;
5121
5141
  this.dayMask = DAY_MASK;
@@ -5438,9 +5458,9 @@ const DEFAULT_VALUE_ACCESSOR$2 = {
5438
5458
  };
5439
5459
  const HOUR_TIME_PATTERN = /[0-9]\d\d:[0-5]\d/;
5440
5460
  const HOUR_MASK = [/\d/, /\d/, /\d/, ':', /[0-5]/, /\d/];
5441
- const noop$2 = () => {
5461
+ const noop$3 = () => {
5442
5462
  };
5443
- const ɵ0$5 = noop$2;
5463
+ const ɵ0$6 = noop$3;
5444
5464
  class MatDuration {
5445
5465
  constructor(platform, dateAdapter, translate, formBuilder, cd, formGroupDir) {
5446
5466
  this.dateAdapter = dateAdapter;
@@ -5449,8 +5469,8 @@ class MatDuration {
5449
5469
  this.cd = cd;
5450
5470
  this.formGroupDir = formGroupDir;
5451
5471
  this._subscription = new Subscription();
5452
- this._onChangeCallback = noop$2;
5453
- this._onTouchedCallback = noop$2;
5472
+ this._onChangeCallback = noop$3;
5473
+ this._onTouchedCallback = noop$3;
5454
5474
  this.writing = true;
5455
5475
  this.disabling = false;
5456
5476
  this.hourMask = HOUR_MASK;
@@ -5695,17 +5715,17 @@ const DEFAULT_VALUE_ACCESSOR$1 = {
5695
5715
  useExisting: forwardRef(() => MatBooleanField),
5696
5716
  multi: true
5697
5717
  };
5698
- const noop$1 = () => {
5718
+ const noop$2 = () => {
5699
5719
  };
5700
- const ɵ0$4 = noop$1;
5720
+ const ɵ0$5 = noop$2;
5701
5721
  class MatBooleanField {
5702
5722
  constructor(translate, formBuilder, cd, formGroupDir) {
5703
5723
  this.translate = translate;
5704
5724
  this.formBuilder = formBuilder;
5705
5725
  this.cd = cd;
5706
5726
  this.formGroupDir = formGroupDir;
5707
- this._onChangeCallback = noop$1;
5708
- this._onTouchedCallback = noop$1;
5727
+ this._onChangeCallback = noop$2;
5728
+ this._onTouchedCallback = noop$2;
5709
5729
  this._writing = false;
5710
5730
  this.showRadio = false;
5711
5731
  this.disabled = false;
@@ -6488,8 +6508,8 @@ class MatSwipeField {
6488
6508
  constructor(cd, formGroupDir) {
6489
6509
  this.cd = cd;
6490
6510
  this.formGroupDir = formGroupDir;
6491
- this._onChangeCallback = noop$8;
6492
- this._onTouchedCallback = noop$8;
6511
+ this._onChangeCallback = noop$9;
6512
+ this._onTouchedCallback = noop$9;
6493
6513
  this._subscription = new Subscription();
6494
6514
  this._writing = false;
6495
6515
  this.showSlides = false;
@@ -6800,12 +6820,14 @@ SharedMatSwipeModule.decorators = [
6800
6820
  },] }
6801
6821
  ];
6802
6822
 
6823
+ const noop$1 = () => { };
6824
+ const ɵ0$4 = noop$1;
6803
6825
  class MatChipsField {
6804
6826
  constructor(cd, formGroupDir) {
6805
6827
  this.cd = cd;
6806
6828
  this.formGroupDir = formGroupDir;
6807
- this._onChangeCallback = (_) => { };
6808
- this._onTouchedCallback = () => { };
6829
+ this._onChangeCallback = noop$1;
6830
+ this._onTouchedCallback = noop$1;
6809
6831
  this.logPrefix = '[mat-chips] ';
6810
6832
  this.formControlName = null;
6811
6833
  this.required = false;
@@ -6814,12 +6836,12 @@ class MatChipsField {
6814
6836
  this.debounceTime = null;
6815
6837
  this.i18nPrefix = 'REFERENTIAL.';
6816
6838
  this.noResultMessage = 'COMMON.NO_RESULT';
6817
- this.debug = false;
6818
6839
  this.itemSize = '48px';
6819
6840
  this.fetchMoreThreshold = '15%';
6820
6841
  this.suggestLengthThreshold = null;
6821
6842
  this.showLoadingSpinner = true;
6822
6843
  this.chipColor = null;
6844
+ this.debug = false;
6823
6845
  this.clicked = new EventEmitter();
6824
6846
  this.blurred = new EventEmitter();
6825
6847
  this.focused = new EventEmitter();
@@ -6888,6 +6910,9 @@ class MatChipsField {
6888
6910
  get enabled() {
6889
6911
  return !this.readonly && this.formControl.enabled;
6890
6912
  }
6913
+ get loading() {
6914
+ return isNil(this.$filteredItems.value);
6915
+ }
6891
6916
  ngOnInit() {
6892
6917
  var _a, _b;
6893
6918
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
@@ -6983,19 +7008,9 @@ class MatChipsField {
6983
7008
  ),
6984
7009
  // Object set: use it (no distinctUntilChanged() pipe need)
6985
7010
  this.inputControl.valueChanges
6986
- .pipe(startWith(this.inputControl.value), filter(value => isNotNil(value) && typeof value === 'object'), tap(value => {
6987
- // DEBUG
6988
- //console.debug(this.logPrefix + ' object changes:', value)
6989
- // Update the display value (if need)
6990
- const displayValue = this.displayWith(value) || '';
6991
- // Apply to the input[type=text] field
6992
- if (this.matInputText && this.matInputText.nativeElement) {
6993
- this.matInputText.nativeElement.value = displayValue;
6994
- }
6995
- })
7011
+ .pipe(startWith(this.inputControl.value), filter(value => isNotNil(value) && typeof value === 'object'),
6996
7012
  // DEBUG
6997
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
6998
- ),
7013
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
6999
7014
  // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
7000
7015
  this.dropButtonClick
7001
7016
  .pipe(filter(event => this.enabled && (!event || !event.defaultPrevented)), tap(_ => this.matInputText.nativeElement.focus()), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
@@ -7085,7 +7100,9 @@ class MatChipsField {
7085
7100
  this._openedSubscription.unsubscribe();
7086
7101
  }
7087
7102
  this.$inputItems.complete();
7103
+ this.$inputItems.unsubscribe();
7088
7104
  this.$filteredItems.complete();
7105
+ this.$filteredItems.unsubscribe();
7089
7106
  this._reload$.complete();
7090
7107
  this._$filter.complete();
7091
7108
  this.dropButtonClick.complete();
@@ -7147,12 +7164,18 @@ class MatChipsField {
7147
7164
  this._reload$.next(value || '*');
7148
7165
  }
7149
7166
  writeValue(value) {
7150
- if (this.debug)
7151
- console.debug(this.logPrefix + ' Writing value: ', value);
7167
+ if (value && !Array.isArray(value)) {
7168
+ value = [value];
7169
+ }
7152
7170
  if (value !== this.formControl.value) {
7171
+ if (this.debug)
7172
+ console.debug(this.logPrefix + ' Writing value: ', value);
7153
7173
  this.formControl.patchValue(value, { emitEvent: false });
7154
7174
  this._onChangeCallback(value);
7155
7175
  }
7176
+ else {
7177
+ this.markForCheck();
7178
+ }
7156
7179
  }
7157
7180
  registerOnChange(fn) {
7158
7181
  this._onChangeCallback = fn;
@@ -7261,7 +7284,7 @@ class MatChipsField {
7261
7284
  // Call suggestion function
7262
7285
  let res = yield this.suggestFn(value, filter);
7263
7286
  // DEBUG
7264
- // console.debug(this.logPrefix + " Filtered items by suggestFn:", value, res);
7287
+ //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
7265
7288
  if (!res) {
7266
7289
  this._itemCount = 0;
7267
7290
  res = [];
@@ -7271,14 +7294,17 @@ class MatChipsField {
7271
7294
  this._itemCount = res.length || 0;
7272
7295
  }
7273
7296
  else {
7274
- const { data, total } = res;
7275
- res = data;
7297
+ const { data, total, fetchMore } = res;
7276
7298
  this._itemCount = toNumber(total, data && data.length || 0);
7299
+ this._onFetchMoreCallback = fetchMore;
7300
+ this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
7301
+ res = data;
7277
7302
  }
7278
7303
  // Filter out existing items
7279
7304
  const filteredData = (res || []).slice().filter(item1 => this.value.findIndex(item2 => this.equals(item1, item2)) === -1);
7280
- // Update items count
7281
- this._itemCount = this._itemCount - (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
7305
+ const removedItemCount = (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
7306
+ // Decrease the item count, with delta
7307
+ this._itemCount -= removedItemCount;
7282
7308
  if (this.debug)
7283
7309
  console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
7284
7310
  return res;
@@ -7308,6 +7334,12 @@ class MatChipsField {
7308
7334
  this._implicitValue = undefined;
7309
7335
  }
7310
7336
  }
7337
+ checkIfTouched() {
7338
+ if (this.formControl.touched) {
7339
+ this.cd.markForCheck();
7340
+ this._onTouchedCallback();
7341
+ }
7342
+ }
7311
7343
  getAutocompletePanel() {
7312
7344
  var _a, _b;
7313
7345
  const ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
@@ -7317,12 +7349,6 @@ class MatChipsField {
7317
7349
  }
7318
7350
  return ele;
7319
7351
  }
7320
- checkIfTouched() {
7321
- if (this.formControl.touched) {
7322
- this.cd.markForCheck();
7323
- this._onTouchedCallback();
7324
- }
7325
- }
7326
7352
  markForCheck() {
7327
7353
  this.cd.markForCheck();
7328
7354
  }
@@ -7342,13 +7368,11 @@ MatChipsField.decorators = [
7342
7368
  // eslint-disable-next-line @angular-eslint/component-selector
7343
7369
  selector: 'mat-chips-field',
7344
7370
  template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\" class=\"material-chips\" [class.mat-form-field-disabled]=\"disabled\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList\n (focus)=\"filterChipsFocusEvent($event)\" >\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\"\n [color]=\"chipColor\"\n >\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
7345
- providers: [
7346
- {
7371
+ providers: [{
7347
7372
  provide: NG_VALUE_ACCESSOR,
7348
7373
  multi: true,
7349
7374
  useExisting: forwardRef(() => MatChipsField)
7350
- }
7351
- ],
7375
+ }],
7352
7376
  encapsulation: ViewEncapsulation.None,
7353
7377
  changeDetection: ChangeDetectionStrategy.OnPush,
7354
7378
  styles: [":host{width:100%;display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}.mat-form-field-suffix{position:absolute!important;right:0!important;top:calc(100% - 50px)!important}.mat-chip.mat-standard-chip.mat-primary{background-color:var(--ion-color-primary);color:var(--ion-color-primary-contrast)}.mat-chip.mat-standard-chip.mat-secondary{background-color:var(--ion-color-secondary);color:var(--ion-color-secondary-contrast)}.mat-chip.mat-standard-chip.mat-tertiary{background-color:var(--ion-color-tertiary);color:var(--ion-color-tertiary-contrast)}.mat-chip.mat-standard-chip.mat-accent{background-color:var(--ion-color-accent);color:var(--ion-color-accent-contrast)}.mat-chip.mat-standard-chip.mat-warning{background-color:var(--ion-color-warning);color:var(--ion-color-warning-contrast)}"]
@@ -7385,12 +7409,12 @@ MatChipsField.propDecorators = {
7385
7409
  classList: [{ type: Input, args: ['class',] }],
7386
7410
  panelWidth: [{ type: Input }],
7387
7411
  matAutocompletePosition: [{ type: Input }],
7388
- debug: [{ type: Input }],
7389
7412
  itemSize: [{ type: Input }],
7390
7413
  fetchMoreThreshold: [{ type: Input }],
7391
7414
  suggestLengthThreshold: [{ type: Input }],
7392
7415
  showLoadingSpinner: [{ type: Input }],
7393
7416
  chipColor: [{ type: Input }],
7417
+ debug: [{ type: Input }],
7394
7418
  clicked: [{ type: Output }],
7395
7419
  blurred: [{ type: Output }],
7396
7420
  focused: [{ type: Output }],
@@ -16512,7 +16536,7 @@ class AutocompleteTestPage {
16512
16536
  constructor(formBuilder) {
16513
16537
  this.formBuilder = formBuilder;
16514
16538
  this._items = deepCopy$1(FAKE_ENTITIES$1, 100);
16515
- this.$items = new BehaviorSubject(undefined);
16539
+ this._$items = new BehaviorSubject(undefined);
16516
16540
  this.autocompleteFields = new MatAutocompleteConfigHolder();
16517
16541
  this.memoryHide = false;
16518
16542
  this.memoryMobile = true;
@@ -16541,7 +16565,7 @@ class AutocompleteTestPage {
16541
16565
  });
16542
16566
  // From $items observable
16543
16567
  this.autocompleteFields.add('entity-$items', {
16544
- items: this.$items,
16568
+ items: this._$items,
16545
16569
  attributes: ['label', 'name'],
16546
16570
  displayWith: this.entityToString
16547
16571
  });
@@ -16579,7 +16603,7 @@ class AutocompleteTestPage {
16579
16603
  }
16580
16604
  loadItems() {
16581
16605
  return __awaiter(this, void 0, void 0, function* () {
16582
- this.$items.next(this._items.slice());
16606
+ this._$items.next(this._items.slice());
16583
16607
  });
16584
16608
  }
16585
16609
  entityToString(item) {
@@ -16609,7 +16633,7 @@ class AutocompleteTestPage {
16609
16633
  doSubmit(event) {
16610
16634
  console.debug('Validate form: ', this.form.value);
16611
16635
  }
16612
- compareWithFn(o1, o2) {
16636
+ equals(o1, o2) {
16613
16637
  return o1 && o2 && o1.id === o2.id;
16614
16638
  }
16615
16639
  toggleMode(value) {
@@ -16640,7 +16664,7 @@ class AutocompleteTestPage {
16640
16664
  AutocompleteTestPage.decorators = [
16641
16665
  { type: Component, args: [{
16642
16666
  selector: 'app-autocomplete-test',
16643
- template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable&lt;any[]&gt;</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) =&gt; any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\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\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\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\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-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\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-suggest]'\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\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-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\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\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\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\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [equals]=\"compareWithFn\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\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\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16667
+ template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable&lt;any[]&gt;</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) =&gt; any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\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\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\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\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-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\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-suggest]'\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\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-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\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\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\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\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\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\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16644
16668
  },] }
16645
16669
  ];
16646
16670
  AutocompleteTestPage.ctorParameters = () => [
@@ -16907,13 +16931,24 @@ const FAKE_ENTITIES = [
16907
16931
  { id: 6, label: 'FFF', name: 'Item F' },
16908
16932
  { id: 7, label: 'GGG', name: 'Item G' }
16909
16933
  ];
16910
- function deepCopy(values) {
16911
- return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));
16934
+ function deepCopy(values, size) {
16935
+ if (isNil(size)) {
16936
+ return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));
16937
+ }
16938
+ let result = [];
16939
+ let i = 1;
16940
+ while (result.length < size) {
16941
+ result = result.concat((values || FAKE_ENTITIES).map(entity => {
16942
+ const name = entity.name + ' #' + i;
16943
+ return Object.assign(Object.assign({}, entity), { id: i++, name });
16944
+ }));
16945
+ }
16946
+ return result.slice(0, size);
16912
16947
  }
16913
16948
  class ChipsTestPage {
16914
16949
  constructor(formBuilder) {
16915
16950
  this.formBuilder = formBuilder;
16916
- this._items = deepCopy(FAKE_ENTITIES);
16951
+ this._items = deepCopy(FAKE_ENTITIES, 100);
16917
16952
  this._$items = new BehaviorSubject(undefined);
16918
16953
  this.autocompleteFields = new MatAutocompleteConfigHolder();
16919
16954
  this.form = formBuilder.group({
@@ -16933,12 +16968,12 @@ class ChipsTestPage {
16933
16968
  });
16934
16969
  // From items
16935
16970
  this.autocompleteFields.add('entity-items', {
16936
- items: FAKE_ENTITIES.slice(),
16971
+ items: this._items.slice(),
16937
16972
  attributes: ['label', 'name'],
16938
16973
  displayWith: this.entityToString,
16939
16974
  equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0
16940
16975
  });
16941
- // From items
16976
+ // From $items observable
16942
16977
  this.autocompleteFields.add('entity-$items', {
16943
16978
  items: this._$items,
16944
16979
  attributes: ['label', 'name'],
@@ -16952,18 +16987,20 @@ class ChipsTestPage {
16952
16987
  // Load the form with data
16953
16988
  loadData() {
16954
16989
  return __awaiter(this, void 0, void 0, function* () {
16990
+ const items = deepCopy(FAKE_ENTITIES);
16955
16991
  const data = {
16956
- entity: [],
16957
- // THis item is NOT in the items list => i should be displayed anyway
16958
- entityInitial: FAKE_ENTITIES.slice(1, 2),
16959
- disableEntity: FAKE_ENTITIES.slice(1, 2)
16992
+ entity: items.slice(0, 1),
16993
+ entityInitial: items.slice(1, 2),
16994
+ disableEntity: items.slice(1, 2)
16960
16995
  };
16961
16996
  this.form.setValue(data);
16997
+ // Load observables
16998
+ setTimeout(() => this.loadItems(), 1000);
16962
16999
  });
16963
17000
  }
16964
17001
  loadItems() {
16965
17002
  return __awaiter(this, void 0, void 0, function* () {
16966
- this._$items.next(deepCopy(FAKE_ENTITIES));
17003
+ this._$items.next(this._items.slice());
16967
17004
  });
16968
17005
  }
16969
17006
  entityToString(item) {
@@ -16971,7 +17008,23 @@ class ChipsTestPage {
16971
17008
  }
16972
17009
  suggest(value, filter) {
16973
17010
  return __awaiter(this, void 0, void 0, function* () {
16974
- return suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
17011
+ filter = Object.assign({ offset: 0, size: 30 }, filter);
17012
+ const res = suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
17013
+ // Simulate a size = 30
17014
+ const total = res.total || res.data.length;
17015
+ const nextOffset = filter.offset + res.data.length;
17016
+ if (nextOffset < total) {
17017
+ filter = Object.assign(Object.assign({}, filter), { offset: nextOffset });
17018
+ return {
17019
+ total,
17020
+ data: res.data,
17021
+ fetchMore: (variables) => __awaiter(this, void 0, void 0, function* () {
17022
+ yield sleep(1000);
17023
+ return this.suggest(value, Object.assign(Object.assign({}, filter), variables));
17024
+ })
17025
+ };
17026
+ }
17027
+ return res;
16975
17028
  });
16976
17029
  }
16977
17030
  doSubmit(event) {
@@ -16988,7 +17041,7 @@ class ChipsTestPage {
16988
17041
  ChipsTestPage.decorators = [
16989
17042
  { type: Component, args: [{
16990
17043
  selector: 'app-chips-test',
16991
- template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Chips field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Suggest() function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-empty] '\"\n chipColor=\"accent\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\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\">\n Suggest() function with initial value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entityInitial\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\n chipColor=\"primary\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entityInitial.value)}}\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\n chipColor=\"warning\"\n ></mat-chips-field>\n {{stringify(form.controls.disableEntity.value)}}\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\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-readonly] '\"\n [readonly]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
17044
+ template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Chips field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Suggest() function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-empty] '\"\n chipColor=\"accent\"\n [debug]=\"false\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\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\">\n Suggest() function with initial value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entityInitial\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\n chipColor=\"primary\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entityInitial.value)}}\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\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\n chipColor=\"warning\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.disableEntity.value)}}\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\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-readonly] '\"\n [readonly]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16992
17045
  },] }
16993
17046
  ];
16994
17047
  ChipsTestPage.ctorParameters = () => [
@@ -24924,5 +24977,5 @@ const ErrorCodes = {
24924
24977
  * Generated bundle index. Do not edit.
24925
24978
  */
24926
24979
 
24927
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0$5 as ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk, AppIconComponent as ɵl };
24980
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk, AppIconComponent as ɵl };
24928
24981
  //# sourceMappingURL=sumaris-net.ngx-components.js.map