@sumaris-net/ngx-components 1.6.2 → 1.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/sumaris-net.ngx-components.umd.js +665 -294
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +13 -0
- package/esm2015/src/app/core/auth/modal/modal-auth.js +21 -9
- package/esm2015/src/app/shared/form/field.model.js +1 -1
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +143 -122
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +6 -6
- package/esm2015/src/app/shared/material/chips/material.chips.js +372 -94
- package/esm2015/src/app/shared/material/chips/testing/chips.test.js +54 -18
- package/esm2015/src/app/shared/material/swipe/material.swipe.js +5 -5
- package/esm2015/src/app/shared/material/swipe/testing/swipe.test.js +2 -2
- package/fesm2015/sumaris-net.ngx-components.js +616 -272
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/src/app/core/auth/modal/modal-auth.d.ts +12 -5
- package/src/app/shared/form/field.model.d.ts +2 -1
- package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +39 -38
- package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +4 -5
- package/src/app/shared/material/chips/material.chips.d.ts +42 -13
- package/src/app/shared/material/chips/testing/chips.test.d.ts +1 -1
- package/src/app/shared/material/swipe/material.swipe.d.ts +2 -2
- package/src/theme/_ngx-components.scss +3 -1
- package/sumaris-net.ngx-components.metadata.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, EventEmitter,
|
|
2
|
+
import { InjectionToken, EventEmitter, Component, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Input, Output, ViewChild, Pipe, Injectable, Directive, Inject, NgModule, ElementRef, ViewChildren, HostListener, ComponentFactoryResolver, ApplicationRef, Injector, Renderer2, ViewEncapsulation } from '@angular/core';
|
|
3
3
|
import * as i1$3 from '@angular/common';
|
|
4
4
|
import { CommonModule, DOCUMENT, Location } from '@angular/common';
|
|
5
5
|
import { CdkTableModule } from '@angular/cdk/table';
|
|
@@ -36,7 +36,7 @@ import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteModule, MAT_AUT
|
|
|
36
36
|
import { __awaiter, __decorate } from 'tslib';
|
|
37
37
|
import * as i1$6 from '@angular/forms';
|
|
38
38
|
import { NG_VALUE_ACCESSOR, FormGroupDirective, AbstractControl, FormGroup, FormArray, FormControl, ReactiveFormsModule, Validators, FormBuilder } from '@angular/forms';
|
|
39
|
-
import { timer, merge, fromEvent,
|
|
39
|
+
import { timer, merge, fromEvent, BehaviorSubject, Subscription, Subject, isObservable, noop as noop$9, Observable, defer, of, from, combineLatest, EMPTY } from 'rxjs';
|
|
40
40
|
import { filter, first, map, takeUntil, switchMap, startWith, debounceTime, takeWhile, tap, distinctUntilChanged, mergeMap, catchError, throttleTime, skip } from 'rxjs/operators';
|
|
41
41
|
import * as i1$1 from '@ngx-translate/core';
|
|
42
42
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
@@ -976,11 +976,11 @@ class MatAutocompleteConfigHolder {
|
|
|
976
976
|
const attributesOrFn = attributes.map((a, index) => typeof a === 'function' && options.attributes[index] || a);
|
|
977
977
|
const filter = Object.assign({ searchAttribute: attributes.length === 1 ? attributes[0] : undefined, searchAttributes: attributes.length > 1 ? attributes : undefined }, options.filter);
|
|
978
978
|
const displayWith = options.displayWith || ((obj) => obj && joinPropertiesPath(obj, attributes));
|
|
979
|
-
const
|
|
979
|
+
const equals = options.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
|
|
980
980
|
const config = Object.assign(Object.assign({}, options), { attributes: attributesOrFn, suggestFn,
|
|
981
981
|
filter,
|
|
982
982
|
displayWith,
|
|
983
|
-
|
|
983
|
+
equals });
|
|
984
984
|
this.fields[fieldName] = config;
|
|
985
985
|
return config;
|
|
986
986
|
}
|
|
@@ -991,27 +991,14 @@ class MatAutocompleteConfigHolder {
|
|
|
991
991
|
return this.fields[fieldName] || this.add(fieldName);
|
|
992
992
|
}
|
|
993
993
|
}
|
|
994
|
-
const
|
|
995
|
-
|
|
996
|
-
useExisting: forwardRef(() => MatAutocompleteField),
|
|
997
|
-
multi: true
|
|
998
|
-
};
|
|
999
|
-
const noop$7 = () => { };
|
|
1000
|
-
const ɵ0$a = noop$7;
|
|
994
|
+
const noop$8 = (_) => { };
|
|
995
|
+
const ɵ0$b = noop$8;
|
|
1001
996
|
class MatAutocompleteField {
|
|
1002
997
|
constructor(cd, formGroupDir) {
|
|
1003
998
|
this.cd = cd;
|
|
1004
999
|
this.formGroupDir = formGroupDir;
|
|
1005
|
-
this._onChangeCallback = noop$
|
|
1006
|
-
this._onTouchedCallback = noop$
|
|
1007
|
-
this._subscription = new Subscription();
|
|
1008
|
-
this._filter$ = new BehaviorSubject(undefined);
|
|
1009
|
-
this._reload$ = new Subject();
|
|
1010
|
-
this._readonly = false;
|
|
1011
|
-
this.$inputItems = new BehaviorSubject(undefined);
|
|
1012
|
-
this.$filteredItems = new BehaviorSubject(undefined);
|
|
1013
|
-
this.displayValue = '';
|
|
1014
|
-
this._fetchMore$ = new EventEmitter();
|
|
1000
|
+
this._onChangeCallback = noop$8;
|
|
1001
|
+
this._onTouchedCallback = noop$8;
|
|
1015
1002
|
this.logPrefix = '[mat-autocomplete] ';
|
|
1016
1003
|
this.formControlName = null;
|
|
1017
1004
|
this.required = false;
|
|
@@ -1024,13 +1011,21 @@ class MatAutocompleteField {
|
|
|
1024
1011
|
this.fetchMoreThreshold = '15%';
|
|
1025
1012
|
this.suggestLengthThreshold = null;
|
|
1026
1013
|
this.showLoadingSpinner = true;
|
|
1027
|
-
this.
|
|
1028
|
-
this.
|
|
1029
|
-
this.
|
|
1030
|
-
this.
|
|
1031
|
-
this.
|
|
1032
|
-
this.
|
|
1033
|
-
this.
|
|
1014
|
+
this.debug = false;
|
|
1015
|
+
this.clicked = new EventEmitter();
|
|
1016
|
+
this.blurred = new EventEmitter();
|
|
1017
|
+
this.focused = new EventEmitter();
|
|
1018
|
+
this.dropButtonClick = new EventEmitter(true);
|
|
1019
|
+
this.keydownEscape = new EventEmitter();
|
|
1020
|
+
this.keyupEnter = new EventEmitter();
|
|
1021
|
+
this._readonly = false;
|
|
1022
|
+
this.$inputItems = new BehaviorSubject(undefined);
|
|
1023
|
+
this.$filteredItems = new BehaviorSubject(undefined);
|
|
1024
|
+
this.displayValue = '';
|
|
1025
|
+
this._fetchMore$ = new EventEmitter();
|
|
1026
|
+
this._subscription = new Subscription();
|
|
1027
|
+
this._$filter = new BehaviorSubject(undefined);
|
|
1028
|
+
this._reload$ = new Subject();
|
|
1034
1029
|
}
|
|
1035
1030
|
get itemCount() {
|
|
1036
1031
|
return this._itemCount;
|
|
@@ -1039,14 +1034,14 @@ class MatAutocompleteField {
|
|
|
1039
1034
|
return this._onFetchMoreCallback && this._moreItemsCount > 0;
|
|
1040
1035
|
}
|
|
1041
1036
|
set filter(value) {
|
|
1042
|
-
if (value !== this.
|
|
1037
|
+
if (value !== this._$filter.value) {
|
|
1043
1038
|
// DEBUG
|
|
1044
1039
|
//console.debug(this.logPrefix + " Setting filter:", value);
|
|
1045
|
-
this.
|
|
1040
|
+
this._$filter.next(value);
|
|
1046
1041
|
}
|
|
1047
1042
|
}
|
|
1048
1043
|
get filter() {
|
|
1049
|
-
return this.
|
|
1044
|
+
return this._$filter.value;
|
|
1050
1045
|
}
|
|
1051
1046
|
set readonly(value) {
|
|
1052
1047
|
this._readonly = value;
|
|
@@ -1093,6 +1088,9 @@ class MatAutocompleteField {
|
|
|
1093
1088
|
get enabled() {
|
|
1094
1089
|
return !this._readonly && this.formControl.enabled;
|
|
1095
1090
|
}
|
|
1091
|
+
get loading() {
|
|
1092
|
+
return isNil(this.$filteredItems.value);
|
|
1093
|
+
}
|
|
1096
1094
|
ngOnInit() {
|
|
1097
1095
|
var _a, _b;
|
|
1098
1096
|
this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
|
|
@@ -1109,10 +1107,11 @@ class MatAutocompleteField {
|
|
|
1109
1107
|
this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;
|
|
1110
1108
|
this.displayColumnNames = this.displayColumnNames || this.config.columnNames;
|
|
1111
1109
|
this.displayWith = this.displayWith || this.config.displayWith;
|
|
1110
|
+
this.equals = this.equals || this.config.equals;
|
|
1112
1111
|
this.mobile = toBoolean(this.mobile, this.config.mobile);
|
|
1113
1112
|
this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
|
|
1114
1113
|
this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
|
|
1115
|
-
this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus));
|
|
1114
|
+
this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
|
|
1116
1115
|
this.classList = this.classList || this.config.class;
|
|
1117
1116
|
this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
|
|
1118
1117
|
this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
|
|
@@ -1123,20 +1122,18 @@ class MatAutocompleteField {
|
|
|
1123
1122
|
this.displayColumnSizes = this.displayColumnSizes
|
|
1124
1123
|
// if only column: auto size
|
|
1125
1124
|
|| (this.displayAttributes.length === 1 && [undefined])
|
|
1126
|
-
|
|
1127
|
-
//
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1125
|
+
// Computed column size:
|
|
1126
|
+
// - if label then col size = 2
|
|
1127
|
+
// - if rankOrder then col size = 1
|
|
1128
|
+
// - ese => auto size
|
|
1129
|
+
|| this.displayAttributes.map(attr => (attr && attr.endsWith('label')) ? 2
|
|
1130
|
+
: ((attr && attr.endsWith('rankOrder')) ? 1
|
|
1132
1131
|
: undefined));
|
|
1133
1132
|
this.displayColumnNames = this.displayAttributes.map((attr, index) => this.displayColumnNames && this.displayColumnNames[index] ||
|
|
1134
1133
|
(this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()));
|
|
1135
1134
|
this.mobile = toBoolean(this.mobile, false);
|
|
1136
1135
|
this.searchable = !this.mobile && !this.multiple;
|
|
1137
|
-
|
|
1138
|
-
if (!this.searchable && !this.compareWith)
|
|
1139
|
-
this.compareWith = (o1, o2) => o1 && o2 && o1.id === o2.id;
|
|
1136
|
+
this.equals = this.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
|
|
1140
1137
|
const classList = (_b = this.classList) === null || _b === void 0 ? void 0 : _b.split(' ');
|
|
1141
1138
|
this.panelWidth = this.panelWidth || (classList && ((classList.includes('min-width-medium') && '300px')
|
|
1142
1139
|
|| (classList.includes('min-width-large') && '400px')
|
|
@@ -1151,7 +1148,7 @@ class MatAutocompleteField {
|
|
|
1151
1148
|
if (!this.suggestFn) {
|
|
1152
1149
|
const suggestFromArrayFn = (value, filter) => __awaiter(this, void 0, void 0, function* () {
|
|
1153
1150
|
// DEBUG
|
|
1154
|
-
//console.debug(this.logPrefix +
|
|
1151
|
+
//console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);
|
|
1155
1152
|
return suggestFromArray(this.$inputItems.value, value, Object.assign({ searchAttributes: this.displayAttributes }, filter));
|
|
1156
1153
|
});
|
|
1157
1154
|
// Wait (once) that items are loaded, then call suggest from array fn
|
|
@@ -1169,10 +1166,18 @@ class MatAutocompleteField {
|
|
|
1169
1166
|
}
|
|
1170
1167
|
else if (!this.searchable) {
|
|
1171
1168
|
// Manually fill input items, from the given suggest function
|
|
1172
|
-
this._subscription.add(this.
|
|
1169
|
+
this._subscription.add(this._$filter.pipe(startWith(this.filter), debounceTime(250), takeWhile((_) => !this.searchable), // Close subscription, when enabling search (no more mat-select)
|
|
1173
1170
|
switchMap((filter) => this.suggest('*', filter)))
|
|
1174
1171
|
.subscribe(items => this.$inputItems.next(items)));
|
|
1175
1172
|
}
|
|
1173
|
+
// Send value to suggest when :
|
|
1174
|
+
// - is nil and '*', and no min length threshold
|
|
1175
|
+
// - is not nil and not a string type (e.g. object)
|
|
1176
|
+
// - is not nil and is a string, and has enough character
|
|
1177
|
+
const thresholdFilterFn = (value) => (isNilOrBlank(value) || (value === '*')
|
|
1178
|
+
? (this.suggestLengthThreshold <= 0)
|
|
1179
|
+
: (!(typeof value === 'string')
|
|
1180
|
+
|| value.length >= this.suggestLengthThreshold));
|
|
1176
1181
|
const filteredItemsChanges = merge(
|
|
1177
1182
|
// Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
|
|
1178
1183
|
this._reload$,
|
|
@@ -1180,23 +1185,19 @@ class MatAutocompleteField {
|
|
|
1180
1185
|
this.formControl.valueChanges
|
|
1181
1186
|
.pipe(filter(value => this.enabled && this.searchable && isNotNilString(value)),
|
|
1182
1187
|
// Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
|
|
1183
|
-
tap(
|
|
1184
|
-
if (this.showLoadingSpinner) {
|
|
1185
|
-
this.markAsLoading();
|
|
1186
|
-
}
|
|
1187
|
-
}),
|
|
1188
|
+
tap(_ => this.showLoadingSpinner && this.markAsLoading()),
|
|
1188
1189
|
// Filter if not enough character
|
|
1189
1190
|
filter(value => value.length >= this.suggestLengthThreshold),
|
|
1190
1191
|
// Wait a debounce time
|
|
1191
|
-
debounceTime(this.debounceTime)
|
|
1192
|
+
debounceTime(this.debounceTime),
|
|
1192
1193
|
// DEBUG
|
|
1193
|
-
|
|
1194
|
-
),
|
|
1194
|
+
tap((value) => console.debug(this.logPrefix + ' Search text changes:', value))),
|
|
1195
1195
|
// Object set: use it (no distinctUntilChanged() pipe need)
|
|
1196
1196
|
this.formControl.valueChanges
|
|
1197
1197
|
.pipe(startWith(this.formControl.value), filter(value => (this.searchable && isNotNil(value) && typeof value === 'object')), tap(value => {
|
|
1198
1198
|
// DEBUG
|
|
1199
|
-
|
|
1199
|
+
if (this.debug)
|
|
1200
|
+
console.debug(this.logPrefix + ' object changes:', value);
|
|
1200
1201
|
// Update the display value (if need)
|
|
1201
1202
|
const displayValue = this.displayWith(value) || '';
|
|
1202
1203
|
if (this.displayValue !== displayValue) {
|
|
@@ -1206,37 +1207,35 @@ class MatAutocompleteField {
|
|
|
1206
1207
|
this.matInputText.nativeElement.value = this.displayValue;
|
|
1207
1208
|
}
|
|
1208
1209
|
}
|
|
1209
|
-
})
|
|
1210
|
+
}),
|
|
1210
1211
|
// DEBUG
|
|
1211
|
-
|
|
1212
|
-
),
|
|
1212
|
+
tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
|
|
1213
|
+
// On dropdown button click (no distinctUntilChanged(), nor debounceTime)
|
|
1214
|
+
this.dropButtonClick
|
|
1215
|
+
.pipe(filter(event => this.searchable && this.enabled && (!event || !event.defaultPrevented)), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
|
|
1216
|
+
// Make enough characters
|
|
1217
|
+
filter(thresholdFilterFn)),
|
|
1213
1218
|
// Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
|
|
1214
1219
|
merge(
|
|
1215
1220
|
// Focus or click => Load all
|
|
1216
|
-
merge(this.
|
|
1217
|
-
.pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value)
|
|
1218
|
-
//
|
|
1219
|
-
this.
|
|
1220
|
-
.pipe(filter(
|
|
1221
|
-
|
|
1221
|
+
merge(this.focused, this.clicked)
|
|
1222
|
+
.pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
|
|
1223
|
+
// DEBUG
|
|
1224
|
+
tap(value => this.debug && console.debug(this.logPrefix + ' Received focused or clicked event: ', value))), merge(this.$inputItems, this._$filter)
|
|
1225
|
+
.pipe(filter(_ => this.searchable && this.enabled), map(_ => this.formControl.value),
|
|
1226
|
+
// DEBUG
|
|
1227
|
+
tap(value => this.debug && console.debug(this.logPrefix + ' Received $inputItems or filter event: ', value))))
|
|
1222
1228
|
.pipe(
|
|
1223
|
-
//
|
|
1224
|
-
|
|
1225
|
-
// - is nil, and there is no min length threshold
|
|
1226
|
-
// - is not nil and not a string type (e.g. object)
|
|
1227
|
-
// - is not nil and is a string, and has enough character
|
|
1228
|
-
filter(value => value === '*'
|
|
1229
|
-
|| (isNil(value)
|
|
1230
|
-
? (this.suggestLengthThreshold <= 0)
|
|
1231
|
-
: (!(typeof value === 'string')
|
|
1232
|
-
|| value.length >= this.suggestLengthThreshold))),
|
|
1229
|
+
// Make sure there is enough characters
|
|
1230
|
+
filter(thresholdFilterFn),
|
|
1233
1231
|
// Distinguish changes
|
|
1234
|
-
|
|
1232
|
+
// - do NOT filter if loading, to force update after a blur event
|
|
1233
|
+
distinctUntilChanged((v1, v2) => !this.loading && (v1 === v2 || this.equals(v1, v2)))))
|
|
1235
1234
|
.pipe(
|
|
1236
1235
|
// Suggest values
|
|
1237
1236
|
mergeMap(value => this.suggest(value, this.filter)),
|
|
1238
1237
|
// DEBUG
|
|
1239
|
-
|
|
1238
|
+
tap(items => this.debug && console.debug(this.logPrefix + ' Received from suggest: ', items)),
|
|
1240
1239
|
// Store implicit value (will use it onBlur if not other value selected)
|
|
1241
1240
|
tap(items => this.updateImplicitValue(items)));
|
|
1242
1241
|
// Fetch more events
|
|
@@ -1257,7 +1256,7 @@ class MatAutocompleteField {
|
|
|
1257
1256
|
// Make sure control value is inside (mat-select)
|
|
1258
1257
|
if (items && !this.searchable) {
|
|
1259
1258
|
const value = this.formControl.value;
|
|
1260
|
-
if (isNotNil(value) && typeof value === 'object' && items.findIndex(item => this.
|
|
1259
|
+
if (isNotNil(value) && typeof value === 'object' && items.findIndex(item => this.equals(item, value)) === -1) {
|
|
1261
1260
|
// If form value is missing: add it to the list
|
|
1262
1261
|
items = items.concat(value);
|
|
1263
1262
|
}
|
|
@@ -1266,10 +1265,12 @@ class MatAutocompleteField {
|
|
|
1266
1265
|
this.$filteredItems.next(items);
|
|
1267
1266
|
}));
|
|
1268
1267
|
// Applying implicit value, on blur
|
|
1269
|
-
this._subscription.add(this.
|
|
1268
|
+
this._subscription.add(this.blurred
|
|
1270
1269
|
.pipe(
|
|
1271
1270
|
// Skip if not searchable
|
|
1272
|
-
filter(_ => this.searchable), map(_ => this.formControl.value)
|
|
1271
|
+
filter(_ => this.searchable), map(_ => this.formControl.value),
|
|
1272
|
+
// DEBUG
|
|
1273
|
+
tap(value => console.debug(this.logPrefix + ' Received blurred event: ', value)))
|
|
1273
1274
|
.subscribe(value => {
|
|
1274
1275
|
// When leave component without object, use implicit value if :
|
|
1275
1276
|
// - an explicit value
|
|
@@ -1280,12 +1281,14 @@ class MatAutocompleteField {
|
|
|
1280
1281
|
this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
|
|
1281
1282
|
this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
1282
1283
|
this.checkIfTouched();
|
|
1284
|
+
this.$filteredItems.next([this._implicitValue]);
|
|
1283
1285
|
}
|
|
1284
1286
|
else if (isNilOrBlank(value)) {
|
|
1285
1287
|
this.writeValue(null);
|
|
1286
1288
|
this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
|
|
1287
1289
|
this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
1288
1290
|
this.checkIfTouched();
|
|
1291
|
+
this.$filteredItems.next(undefined);
|
|
1289
1292
|
}
|
|
1290
1293
|
this._implicitValue = null; // reset the implicit value
|
|
1291
1294
|
}));
|
|
@@ -1296,7 +1299,7 @@ class MatAutocompleteField {
|
|
|
1296
1299
|
distinctUntilChanged())
|
|
1297
1300
|
// Update component state
|
|
1298
1301
|
.subscribe(() => this.checkIfTouched()));
|
|
1299
|
-
this._subscription.add(this.
|
|
1302
|
+
this._subscription.add(this.keydownEscape.subscribe(event => {
|
|
1300
1303
|
if (this.isOpen) {
|
|
1301
1304
|
event === null || event === void 0 ? void 0 : event.stopPropagation();
|
|
1302
1305
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
@@ -1315,20 +1318,22 @@ class MatAutocompleteField {
|
|
|
1315
1318
|
this._openedSubscription.unsubscribe();
|
|
1316
1319
|
}
|
|
1317
1320
|
this.$inputItems.complete();
|
|
1321
|
+
this.$inputItems.unsubscribe();
|
|
1318
1322
|
this.$filteredItems.complete();
|
|
1323
|
+
this.$filteredItems.unsubscribe();
|
|
1319
1324
|
this._reload$.complete();
|
|
1320
|
-
this.
|
|
1321
|
-
this.
|
|
1322
|
-
this.
|
|
1323
|
-
this.
|
|
1324
|
-
this.
|
|
1325
|
-
this.
|
|
1326
|
-
this.
|
|
1325
|
+
this._$filter.complete();
|
|
1326
|
+
this.dropButtonClick.complete();
|
|
1327
|
+
this.clicked.complete();
|
|
1328
|
+
this.blurred.complete();
|
|
1329
|
+
this.focused.complete();
|
|
1330
|
+
this.keydownEscape.complete();
|
|
1331
|
+
this.keyupEnter.complete();
|
|
1327
1332
|
this._fetchMore$.complete();
|
|
1328
1333
|
this._implicitValue = undefined;
|
|
1329
1334
|
this.formControl = null;
|
|
1330
1335
|
this.displayWith = null;
|
|
1331
|
-
this.
|
|
1336
|
+
this.equals = null;
|
|
1332
1337
|
this.suggestFn = null;
|
|
1333
1338
|
this.$filteredItems = null;
|
|
1334
1339
|
this.matSelectItems$ = null;
|
|
@@ -1338,8 +1343,8 @@ class MatAutocompleteField {
|
|
|
1338
1343
|
this._onTouchedCallback = null;
|
|
1339
1344
|
this._onFetchMoreCallback = null;
|
|
1340
1345
|
// Destroy the 'autocomplete' instance, to avoid memory leak
|
|
1341
|
-
if (this.
|
|
1342
|
-
this.
|
|
1346
|
+
if (this.autocomplete) {
|
|
1347
|
+
this.autocomplete.ngOnDestroy();
|
|
1343
1348
|
}
|
|
1344
1349
|
}
|
|
1345
1350
|
/**
|
|
@@ -1351,7 +1356,7 @@ class MatAutocompleteField {
|
|
|
1351
1356
|
}
|
|
1352
1357
|
writeValue(value) {
|
|
1353
1358
|
// DEBUG
|
|
1354
|
-
// console.debug(this.logPrefix +
|
|
1359
|
+
// console.debug(this.logPrefix + ' Writing value: ', value);
|
|
1355
1360
|
if (value !== this.formControl.value) {
|
|
1356
1361
|
this.formControl.patchValue(value, { emitEvent: false });
|
|
1357
1362
|
this._onChangeCallback(value);
|
|
@@ -1365,7 +1370,7 @@ class MatAutocompleteField {
|
|
|
1365
1370
|
}
|
|
1366
1371
|
setDisabledState(isDisabled) {
|
|
1367
1372
|
var _a;
|
|
1368
|
-
if (isDisabled && ((_a = this.
|
|
1373
|
+
if (isDisabled && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
|
|
1369
1374
|
this.closePanel();
|
|
1370
1375
|
}
|
|
1371
1376
|
this.cd.markForCheck();
|
|
@@ -1379,7 +1384,7 @@ class MatAutocompleteField {
|
|
|
1379
1384
|
(_a = this.matSelect) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1380
1385
|
}
|
|
1381
1386
|
}
|
|
1382
|
-
|
|
1387
|
+
filterInputTextFocusEvent(event) {
|
|
1383
1388
|
if (!event || event.defaultPrevented)
|
|
1384
1389
|
return;
|
|
1385
1390
|
// Ignore event from mat-option
|
|
@@ -1388,15 +1393,20 @@ class MatAutocompleteField {
|
|
|
1388
1393
|
if (event.stopPropagation)
|
|
1389
1394
|
event.stopPropagation();
|
|
1390
1395
|
event.returnValue = false;
|
|
1391
|
-
//DEBUG
|
|
1396
|
+
// DEBUG
|
|
1397
|
+
if (this.debug)
|
|
1398
|
+
console.debug(this.logPrefix + ' Cancelling focus event');
|
|
1392
1399
|
return false;
|
|
1393
1400
|
}
|
|
1394
|
-
|
|
1401
|
+
if (this.debug)
|
|
1402
|
+
console.debug(this.logPrefix + ' Select input content');
|
|
1403
|
+
const hasContent = true; // selectInputContent(event);
|
|
1395
1404
|
// If combo is empty, or if has content but should force to show panel on focus
|
|
1396
|
-
if (!hasContent ||
|
|
1405
|
+
if (!hasContent || this.showPanelOnFocus || this.showAllOnFocus) {
|
|
1397
1406
|
// DEBUG
|
|
1398
|
-
|
|
1399
|
-
|
|
1407
|
+
if (this.debug)
|
|
1408
|
+
console.debug(this.logPrefix + ' Emit focus event');
|
|
1409
|
+
this.focused.emit();
|
|
1400
1410
|
return true;
|
|
1401
1411
|
}
|
|
1402
1412
|
return false;
|
|
@@ -1410,14 +1420,17 @@ class MatAutocompleteField {
|
|
|
1410
1420
|
if (event.stopPropagation)
|
|
1411
1421
|
event.stopPropagation();
|
|
1412
1422
|
event.returnValue = false;
|
|
1413
|
-
//DEBUG
|
|
1423
|
+
// DEBUG
|
|
1424
|
+
if (this.debug)
|
|
1425
|
+
console.debug(this.logPrefix + " Cancelling blur event");
|
|
1414
1426
|
return false;
|
|
1415
1427
|
}
|
|
1416
1428
|
//DEBUG
|
|
1417
|
-
|
|
1429
|
+
if (this.debug)
|
|
1430
|
+
console.debug(this.logPrefix + ' Blur: move caret to the beginning');
|
|
1418
1431
|
// Move caret to the beginning (fix issue IMAGINE-469)
|
|
1419
1432
|
selectInputRange(event.target, 0, 0);
|
|
1420
|
-
this.
|
|
1433
|
+
this.blurred.emit(event);
|
|
1421
1434
|
return true;
|
|
1422
1435
|
}
|
|
1423
1436
|
filterMatSelectFocusEvent(event) {
|
|
@@ -1425,7 +1438,7 @@ class MatAutocompleteField {
|
|
|
1425
1438
|
return;
|
|
1426
1439
|
// DEBUG
|
|
1427
1440
|
// console.debug(this.logPrefix + " Received <mat-select> focus event", event);
|
|
1428
|
-
this.
|
|
1441
|
+
this.focused.emit(event);
|
|
1429
1442
|
}
|
|
1430
1443
|
filterMatSelectBlurEvent(event) {
|
|
1431
1444
|
if (!event || event.defaultPrevented)
|
|
@@ -1442,7 +1455,7 @@ class MatAutocompleteField {
|
|
|
1442
1455
|
// console.debug(this.logPrefix + " Cancelling <mat-select> blur event");
|
|
1443
1456
|
return false;
|
|
1444
1457
|
}
|
|
1445
|
-
this.
|
|
1458
|
+
this.blurred.emit(event);
|
|
1446
1459
|
return true;
|
|
1447
1460
|
}
|
|
1448
1461
|
toggleSearch(event) {
|
|
@@ -1464,7 +1477,7 @@ class MatAutocompleteField {
|
|
|
1464
1477
|
event.stopPropagation();
|
|
1465
1478
|
}
|
|
1466
1479
|
_initAutocompleteInfiniteScroll(threshold) {
|
|
1467
|
-
if (!this.
|
|
1480
|
+
if (!this.autocomplete)
|
|
1468
1481
|
return; // Skip
|
|
1469
1482
|
// DEBUG
|
|
1470
1483
|
//console.debug(this.logPrefix + ' Init autocomplete scroll listener');
|
|
@@ -1472,12 +1485,12 @@ class MatAutocompleteField {
|
|
|
1472
1485
|
this._openedSubscription.unsubscribe();
|
|
1473
1486
|
this._subscription.remove(this._openedSubscription);
|
|
1474
1487
|
}
|
|
1475
|
-
const opened$ = this.
|
|
1488
|
+
const opened$ = this.autocomplete._isOpen
|
|
1476
1489
|
? timer(0)
|
|
1477
|
-
: this.
|
|
1490
|
+
: this.autocomplete.opened.pipe(debounceTime(200));
|
|
1478
1491
|
const scrollEnd$ = opened$
|
|
1479
1492
|
.pipe(map((_) => this.getAutocompletePanel()), filter(isNotNil), switchMap((panel) => fromScrollEndEvent(panel, threshold)
|
|
1480
|
-
.pipe(takeUntil(this.
|
|
1493
|
+
.pipe(takeUntil(this.autocomplete.closed))));
|
|
1481
1494
|
// Trigger fetch more, end end scroll reached
|
|
1482
1495
|
this._openedSubscription = scrollEnd$
|
|
1483
1496
|
.subscribe(() => this._fetchMore$.emit());
|
|
@@ -1508,14 +1521,14 @@ class MatAutocompleteField {
|
|
|
1508
1521
|
}
|
|
1509
1522
|
get isOpen() {
|
|
1510
1523
|
var _a, _b;
|
|
1511
|
-
return (this.searchable && ((_a = this.
|
|
1524
|
+
return (this.searchable && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen))
|
|
1512
1525
|
|| ((_b = this.matSelect) === null || _b === void 0 ? void 0 : _b.panelOpen)
|
|
1513
1526
|
|| false;
|
|
1514
1527
|
}
|
|
1515
1528
|
closePanel() {
|
|
1516
1529
|
var _a, _b, _c, _d;
|
|
1517
|
-
if ((_a = this.
|
|
1518
|
-
(_b = this.
|
|
1530
|
+
if ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
|
|
1531
|
+
(_b = this.autocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
|
|
1519
1532
|
return;
|
|
1520
1533
|
}
|
|
1521
1534
|
if ((_c = this.matSelect) === null || _c === void 0 ? void 0 : _c.panelOpen) {
|
|
@@ -1525,6 +1538,7 @@ class MatAutocompleteField {
|
|
|
1525
1538
|
/* -- private method -- */
|
|
1526
1539
|
suggest(value, filter) {
|
|
1527
1540
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1541
|
+
// Call suggestion function
|
|
1528
1542
|
let res = yield this.suggestFn(value, filter);
|
|
1529
1543
|
// DEBUG
|
|
1530
1544
|
//console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
|
|
@@ -1545,6 +1559,9 @@ class MatAutocompleteField {
|
|
|
1545
1559
|
this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
|
|
1546
1560
|
res = data;
|
|
1547
1561
|
}
|
|
1562
|
+
// DEBUG
|
|
1563
|
+
if (this.debug)
|
|
1564
|
+
console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
|
|
1548
1565
|
return res;
|
|
1549
1566
|
});
|
|
1550
1567
|
}
|
|
@@ -1582,7 +1599,7 @@ class MatAutocompleteField {
|
|
|
1582
1599
|
}
|
|
1583
1600
|
getAutocompletePanel() {
|
|
1584
1601
|
var _a, _b;
|
|
1585
|
-
const ele = (_b = (_a = this.
|
|
1602
|
+
const ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
|
|
1586
1603
|
if (!ele) {
|
|
1587
1604
|
// DEBUG
|
|
1588
1605
|
console.warn(this.logPrefix + ' Unable to find the autocomplete div...');
|
|
@@ -1616,10 +1633,14 @@ MatAutocompleteField.decorators = [
|
|
|
1616
1633
|
{ type: Component, args: [{
|
|
1617
1634
|
// eslint-disable-next-line @angular-eslint/component-selector
|
|
1618
1635
|
selector: 'mat-autocomplete-field',
|
|
1619
|
-
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
|
|
1620
|
-
providers: [
|
|
1636
|
+
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <!-- readonly -->\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 <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
|
|
1637
|
+
providers: [{
|
|
1638
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1639
|
+
multi: true,
|
|
1640
|
+
useExisting: forwardRef(() => MatAutocompleteField)
|
|
1641
|
+
}],
|
|
1621
1642
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1622
|
-
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%}
|
|
1643
|
+
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%}"]
|
|
1623
1644
|
},] }
|
|
1624
1645
|
];
|
|
1625
1646
|
MatAutocompleteField.ctorParameters = () => [
|
|
@@ -1627,7 +1648,7 @@ MatAutocompleteField.ctorParameters = () => [
|
|
|
1627
1648
|
{ type: FormGroupDirective, decorators: [{ type: Optional }] }
|
|
1628
1649
|
];
|
|
1629
1650
|
MatAutocompleteField.propDecorators = {
|
|
1630
|
-
|
|
1651
|
+
equals: [{ type: Input }],
|
|
1631
1652
|
logPrefix: [{ type: Input }],
|
|
1632
1653
|
formControl: [{ type: Input }],
|
|
1633
1654
|
formControlName: [{ type: Input }],
|
|
@@ -1657,21 +1678,21 @@ MatAutocompleteField.propDecorators = {
|
|
|
1657
1678
|
fetchMoreThreshold: [{ type: Input }],
|
|
1658
1679
|
suggestLengthThreshold: [{ type: Input }],
|
|
1659
1680
|
showLoadingSpinner: [{ type: Input }],
|
|
1660
|
-
|
|
1681
|
+
debug: [{ type: Input }],
|
|
1682
|
+
clicked: [{ type: Output, args: ['click',] }],
|
|
1683
|
+
blurred: [{ type: Output, args: ['blur',] }],
|
|
1684
|
+
focused: [{ type: Output, args: ['focus',] }],
|
|
1685
|
+
dropButtonClick: [{ type: Output }],
|
|
1686
|
+
keydownEscape: [{ type: Output, args: ['keydown.escape',] }],
|
|
1687
|
+
keyupEnter: [{ type: Output, args: ['keyup.enter',] }],
|
|
1688
|
+
matSelect: [{ type: ViewChild, args: ['matSelect',] }],
|
|
1689
|
+
matInputText: [{ type: ViewChild, args: ['matInputText',] }],
|
|
1690
|
+
autocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
|
|
1691
|
+
autocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }],
|
|
1661
1692
|
filter: [{ type: Input }],
|
|
1662
1693
|
readonly: [{ type: Input }],
|
|
1663
1694
|
tabindex: [{ type: Input }],
|
|
1664
|
-
items: [{ type: Input }]
|
|
1665
|
-
onClick: [{ type: Output, args: ['click',] }],
|
|
1666
|
-
onBlur: [{ type: Output, args: ['blur',] }],
|
|
1667
|
-
onFocus: [{ type: Output, args: ['focus',] }],
|
|
1668
|
-
onDropButtonClick: [{ type: Output, args: ['dropButtonClick',] }],
|
|
1669
|
-
onKeydownEscape: [{ type: Output, args: ['keydown.escape',] }],
|
|
1670
|
-
onKeyupEnter: [{ type: Output, args: ['keyup.enter',] }],
|
|
1671
|
-
matSelect: [{ type: ViewChild, args: ['matSelect',] }],
|
|
1672
|
-
matInputText: [{ type: ViewChild, args: ['matInputText',] }],
|
|
1673
|
-
matAutocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
|
|
1674
|
-
matAutocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }]
|
|
1695
|
+
items: [{ type: Input }]
|
|
1675
1696
|
};
|
|
1676
1697
|
|
|
1677
1698
|
class DateFormatPipe {
|
|
@@ -4085,9 +4106,9 @@ const MASKS = {
|
|
|
4085
4106
|
DD: [/[+-]/, /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, '°']
|
|
4086
4107
|
}
|
|
4087
4108
|
};
|
|
4088
|
-
const noop$
|
|
4109
|
+
const noop$7 = () => {
|
|
4089
4110
|
};
|
|
4090
|
-
const ɵ0$
|
|
4111
|
+
const ɵ0$a = noop$7;
|
|
4091
4112
|
class MatLatLongField {
|
|
4092
4113
|
constructor(platform, translate, formBuilder, cd, formGroupDir) {
|
|
4093
4114
|
this.platform = platform;
|
|
@@ -4095,8 +4116,8 @@ class MatLatLongField {
|
|
|
4095
4116
|
this.formBuilder = formBuilder;
|
|
4096
4117
|
this.cd = cd;
|
|
4097
4118
|
this.formGroupDir = formGroupDir;
|
|
4098
|
-
this._onChangeCallback = noop$
|
|
4099
|
-
this._onTouchedCallback = noop$
|
|
4119
|
+
this._onChangeCallback = noop$7;
|
|
4120
|
+
this._onTouchedCallback = noop$7;
|
|
4100
4121
|
this._subscription = new Subscription();
|
|
4101
4122
|
this.disabling = false;
|
|
4102
4123
|
this.writing = false;
|
|
@@ -4438,8 +4459,8 @@ const DEFAULT_VALUE_ACCESSOR$5 = {
|
|
|
4438
4459
|
multi: true
|
|
4439
4460
|
};
|
|
4440
4461
|
const DAY_MASK$2 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
|
|
4441
|
-
const noop$
|
|
4442
|
-
const ɵ0$
|
|
4462
|
+
const noop$6 = () => { };
|
|
4463
|
+
const ɵ0$9 = noop$6;
|
|
4443
4464
|
class MatDate {
|
|
4444
4465
|
constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
|
|
4445
4466
|
this.dateAdapter = dateAdapter;
|
|
@@ -4448,8 +4469,8 @@ class MatDate {
|
|
|
4448
4469
|
this.cd = cd;
|
|
4449
4470
|
this.keyboard = keyboard;
|
|
4450
4471
|
this.formGroupDir = formGroupDir;
|
|
4451
|
-
this._onChangeCallback = noop$
|
|
4452
|
-
this._onTouchedCallback = noop$
|
|
4472
|
+
this._onChangeCallback = noop$6;
|
|
4473
|
+
this._onTouchedCallback = noop$6;
|
|
4453
4474
|
this._subscription = new Subscription();
|
|
4454
4475
|
this.writing = true;
|
|
4455
4476
|
this.disabling = false;
|
|
@@ -4731,9 +4752,9 @@ const DEFAULT_VALUE_ACCESSOR$4 = {
|
|
|
4731
4752
|
const DAY_MASK$1 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
|
|
4732
4753
|
const HOUR_REGEXP = /^[012][0-9][:][012345][0-9]$/;
|
|
4733
4754
|
const HOUR_MASK$1 = [/[012]/, /\d/, ':', /[012345]/, /\d/];
|
|
4734
|
-
const noop$
|
|
4755
|
+
const noop$5 = () => {
|
|
4735
4756
|
};
|
|
4736
|
-
const ɵ0$
|
|
4757
|
+
const ɵ0$8 = noop$5;
|
|
4737
4758
|
class MatDateTime {
|
|
4738
4759
|
constructor(platform, dateAdapter, translate, formBuilder, keyboard, cd, formGroupDir) {
|
|
4739
4760
|
this.platform = platform;
|
|
@@ -4743,8 +4764,8 @@ class MatDateTime {
|
|
|
4743
4764
|
this.keyboard = keyboard;
|
|
4744
4765
|
this.cd = cd;
|
|
4745
4766
|
this.formGroupDir = formGroupDir;
|
|
4746
|
-
this._onChangeCallback = noop$
|
|
4747
|
-
this._onTouchedCallback = noop$
|
|
4767
|
+
this._onChangeCallback = noop$5;
|
|
4768
|
+
this._onTouchedCallback = noop$5;
|
|
4748
4769
|
this._subscription = new Subscription();
|
|
4749
4770
|
this.writing = true;
|
|
4750
4771
|
this.disabling = false;
|
|
@@ -5102,9 +5123,9 @@ const DEFAULT_VALUE_ACCESSOR$3 = {
|
|
|
5102
5123
|
multi: true
|
|
5103
5124
|
};
|
|
5104
5125
|
const DAY_MASK = [/\d/, /\d/, /\d/, /\d/];
|
|
5105
|
-
const noop$
|
|
5126
|
+
const noop$4 = () => {
|
|
5106
5127
|
};
|
|
5107
|
-
const ɵ0$
|
|
5128
|
+
const ɵ0$7 = noop$4;
|
|
5108
5129
|
class MatDateShort {
|
|
5109
5130
|
constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
|
|
5110
5131
|
this.dateAdapter = dateAdapter;
|
|
@@ -5113,8 +5134,8 @@ class MatDateShort {
|
|
|
5113
5134
|
this.cd = cd;
|
|
5114
5135
|
this.keyboard = keyboard;
|
|
5115
5136
|
this.formGroupDir = formGroupDir;
|
|
5116
|
-
this._onChangeCallback = noop$
|
|
5117
|
-
this._onTouchedCallback = noop$
|
|
5137
|
+
this._onChangeCallback = noop$4;
|
|
5138
|
+
this._onTouchedCallback = noop$4;
|
|
5118
5139
|
this.writing = true;
|
|
5119
5140
|
this.disabling = false;
|
|
5120
5141
|
this.dayMask = DAY_MASK;
|
|
@@ -5437,9 +5458,9 @@ const DEFAULT_VALUE_ACCESSOR$2 = {
|
|
|
5437
5458
|
};
|
|
5438
5459
|
const HOUR_TIME_PATTERN = /[0-9]\d\d:[0-5]\d/;
|
|
5439
5460
|
const HOUR_MASK = [/\d/, /\d/, /\d/, ':', /[0-5]/, /\d/];
|
|
5440
|
-
const noop$
|
|
5461
|
+
const noop$3 = () => {
|
|
5441
5462
|
};
|
|
5442
|
-
const ɵ0$
|
|
5463
|
+
const ɵ0$6 = noop$3;
|
|
5443
5464
|
class MatDuration {
|
|
5444
5465
|
constructor(platform, dateAdapter, translate, formBuilder, cd, formGroupDir) {
|
|
5445
5466
|
this.dateAdapter = dateAdapter;
|
|
@@ -5448,8 +5469,8 @@ class MatDuration {
|
|
|
5448
5469
|
this.cd = cd;
|
|
5449
5470
|
this.formGroupDir = formGroupDir;
|
|
5450
5471
|
this._subscription = new Subscription();
|
|
5451
|
-
this._onChangeCallback = noop$
|
|
5452
|
-
this._onTouchedCallback = noop$
|
|
5472
|
+
this._onChangeCallback = noop$3;
|
|
5473
|
+
this._onTouchedCallback = noop$3;
|
|
5453
5474
|
this.writing = true;
|
|
5454
5475
|
this.disabling = false;
|
|
5455
5476
|
this.hourMask = HOUR_MASK;
|
|
@@ -5694,17 +5715,17 @@ const DEFAULT_VALUE_ACCESSOR$1 = {
|
|
|
5694
5715
|
useExisting: forwardRef(() => MatBooleanField),
|
|
5695
5716
|
multi: true
|
|
5696
5717
|
};
|
|
5697
|
-
const noop$
|
|
5718
|
+
const noop$2 = () => {
|
|
5698
5719
|
};
|
|
5699
|
-
const ɵ0$
|
|
5720
|
+
const ɵ0$5 = noop$2;
|
|
5700
5721
|
class MatBooleanField {
|
|
5701
5722
|
constructor(translate, formBuilder, cd, formGroupDir) {
|
|
5702
5723
|
this.translate = translate;
|
|
5703
5724
|
this.formBuilder = formBuilder;
|
|
5704
5725
|
this.cd = cd;
|
|
5705
5726
|
this.formGroupDir = formGroupDir;
|
|
5706
|
-
this._onChangeCallback = noop$
|
|
5707
|
-
this._onTouchedCallback = noop$
|
|
5727
|
+
this._onChangeCallback = noop$2;
|
|
5728
|
+
this._onTouchedCallback = noop$2;
|
|
5708
5729
|
this._writing = false;
|
|
5709
5730
|
this.showRadio = false;
|
|
5710
5731
|
this.disabled = false;
|
|
@@ -6487,8 +6508,8 @@ class MatSwipeField {
|
|
|
6487
6508
|
constructor(cd, formGroupDir) {
|
|
6488
6509
|
this.cd = cd;
|
|
6489
6510
|
this.formGroupDir = formGroupDir;
|
|
6490
|
-
this._onChangeCallback = noop$
|
|
6491
|
-
this._onTouchedCallback = noop$
|
|
6511
|
+
this._onChangeCallback = noop$9;
|
|
6512
|
+
this._onTouchedCallback = noop$9;
|
|
6492
6513
|
this._subscription = new Subscription();
|
|
6493
6514
|
this._writing = false;
|
|
6494
6515
|
this.showSlides = false;
|
|
@@ -6552,7 +6573,7 @@ class MatSwipeField {
|
|
|
6552
6573
|
// Default values
|
|
6553
6574
|
this.displayAttributes = this.displayAttributes || ['label', 'name'];
|
|
6554
6575
|
this.displayWith = this.displayWith || ((obj) => obj && joinPropertiesPath(obj, this.displayAttributes));
|
|
6555
|
-
this.
|
|
6576
|
+
this.equals = this.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
|
|
6556
6577
|
this.mobile = toBoolean(this.mobile, false);
|
|
6557
6578
|
}
|
|
6558
6579
|
ngOnDestroy() {
|
|
@@ -6612,7 +6633,7 @@ class MatSwipeField {
|
|
|
6612
6633
|
if (this._writing)
|
|
6613
6634
|
return;
|
|
6614
6635
|
this._writing = true;
|
|
6615
|
-
if (!this.
|
|
6636
|
+
if (!this.equals(value, this._value)) {
|
|
6616
6637
|
this._value = value;
|
|
6617
6638
|
this.showSlides = isNotNil(this._value);
|
|
6618
6639
|
this.updateSlides();
|
|
@@ -6696,7 +6717,7 @@ class MatSwipeField {
|
|
|
6696
6717
|
}
|
|
6697
6718
|
updateSlides() {
|
|
6698
6719
|
if (this.showSlides) {
|
|
6699
|
-
const itemIndex = (this.$items.getValue() || []).findIndex(value => this.
|
|
6720
|
+
const itemIndex = (this.$items.getValue() || []).findIndex(value => this.equals(value, this._value));
|
|
6700
6721
|
if (itemIndex >= 0) {
|
|
6701
6722
|
this.slideTo(itemIndex);
|
|
6702
6723
|
}
|
|
@@ -6760,7 +6781,7 @@ MatSwipeField.propDecorators = {
|
|
|
6760
6781
|
required: [{ type: Input }],
|
|
6761
6782
|
mobile: [{ type: Input }],
|
|
6762
6783
|
clearable: [{ type: Input }],
|
|
6763
|
-
|
|
6784
|
+
equals: [{ type: Input }],
|
|
6764
6785
|
displayWith: [{ type: Input }],
|
|
6765
6786
|
displayAttributes: [{ type: Input }],
|
|
6766
6787
|
appAutofocus: [{ type: Input }],
|
|
@@ -6799,43 +6820,57 @@ SharedMatSwipeModule.decorators = [
|
|
|
6799
6820
|
},] }
|
|
6800
6821
|
];
|
|
6801
6822
|
|
|
6823
|
+
const noop$1 = () => { };
|
|
6824
|
+
const ɵ0$4 = noop$1;
|
|
6802
6825
|
class MatChipsField {
|
|
6803
6826
|
constructor(cd, formGroupDir) {
|
|
6804
6827
|
this.cd = cd;
|
|
6805
6828
|
this.formGroupDir = formGroupDir;
|
|
6806
|
-
this._onChangeCallback =
|
|
6807
|
-
this._onTouchedCallback =
|
|
6829
|
+
this._onChangeCallback = noop$1;
|
|
6830
|
+
this._onTouchedCallback = noop$1;
|
|
6808
6831
|
this.logPrefix = '[mat-chips] ';
|
|
6832
|
+
this.formControlName = null;
|
|
6809
6833
|
this.required = false;
|
|
6810
6834
|
this.readonly = false;
|
|
6811
6835
|
this.clearable = false;
|
|
6812
|
-
this.debounceTime =
|
|
6813
|
-
this.highlightAccent = false;
|
|
6836
|
+
this.debounceTime = null;
|
|
6814
6837
|
this.i18nPrefix = 'REFERENTIAL.';
|
|
6815
6838
|
this.noResultMessage = 'COMMON.NO_RESULT';
|
|
6839
|
+
this.itemSize = '48px';
|
|
6840
|
+
this.fetchMoreThreshold = '15%';
|
|
6841
|
+
this.suggestLengthThreshold = null;
|
|
6842
|
+
this.showLoadingSpinner = true;
|
|
6843
|
+
this.chipColor = null;
|
|
6816
6844
|
this.debug = false;
|
|
6817
6845
|
this.clicked = new EventEmitter();
|
|
6818
6846
|
this.blurred = new EventEmitter();
|
|
6819
6847
|
this.focused = new EventEmitter();
|
|
6848
|
+
this.dropButtonClick = new EventEmitter(true);
|
|
6849
|
+
this.keydownEscape = new EventEmitter();
|
|
6850
|
+
this.keyupEnter = new EventEmitter();
|
|
6820
6851
|
this.$inputItems = new BehaviorSubject(undefined);
|
|
6821
|
-
this
|
|
6852
|
+
this.$filteredItems = new BehaviorSubject(undefined);
|
|
6822
6853
|
this.inputControl = new FormControl();
|
|
6823
|
-
this.
|
|
6854
|
+
this._fetchMore$ = new EventEmitter();
|
|
6824
6855
|
this._subscription = new Subscription();
|
|
6825
6856
|
this._$filter = new BehaviorSubject(undefined);
|
|
6857
|
+
this._reload$ = new Subject();
|
|
6826
6858
|
}
|
|
6827
6859
|
get itemCount() {
|
|
6828
6860
|
return this._itemCount;
|
|
6829
6861
|
}
|
|
6862
|
+
get canFetchMore() {
|
|
6863
|
+
return this._onFetchMoreCallback && this._moreItemsCount > 0;
|
|
6864
|
+
}
|
|
6830
6865
|
set filter(value) {
|
|
6831
|
-
if (this.
|
|
6832
|
-
|
|
6833
|
-
|
|
6866
|
+
if (value !== this._$filter.value) {
|
|
6867
|
+
// DEBUG
|
|
6868
|
+
//console.debug(this.logPrefix + " Setting filter:", value);
|
|
6834
6869
|
this._$filter.next(value);
|
|
6835
6870
|
}
|
|
6836
6871
|
}
|
|
6837
6872
|
get filter() {
|
|
6838
|
-
return this._$filter.
|
|
6873
|
+
return this._$filter.value;
|
|
6839
6874
|
}
|
|
6840
6875
|
set tabindex(value) {
|
|
6841
6876
|
this._tabindex = value;
|
|
@@ -6847,19 +6882,25 @@ class MatChipsField {
|
|
|
6847
6882
|
set items(value) {
|
|
6848
6883
|
// Remove previous subscription on items, (if exits)
|
|
6849
6884
|
if (this._itemsSubscription) {
|
|
6850
|
-
console.warn('Items received twice !');
|
|
6885
|
+
console.warn(this.logPrefix + ' Items received twice !');
|
|
6851
6886
|
this._subscription.remove(this._itemsSubscription);
|
|
6852
6887
|
this._itemsSubscription.unsubscribe();
|
|
6853
6888
|
}
|
|
6854
6889
|
if (isObservable(value)) {
|
|
6855
|
-
this._itemsSubscription = this._subscription.add(value.subscribe(v =>
|
|
6890
|
+
this._itemsSubscription = this._subscription.add(value.subscribe(v => {
|
|
6891
|
+
//console.warn(this.logPrefix + " Received items: ", v);
|
|
6892
|
+
this.$inputItems.next(v);
|
|
6893
|
+
}));
|
|
6856
6894
|
}
|
|
6857
6895
|
else {
|
|
6858
|
-
if (value !== this.$inputItems.
|
|
6896
|
+
if (value !== this.$inputItems.value) {
|
|
6859
6897
|
this.$inputItems.next(value);
|
|
6860
6898
|
}
|
|
6861
6899
|
}
|
|
6862
6900
|
}
|
|
6901
|
+
get items() {
|
|
6902
|
+
return this.$inputItems;
|
|
6903
|
+
}
|
|
6863
6904
|
get value() {
|
|
6864
6905
|
return this.formControl.value || [];
|
|
6865
6906
|
}
|
|
@@ -6869,7 +6910,11 @@ class MatChipsField {
|
|
|
6869
6910
|
get enabled() {
|
|
6870
6911
|
return !this.readonly && this.formControl.enabled;
|
|
6871
6912
|
}
|
|
6913
|
+
get loading() {
|
|
6914
|
+
return isNil(this.$filteredItems.value);
|
|
6915
|
+
}
|
|
6872
6916
|
ngOnInit() {
|
|
6917
|
+
var _a, _b;
|
|
6873
6918
|
this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
|
|
6874
6919
|
if (!this.formControl)
|
|
6875
6920
|
throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-chips-field>.');
|
|
@@ -6884,85 +6929,204 @@ class MatChipsField {
|
|
|
6884
6929
|
this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;
|
|
6885
6930
|
this.displayColumnNames = this.displayColumnNames || this.config.columnNames;
|
|
6886
6931
|
this.displayWith = this.displayWith || this.config.displayWith;
|
|
6887
|
-
this.
|
|
6932
|
+
this.equals = this.equals || this.config.equals;
|
|
6888
6933
|
this.mobile = toBoolean(this.mobile, this.config.mobile);
|
|
6889
|
-
this.
|
|
6934
|
+
this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
|
|
6935
|
+
this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
|
|
6890
6936
|
this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
|
|
6891
|
-
this.
|
|
6937
|
+
this.classList = this.classList || this.config.class;
|
|
6938
|
+
this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
|
|
6939
|
+
this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
|
|
6892
6940
|
}
|
|
6893
6941
|
// Default values
|
|
6894
|
-
this.displayAttributes = this.displayAttributes || (this.filter
|
|
6942
|
+
this.displayAttributes = this.displayAttributes || ((_a = this.filter) === null || _a === void 0 ? void 0 : _a.attributes) || ['label', 'name'];
|
|
6895
6943
|
this.displayWith = this.displayWith || ((obj) => obj && joinPropertiesPath(obj, this.displayAttributes));
|
|
6896
|
-
this.
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
//
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6944
|
+
this.displayColumnSizes = this.displayColumnSizes
|
|
6945
|
+
// if only column: auto size
|
|
6946
|
+
|| (this.displayAttributes.length === 1 && [undefined])
|
|
6947
|
+
// Computed column size:
|
|
6948
|
+
// - if label then col size = 2
|
|
6949
|
+
// - if rankOrder then col size = 1
|
|
6950
|
+
// - ese => auto size
|
|
6951
|
+
|| this.displayAttributes.map(attr => (attr && attr.endsWith('label')) ? 2
|
|
6952
|
+
: ((attr && attr.endsWith('rankOrder')) ? 1
|
|
6953
|
+
: undefined));
|
|
6904
6954
|
this.displayColumnNames = this.displayAttributes.map((attr, index) => this.displayColumnNames && this.displayColumnNames[index] ||
|
|
6905
6955
|
(this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()));
|
|
6906
6956
|
this.mobile = toBoolean(this.mobile, false);
|
|
6957
|
+
this.equals = this.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
|
|
6958
|
+
const classList = (_b = this.classList) === null || _b === void 0 ? void 0 : _b.split(' ');
|
|
6959
|
+
this.panelWidth = this.panelWidth || (classList && ((classList.includes('min-width-medium') && '300px')
|
|
6960
|
+
|| (classList.includes('min-width-large') && '400px')
|
|
6961
|
+
|| (classList.includes('min-width-xlarge') && '450px')
|
|
6962
|
+
|| (classList.includes('mat-autocomplete-panel-full-size') && '100vw')));
|
|
6963
|
+
this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, true);
|
|
6964
|
+
this.debounceTime = toNumber(this.debounceTime, 250);
|
|
6965
|
+
this.highlightAccent = toBoolean(this.highlightAccent, false);
|
|
6966
|
+
this.suggestLengthThreshold = this.suggestLengthThreshold || 0;
|
|
6967
|
+
this.matAutocompletePosition = this.matAutocompletePosition || (this.mobile ? 'above' : 'auto'); // On mobile, set position to above (because of bottom keyboard)
|
|
6907
6968
|
// No suggestFn: filter on the given items
|
|
6908
6969
|
if (!this.suggestFn) {
|
|
6909
6970
|
const suggestFromArrayFn = (value, filter) => __awaiter(this, void 0, void 0, function* () {
|
|
6910
6971
|
if (this.debug)
|
|
6911
6972
|
console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);
|
|
6912
|
-
|
|
6913
|
-
this._itemCount = toNumber(total, data && data.length || 0);
|
|
6914
|
-
return { data, total };
|
|
6973
|
+
return suggestFromArray(this.$inputItems.value, value, Object.assign({ searchAttributes: this.displayAttributes }, filter));
|
|
6915
6974
|
});
|
|
6916
6975
|
// Wait (once) that items are loaded, then call suggest from array fn
|
|
6917
6976
|
this.suggestFn = (value, filter) => __awaiter(this, void 0, void 0, function* () {
|
|
6918
|
-
if (isNil(this.$inputItems.
|
|
6977
|
+
if (isNil(this.$inputItems.value)) {
|
|
6919
6978
|
if (this.debug)
|
|
6920
6979
|
console.debug('[mat-chips] Waiting items to be set...');
|
|
6921
6980
|
yield firstNotNilPromise(this.$inputItems);
|
|
6922
6981
|
if (this.debug)
|
|
6923
|
-
console.debug('[mat-chips] Received items:', this.$inputItems.
|
|
6982
|
+
console.debug('[mat-chips] Received items:', this.$inputItems.value);
|
|
6924
6983
|
}
|
|
6925
6984
|
this.suggestFn = suggestFromArrayFn;
|
|
6926
|
-
return this.
|
|
6985
|
+
return this.suggestFn(value, filter); // Loop
|
|
6927
6986
|
});
|
|
6928
6987
|
}
|
|
6929
|
-
//
|
|
6930
|
-
//
|
|
6931
|
-
//
|
|
6932
|
-
//
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
//
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
//
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6988
|
+
// Send value to suggest when :
|
|
6989
|
+
// - is nil and '*', and no min length threshold
|
|
6990
|
+
// - is not nil and not a string type (e.g. object)
|
|
6991
|
+
// - is not nil and is a string, and has enough character
|
|
6992
|
+
const thresholdFilterFn = (value) => (isNilOrBlank(value) || (value === '*')
|
|
6993
|
+
? (this.suggestLengthThreshold <= 0)
|
|
6994
|
+
: (!(typeof value === 'string')
|
|
6995
|
+
|| value.length >= this.suggestLengthThreshold));
|
|
6996
|
+
const filteredItemsChanges = merge(
|
|
6997
|
+
// Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
|
|
6998
|
+
this._reload$, this.inputControl.valueChanges
|
|
6999
|
+
.pipe(filter(value => this.enabled && isNotNilString(value)),
|
|
7000
|
+
// Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
|
|
7001
|
+
tap(_ => this.showLoadingSpinner && this.markAsLoading()),
|
|
7002
|
+
// Filter if not enough character
|
|
7003
|
+
filter(value => value.length >= this.suggestLengthThreshold),
|
|
7004
|
+
// Wait a debounce time
|
|
7005
|
+
debounceTime(this.debounceTime)
|
|
7006
|
+
// DEBUG
|
|
7007
|
+
//tap((value) => console.debug(this.logPrefix + ' Search text changes:', value))
|
|
7008
|
+
),
|
|
7009
|
+
// Object set: use it (no distinctUntilChanged() pipe need)
|
|
7010
|
+
this.inputControl.valueChanges
|
|
7011
|
+
.pipe(startWith(this.inputControl.value), filter(value => isNotNil(value) && typeof value === 'object'),
|
|
7012
|
+
// DEBUG
|
|
7013
|
+
tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
|
|
7014
|
+
// On dropdown button click (no distinctUntilChanged(), nor debounceTime)
|
|
7015
|
+
this.dropButtonClick
|
|
7016
|
+
.pipe(filter(event => this.enabled && (!event || !event.defaultPrevented)), tap(_ => this.matInputText.nativeElement.focus()), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
|
|
7017
|
+
// Make sure there is enough characters
|
|
7018
|
+
filter(thresholdFilterFn)),
|
|
7019
|
+
// Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
|
|
7020
|
+
merge(
|
|
6949
7021
|
// Focus or click => Load all
|
|
6950
7022
|
merge(this.focused, this.clicked)
|
|
6951
|
-
.pipe(filter(_ => this.enabled), map((_) => this.showAllOnFocus ? '*' : this.inputControl.value)), this.
|
|
6952
|
-
.pipe(
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
7023
|
+
.pipe(filter(_ => this.enabled), map((_) => this.showAllOnFocus ? '*' : this.inputControl.value)), merge(this.$inputItems, this._$filter)
|
|
7024
|
+
.pipe(filter(_ => this.enabled), map(_ => this.inputControl.value)))
|
|
7025
|
+
.pipe(
|
|
7026
|
+
// Make sure there is enough characters
|
|
7027
|
+
filter(thresholdFilterFn),
|
|
7028
|
+
// Distinguish changes
|
|
7029
|
+
distinctUntilChanged()))
|
|
7030
|
+
.pipe(
|
|
7031
|
+
// Suggest values
|
|
7032
|
+
mergeMap(value => this.suggest(value, this.filter)),
|
|
7033
|
+
// DEBUG
|
|
7034
|
+
//tap(items => console.debug(this.logPrefix + ' Received from suggest: ', items)),
|
|
7035
|
+
// Store implicit value (will use it onBlur if not other value selected)
|
|
7036
|
+
tap(items => this.updateImplicitValue(items)));
|
|
7037
|
+
// Fetch more events
|
|
7038
|
+
const fetchMoreItemsChanges = this._fetchMore$
|
|
7039
|
+
.pipe(tap(event => event === null || event === void 0 ? void 0 : event.preventDefault()), // Avoid to close the mat-select
|
|
7040
|
+
filter(() => this.canFetchMore), mergeMap(() => this.fetchMore()),
|
|
7041
|
+
// DEBUG
|
|
7042
|
+
//tap(moreItems => console.debug(this.logPrefix + ' Received from fetch More: ', moreItems)),
|
|
7043
|
+
// Concat to existing items
|
|
7044
|
+
map(moreItems => (this.$filteredItems.value || []).concat(moreItems)));
|
|
7045
|
+
// Update filtered items
|
|
7046
|
+
this._subscription.add(merge(this.$inputItems,
|
|
7047
|
+
// Update items events
|
|
7048
|
+
filteredItemsChanges,
|
|
7049
|
+
// Fetch more events
|
|
7050
|
+
fetchMoreItemsChanges)
|
|
7051
|
+
// Emit items
|
|
7052
|
+
.subscribe(items => this.$filteredItems.next(items)));
|
|
7053
|
+
// Applying implicit value, on blur
|
|
7054
|
+
this._subscription.add(this.blurred
|
|
7055
|
+
.pipe(map(_ => this.formControl.value))
|
|
7056
|
+
.subscribe(value => {
|
|
7057
|
+
// When leave component without object, use implicit value if :
|
|
7058
|
+
// - an explicit value
|
|
7059
|
+
// - field is not empty (user fill something)
|
|
7060
|
+
// - OR field empty but is required
|
|
7061
|
+
if (this._implicitValue && ((this.required && isNilOrBlank(value)) || (isNotNilOrBlank(value) && typeof value !== 'object'))) {
|
|
7062
|
+
this.writeValue(this._implicitValue);
|
|
7063
|
+
this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
|
|
7064
|
+
this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
7065
|
+
this.checkIfTouched();
|
|
7066
|
+
this.$filteredItems.next([this._implicitValue]);
|
|
7067
|
+
}
|
|
7068
|
+
else if (isNilOrBlank(value)) {
|
|
7069
|
+
this.writeValue(null);
|
|
7070
|
+
this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
|
|
7071
|
+
this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
7072
|
+
this.checkIfTouched();
|
|
7073
|
+
this.$filteredItems.next(undefined);
|
|
7074
|
+
}
|
|
7075
|
+
this._implicitValue = null; // reset the implicit value
|
|
7076
|
+
}));
|
|
7077
|
+
// Listen form control status change
|
|
7078
|
+
this._subscription.add(this.formControl.statusChanges
|
|
7079
|
+
.pipe(
|
|
7080
|
+
//filter(() => this.enabled),
|
|
7081
|
+
distinctUntilChanged())
|
|
7082
|
+
// Update component state
|
|
7083
|
+
.subscribe(() => this.checkIfTouched()));
|
|
7084
|
+
this._subscription.add(this.keydownEscape.subscribe(event => {
|
|
7085
|
+
if (this.isOpen) {
|
|
7086
|
+
event === null || event === void 0 ? void 0 : event.stopPropagation();
|
|
7087
|
+
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
7088
|
+
// DEBUG
|
|
7089
|
+
//console.debug(this.logPrefix + " Closing the panel (keydown.escape)");
|
|
7090
|
+
this.closePanel();
|
|
7091
|
+
}
|
|
7092
|
+
}));
|
|
6962
7093
|
}
|
|
6963
7094
|
ngOnDestroy() {
|
|
6964
7095
|
this._subscription.unsubscribe();
|
|
7096
|
+
if (this._itemsSubscription) {
|
|
7097
|
+
this._itemsSubscription.unsubscribe();
|
|
7098
|
+
}
|
|
7099
|
+
if (this._openedSubscription) {
|
|
7100
|
+
this._openedSubscription.unsubscribe();
|
|
7101
|
+
}
|
|
6965
7102
|
this.$inputItems.complete();
|
|
7103
|
+
this.$inputItems.unsubscribe();
|
|
7104
|
+
this.$filteredItems.complete();
|
|
7105
|
+
this.$filteredItems.unsubscribe();
|
|
7106
|
+
this._reload$.complete();
|
|
7107
|
+
this._$filter.complete();
|
|
7108
|
+
this.dropButtonClick.complete();
|
|
7109
|
+
this.clicked.complete();
|
|
7110
|
+
this.blurred.complete();
|
|
7111
|
+
this.focused.complete();
|
|
7112
|
+
this.keydownEscape.complete();
|
|
7113
|
+
this.keyupEnter.complete();
|
|
7114
|
+
this._fetchMore$.complete();
|
|
7115
|
+
this._implicitValue = undefined;
|
|
7116
|
+
this.formControl = null;
|
|
7117
|
+
this.displayWith = null;
|
|
7118
|
+
this.equals = null;
|
|
7119
|
+
this.suggestFn = null;
|
|
7120
|
+
this.$filteredItems = null;
|
|
7121
|
+
this.config = null;
|
|
7122
|
+
this.classList = null;
|
|
7123
|
+
this._onChangeCallback = null;
|
|
7124
|
+
this._onTouchedCallback = null;
|
|
7125
|
+
this._onFetchMoreCallback = null;
|
|
7126
|
+
// Destroy the 'autocomplete' instance, to avoid memory leak
|
|
7127
|
+
if (this.autocomplete) {
|
|
7128
|
+
this.autocomplete.ngOnDestroy();
|
|
7129
|
+
}
|
|
6966
7130
|
}
|
|
6967
7131
|
/**
|
|
6968
7132
|
* Add item to chips
|
|
@@ -6983,27 +7147,35 @@ class MatChipsField {
|
|
|
6983
7147
|
* @param item
|
|
6984
7148
|
*/
|
|
6985
7149
|
remove(item) {
|
|
6986
|
-
const
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
value.
|
|
6990
|
-
|
|
6991
|
-
this.
|
|
7150
|
+
const value = this.value;
|
|
7151
|
+
const index = value ? value.indexOf(item) : -1;
|
|
7152
|
+
if (index !== -1) {
|
|
7153
|
+
const newValue = value.slice();
|
|
7154
|
+
newValue.splice(index, 1);
|
|
7155
|
+
this.writeValue(newValue);
|
|
7156
|
+
this.closePanel();
|
|
6992
7157
|
}
|
|
6993
7158
|
}
|
|
6994
7159
|
/**
|
|
6995
7160
|
* Allow to reload content. Useful when filter has been changed but not detected
|
|
6996
7161
|
*/
|
|
6997
|
-
reloadItems() {
|
|
6998
|
-
|
|
7162
|
+
reloadItems(value) {
|
|
7163
|
+
// Force a refresh
|
|
7164
|
+
this._reload$.next(value || '*');
|
|
6999
7165
|
}
|
|
7000
7166
|
writeValue(value) {
|
|
7001
|
-
if (
|
|
7002
|
-
|
|
7167
|
+
if (value && !Array.isArray(value)) {
|
|
7168
|
+
value = [value];
|
|
7169
|
+
}
|
|
7003
7170
|
if (value !== this.formControl.value) {
|
|
7171
|
+
if (this.debug)
|
|
7172
|
+
console.debug(this.logPrefix + ' Writing value: ', value);
|
|
7004
7173
|
this.formControl.patchValue(value, { emitEvent: false });
|
|
7005
7174
|
this._onChangeCallback(value);
|
|
7006
7175
|
}
|
|
7176
|
+
else {
|
|
7177
|
+
this.markForCheck();
|
|
7178
|
+
}
|
|
7007
7179
|
}
|
|
7008
7180
|
registerOnChange(fn) {
|
|
7009
7181
|
this._onChangeCallback = fn;
|
|
@@ -7012,6 +7184,10 @@ class MatChipsField {
|
|
|
7012
7184
|
this._onTouchedCallback = fn;
|
|
7013
7185
|
}
|
|
7014
7186
|
setDisabledState(isDisabled) {
|
|
7187
|
+
var _a;
|
|
7188
|
+
if (isDisabled && ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
|
|
7189
|
+
this.closePanel();
|
|
7190
|
+
}
|
|
7015
7191
|
this.cd.markForCheck();
|
|
7016
7192
|
}
|
|
7017
7193
|
focus() {
|
|
@@ -7031,6 +7207,7 @@ class MatChipsField {
|
|
|
7031
7207
|
return false;
|
|
7032
7208
|
}
|
|
7033
7209
|
const hasContent = selectInputContent(event);
|
|
7210
|
+
// If combo is empty, or if has content but should force to show panel on focus
|
|
7034
7211
|
if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
|
|
7035
7212
|
if (this.debug)
|
|
7036
7213
|
console.debug(this.logPrefix + ' Emit focus event');
|
|
@@ -7039,17 +7216,75 @@ class MatChipsField {
|
|
|
7039
7216
|
}
|
|
7040
7217
|
return false;
|
|
7041
7218
|
}
|
|
7219
|
+
filterInputTextBlurEvent(event) {
|
|
7220
|
+
if (!event || event.defaultPrevented)
|
|
7221
|
+
return;
|
|
7222
|
+
// Ignore event from mat-option
|
|
7223
|
+
if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {
|
|
7224
|
+
event.preventDefault();
|
|
7225
|
+
if (event.stopPropagation)
|
|
7226
|
+
event.stopPropagation();
|
|
7227
|
+
event.returnValue = false;
|
|
7228
|
+
//DEBUG console.debug(this.logPrefix + " Cancelling blur event");
|
|
7229
|
+
return false;
|
|
7230
|
+
}
|
|
7231
|
+
//DEBUG
|
|
7232
|
+
//console.debug(this.logPrefix + ' Blur: move caret to the beginning');
|
|
7233
|
+
// Move caret to the beginning (fix issue IMAGINE-469)
|
|
7234
|
+
selectInputRange(event.target, 0, 0);
|
|
7235
|
+
this.blurred.emit(event);
|
|
7236
|
+
return true;
|
|
7237
|
+
}
|
|
7238
|
+
filterChipsFocusEvent(event) {
|
|
7239
|
+
// DEBUG
|
|
7240
|
+
if (this.debug)
|
|
7241
|
+
console.debug(this.logPrefix + ' Focus in chips list', event);
|
|
7242
|
+
// Ignore event in button
|
|
7243
|
+
this.matInputText.nativeElement.focus();
|
|
7244
|
+
}
|
|
7042
7245
|
clearValue(event) {
|
|
7043
7246
|
this.writeValue(null);
|
|
7044
7247
|
event.stopPropagation();
|
|
7045
7248
|
}
|
|
7249
|
+
_initAutocompleteInfiniteScroll(threshold) {
|
|
7250
|
+
if (!this.autocomplete)
|
|
7251
|
+
return; // Skip
|
|
7252
|
+
// DEBUG
|
|
7253
|
+
//console.debug(this.logPrefix + ' Init autocomplete scroll listener');
|
|
7254
|
+
if (this._openedSubscription) {
|
|
7255
|
+
this._openedSubscription.unsubscribe();
|
|
7256
|
+
this._subscription.remove(this._openedSubscription);
|
|
7257
|
+
}
|
|
7258
|
+
const opened$ = this.autocomplete._isOpen
|
|
7259
|
+
? timer(0)
|
|
7260
|
+
: this.autocomplete.opened.pipe(debounceTime(200));
|
|
7261
|
+
const scrollEnd$ = opened$
|
|
7262
|
+
.pipe(map((_) => this.getAutocompletePanel()), filter(isNotNil), switchMap((panel) => fromScrollEndEvent(panel, threshold)
|
|
7263
|
+
.pipe(takeUntil(this.autocomplete.closed))));
|
|
7264
|
+
// Trigger fetch more, end end scroll reached
|
|
7265
|
+
this._openedSubscription = scrollEnd$
|
|
7266
|
+
.subscribe(() => this._fetchMore$.emit());
|
|
7267
|
+
// Register subscription
|
|
7268
|
+
this._subscription.add(this._openedSubscription);
|
|
7269
|
+
}
|
|
7270
|
+
get isOpen() {
|
|
7271
|
+
var _a;
|
|
7272
|
+
return ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) || false;
|
|
7273
|
+
}
|
|
7274
|
+
closePanel() {
|
|
7275
|
+
var _a, _b;
|
|
7276
|
+
if ((_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
|
|
7277
|
+
(_b = this.autocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
|
|
7278
|
+
return;
|
|
7279
|
+
}
|
|
7280
|
+
}
|
|
7046
7281
|
/* -- private method -- */
|
|
7047
7282
|
suggest(value, filter) {
|
|
7048
7283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7049
7284
|
// Call suggestion function
|
|
7050
7285
|
let res = yield this.suggestFn(value, filter);
|
|
7051
7286
|
// DEBUG
|
|
7052
|
-
//
|
|
7287
|
+
//console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
|
|
7053
7288
|
if (!res) {
|
|
7054
7289
|
this._itemCount = 0;
|
|
7055
7290
|
res = [];
|
|
@@ -7059,37 +7294,88 @@ class MatChipsField {
|
|
|
7059
7294
|
this._itemCount = res.length || 0;
|
|
7060
7295
|
}
|
|
7061
7296
|
else {
|
|
7062
|
-
const { data, total } = res;
|
|
7063
|
-
res = data;
|
|
7297
|
+
const { data, total, fetchMore } = res;
|
|
7064
7298
|
this._itemCount = toNumber(total, data && data.length || 0);
|
|
7299
|
+
this._onFetchMoreCallback = fetchMore;
|
|
7300
|
+
this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
|
|
7301
|
+
res = data;
|
|
7065
7302
|
}
|
|
7066
7303
|
// Filter out existing items
|
|
7067
|
-
const filteredData = (res || []).slice().filter(item1 => this.value.findIndex(item2 => this.
|
|
7068
|
-
|
|
7069
|
-
|
|
7304
|
+
const filteredData = (res || []).slice().filter(item1 => this.value.findIndex(item2 => this.equals(item1, item2)) === -1);
|
|
7305
|
+
const removedItemCount = (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
|
|
7306
|
+
// Decrease the item count, with delta
|
|
7307
|
+
this._itemCount -= removedItemCount;
|
|
7070
7308
|
if (this.debug)
|
|
7071
7309
|
console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
|
|
7072
7310
|
return res;
|
|
7073
7311
|
});
|
|
7074
7312
|
}
|
|
7313
|
+
fetchMore() {
|
|
7314
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7315
|
+
if (!this._onFetchMoreCallback)
|
|
7316
|
+
return [];
|
|
7317
|
+
// Save then remove fetch function (to avoid multi-call)
|
|
7318
|
+
const fetchMoreFn = this._onFetchMoreCallback;
|
|
7319
|
+
this._onFetchMoreCallback = undefined;
|
|
7320
|
+
const { data, total, fetchMore } = yield fetchMoreFn();
|
|
7321
|
+
this._itemCount = total || this._itemCount;
|
|
7322
|
+
this._onFetchMoreCallback = fetchMore;
|
|
7323
|
+
this._moreItemsCount = Math.max(0, this._moreItemsCount - data.length); // Borne min = 0
|
|
7324
|
+
return data;
|
|
7325
|
+
});
|
|
7326
|
+
}
|
|
7327
|
+
updateImplicitValue(items) {
|
|
7328
|
+
// Store implicit value (will use it onBlur if not other value selected)
|
|
7329
|
+
if (items && items.length === 1) {
|
|
7330
|
+
this._implicitValue = items[0];
|
|
7331
|
+
//this.formControl.setErrors(null);
|
|
7332
|
+
}
|
|
7333
|
+
else {
|
|
7334
|
+
this._implicitValue = undefined;
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7337
|
+
checkIfTouched() {
|
|
7338
|
+
if (this.formControl.touched) {
|
|
7339
|
+
this.cd.markForCheck();
|
|
7340
|
+
this._onTouchedCallback();
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
getAutocompletePanel() {
|
|
7344
|
+
var _a, _b;
|
|
7345
|
+
const ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
|
|
7346
|
+
if (!ele) {
|
|
7347
|
+
// DEBUG
|
|
7348
|
+
console.warn(this.logPrefix + ' Unable to find the autocomplete div...');
|
|
7349
|
+
}
|
|
7350
|
+
return ele;
|
|
7351
|
+
}
|
|
7075
7352
|
markForCheck() {
|
|
7076
7353
|
this.cd.markForCheck();
|
|
7077
7354
|
}
|
|
7355
|
+
markAsLoading() {
|
|
7356
|
+
if (this.$filteredItems.value) {
|
|
7357
|
+
this.$filteredItems.next(undefined);
|
|
7358
|
+
this._itemCount = undefined;
|
|
7359
|
+
this._implicitValue = undefined;
|
|
7360
|
+
this._onFetchMoreCallback = undefined;
|
|
7361
|
+
this._moreItemsCount = 0;
|
|
7362
|
+
this.markForCheck();
|
|
7363
|
+
}
|
|
7364
|
+
}
|
|
7078
7365
|
}
|
|
7079
7366
|
MatChipsField.decorators = [
|
|
7080
7367
|
{ type: Component, args: [{
|
|
7081
7368
|
// eslint-disable-next-line @angular-eslint/component-selector
|
|
7082
7369
|
selector: 'mat-chips-field',
|
|
7083
|
-
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-
|
|
7084
|
-
providers: [
|
|
7085
|
-
{
|
|
7370
|
+
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\" class=\"material-chips\" [class.mat-form-field-disabled]=\"disabled\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList\n (focus)=\"filterChipsFocusEvent($event)\" >\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\"\n [color]=\"chipColor\"\n >\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
|
|
7371
|
+
providers: [{
|
|
7086
7372
|
provide: NG_VALUE_ACCESSOR,
|
|
7087
7373
|
multi: true,
|
|
7088
7374
|
useExisting: forwardRef(() => MatChipsField)
|
|
7089
|
-
}
|
|
7090
|
-
|
|
7375
|
+
}],
|
|
7376
|
+
encapsulation: ViewEncapsulation.None,
|
|
7091
7377
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7092
|
-
styles: [":host{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%}"]
|
|
7378
|
+
styles: [":host{width:100%;display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}.mat-form-field-suffix{position:absolute!important;right:0!important;top:calc(100% - 50px)!important}.mat-chip.mat-standard-chip.mat-primary{background-color:var(--ion-color-primary);color:var(--ion-color-primary-contrast)}.mat-chip.mat-standard-chip.mat-secondary{background-color:var(--ion-color-secondary);color:var(--ion-color-secondary-contrast)}.mat-chip.mat-standard-chip.mat-tertiary{background-color:var(--ion-color-tertiary);color:var(--ion-color-tertiary-contrast)}.mat-chip.mat-standard-chip.mat-accent{background-color:var(--ion-color-accent);color:var(--ion-color-accent-contrast)}.mat-chip.mat-standard-chip.mat-warning{background-color:var(--ion-color-warning);color:var(--ion-color-warning-contrast)}"]
|
|
7093
7379
|
},] }
|
|
7094
7380
|
];
|
|
7095
7381
|
MatChipsField.ctorParameters = () => [
|
|
@@ -7097,7 +7383,7 @@ MatChipsField.ctorParameters = () => [
|
|
|
7097
7383
|
{ type: FormGroupDirective, decorators: [{ type: Optional }] }
|
|
7098
7384
|
];
|
|
7099
7385
|
MatChipsField.propDecorators = {
|
|
7100
|
-
|
|
7386
|
+
equals: [{ type: Input }],
|
|
7101
7387
|
logPrefix: [{ type: Input }],
|
|
7102
7388
|
formControl: [{ type: Input }],
|
|
7103
7389
|
formControlName: [{ type: Input }],
|
|
@@ -7116,16 +7402,27 @@ MatChipsField.propDecorators = {
|
|
|
7116
7402
|
highlightAccent: [{ type: Input }],
|
|
7117
7403
|
showAllOnFocus: [{ type: Input }],
|
|
7118
7404
|
showPanelOnFocus: [{ type: Input }],
|
|
7119
|
-
|
|
7405
|
+
autofocus: [{ type: Input }],
|
|
7120
7406
|
config: [{ type: Input }],
|
|
7121
7407
|
i18nPrefix: [{ type: Input }],
|
|
7122
7408
|
noResultMessage: [{ type: Input }],
|
|
7123
|
-
|
|
7409
|
+
classList: [{ type: Input, args: ['class',] }],
|
|
7410
|
+
panelWidth: [{ type: Input }],
|
|
7411
|
+
matAutocompletePosition: [{ type: Input }],
|
|
7412
|
+
itemSize: [{ type: Input }],
|
|
7413
|
+
fetchMoreThreshold: [{ type: Input }],
|
|
7414
|
+
suggestLengthThreshold: [{ type: Input }],
|
|
7415
|
+
showLoadingSpinner: [{ type: Input }],
|
|
7416
|
+
chipColor: [{ type: Input }],
|
|
7124
7417
|
debug: [{ type: Input }],
|
|
7125
7418
|
clicked: [{ type: Output }],
|
|
7126
7419
|
blurred: [{ type: Output }],
|
|
7127
7420
|
focused: [{ type: Output }],
|
|
7421
|
+
dropButtonClick: [{ type: Output }],
|
|
7422
|
+
keydownEscape: [{ type: Output, args: ['keydown.escape',] }],
|
|
7423
|
+
keyupEnter: [{ type: Output, args: ['keyup.enter',] }],
|
|
7128
7424
|
matInputText: [{ type: ViewChild, args: ['matInputText',] }],
|
|
7425
|
+
autocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
|
|
7129
7426
|
autocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }],
|
|
7130
7427
|
filter: [{ type: Input }],
|
|
7131
7428
|
tabindex: [{ type: Input }],
|
|
@@ -16239,7 +16536,7 @@ class AutocompleteTestPage {
|
|
|
16239
16536
|
constructor(formBuilder) {
|
|
16240
16537
|
this.formBuilder = formBuilder;
|
|
16241
16538
|
this._items = deepCopy$1(FAKE_ENTITIES$1, 100);
|
|
16242
|
-
this
|
|
16539
|
+
this._$items = new BehaviorSubject(undefined);
|
|
16243
16540
|
this.autocompleteFields = new MatAutocompleteConfigHolder();
|
|
16244
16541
|
this.memoryHide = false;
|
|
16245
16542
|
this.memoryMobile = true;
|
|
@@ -16268,7 +16565,7 @@ class AutocompleteTestPage {
|
|
|
16268
16565
|
});
|
|
16269
16566
|
// From $items observable
|
|
16270
16567
|
this.autocompleteFields.add('entity-$items', {
|
|
16271
|
-
items: this
|
|
16568
|
+
items: this._$items,
|
|
16272
16569
|
attributes: ['label', 'name'],
|
|
16273
16570
|
displayWith: this.entityToString
|
|
16274
16571
|
});
|
|
@@ -16306,7 +16603,7 @@ class AutocompleteTestPage {
|
|
|
16306
16603
|
}
|
|
16307
16604
|
loadItems() {
|
|
16308
16605
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16309
|
-
this
|
|
16606
|
+
this._$items.next(this._items.slice());
|
|
16310
16607
|
});
|
|
16311
16608
|
}
|
|
16312
16609
|
entityToString(item) {
|
|
@@ -16336,7 +16633,7 @@ class AutocompleteTestPage {
|
|
|
16336
16633
|
doSubmit(event) {
|
|
16337
16634
|
console.debug('Validate form: ', this.form.value);
|
|
16338
16635
|
}
|
|
16339
|
-
|
|
16636
|
+
equals(o1, o2) {
|
|
16340
16637
|
return o1 && o2 && o1.id === o2.id;
|
|
16341
16638
|
}
|
|
16342
16639
|
toggleMode(value) {
|
|
@@ -16367,7 +16664,7 @@ class AutocompleteTestPage {
|
|
|
16367
16664
|
AutocompleteTestPage.decorators = [
|
|
16368
16665
|
{ type: Component, args: [{
|
|
16369
16666
|
selector: 'app-autocomplete-test',
|
|
16370
|
-
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<any[]></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) => 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<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-$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<any[]></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<any>\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<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-$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<any[]></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"
|
|
16667
|
+
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<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-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<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-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-suggest]'\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<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-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
16371
16668
|
},] }
|
|
16372
16669
|
];
|
|
16373
16670
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -16522,7 +16819,7 @@ class SwipeTestPage {
|
|
|
16522
16819
|
SwipeTestPage.decorators = [
|
|
16523
16820
|
{ type: Component, args: [{
|
|
16524
16821
|
selector: 'app-swipe-test',
|
|
16525
|
-
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 [
|
|
16822
|
+
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"
|
|
16526
16823
|
},] }
|
|
16527
16824
|
];
|
|
16528
16825
|
SwipeTestPage.ctorParameters = () => [
|
|
@@ -16628,15 +16925,30 @@ class EntityTestClass {
|
|
|
16628
16925
|
const FAKE_ENTITIES = [
|
|
16629
16926
|
{ id: 1, label: 'AAA', name: 'Item A' },
|
|
16630
16927
|
{ id: 2, label: 'BBB', name: 'Item B' },
|
|
16631
|
-
{ id: 3, label: 'CCC', name: 'Item C' }
|
|
16928
|
+
{ id: 3, label: 'CCC', name: 'Item C' },
|
|
16929
|
+
{ id: 4, label: 'DDD', name: 'Item D' },
|
|
16930
|
+
{ id: 5, label: 'EEE', name: 'Item E' },
|
|
16931
|
+
{ id: 6, label: 'FFF', name: 'Item F' },
|
|
16932
|
+
{ id: 7, label: 'GGG', name: 'Item G' }
|
|
16632
16933
|
];
|
|
16633
|
-
function deepCopy(values) {
|
|
16634
|
-
|
|
16934
|
+
function deepCopy(values, size) {
|
|
16935
|
+
if (isNil(size)) {
|
|
16936
|
+
return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));
|
|
16937
|
+
}
|
|
16938
|
+
let result = [];
|
|
16939
|
+
let i = 1;
|
|
16940
|
+
while (result.length < size) {
|
|
16941
|
+
result = result.concat((values || FAKE_ENTITIES).map(entity => {
|
|
16942
|
+
const name = entity.name + ' #' + i;
|
|
16943
|
+
return Object.assign(Object.assign({}, entity), { id: i++, name });
|
|
16944
|
+
}));
|
|
16945
|
+
}
|
|
16946
|
+
return result.slice(0, size);
|
|
16635
16947
|
}
|
|
16636
16948
|
class ChipsTestPage {
|
|
16637
16949
|
constructor(formBuilder) {
|
|
16638
16950
|
this.formBuilder = formBuilder;
|
|
16639
|
-
this._items = deepCopy(FAKE_ENTITIES);
|
|
16951
|
+
this._items = deepCopy(FAKE_ENTITIES, 100);
|
|
16640
16952
|
this._$items = new BehaviorSubject(undefined);
|
|
16641
16953
|
this.autocompleteFields = new MatAutocompleteConfigHolder();
|
|
16642
16954
|
this.form = formBuilder.group({
|
|
@@ -16651,15 +16963,17 @@ class ChipsTestPage {
|
|
|
16651
16963
|
this.autocompleteFields.add('entity-suggestFn', {
|
|
16652
16964
|
suggestFn: (value, filter) => this.suggest(value, filter),
|
|
16653
16965
|
attributes: ['label', 'name'],
|
|
16654
|
-
displayWith: this.entityToString
|
|
16966
|
+
displayWith: this.entityToString,
|
|
16967
|
+
equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0
|
|
16655
16968
|
});
|
|
16656
16969
|
// From items
|
|
16657
16970
|
this.autocompleteFields.add('entity-items', {
|
|
16658
|
-
items:
|
|
16971
|
+
items: this._items.slice(),
|
|
16659
16972
|
attributes: ['label', 'name'],
|
|
16660
|
-
displayWith: this.entityToString
|
|
16973
|
+
displayWith: this.entityToString,
|
|
16974
|
+
equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0
|
|
16661
16975
|
});
|
|
16662
|
-
// From items
|
|
16976
|
+
// From $items observable
|
|
16663
16977
|
this.autocompleteFields.add('entity-$items', {
|
|
16664
16978
|
items: this._$items,
|
|
16665
16979
|
attributes: ['label', 'name'],
|
|
@@ -16673,18 +16987,20 @@ class ChipsTestPage {
|
|
|
16673
16987
|
// Load the form with data
|
|
16674
16988
|
loadData() {
|
|
16675
16989
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16990
|
+
const items = deepCopy(FAKE_ENTITIES);
|
|
16676
16991
|
const data = {
|
|
16677
|
-
entity:
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
disableEntity: FAKE_ENTITIES.slice(1, 2)
|
|
16992
|
+
entity: items.slice(0, 1),
|
|
16993
|
+
entityInitial: items.slice(1, 2),
|
|
16994
|
+
disableEntity: items.slice(1, 2)
|
|
16681
16995
|
};
|
|
16682
16996
|
this.form.setValue(data);
|
|
16997
|
+
// Load observables
|
|
16998
|
+
setTimeout(() => this.loadItems(), 1000);
|
|
16683
16999
|
});
|
|
16684
17000
|
}
|
|
16685
17001
|
loadItems() {
|
|
16686
17002
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16687
|
-
this._$items.next(
|
|
17003
|
+
this._$items.next(this._items.slice());
|
|
16688
17004
|
});
|
|
16689
17005
|
}
|
|
16690
17006
|
entityToString(item) {
|
|
@@ -16692,13 +17008,29 @@ class ChipsTestPage {
|
|
|
16692
17008
|
}
|
|
16693
17009
|
suggest(value, filter) {
|
|
16694
17010
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16695
|
-
|
|
17011
|
+
filter = Object.assign({ offset: 0, size: 30 }, filter);
|
|
17012
|
+
const res = suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
|
|
17013
|
+
// Simulate a size = 30
|
|
17014
|
+
const total = res.total || res.data.length;
|
|
17015
|
+
const nextOffset = filter.offset + res.data.length;
|
|
17016
|
+
if (nextOffset < total) {
|
|
17017
|
+
filter = Object.assign(Object.assign({}, filter), { offset: nextOffset });
|
|
17018
|
+
return {
|
|
17019
|
+
total,
|
|
17020
|
+
data: res.data,
|
|
17021
|
+
fetchMore: (variables) => __awaiter(this, void 0, void 0, function* () {
|
|
17022
|
+
yield sleep(1000);
|
|
17023
|
+
return this.suggest(value, Object.assign(Object.assign({}, filter), variables));
|
|
17024
|
+
})
|
|
17025
|
+
};
|
|
17026
|
+
}
|
|
17027
|
+
return res;
|
|
16696
17028
|
});
|
|
16697
17029
|
}
|
|
16698
17030
|
doSubmit(event) {
|
|
16699
17031
|
console.debug('Validate form: ', this.form.value);
|
|
16700
17032
|
}
|
|
16701
|
-
|
|
17033
|
+
equals(o1, o2) {
|
|
16702
17034
|
return o1 && o2 && o1.id === o2.id;
|
|
16703
17035
|
}
|
|
16704
17036
|
/* -- protected methods -- */
|
|
@@ -16709,7 +17041,7 @@ class ChipsTestPage {
|
|
|
16709
17041
|
ChipsTestPage.decorators = [
|
|
16710
17042
|
{ type: Component, args: [{
|
|
16711
17043
|
selector: 'app-chips-test',
|
|
16712
|
-
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) => 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
|
|
17044
|
+
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Chips field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Suggest() function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) => any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-empty] '\"\n chipColor=\"accent\"\n [debug]=\"false\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function with initial value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) => any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entityInitial\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\n chipColor=\"primary\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entityInitial.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\n chipColor=\"warning\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.disableEntity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-readonly] '\"\n [readonly]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
16713
17045
|
},] }
|
|
16714
17046
|
];
|
|
16715
17047
|
ChipsTestPage.ctorParameters = () => [
|
|
@@ -17253,11 +17585,18 @@ AuthForm.propDecorators = {
|
|
|
17253
17585
|
};
|
|
17254
17586
|
|
|
17255
17587
|
class AuthModal {
|
|
17256
|
-
constructor(accountService, viewCtrl,
|
|
17588
|
+
constructor(accountService, viewCtrl, cd) {
|
|
17257
17589
|
this.accountService = accountService;
|
|
17258
17590
|
this.viewCtrl = viewCtrl;
|
|
17259
|
-
this.
|
|
17260
|
-
|
|
17591
|
+
this.cd = cd;
|
|
17592
|
+
}
|
|
17593
|
+
get loading() {
|
|
17594
|
+
var _a;
|
|
17595
|
+
return (_a = this.form) === null || _a === void 0 ? void 0 : _a.loading;
|
|
17596
|
+
}
|
|
17597
|
+
ngOnInit() {
|
|
17598
|
+
this.form.markAsReady({ emitEvent: false });
|
|
17599
|
+
this.form.markAsLoaded();
|
|
17261
17600
|
}
|
|
17262
17601
|
cancel() {
|
|
17263
17602
|
this.viewCtrl.dismiss();
|
|
@@ -17267,10 +17606,10 @@ class AuthModal {
|
|
|
17267
17606
|
if (this.form.disabled)
|
|
17268
17607
|
return;
|
|
17269
17608
|
if (!this.form.valid) {
|
|
17270
|
-
this.form.
|
|
17609
|
+
this.form.markAllAsTouched();
|
|
17271
17610
|
return;
|
|
17272
17611
|
}
|
|
17273
|
-
this.
|
|
17612
|
+
this.markAsLoading();
|
|
17274
17613
|
try {
|
|
17275
17614
|
const data = this.form.value;
|
|
17276
17615
|
// Disable the form
|
|
@@ -17279,9 +17618,8 @@ class AuthModal {
|
|
|
17279
17618
|
return this.viewCtrl.dismiss(account);
|
|
17280
17619
|
}
|
|
17281
17620
|
catch (err) {
|
|
17282
|
-
this.loading = false;
|
|
17283
17621
|
this.form.error = err && err.message || err;
|
|
17284
|
-
this.
|
|
17622
|
+
this.markAsLoaded();
|
|
17285
17623
|
// Enable the form
|
|
17286
17624
|
this.form.enable();
|
|
17287
17625
|
// Reset form error on next changes
|
|
@@ -17294,7 +17632,13 @@ class AuthModal {
|
|
|
17294
17632
|
});
|
|
17295
17633
|
}
|
|
17296
17634
|
markForCheck() {
|
|
17297
|
-
this.
|
|
17635
|
+
this.cd.markForCheck();
|
|
17636
|
+
}
|
|
17637
|
+
markAsLoading(opts) {
|
|
17638
|
+
this.form.markAsLoading(opts);
|
|
17639
|
+
}
|
|
17640
|
+
markAsLoaded(opts) {
|
|
17641
|
+
this.form.markAsLoaded(opts);
|
|
17298
17642
|
}
|
|
17299
17643
|
}
|
|
17300
17644
|
AuthModal.decorators = [
|
|
@@ -24633,5 +24977,5 @@ const ErrorCodes = {
|
|
|
24633
24977
|
* Generated bundle index. Do not edit.
|
|
24634
24978
|
*/
|
|
24635
24979
|
|
|
24636
|
-
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending,
|
|
24980
|
+
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk, AppIconComponent as ɵl };
|
|
24637
24981
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|