@sumaris-net/ngx-components 1.6.2 → 1.6.3

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.
@@ -1262,11 +1262,10 @@
1262
1262
  var attributesOrFn = attributes.map(function (a, index) { return typeof a === 'function' && options.attributes[index] || a; });
1263
1263
  var filter = Object.assign({ searchAttribute: attributes.length === 1 ? attributes[0] : undefined, searchAttributes: attributes.length > 1 ? attributes : undefined }, options.filter);
1264
1264
  var displayWith = options.displayWith || (function (obj) { return obj && joinPropertiesPath(obj, attributes); });
1265
- var compareWith = options.compareWith || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
1265
+ var compareWith = options.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
1266
1266
  var config = Object.assign(Object.assign({}, options), { attributes: attributesOrFn, suggestFn: suggestFn,
1267
1267
  filter: filter,
1268
- displayWith: displayWith,
1269
- compareWith: compareWith });
1268
+ displayWith: displayWith, equals: compareWith });
1270
1269
  this.fields[fieldName] = config;
1271
1270
  return config;
1272
1271
  };
@@ -1278,11 +1277,6 @@
1278
1277
  };
1279
1278
  return MatAutocompleteConfigHolder;
1280
1279
  }());
1281
- var DEFAULT_VALUE_ACCESSOR$6 = {
1282
- provide: i1.NG_VALUE_ACCESSOR,
1283
- useExisting: i0.forwardRef(function () { return MatAutocompleteField; }),
1284
- multi: true
1285
- };
1286
1280
  var noop$7 = function () { };
1287
1281
  var ɵ0$a = noop$7;
1288
1282
  var MatAutocompleteField = /** @class */ (function () {
@@ -1291,14 +1285,6 @@
1291
1285
  this.formGroupDir = formGroupDir;
1292
1286
  this._onChangeCallback = noop$7;
1293
1287
  this._onTouchedCallback = noop$7;
1294
- this._subscription = new rxjs.Subscription();
1295
- this._filter$ = new rxjs.BehaviorSubject(undefined);
1296
- this._reload$ = new rxjs.Subject();
1297
- this._readonly = false;
1298
- this.$inputItems = new rxjs.BehaviorSubject(undefined);
1299
- this.$filteredItems = new rxjs.BehaviorSubject(undefined);
1300
- this.displayValue = '';
1301
- this._fetchMore$ = new i0.EventEmitter();
1302
1288
  this.logPrefix = '[mat-autocomplete] ';
1303
1289
  this.formControlName = null;
1304
1290
  this.required = false;
@@ -1311,13 +1297,21 @@
1311
1297
  this.fetchMoreThreshold = '15%';
1312
1298
  this.suggestLengthThreshold = null;
1313
1299
  this.showLoadingSpinner = true;
1300
+ this.clicked = new i0.EventEmitter();
1301
+ this.blurred = new i0.EventEmitter();
1302
+ this.focused = new i0.EventEmitter();
1303
+ this.dropButtonClick = new i0.EventEmitter(true);
1304
+ this.keydownEscape = new i0.EventEmitter();
1305
+ this.keyupEnter = new i0.EventEmitter();
1314
1306
  this.animationsDisabled = true;
1315
- this.onClick = new i0.EventEmitter();
1316
- this.onBlur = new i0.EventEmitter();
1317
- this.onFocus = new i0.EventEmitter();
1318
- this.onDropButtonClick = new i0.EventEmitter(true);
1319
- this.onKeydownEscape = new i0.EventEmitter();
1320
- this.onKeyupEnter = new i0.EventEmitter();
1307
+ this._readonly = false;
1308
+ this.$inputItems = new rxjs.BehaviorSubject(undefined);
1309
+ this.$filteredItems = new rxjs.BehaviorSubject(undefined);
1310
+ this.displayValue = '';
1311
+ this._fetchMore$ = new i0.EventEmitter();
1312
+ this._subscription = new rxjs.Subscription();
1313
+ this._$filter = new rxjs.BehaviorSubject(undefined);
1314
+ this._reload$ = new rxjs.Subject();
1321
1315
  }
1322
1316
  Object.defineProperty(MatAutocompleteField.prototype, "itemCount", {
1323
1317
  get: function () {
@@ -1335,13 +1329,13 @@
1335
1329
  });
1336
1330
  Object.defineProperty(MatAutocompleteField.prototype, "filter", {
1337
1331
  get: function () {
1338
- return this._filter$.value;
1332
+ return this._$filter.value;
1339
1333
  },
1340
1334
  set: function (value) {
1341
- if (value !== this._filter$.value) {
1335
+ if (value !== this._$filter.value) {
1342
1336
  // DEBUG
1343
1337
  //console.debug(this.logPrefix + " Setting filter:", value);
1344
- this._filter$.next(value);
1338
+ this._$filter.next(value);
1345
1339
  }
1346
1340
  },
1347
1341
  enumerable: false,
@@ -1434,6 +1428,7 @@
1434
1428
  this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;
1435
1429
  this.displayColumnNames = this.displayColumnNames || this.config.columnNames;
1436
1430
  this.displayWith = this.displayWith || this.config.displayWith;
1431
+ this.equals = this.equals || this.config.equals;
1437
1432
  this.mobile = toBoolean(this.mobile, this.config.mobile);
1438
1433
  this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
1439
1434
  this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
@@ -1448,21 +1443,18 @@
1448
1443
  this.displayColumnSizes = this.displayColumnSizes
1449
1444
  // if only column: auto size
1450
1445
  || (this.displayAttributes.length === 1 && [undefined])
1451
- || this.displayAttributes.map(function (attr) {
1452
- // If label, set col size = 2
1453
- return (attr && attr.endsWith('label')) ? 2 :
1454
- // If rankOrder => col size = 1
1455
- ((attr && attr.endsWith('rankOrder')) ? 1
1456
- // Else => auto size
1457
- : undefined);
1458
- });
1446
+ // Computed column size:
1447
+ // - if label then col size = 2
1448
+ // - if rankOrder then col size = 1
1449
+ // - ese => auto size
1450
+ || this.displayAttributes.map(function (attr) { return (attr && attr.endsWith('label')) ? 2
1451
+ : ((attr && attr.endsWith('rankOrder')) ? 1
1452
+ : undefined); });
1459
1453
  this.displayColumnNames = this.displayAttributes.map(function (attr, index) { return _this.displayColumnNames && _this.displayColumnNames[index] ||
1460
1454
  (_this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()); });
1461
1455
  this.mobile = toBoolean(this.mobile, false);
1462
1456
  this.searchable = !this.mobile && !this.multiple;
1463
- // Default comparator (only need when using mat-select)
1464
- if (!this.searchable && !this.compareWith)
1465
- this.compareWith = function (o1, o2) { return o1 && o2 && o1.id === o2.id; };
1457
+ this.equals = this.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
1466
1458
  var classList = (_b = this.classList) === null || _b === void 0 ? void 0 : _b.split(' ');
1467
1459
  this.panelWidth = this.panelWidth || (classList && ((classList.includes('min-width-medium') && '300px')
1468
1460
  || (classList.includes('min-width-large') && '400px')
@@ -1478,7 +1470,7 @@
1478
1470
  var suggestFromArrayFn_1 = function (value, filter) { return __awaiter(_this, void 0, void 0, function () {
1479
1471
  return __generator(this, function (_e) {
1480
1472
  // DEBUG
1481
- //console.debug(this.logPrefix + " Calling suggestFromArray with value=", value);
1473
+ //console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);
1482
1474
  return [2 /*return*/, suggestFromArray(this.$inputItems.value, value, Object.assign({ searchAttributes: this.displayAttributes }, filter))];
1483
1475
  });
1484
1476
  }); };
@@ -1505,7 +1497,7 @@
1505
1497
  }
1506
1498
  else if (!this.searchable) {
1507
1499
  // Manually fill input items, from the given suggest function
1508
- this._subscription.add(this._filter$.pipe(operators.startWith(this.filter), operators.debounceTime(250), operators.takeWhile(function (_) { return !_this.searchable; }), // Close subscription, when enabling search (no more mat-select)
1500
+ this._subscription.add(this._$filter.pipe(operators.startWith(this.filter), operators.debounceTime(250), operators.takeWhile(function (_) { return !_this.searchable; }), // Close subscription, when enabling search (no more mat-select)
1509
1501
  operators.switchMap(function (filter) { return _this.suggest('*', filter); }))
1510
1502
  .subscribe(function (items) { return _this.$inputItems.next(items); }));
1511
1503
  }
@@ -1516,11 +1508,7 @@
1516
1508
  this.formControl.valueChanges
1517
1509
  .pipe(operators.filter(function (value) { return _this.enabled && _this.searchable && isNotNilString(value); }),
1518
1510
  // Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
1519
- operators.tap(function (value) {
1520
- if (_this.showLoadingSpinner) {
1521
- _this.markAsLoading();
1522
- }
1523
- }),
1511
+ operators.tap(function (_) { return _this.showLoadingSpinner && _this.markAsLoading(); }),
1524
1512
  // Filter if not enough character
1525
1513
  operators.filter(function (value) { return value.length >= _this.suggestLengthThreshold; }),
1526
1514
  // Wait a debounce time
@@ -1549,12 +1537,12 @@
1549
1537
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
1550
1538
  rxjs.merge(
1551
1539
  // Focus or click => Load all
1552
- rxjs.merge(this.onFocus, this.onClick)
1540
+ rxjs.merge(this.focused, this.clicked)
1553
1541
  .pipe(operators.filter(function (_) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })),
1554
1542
  // On dropdown button click
1555
- this.onDropButtonClick
1556
- .pipe(operators.filter(function (event) { return _this.enabled && _this.searchable && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })), rxjs.merge(this.$inputItems, this._filter$)
1557
- .pipe(operators.filter(function (event) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.formControl.value; })))
1543
+ this.dropButtonClick
1544
+ .pipe(operators.filter(function (event) { return _this.searchable && _this.enabled && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })), rxjs.merge(this.$inputItems, this._$filter)
1545
+ .pipe(operators.filter(function (_) { return _this.searchable && _this.enabled; }), operators.map(function (_) { return _this.formControl.value; })))
1558
1546
  .pipe(
1559
1547
  // Start to suggest when :
1560
1548
  // - '*'
@@ -1593,7 +1581,7 @@
1593
1581
  // Make sure control value is inside (mat-select)
1594
1582
  if (items && !_this.searchable) {
1595
1583
  var value_1 = _this.formControl.value;
1596
- if (isNotNil(value_1) && typeof value_1 === 'object' && items.findIndex(function (item) { return _this.compareWith(item, value_1); }) === -1) {
1584
+ if (isNotNil(value_1) && typeof value_1 === 'object' && items.findIndex(function (item) { return _this.equals(item, value_1); }) === -1) {
1597
1585
  // If form value is missing: add it to the list
1598
1586
  items = items.concat(value_1);
1599
1587
  }
@@ -1602,7 +1590,7 @@
1602
1590
  _this.$filteredItems.next(items);
1603
1591
  }));
1604
1592
  // Applying implicit value, on blur
1605
- this._subscription.add(this.onBlur
1593
+ this._subscription.add(this.blurred
1606
1594
  .pipe(
1607
1595
  // Skip if not searchable
1608
1596
  operators.filter(function (_) { return _this.searchable; }), operators.map(function (_) { return _this.formControl.value; }))
@@ -1632,7 +1620,7 @@
1632
1620
  operators.distinctUntilChanged())
1633
1621
  // Update component state
1634
1622
  .subscribe(function () { return _this.checkIfTouched(); }));
1635
- this._subscription.add(this.onKeydownEscape.subscribe(function (event) {
1623
+ this._subscription.add(this.keydownEscape.subscribe(function (event) {
1636
1624
  if (_this.isOpen) {
1637
1625
  event === null || event === void 0 ? void 0 : event.stopPropagation();
1638
1626
  event === null || event === void 0 ? void 0 : event.preventDefault();
@@ -1653,18 +1641,18 @@
1653
1641
  this.$inputItems.complete();
1654
1642
  this.$filteredItems.complete();
1655
1643
  this._reload$.complete();
1656
- this._filter$.complete();
1657
- this.onDropButtonClick.complete();
1658
- this.onClick.complete();
1659
- this.onBlur.complete();
1660
- this.onFocus.complete();
1661
- this.onKeydownEscape.complete();
1662
- this.onKeyupEnter.complete();
1644
+ this._$filter.complete();
1645
+ this.dropButtonClick.complete();
1646
+ this.clicked.complete();
1647
+ this.blurred.complete();
1648
+ this.focused.complete();
1649
+ this.keydownEscape.complete();
1650
+ this.keyupEnter.complete();
1663
1651
  this._fetchMore$.complete();
1664
1652
  this._implicitValue = undefined;
1665
1653
  this.formControl = null;
1666
1654
  this.displayWith = null;
1667
- this.compareWith = null;
1655
+ this.equals = null;
1668
1656
  this.suggestFn = null;
1669
1657
  this.$filteredItems = null;
1670
1658
  this.matSelectItems$ = null;
@@ -1674,8 +1662,8 @@
1674
1662
  this._onTouchedCallback = null;
1675
1663
  this._onFetchMoreCallback = null;
1676
1664
  // Destroy the 'autocomplete' instance, to avoid memory leak
1677
- if (this.matAutocomplete) {
1678
- this.matAutocomplete.ngOnDestroy();
1665
+ if (this.autocomplete) {
1666
+ this.autocomplete.ngOnDestroy();
1679
1667
  }
1680
1668
  };
1681
1669
  /**
@@ -1701,7 +1689,7 @@
1701
1689
  };
1702
1690
  MatAutocompleteField.prototype.setDisabledState = function (isDisabled) {
1703
1691
  var _a;
1704
- if (isDisabled && ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
1692
+ if (isDisabled && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
1705
1693
  this.closePanel();
1706
1694
  }
1707
1695
  this.cd.markForCheck();
@@ -1715,7 +1703,7 @@
1715
1703
  (_a = this.matSelect) === null || _a === void 0 ? void 0 : _a.focus();
1716
1704
  }
1717
1705
  };
1718
- MatAutocompleteField.prototype.filterInputTextFocusInEvent = function (event) {
1706
+ MatAutocompleteField.prototype.filterInputTextFocusEvent = function (event) {
1719
1707
  if (!event || event.defaultPrevented)
1720
1708
  return;
1721
1709
  // Ignore event from mat-option
@@ -1724,7 +1712,7 @@
1724
1712
  if (event.stopPropagation)
1725
1713
  event.stopPropagation();
1726
1714
  event.returnValue = false;
1727
- //DEBUG console.debug(this.logPrefix + " Cancelling focus event");
1715
+ //DEBUG console.debug(this.logPrefix + ' Cancelling focus event');
1728
1716
  return false;
1729
1717
  }
1730
1718
  var hasContent = selectInputContent(event);
@@ -1732,7 +1720,7 @@
1732
1720
  if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
1733
1721
  // DEBUG
1734
1722
  //console.debug(this.logPrefix + ' Emit focus event');
1735
- this.onFocus.emit(event);
1723
+ this.focused.emit(event);
1736
1724
  return true;
1737
1725
  }
1738
1726
  return false;
@@ -1753,7 +1741,7 @@
1753
1741
  //console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1754
1742
  // Move caret to the beginning (fix issue IMAGINE-469)
1755
1743
  selectInputRange(event.target, 0, 0);
1756
- this.onBlur.emit(event);
1744
+ this.blurred.emit(event);
1757
1745
  return true;
1758
1746
  };
1759
1747
  MatAutocompleteField.prototype.filterMatSelectFocusEvent = function (event) {
@@ -1761,7 +1749,7 @@
1761
1749
  return;
1762
1750
  // DEBUG
1763
1751
  // console.debug(this.logPrefix + " Received <mat-select> focus event", event);
1764
- this.onFocus.emit(event);
1752
+ this.focused.emit(event);
1765
1753
  };
1766
1754
  MatAutocompleteField.prototype.filterMatSelectBlurEvent = function (event) {
1767
1755
  if (!event || event.defaultPrevented)
@@ -1778,7 +1766,7 @@
1778
1766
  // console.debug(this.logPrefix + " Cancelling <mat-select> blur event");
1779
1767
  return false;
1780
1768
  }
1781
- this.onBlur.emit(event);
1769
+ this.blurred.emit(event);
1782
1770
  return true;
1783
1771
  };
1784
1772
  MatAutocompleteField.prototype.toggleSearch = function (event) {
@@ -1801,7 +1789,7 @@
1801
1789
  };
1802
1790
  MatAutocompleteField.prototype._initAutocompleteInfiniteScroll = function (threshold) {
1803
1791
  var _this = this;
1804
- if (!this.matAutocomplete)
1792
+ if (!this.autocomplete)
1805
1793
  return; // Skip
1806
1794
  // DEBUG
1807
1795
  //console.debug(this.logPrefix + ' Init autocomplete scroll listener');
@@ -1809,12 +1797,12 @@
1809
1797
  this._openedSubscription.unsubscribe();
1810
1798
  this._subscription.remove(this._openedSubscription);
1811
1799
  }
1812
- var opened$ = this.matAutocomplete._isOpen
1800
+ var opened$ = this.autocomplete._isOpen
1813
1801
  ? rxjs.timer(0)
1814
- : this.matAutocomplete.opened.pipe(operators.debounceTime(200));
1802
+ : this.autocomplete.opened.pipe(operators.debounceTime(200));
1815
1803
  var scrollEnd$ = opened$
1816
1804
  .pipe(operators.map(function (_) { return _this.getAutocompletePanel(); }), operators.filter(isNotNil), operators.switchMap(function (panel) { return fromScrollEndEvent(panel, threshold)
1817
- .pipe(operators.takeUntil(_this.matAutocomplete.closed)); }));
1805
+ .pipe(operators.takeUntil(_this.autocomplete.closed)); }));
1818
1806
  // Trigger fetch more, end end scroll reached
1819
1807
  this._openedSubscription = scrollEnd$
1820
1808
  .subscribe(function () { return _this._fetchMore$.emit(); });
@@ -1847,7 +1835,7 @@
1847
1835
  Object.defineProperty(MatAutocompleteField.prototype, "isOpen", {
1848
1836
  get: function () {
1849
1837
  var _a, _b;
1850
- return (this.searchable && ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen))
1838
+ return (this.searchable && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen))
1851
1839
  || ((_b = this.matSelect) === null || _b === void 0 ? void 0 : _b.panelOpen)
1852
1840
  || false;
1853
1841
  },
@@ -1856,8 +1844,8 @@
1856
1844
  });
1857
1845
  MatAutocompleteField.prototype.closePanel = function () {
1858
1846
  var _a, _b, _c, _d;
1859
- if ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
1860
- (_b = this.matAutocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
1847
+ if ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
1848
+ (_b = this.autocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
1861
1849
  return;
1862
1850
  }
1863
1851
  if ((_c = this.matSelect) === null || _c === void 0 ? void 0 : _c.panelOpen) {
@@ -1938,7 +1926,7 @@
1938
1926
  };
1939
1927
  MatAutocompleteField.prototype.getAutocompletePanel = function () {
1940
1928
  var _a, _b;
1941
- var ele = (_b = (_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
1929
+ var ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
1942
1930
  if (!ele) {
1943
1931
  // DEBUG
1944
1932
  console.warn(this.logPrefix + ' Unable to find the autocomplete div...');
@@ -1973,8 +1961,12 @@
1973
1961
  { type: i0.Component, args: [{
1974
1962
  // eslint-disable-next-line @angular-eslint/component-selector
1975
1963
  selector: 'mat-autocomplete-field',
1976
- 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)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n [compareWith]=\"compareWith\"\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)=\"onClick.emit($event)\"\n (focus)=\"filterInputTextFocusInEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.opened && onDropButtonClick.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>{{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: 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\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)=\"onDropButtonClick.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",
1977
- providers: [DEFAULT_VALUE_ACCESSOR$6],
1964
+ 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)=\"!autocomplete.opened && 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",
1965
+ providers: [{
1966
+ provide: i1.NG_VALUE_ACCESSOR,
1967
+ multi: true,
1968
+ useExisting: i0.forwardRef(function () { return MatAutocompleteField; })
1969
+ }],
1978
1970
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
1979
1971
  styles: [":host{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%}.fact-scroll-viewport{height:100%;width:100%}.fact-item{height:54px;display:flex}.fact-item .fact-date{min-width:100px;text-align:center;font-size:24pt}.fact-item .fact-date,.fact-item .fact-text{height:100%;align-items:center;justify-content:center;display:flex}.fact-item .fact-text{border-radius:10px}cdk-virtual-scroll-viewport{border:1px solid #000}cdk-virtual-scroll-viewport li{list-style:none}"]
1980
1972
  },] }
@@ -1984,7 +1976,7 @@
1984
1976
  { type: i1.FormGroupDirective, decorators: [{ type: i0.Optional }] }
1985
1977
  ]; };
1986
1978
  MatAutocompleteField.propDecorators = {
1987
- compareWith: [{ type: i0.Input }],
1979
+ equals: [{ type: i0.Input }],
1988
1980
  logPrefix: [{ type: i0.Input }],
1989
1981
  formControl: [{ type: i0.Input }],
1990
1982
  formControlName: [{ type: i0.Input }],
@@ -2014,21 +2006,21 @@
2014
2006
  fetchMoreThreshold: [{ type: i0.Input }],
2015
2007
  suggestLengthThreshold: [{ type: i0.Input }],
2016
2008
  showLoadingSpinner: [{ type: i0.Input }],
2009
+ clicked: [{ type: i0.Output, args: ['click',] }],
2010
+ blurred: [{ type: i0.Output, args: ['blur',] }],
2011
+ focused: [{ type: i0.Output, args: ['focus',] }],
2012
+ dropButtonClick: [{ type: i0.Output }],
2013
+ keydownEscape: [{ type: i0.Output, args: ['keydown.escape',] }],
2014
+ keyupEnter: [{ type: i0.Output, args: ['keyup.enter',] }],
2015
+ matSelect: [{ type: i0.ViewChild, args: ['matSelect',] }],
2016
+ matInputText: [{ type: i0.ViewChild, args: ['matInputText',] }],
2017
+ autocomplete: [{ type: i0.ViewChild, args: [autocomplete.MatAutocomplete,] }],
2018
+ autocompleteTrigger: [{ type: i0.ViewChild, args: [autocomplete.MatAutocompleteTrigger,] }],
2017
2019
  animationsDisabled: [{ type: i0.HostBinding, args: ['@.disabled',] }],
2018
2020
  filter: [{ type: i0.Input }],
2019
2021
  readonly: [{ type: i0.Input }],
2020
2022
  tabindex: [{ type: i0.Input }],
2021
- items: [{ type: i0.Input }],
2022
- onClick: [{ type: i0.Output, args: ['click',] }],
2023
- onBlur: [{ type: i0.Output, args: ['blur',] }],
2024
- onFocus: [{ type: i0.Output, args: ['focus',] }],
2025
- onDropButtonClick: [{ type: i0.Output, args: ['dropButtonClick',] }],
2026
- onKeydownEscape: [{ type: i0.Output, args: ['keydown.escape',] }],
2027
- onKeyupEnter: [{ type: i0.Output, args: ['keyup.enter',] }],
2028
- matSelect: [{ type: i0.ViewChild, args: ['matSelect',] }],
2029
- matInputText: [{ type: i0.ViewChild, args: ['matInputText',] }],
2030
- matAutocomplete: [{ type: i0.ViewChild, args: [autocomplete.MatAutocomplete,] }],
2031
- matAutocompleteTrigger: [{ type: i0.ViewChild, args: [autocomplete.MatAutocompleteTrigger,] }]
2023
+ items: [{ type: i0.Input }]
2032
2024
  };
2033
2025
 
2034
2026
  var DateFormatPipe = /** @class */ (function () {
@@ -7347,7 +7339,7 @@
7347
7339
  // Default values
7348
7340
  this.displayAttributes = this.displayAttributes || ['label', 'name'];
7349
7341
  this.displayWith = this.displayWith || (function (obj) { return obj && joinPropertiesPath(obj, _this.displayAttributes); });
7350
- this.compareWithFn = this.compareWithFn || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
7342
+ this.equals = this.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
7351
7343
  this.mobile = toBoolean(this.mobile, false);
7352
7344
  };
7353
7345
  MatSwipeField.prototype.ngOnDestroy = function () {
@@ -7409,7 +7401,7 @@
7409
7401
  if (this._writing)
7410
7402
  return;
7411
7403
  this._writing = true;
7412
- if (!this.compareWithFn(value, this._value)) {
7404
+ if (!this.equals(value, this._value)) {
7413
7405
  this._value = value;
7414
7406
  this.showSlides = isNotNil(this._value);
7415
7407
  this.updateSlides();
@@ -7498,7 +7490,7 @@
7498
7490
  MatSwipeField.prototype.updateSlides = function () {
7499
7491
  var _this = this;
7500
7492
  if (this.showSlides) {
7501
- var itemIndex = (this.$items.getValue() || []).findIndex(function (value) { return _this.compareWithFn(value, _this._value); });
7493
+ var itemIndex = (this.$items.getValue() || []).findIndex(function (value) { return _this.equals(value, _this._value); });
7502
7494
  if (itemIndex >= 0) {
7503
7495
  this.slideTo(itemIndex);
7504
7496
  }
@@ -7585,7 +7577,7 @@
7585
7577
  required: [{ type: i0.Input }],
7586
7578
  mobile: [{ type: i0.Input }],
7587
7579
  clearable: [{ type: i0.Input }],
7588
- compareWithFn: [{ type: i0.Input }],
7580
+ equals: [{ type: i0.Input }],
7589
7581
  displayWith: [{ type: i0.Input }],
7590
7582
  displayAttributes: [{ type: i0.Input }],
7591
7583
  appAutofocus: [{ type: i0.Input }],
@@ -7637,20 +7629,27 @@
7637
7629
  this.required = false;
7638
7630
  this.readonly = false;
7639
7631
  this.clearable = false;
7640
- this.debounceTime = 250;
7641
- this.highlightAccent = false;
7632
+ this.debounceTime = null;
7642
7633
  this.i18nPrefix = 'REFERENTIAL.';
7643
7634
  this.noResultMessage = 'COMMON.NO_RESULT';
7644
7635
  this.debug = false;
7636
+ this.itemSize = '48px';
7637
+ this.fetchMoreThreshold = '15%';
7638
+ this.suggestLengthThreshold = null;
7639
+ this.showLoadingSpinner = true;
7645
7640
  this.clicked = new i0.EventEmitter();
7646
7641
  this.blurred = new i0.EventEmitter();
7647
7642
  this.focused = new i0.EventEmitter();
7643
+ this.dropButtonClick = new i0.EventEmitter(true);
7644
+ this.keydownEscape = new i0.EventEmitter();
7645
+ this.keyupEnter = new i0.EventEmitter();
7648
7646
  this.$inputItems = new rxjs.BehaviorSubject(undefined);
7649
- this.onDropButtonClick = new i0.EventEmitter(true);
7647
+ this.$filteredItems = new rxjs.BehaviorSubject(undefined);
7650
7648
  this.inputControl = new i1.FormControl();
7651
- this.getPropertyByPath = getPropertyByPath;
7649
+ this._fetchMore$ = new i0.EventEmitter();
7652
7650
  this._subscription = new rxjs.Subscription();
7653
7651
  this._$filter = new rxjs.BehaviorSubject(undefined);
7652
+ this._reload$ = new rxjs.Subject();
7654
7653
  }
7655
7654
  Object.defineProperty(MatChipsField.prototype, "itemCount", {
7656
7655
  get: function () {
@@ -7659,14 +7658,21 @@
7659
7658
  enumerable: false,
7660
7659
  configurable: true
7661
7660
  });
7661
+ Object.defineProperty(MatChipsField.prototype, "canFetchMore", {
7662
+ get: function () {
7663
+ return this._onFetchMoreCallback && this._moreItemsCount > 0;
7664
+ },
7665
+ enumerable: false,
7666
+ configurable: true
7667
+ });
7662
7668
  Object.defineProperty(MatChipsField.prototype, "filter", {
7663
7669
  get: function () {
7664
- return this._$filter.getValue();
7670
+ return this._$filter.value;
7665
7671
  },
7666
7672
  set: function (value) {
7667
- if (this.debug)
7668
- console.debug(this.logPrefix + ' Setting filter:', value);
7669
- if (value !== this._$filter.getValue()) {
7673
+ if (value !== this._$filter.value) {
7674
+ // DEBUG
7675
+ //console.debug(this.logPrefix + " Setting filter:", value);
7670
7676
  this._$filter.next(value);
7671
7677
  }
7672
7678
  },
@@ -7685,19 +7691,25 @@
7685
7691
  configurable: true
7686
7692
  });
7687
7693
  Object.defineProperty(MatChipsField.prototype, "items", {
7694
+ get: function () {
7695
+ return this.$inputItems;
7696
+ },
7688
7697
  set: function (value) {
7689
7698
  var _this = this;
7690
7699
  // Remove previous subscription on items, (if exits)
7691
7700
  if (this._itemsSubscription) {
7692
- console.warn('Items received twice !');
7701
+ console.warn(this.logPrefix + ' Items received twice !');
7693
7702
  this._subscription.remove(this._itemsSubscription);
7694
7703
  this._itemsSubscription.unsubscribe();
7695
7704
  }
7696
7705
  if (rxjs.isObservable(value)) {
7697
- this._itemsSubscription = this._subscription.add(value.subscribe(function (v) { return _this.$inputItems.next(v); }));
7706
+ this._itemsSubscription = this._subscription.add(value.subscribe(function (v) {
7707
+ //console.warn(this.logPrefix + " Received items: ", v);
7708
+ _this.$inputItems.next(v);
7709
+ }));
7698
7710
  }
7699
7711
  else {
7700
- if (value !== this.$inputItems.getValue()) {
7712
+ if (value !== this.$inputItems.value) {
7701
7713
  this.$inputItems.next(value);
7702
7714
  }
7703
7715
  }
@@ -7728,6 +7740,7 @@
7728
7740
  });
7729
7741
  MatChipsField.prototype.ngOnInit = function () {
7730
7742
  var _this = this;
7743
+ var _a, _b;
7731
7744
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
7732
7745
  if (!this.formControl)
7733
7746
  throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-chips-field>.');
@@ -7742,101 +7755,211 @@
7742
7755
  this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;
7743
7756
  this.displayColumnNames = this.displayColumnNames || this.config.columnNames;
7744
7757
  this.displayWith = this.displayWith || this.config.displayWith;
7745
- this.compareWith = this.compareWith || this.config.compareWith;
7758
+ this.equals = this.equals || this.config.equals;
7746
7759
  this.mobile = toBoolean(this.mobile, this.config.mobile);
7747
- this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, true));
7760
+ this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
7761
+ this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
7748
7762
  this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
7749
- this.class = this.class || this.config.class;
7763
+ this.classList = this.classList || this.config.class;
7764
+ this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
7765
+ this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
7750
7766
  }
7751
7767
  // Default values
7752
- this.displayAttributes = this.displayAttributes || (this.filter && this.filter.attributes) || ['label', 'name'];
7768
+ this.displayAttributes = this.displayAttributes || ((_a = this.filter) === null || _a === void 0 ? void 0 : _a.attributes) || ['label', 'name'];
7753
7769
  this.displayWith = this.displayWith || (function (obj) { return obj && joinPropertiesPath(obj, _this.displayAttributes); });
7754
- this.compareWith = this.compareWith || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
7755
- this.displayColumnSizes = this.displayColumnSizes || this.displayAttributes.map(function (attr) { return (
7756
- // If label then col size = 2
7757
- attr && attr.endsWith('label')) ? 2 :
7758
- // If rankOrder then col size = 1
7759
- (attr && attr.endsWith('rankOrder') ? 1 :
7760
- // Else, auto size
7761
- undefined); });
7770
+ this.displayColumnSizes = this.displayColumnSizes
7771
+ // if only column: auto size
7772
+ || (this.displayAttributes.length === 1 && [undefined])
7773
+ // Computed column size:
7774
+ // - if label then col size = 2
7775
+ // - if rankOrder then col size = 1
7776
+ // - ese => auto size
7777
+ || this.displayAttributes.map(function (attr) { return (attr && attr.endsWith('label')) ? 2
7778
+ : ((attr && attr.endsWith('rankOrder')) ? 1
7779
+ : undefined); });
7762
7780
  this.displayColumnNames = this.displayAttributes.map(function (attr, index) { return _this.displayColumnNames && _this.displayColumnNames[index] ||
7763
7781
  (_this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()); });
7764
7782
  this.mobile = toBoolean(this.mobile, false);
7783
+ this.equals = this.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
7784
+ var classList = (_b = this.classList) === null || _b === void 0 ? void 0 : _b.split(' ');
7785
+ this.panelWidth = this.panelWidth || (classList && ((classList.includes('min-width-medium') && '300px')
7786
+ || (classList.includes('min-width-large') && '400px')
7787
+ || (classList.includes('min-width-xlarge') && '450px')
7788
+ || (classList.includes('mat-autocomplete-panel-full-size') && '100vw')));
7789
+ this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, true);
7790
+ this.debounceTime = toNumber(this.debounceTime, 250);
7791
+ this.highlightAccent = toBoolean(this.highlightAccent, false);
7792
+ this.suggestLengthThreshold = this.suggestLengthThreshold || 0;
7793
+ this.matAutocompletePosition = this.matAutocompletePosition || (this.mobile ? 'above' : 'auto'); // On mobile, set position to above (because of bottom keyboard)
7765
7794
  // No suggestFn: filter on the given items
7766
7795
  if (!this.suggestFn) {
7767
7796
  var suggestFromArrayFn_1 = function (value, filter) { return __awaiter(_this, void 0, void 0, function () {
7768
- var _a, data, total;
7769
- return __generator(this, function (_b) {
7770
- switch (_b.label) {
7771
- case 0:
7772
- if (this.debug)
7773
- console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);
7774
- return [4 /*yield*/, suggestFromArray(this.$inputItems.getValue(), value, Object.assign({ searchAttributes: this.displayAttributes }, filter))];
7775
- case 1:
7776
- _a = _b.sent(), data = _a.data, total = _a.total;
7777
- this._itemCount = toNumber(total, data && data.length || 0);
7778
- return [2 /*return*/, { data: data, total: total }];
7779
- }
7797
+ return __generator(this, function (_c) {
7798
+ if (this.debug)
7799
+ console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);
7800
+ return [2 /*return*/, suggestFromArray(this.$inputItems.value, value, Object.assign({ searchAttributes: this.displayAttributes }, filter))];
7780
7801
  });
7781
7802
  }); };
7782
7803
  // Wait (once) that items are loaded, then call suggest from array fn
7783
7804
  this.suggestFn = function (value, filter) { return __awaiter(_this, void 0, void 0, function () {
7784
- return __generator(this, function (_a) {
7785
- switch (_a.label) {
7805
+ return __generator(this, function (_c) {
7806
+ switch (_c.label) {
7786
7807
  case 0:
7787
- if (!isNil(this.$inputItems.getValue())) return [3 /*break*/, 2];
7808
+ if (!isNil(this.$inputItems.value)) return [3 /*break*/, 2];
7788
7809
  if (this.debug)
7789
7810
  console.debug('[mat-chips] Waiting items to be set...');
7790
7811
  return [4 /*yield*/, firstNotNilPromise(this.$inputItems)];
7791
7812
  case 1:
7792
- _a.sent();
7813
+ _c.sent();
7793
7814
  if (this.debug)
7794
- console.debug('[mat-chips] Received items:', this.$inputItems.getValue());
7795
- _a.label = 2;
7815
+ console.debug('[mat-chips] Received items:', this.$inputItems.value);
7816
+ _c.label = 2;
7796
7817
  case 2:
7797
7818
  this.suggestFn = suggestFromArrayFn_1;
7798
- return [2 /*return*/, this.suggest(value, filter)]; // Loop
7819
+ return [2 /*return*/, this.suggestFn(value, filter)]; // Loop
7799
7820
  }
7800
7821
  });
7801
7822
  }); };
7802
7823
  }
7803
- // this.matSelectItems$ = this.$inputItems
7804
- // .pipe(
7805
- // filter(isNotNil),
7806
- // map((items) => {
7807
- // // Make sure control value is inside
7808
- // const value = this.inputControl.value;
7809
- // // If form value is missing: add it to the list
7810
- // if (isNotNil(value) && typeof value === 'object' && items.findIndex(item => this.compareWith(item, value)) === -1) {
7811
- // // console.debug(this.logPrefix + " Add form value to items, because missed in items", value);
7812
- // return items.concat(value);
7813
- // }
7814
- // return items;
7815
- // })
7816
- // );
7817
- this._subscription.add(this.onDropButtonClick
7818
- .pipe(operators.filter(function (event) { return (!event || !event.defaultPrevented) && _this.formControl.enabled; }))
7819
- .subscribe(function () {
7820
- _this.matInputText.nativeElement.focus();
7821
- }));
7822
- var updateFilteredItemsEvents$ = rxjs.merge(
7824
+ var filteredItemsChanges = rxjs.merge(
7825
+ // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
7826
+ this._reload$, this.inputControl.valueChanges
7827
+ .pipe(operators.filter(function (value) { return _this.enabled && isNotNilString(value); }),
7828
+ // Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
7829
+ operators.tap(function (_) { return _this.showLoadingSpinner && _this.markAsLoading(); }),
7830
+ // Filter if not enough character
7831
+ operators.filter(function (value) { return value.length >= _this.suggestLengthThreshold; }),
7832
+ // Wait a debounce time
7833
+ operators.debounceTime(this.debounceTime)
7834
+ // DEBUG
7835
+ //tap((value) => console.debug(this.logPrefix + ' Search text changes:', value))
7836
+ ),
7837
+ // Object set: use it (no distinctUntilChanged() pipe need)
7838
+ this.inputControl.valueChanges
7839
+ .pipe(operators.startWith(this.inputControl.value), operators.filter(function (value) { return isNotNil(value) && typeof value === 'object'; }), operators.tap(function (value) {
7840
+ // DEBUG
7841
+ //console.debug(this.logPrefix + ' object changes:', value)
7842
+ // Update the display value (if need)
7843
+ var displayValue = _this.displayWith(value) || '';
7844
+ // Apply to the input[type=text] field
7845
+ if (_this.matInputText && _this.matInputText.nativeElement) {
7846
+ _this.matInputText.nativeElement.value = displayValue;
7847
+ }
7848
+ })
7849
+ // DEBUG
7850
+ //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
7851
+ ),
7852
+ // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
7853
+ rxjs.merge(
7823
7854
  // Focus or click => Load all
7824
7855
  rxjs.merge(this.focused, this.clicked)
7825
- .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })), this.inputControl.valueChanges
7826
- .pipe(operators.startWith(this.inputControl.value), operators.filter(function (value) { return (isNotNil(value) && typeof value === 'object') || (isNotNilString(value) && !value.includes('**')); }), operators.tap(function (value) {
7827
- if (_this.debug)
7828
- console.debug(_this.logPrefix + ' valueChanges:', value);
7829
- }), operators.debounceTime(this.debounceTime)), this.$inputItems
7830
- .pipe(operators.map(function () { return _this.formControl.value; })), this._$filter
7831
- .pipe(operators.map(function () { return _this.formControl.value; })));
7832
- this.filteredItems$ = updateFilteredItemsEvents$
7833
- .pipe(operators.distinctUntilChanged(),
7834
- //tap(value => this.debug && console.debug(this.logPrefix + " Received update event: ", value)),
7835
- operators.switchMap(function (value) { return _this.suggest(value, _this.filter); }));
7856
+ .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })),
7857
+ // On dropdown button click
7858
+ this.dropButtonClick
7859
+ .pipe(operators.filter(function (event) { return _this.enabled && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })), rxjs.merge(this.$inputItems, this._$filter)
7860
+ .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.inputControl.value; })))
7861
+ .pipe(
7862
+ // Start to suggest when :
7863
+ // - '*'
7864
+ // - is nil, and there is no min length threshold
7865
+ // - is not nil and not a string type (e.g. object)
7866
+ // - is not nil and is a string, and has enough character
7867
+ operators.filter(function (value) { return value === '*'
7868
+ || (isNil(value)
7869
+ ? (_this.suggestLengthThreshold <= 0)
7870
+ : (!(typeof value === 'string')
7871
+ || value.length >= _this.suggestLengthThreshold)); }),
7872
+ // Distinguish changes
7873
+ operators.distinctUntilChanged()))
7874
+ .pipe(
7875
+ // Suggest values
7876
+ operators.mergeMap(function (value) { return _this.suggest(value, _this.filter); }),
7877
+ // DEBUG
7878
+ //tap(items => console.debug(this.logPrefix + ' Received from suggest: ', items)),
7879
+ // Store implicit value (will use it onBlur if not other value selected)
7880
+ operators.tap(function (items) { return _this.updateImplicitValue(items); }));
7881
+ // Fetch more events
7882
+ var fetchMoreItemsChanges = this._fetchMore$
7883
+ .pipe(operators.tap(function (event) { return event === null || event === void 0 ? void 0 : event.preventDefault(); }), // Avoid to close the mat-select
7884
+ operators.filter(function () { return _this.canFetchMore; }), operators.mergeMap(function () { return _this.fetchMore(); }),
7885
+ // DEBUG
7886
+ //tap(moreItems => console.debug(this.logPrefix + ' Received from fetch More: ', moreItems)),
7887
+ // Concat to existing items
7888
+ operators.map(function (moreItems) { return (_this.$filteredItems.value || []).concat(moreItems); }));
7889
+ // Update filtered items
7890
+ this._subscription.add(rxjs.merge(this.$inputItems,
7891
+ // Update items events
7892
+ filteredItemsChanges,
7893
+ // Fetch more events
7894
+ fetchMoreItemsChanges)
7895
+ // Emit items
7896
+ .subscribe(function (items) { return _this.$filteredItems.next(items); }));
7897
+ // Applying implicit value, on blur
7898
+ this._subscription.add(this.blurred
7899
+ .pipe(operators.map(function (_) { return _this.formControl.value; }))
7900
+ .subscribe(function (value) {
7901
+ // When leave component without object, use implicit value if :
7902
+ // - an explicit value
7903
+ // - field is not empty (user fill something)
7904
+ // - OR field empty but is required
7905
+ if (_this._implicitValue && ((_this.required && isNilOrBlank(value)) || (isNotNilOrBlank(value) && typeof value !== 'object'))) {
7906
+ _this.writeValue(_this._implicitValue);
7907
+ _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7908
+ _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7909
+ _this.checkIfTouched();
7910
+ }
7911
+ else if (isNilOrBlank(value)) {
7912
+ _this.writeValue(null);
7913
+ _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7914
+ _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7915
+ _this.checkIfTouched();
7916
+ }
7917
+ _this._implicitValue = null; // reset the implicit value
7918
+ }));
7919
+ this._subscription.add(this.keydownEscape.subscribe(function (event) {
7920
+ if (_this.isOpen) {
7921
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
7922
+ event === null || event === void 0 ? void 0 : event.preventDefault();
7923
+ // DEBUG
7924
+ //console.debug(this.logPrefix + " Closing the panel (keydown.escape)");
7925
+ _this.closePanel();
7926
+ }
7927
+ }));
7836
7928
  };
7837
7929
  MatChipsField.prototype.ngOnDestroy = function () {
7838
7930
  this._subscription.unsubscribe();
7931
+ if (this._itemsSubscription) {
7932
+ this._itemsSubscription.unsubscribe();
7933
+ }
7934
+ if (this._openedSubscription) {
7935
+ this._openedSubscription.unsubscribe();
7936
+ }
7839
7937
  this.$inputItems.complete();
7938
+ this.$filteredItems.complete();
7939
+ this._reload$.complete();
7940
+ this._$filter.complete();
7941
+ this.dropButtonClick.complete();
7942
+ this.clicked.complete();
7943
+ this.blurred.complete();
7944
+ this.focused.complete();
7945
+ this.keydownEscape.complete();
7946
+ this.keyupEnter.complete();
7947
+ this._fetchMore$.complete();
7948
+ this._implicitValue = undefined;
7949
+ this.formControl = null;
7950
+ this.displayWith = null;
7951
+ this.equals = null;
7952
+ this.suggestFn = null;
7953
+ this.$filteredItems = null;
7954
+ this.config = null;
7955
+ this.classList = null;
7956
+ this._onChangeCallback = null;
7957
+ this._onTouchedCallback = null;
7958
+ this._onFetchMoreCallback = null;
7959
+ // Destroy the 'autocomplete' instance, to avoid memory leak
7960
+ if (this.autocomplete) {
7961
+ this.autocomplete.ngOnDestroy();
7962
+ }
7840
7963
  };
7841
7964
  /**
7842
7965
  * Add item to chips
@@ -7857,19 +7980,21 @@
7857
7980
  * @param item
7858
7981
  */
7859
7982
  MatChipsField.prototype.remove = function (item) {
7860
- var index = this.value && this.value.indexOf(item);
7861
- if (index >= 0) {
7862
- var value = this.value.slice();
7863
- value.splice(index, 1);
7864
- this.writeValue(value);
7865
- this.inputControl.setValue('');
7983
+ var value = this.value;
7984
+ var index = value ? value.indexOf(item) : -1;
7985
+ if (index !== -1) {
7986
+ var newValue = value.slice();
7987
+ newValue.splice(index, 1);
7988
+ this.writeValue(newValue);
7989
+ this.closePanel();
7866
7990
  }
7867
7991
  };
7868
7992
  /**
7869
7993
  * Allow to reload content. Useful when filter has been changed but not detected
7870
7994
  */
7871
- MatChipsField.prototype.reloadItems = function () {
7872
- this.onDropButtonClick.emit();
7995
+ MatChipsField.prototype.reloadItems = function (value) {
7996
+ // Force a refresh
7997
+ this._reload$.next(value || '*');
7873
7998
  };
7874
7999
  MatChipsField.prototype.writeValue = function (value) {
7875
8000
  if (this.debug)
@@ -7886,6 +8011,10 @@
7886
8011
  this._onTouchedCallback = fn;
7887
8012
  };
7888
8013
  MatChipsField.prototype.setDisabledState = function (isDisabled) {
8014
+ var _a;
8015
+ if (isDisabled && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
8016
+ this.closePanel();
8017
+ }
7889
8018
  this.cd.markForCheck();
7890
8019
  };
7891
8020
  MatChipsField.prototype.focus = function () {
@@ -7905,6 +8034,7 @@
7905
8034
  return false;
7906
8035
  }
7907
8036
  var hasContent = selectInputContent(event);
8037
+ // If combo is empty, or if has content but should force to show panel on focus
7908
8038
  if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
7909
8039
  if (this.debug)
7910
8040
  console.debug(this.logPrefix + ' Emit focus event');
@@ -7913,20 +8043,82 @@
7913
8043
  }
7914
8044
  return false;
7915
8045
  };
8046
+ MatChipsField.prototype.filterInputTextBlurEvent = function (event) {
8047
+ if (!event || event.defaultPrevented)
8048
+ return;
8049
+ // Ignore event from mat-option
8050
+ if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {
8051
+ event.preventDefault();
8052
+ if (event.stopPropagation)
8053
+ event.stopPropagation();
8054
+ event.returnValue = false;
8055
+ //DEBUG console.debug(this.logPrefix + " Cancelling blur event");
8056
+ return false;
8057
+ }
8058
+ //DEBUG
8059
+ //console.debug(this.logPrefix + ' Blur: move caret to the beginning');
8060
+ // Move caret to the beginning (fix issue IMAGINE-469)
8061
+ selectInputRange(event.target, 0, 0);
8062
+ this.blurred.emit(event);
8063
+ return true;
8064
+ };
8065
+ MatChipsField.prototype.filterChipsFocusEvent = function (event) {
8066
+ // DEBUG
8067
+ if (this.debug)
8068
+ console.debug(this.logPrefix + ' Focus in chips list', event);
8069
+ this.matInputText.nativeElement.focus();
8070
+ };
7916
8071
  MatChipsField.prototype.clearValue = function (event) {
7917
8072
  this.writeValue(null);
7918
8073
  event.stopPropagation();
7919
8074
  };
8075
+ MatChipsField.prototype._initAutocompleteInfiniteScroll = function (threshold) {
8076
+ var _this = this;
8077
+ if (!this.autocomplete)
8078
+ return; // Skip
8079
+ // DEBUG
8080
+ //console.debug(this.logPrefix + ' Init autocomplete scroll listener');
8081
+ if (this._openedSubscription) {
8082
+ this._openedSubscription.unsubscribe();
8083
+ this._subscription.remove(this._openedSubscription);
8084
+ }
8085
+ var opened$ = this.autocomplete._isOpen
8086
+ ? rxjs.timer(0)
8087
+ : this.autocomplete.opened.pipe(operators.debounceTime(200));
8088
+ var scrollEnd$ = opened$
8089
+ .pipe(operators.map(function (_) { return _this.getAutocompletePanel(); }), operators.filter(isNotNil), operators.switchMap(function (panel) { return fromScrollEndEvent(panel, threshold)
8090
+ .pipe(operators.takeUntil(_this.autocomplete.closed)); }));
8091
+ // Trigger fetch more, end end scroll reached
8092
+ this._openedSubscription = scrollEnd$
8093
+ .subscribe(function () { return _this._fetchMore$.emit(); });
8094
+ // Register subscription
8095
+ this._subscription.add(this._openedSubscription);
8096
+ };
8097
+ Object.defineProperty(MatChipsField.prototype, "isOpen", {
8098
+ get: function () {
8099
+ var _a;
8100
+ return ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) || false;
8101
+ },
8102
+ enumerable: false,
8103
+ configurable: true
8104
+ });
8105
+ MatChipsField.prototype.closePanel = function () {
8106
+ var _a, _b;
8107
+ if ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
8108
+ (_b = this.autocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
8109
+ return;
8110
+ }
8111
+ };
7920
8112
  /* -- private method -- */
7921
8113
  MatChipsField.prototype.suggest = function (value, filter) {
7922
8114
  return __awaiter(this, void 0, void 0, function () {
7923
8115
  var res, data, total, filteredData;
7924
8116
  var _this = this;
7925
- return __generator(this, function (_a) {
7926
- switch (_a.label) {
8117
+ return __generator(this, function (_c) {
8118
+ switch (_c.label) {
7927
8119
  case 0: return [4 /*yield*/, this.suggestFn(value, filter)];
7928
8120
  case 1:
7929
- res = _a.sent();
8121
+ res = _c.sent();
7930
8122
  // DEBUG
7931
8123
  // console.debug(this.logPrefix + " Filtered items by suggestFn:", value, res);
7932
8124
  if (!res) {
@@ -7942,7 +8134,7 @@
7942
8134
  res = data;
7943
8135
  this._itemCount = toNumber(total, data && data.length || 0);
7944
8136
  }
7945
- filteredData = (res || []).slice().filter(function (item1) { return _this.value.findIndex(function (item2) { return _this.compareWith(item1, item2); }) === -1; });
8137
+ filteredData = (res || []).slice().filter(function (item1) { return _this.value.findIndex(function (item2) { return _this.equals(item1, item2); }) === -1; });
7946
8138
  // Update items count
7947
8139
  this._itemCount = this._itemCount - (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
7948
8140
  if (this.debug)
@@ -7952,16 +8144,72 @@
7952
8144
  });
7953
8145
  });
7954
8146
  };
8147
+ MatChipsField.prototype.fetchMore = function () {
8148
+ return __awaiter(this, void 0, void 0, function () {
8149
+ var fetchMoreFn, _c, data, total, fetchMore;
8150
+ return __generator(this, function (_d) {
8151
+ switch (_d.label) {
8152
+ case 0:
8153
+ if (!this._onFetchMoreCallback)
8154
+ return [2 /*return*/, []];
8155
+ fetchMoreFn = this._onFetchMoreCallback;
8156
+ this._onFetchMoreCallback = undefined;
8157
+ return [4 /*yield*/, fetchMoreFn()];
8158
+ case 1:
8159
+ _c = _d.sent(), data = _c.data, total = _c.total, fetchMore = _c.fetchMore;
8160
+ this._itemCount = total || this._itemCount;
8161
+ this._onFetchMoreCallback = fetchMore;
8162
+ this._moreItemsCount = Math.max(0, this._moreItemsCount - data.length); // Borne min = 0
8163
+ return [2 /*return*/, data];
8164
+ }
8165
+ });
8166
+ });
8167
+ };
8168
+ MatChipsField.prototype.updateImplicitValue = function (items) {
8169
+ // Store implicit value (will use it onBlur if not other value selected)
8170
+ if (items && items.length === 1) {
8171
+ this._implicitValue = items[0];
8172
+ //this.formControl.setErrors(null);
8173
+ }
8174
+ else {
8175
+ this._implicitValue = undefined;
8176
+ }
8177
+ };
8178
+ MatChipsField.prototype.getAutocompletePanel = function () {
8179
+ var _a, _b;
8180
+ var ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
8181
+ if (!ele) {
8182
+ // DEBUG
8183
+ console.warn(this.logPrefix + ' Unable to find the autocomplete div...');
8184
+ }
8185
+ return ele;
8186
+ };
8187
+ MatChipsField.prototype.checkIfTouched = function () {
8188
+ if (this.formControl.touched) {
8189
+ this.cd.markForCheck();
8190
+ this._onTouchedCallback();
8191
+ }
8192
+ };
7955
8193
  MatChipsField.prototype.markForCheck = function () {
7956
8194
  this.cd.markForCheck();
7957
8195
  };
8196
+ MatChipsField.prototype.markAsLoading = function () {
8197
+ if (this.$filteredItems.value) {
8198
+ this.$filteredItems.next(undefined);
8199
+ this._itemCount = undefined;
8200
+ this._implicitValue = undefined;
8201
+ this._onFetchMoreCallback = undefined;
8202
+ this._moreItemsCount = 0;
8203
+ this.markForCheck();
8204
+ }
8205
+ };
7958
8206
  return MatChipsField;
7959
8207
  }());
7960
8208
  MatChipsField.decorators = [
7961
8209
  { type: i0.Component, args: [{
7962
8210
  // eslint-disable-next-line @angular-eslint/component-selector
7963
8211
  selector: 'mat-chips-field',
7964
- 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-content select=\"[matPrefix]\"></ng-content>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList>\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\">\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autoCombo\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"appAutofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (blur)=\"blurred.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (keyup.arrowdown)=\"!autoCombo.showPanel && onDropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autoCombo=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"class\">\n <ng-container *ngIf=\"(filteredItems$ | async) as items\">\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-text color=\"light\" *ngIf=\"isLast\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: itemCount} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <!-- No item option -->\n <mat-option *ngIf=\"!items.length\" class=\"ion-no-padding\" [disabled]=\"true\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row>\n <ion-col *ngFor=\"let attr of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"getPropertyByPath(item, attr) | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n </ng-container>\n </mat-autocomplete>\n\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"onDropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</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 <ng-content matSuffix select=\"[matSuffix]\"></ng-content>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\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",
8212
+ 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 (focus)=\"matInputText.focus()\">\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\">\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input matInput #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\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 matSuffix 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 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",
7965
8213
  providers: [
7966
8214
  {
7967
8215
  provide: i1.NG_VALUE_ACCESSOR,
@@ -7978,7 +8226,7 @@
7978
8226
  { type: i1.FormGroupDirective, decorators: [{ type: i0.Optional }] }
7979
8227
  ]; };
7980
8228
  MatChipsField.propDecorators = {
7981
- compareWith: [{ type: i0.Input }],
8229
+ equals: [{ type: i0.Input }],
7982
8230
  logPrefix: [{ type: i0.Input }],
7983
8231
  formControl: [{ type: i0.Input }],
7984
8232
  formControlName: [{ type: i0.Input }],
@@ -7997,16 +8245,26 @@
7997
8245
  highlightAccent: [{ type: i0.Input }],
7998
8246
  showAllOnFocus: [{ type: i0.Input }],
7999
8247
  showPanelOnFocus: [{ type: i0.Input }],
8000
- appAutofocus: [{ type: i0.Input }],
8248
+ autofocus: [{ type: i0.Input }],
8001
8249
  config: [{ type: i0.Input }],
8002
8250
  i18nPrefix: [{ type: i0.Input }],
8003
8251
  noResultMessage: [{ type: i0.Input }],
8004
- class: [{ type: i0.Input }],
8252
+ classList: [{ type: i0.Input, args: ['class',] }],
8253
+ panelWidth: [{ type: i0.Input }],
8254
+ matAutocompletePosition: [{ type: i0.Input }],
8005
8255
  debug: [{ type: i0.Input }],
8256
+ itemSize: [{ type: i0.Input }],
8257
+ fetchMoreThreshold: [{ type: i0.Input }],
8258
+ suggestLengthThreshold: [{ type: i0.Input }],
8259
+ showLoadingSpinner: [{ type: i0.Input }],
8006
8260
  clicked: [{ type: i0.Output }],
8007
8261
  blurred: [{ type: i0.Output }],
8008
8262
  focused: [{ type: i0.Output }],
8263
+ dropButtonClick: [{ type: i0.Output }],
8264
+ keydownEscape: [{ type: i0.Output, args: ['keydown.escape',] }],
8265
+ keyupEnter: [{ type: i0.Output, args: ['keyup.enter',] }],
8009
8266
  matInputText: [{ type: i0.ViewChild, args: ['matInputText',] }],
8267
+ autocomplete: [{ type: i0.ViewChild, args: [autocomplete.MatAutocomplete,] }],
8010
8268
  autocompleteTrigger: [{ type: i0.ViewChild, args: [autocomplete.MatAutocompleteTrigger,] }],
8011
8269
  filter: [{ type: i0.Input }],
8012
8270
  tabindex: [{ type: i0.Input }],
@@ -18821,7 +19079,7 @@
18821
19079
  AutocompleteTestPage.decorators = [
18822
19080
  { type: i0.Component, args: [{
18823
19081
  selector: 'app-autocomplete-test',
18824
- 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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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;\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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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 [compareWith]=\"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"
19082
+ 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;\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"
18825
19083
  },] }
18826
19084
  ];
18827
19085
  AutocompleteTestPage.ctorParameters = function () { return [
@@ -18992,7 +19250,7 @@
18992
19250
  SwipeTestPage.decorators = [
18993
19251
  { type: i0.Component, args: [{
18994
19252
  selector: 'app-swipe-test',
18995
- 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>Swipe test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <h1>Swipe page:</h1>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n <!-- empty -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"empty\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [compareWithFn]=\"compareDate()\"\n [tabindex]=\"1\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- date -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Date\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"date\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [compareWithFn]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"2\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled empty\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"disabledEmpty\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [compareWithFn]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"3\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n<!-- read-only-->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled with date\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"disabledDate\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [compareWithFn]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"4\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
19253
+ 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>Swipe test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <h1>Swipe page:</h1>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n <!-- empty -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Empty\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"empty\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [equals]=\"compareDate()\"\n [tabindex]=\"1\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <!-- date -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Date\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"date\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [equals]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"2\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <!-- disable -->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled empty\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"disabledEmpty\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [equals]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"3\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n<!-- read-only-->\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled with date\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-swipe-field formControlName=\"disabledDate\"\n placeholder=\"placeholder\"\n [items]=\"$dates\"\n [displayWith]=\"displayDate()\"\n [equals]=\"compareDate()\"\n [clearable]=\"true\"\n [tabindex]=\"4\"\n [debug]=\"true\"\n >\n </mat-swipe-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
18996
19254
  },] }
18997
19255
  ];
18998
19256
  SwipeTestPage.ctorParameters = function () { return [
@@ -19133,13 +19391,15 @@
19133
19391
  this.autocompleteFields.add('entity-suggestFn', {
19134
19392
  suggestFn: function (value, filter) { return _this.suggest(value, filter); },
19135
19393
  attributes: ['label', 'name'],
19136
- displayWith: this.entityToString
19394
+ displayWith: this.entityToString,
19395
+ equals: function (o1, o2) { return EntityUtils.compare(o1, o2, 1, 'id') === 0; }
19137
19396
  });
19138
19397
  // From items
19139
19398
  this.autocompleteFields.add('entity-items', {
19140
19399
  items: FAKE_ENTITIES.slice(),
19141
19400
  attributes: ['label', 'name'],
19142
- displayWith: this.entityToString
19401
+ displayWith: this.entityToString,
19402
+ equals: function (o1, o2) { return EntityUtils.compare(o1, o2, 1, 'id') === 0; }
19143
19403
  });
19144
19404
  // From items
19145
19405
  this.autocompleteFields.add('entity-$items', {
@@ -19201,7 +19461,7 @@
19201
19461
  ChipsTestPage.decorators = [
19202
19462
  { type: i0.Component, args: [{
19203
19463
  selector: 'app-chips-test',
19204
- 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 [compareWith]=\"compareWithFn\"\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 [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\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 [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\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 [compareWith]=\"compareWithFn\"\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"
19464
+ 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 [equals]=\"compareWithFn\"\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 [equals]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\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]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\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]=\"compareWithFn\"\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"
19205
19465
  },] }
19206
19466
  ];
19207
19467
  ChipsTestPage.ctorParameters = function () { return [
@@ -19835,12 +20095,23 @@
19835
20095
  };
19836
20096
 
19837
20097
  var AuthModal = /** @class */ (function () {
19838
- function AuthModal(accountService, viewCtrl, changeDetectorRef) {
20098
+ function AuthModal(accountService, viewCtrl, cd) {
19839
20099
  this.accountService = accountService;
19840
20100
  this.viewCtrl = viewCtrl;
19841
- this.changeDetectorRef = changeDetectorRef;
19842
- this.loading = false;
20101
+ this.cd = cd;
19843
20102
  }
20103
+ Object.defineProperty(AuthModal.prototype, "loading", {
20104
+ get: function () {
20105
+ var _a;
20106
+ return (_a = this.form) === null || _a === void 0 ? void 0 : _a.loading;
20107
+ },
20108
+ enumerable: false,
20109
+ configurable: true
20110
+ });
20111
+ AuthModal.prototype.ngOnInit = function () {
20112
+ this.form.markAsReady({ emitEvent: false });
20113
+ this.form.markAsLoaded();
20114
+ };
19844
20115
  AuthModal.prototype.cancel = function () {
19845
20116
  this.viewCtrl.dismiss();
19846
20117
  };
@@ -19848,31 +20119,30 @@
19848
20119
  return __awaiter(this, void 0, void 0, function () {
19849
20120
  var data, account, err_1;
19850
20121
  var _this = this;
19851
- return __generator(this, function (_a) {
19852
- switch (_a.label) {
20122
+ return __generator(this, function (_b) {
20123
+ switch (_b.label) {
19853
20124
  case 0:
19854
20125
  if (this.form.disabled)
19855
20126
  return [2 /*return*/];
19856
20127
  if (!this.form.valid) {
19857
- this.form.markAsTouched();
20128
+ this.form.markAllAsTouched();
19858
20129
  return [2 /*return*/];
19859
20130
  }
19860
- this.loading = true;
19861
- _a.label = 1;
20131
+ this.markAsLoading();
20132
+ _b.label = 1;
19862
20133
  case 1:
19863
- _a.trys.push([1, 3, , 4]);
20134
+ _b.trys.push([1, 3, , 4]);
19864
20135
  data = this.form.value;
19865
20136
  // Disable the form
19866
20137
  this.form.disable();
19867
20138
  return [4 /*yield*/, this.accountService.login(data)];
19868
20139
  case 2:
19869
- account = _a.sent();
20140
+ account = _b.sent();
19870
20141
  return [2 /*return*/, this.viewCtrl.dismiss(account)];
19871
20142
  case 3:
19872
- err_1 = _a.sent();
19873
- this.loading = false;
20143
+ err_1 = _b.sent();
19874
20144
  this.form.error = err_1 && err_1.message || err_1;
19875
- this.markForCheck();
20145
+ this.markAsLoaded();
19876
20146
  // Enable the form
19877
20147
  this.form.enable();
19878
20148
  // Reset form error on next changes
@@ -19887,7 +20157,13 @@
19887
20157
  });
19888
20158
  };
19889
20159
  AuthModal.prototype.markForCheck = function () {
19890
- this.changeDetectorRef.markForCheck();
20160
+ this.cd.markForCheck();
20161
+ };
20162
+ AuthModal.prototype.markAsLoading = function (opts) {
20163
+ this.form.markAsLoading(opts);
20164
+ };
20165
+ AuthModal.prototype.markAsLoaded = function (opts) {
20166
+ this.form.markAsLoaded(opts);
19891
20167
  };
19892
20168
  return AuthModal;
19893
20169
  }());