@sumaris-net/ngx-components 0.21.1 → 0.23.0
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/ngx-sumaris-components.umd.js +114 -67
- package/bundles/ngx-sumaris-components.umd.js.map +1 -1
- package/bundles/ngx-sumaris-components.umd.min.js +2 -2
- package/bundles/ngx-sumaris-components.umd.min.js.map +1 -1
- package/doc/changelog.md +4 -0
- package/esm2015/src/app/core/form/editor.class.js +1 -1
- package/esm2015/src/app/core/form/entity-editor.class.js +18 -7
- package/esm2015/src/app/core/form/form-buttons-bar.component.js +2 -1
- package/esm2015/src/app/core/form/form.utils.js +3 -3
- package/esm2015/src/app/core/form/list.form.js +11 -2
- package/esm2015/src/app/core/install/install-upgrade-card.component.js +2 -2
- package/esm2015/src/app/core/services/local-settings.service.js +2 -2
- package/esm2015/src/app/core/table/table.class.js +14 -16
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +45 -12
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +2 -2
- package/esm2015/src/app/shared/services/memory-entity-service.class.js +2 -1
- package/fesm2015/ngx-sumaris-components.js +90 -38
- package/fesm2015/ngx-sumaris-components.js.map +1 -1
- package/ngx-sumaris-components.metadata.json +1 -1
- package/package.json +1 -1
- package/src/app/core/form/editor.class.d.ts +1 -1
- package/src/app/core/form/entity-editor.class.d.ts +2 -1
- package/src/app/core/form/list.form.d.ts +3 -0
- package/src/app/core/table/table.class.d.ts +1 -3
- package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +7 -2
- package/src/assets/i18n/fr.json +1 -0
|
@@ -32,7 +32,7 @@ import { MatBadgeModule } from '@angular/material/badge';
|
|
|
32
32
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
33
33
|
import * as i2$1 from '@angular/material/dialog';
|
|
34
34
|
import { MatDialogModule, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
|
|
35
|
-
import {
|
|
35
|
+
import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteModule, MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MAT_AUTOCOMPLETE_DEFAULT_OPTIONS } from '@angular/material/autocomplete';
|
|
36
36
|
import { __awaiter, __decorate } from 'tslib';
|
|
37
37
|
import * as i1$6 from '@angular/forms';
|
|
38
38
|
import { NG_VALUE_ACCESSOR, FormGroupDirective, ReactiveFormsModule, AbstractControl, Validators, FormBuilder, FormControl, FormGroup, FormArray } from '@angular/forms';
|
|
@@ -927,6 +927,8 @@ class MatAutocompleteField {
|
|
|
927
927
|
this.onBlur = new EventEmitter();
|
|
928
928
|
this.onFocus = new EventEmitter();
|
|
929
929
|
this.onDropButtonClick = new EventEmitter(true);
|
|
930
|
+
this.onKeydownEscape = new EventEmitter();
|
|
931
|
+
this.onKeyupEnter = new EventEmitter();
|
|
930
932
|
}
|
|
931
933
|
get itemCount() {
|
|
932
934
|
return this._itemCount;
|
|
@@ -1170,6 +1172,15 @@ class MatAutocompleteField {
|
|
|
1170
1172
|
.pipe(distinctUntilChanged())
|
|
1171
1173
|
// Update component state
|
|
1172
1174
|
.subscribe(() => this.checkIfTouched()));
|
|
1175
|
+
this._subscription.add(this.onKeydownEscape.subscribe(event => {
|
|
1176
|
+
if (this.isOpen) {
|
|
1177
|
+
event === null || event === void 0 ? void 0 : event.stopPropagation();
|
|
1178
|
+
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
1179
|
+
// DEBUG
|
|
1180
|
+
//console.debug(this.logPrefix + " Closing the panel (keydown.escape)");
|
|
1181
|
+
this.closePanel();
|
|
1182
|
+
}
|
|
1183
|
+
}));
|
|
1173
1184
|
}
|
|
1174
1185
|
ngOnDestroy() {
|
|
1175
1186
|
this._subscription.unsubscribe();
|
|
@@ -1181,6 +1192,8 @@ class MatAutocompleteField {
|
|
|
1181
1192
|
this.onClick.complete();
|
|
1182
1193
|
this.onBlur.complete();
|
|
1183
1194
|
this.onFocus.complete();
|
|
1195
|
+
this.onKeydownEscape.complete();
|
|
1196
|
+
this.onKeyupEnter.complete();
|
|
1184
1197
|
this._implicitValue = undefined;
|
|
1185
1198
|
this.formControl = null;
|
|
1186
1199
|
this.displayWith = null;
|
|
@@ -1194,8 +1207,8 @@ class MatAutocompleteField {
|
|
|
1194
1207
|
this._onTouchedCallback = null;
|
|
1195
1208
|
this._onFetchMoreCallback = null;
|
|
1196
1209
|
// Destroy the 'autocomplete' instance, to avoid memory leak
|
|
1197
|
-
if (this.
|
|
1198
|
-
this.
|
|
1210
|
+
if (this.matAutocomplete) {
|
|
1211
|
+
this.matAutocomplete.ngOnDestroy();
|
|
1199
1212
|
}
|
|
1200
1213
|
}
|
|
1201
1214
|
/**
|
|
@@ -1221,8 +1234,8 @@ class MatAutocompleteField {
|
|
|
1221
1234
|
}
|
|
1222
1235
|
setDisabledState(isDisabled) {
|
|
1223
1236
|
var _a;
|
|
1224
|
-
if (isDisabled && ((_a = this.
|
|
1225
|
-
|
|
1237
|
+
if (isDisabled && ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen)) {
|
|
1238
|
+
this.closePanel();
|
|
1226
1239
|
}
|
|
1227
1240
|
this.cd.markForCheck();
|
|
1228
1241
|
}
|
|
@@ -1320,7 +1333,7 @@ class MatAutocompleteField {
|
|
|
1320
1333
|
event.stopPropagation();
|
|
1321
1334
|
}
|
|
1322
1335
|
_initAutocompleteInfiniteScroll(threshold) {
|
|
1323
|
-
if (!this.
|
|
1336
|
+
if (!this.matAutocomplete)
|
|
1324
1337
|
return; // Skip
|
|
1325
1338
|
// DEBUG
|
|
1326
1339
|
//console.debug(this.logPrefix + ' Init autocomplete scroll listener');
|
|
@@ -1328,12 +1341,12 @@ class MatAutocompleteField {
|
|
|
1328
1341
|
this._openedSubscription.unsubscribe();
|
|
1329
1342
|
this._subscription.remove(this._openedSubscription);
|
|
1330
1343
|
}
|
|
1331
|
-
const opened$ = this.
|
|
1344
|
+
const opened$ = this.matAutocomplete._isOpen
|
|
1332
1345
|
? timer(0)
|
|
1333
|
-
: this.
|
|
1346
|
+
: this.matAutocomplete.opened.pipe(debounceTime(200));
|
|
1334
1347
|
const scrollEnd$ = opened$
|
|
1335
1348
|
.pipe(map((_) => this.getAutocompletePanel()), filter(isNotNil), switchMap((panel) => fromScrollEndEvent(panel, threshold)
|
|
1336
|
-
.pipe(takeUntil(this.
|
|
1349
|
+
.pipe(takeUntil(this.matAutocomplete.closed))));
|
|
1337
1350
|
// Trigger fetch more, end end scroll reached
|
|
1338
1351
|
this._openedSubscription = scrollEnd$
|
|
1339
1352
|
.subscribe(() => this._fetchMore$.emit());
|
|
@@ -1362,6 +1375,22 @@ class MatAutocompleteField {
|
|
|
1362
1375
|
// Register subscription
|
|
1363
1376
|
this._subscription.add(this._openedSubscription);
|
|
1364
1377
|
}
|
|
1378
|
+
get isOpen() {
|
|
1379
|
+
var _a, _b;
|
|
1380
|
+
return (this.searchable && ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen))
|
|
1381
|
+
|| ((_b = this.matSelect) === null || _b === void 0 ? void 0 : _b.panelOpen)
|
|
1382
|
+
|| false;
|
|
1383
|
+
}
|
|
1384
|
+
closePanel() {
|
|
1385
|
+
var _a, _b, _c, _d;
|
|
1386
|
+
if ((_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.isOpen) {
|
|
1387
|
+
(_b = this.matAutocompleteTrigger) === null || _b === void 0 ? void 0 : _b.closePanel();
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
if ((_c = this.matSelect) === null || _c === void 0 ? void 0 : _c.panelOpen) {
|
|
1391
|
+
(_d = this.matSelect) === null || _d === void 0 ? void 0 : _d.close();
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1365
1394
|
/* -- private method -- */
|
|
1366
1395
|
suggest(value, filter) {
|
|
1367
1396
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1422,7 +1451,7 @@ class MatAutocompleteField {
|
|
|
1422
1451
|
}
|
|
1423
1452
|
getAutocompletePanel() {
|
|
1424
1453
|
var _a, _b;
|
|
1425
|
-
const ele = (_b = (_a = this.
|
|
1454
|
+
const ele = (_b = (_a = this.matAutocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
|
|
1426
1455
|
if (!ele) {
|
|
1427
1456
|
// DEBUG
|
|
1428
1457
|
console.warn(this.logPrefix + ' Unable to find the autocomplete div...');
|
|
@@ -1456,7 +1485,7 @@ MatAutocompleteField.decorators = [
|
|
|
1456
1485
|
{ type: Component, args: [{
|
|
1457
1486
|
// eslint-disable-next-line @angular-eslint/component-selector
|
|
1458
1487
|
selector: 'mat-autocomplete-field',
|
|
1459
|
-
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix><ng-content select=\"[matPrefix]\"></ng-content></div>\n\n <!-- readonly -->\n <ng-container *ngIf=\"_readonly; else writable\">\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <ng-template #writable>\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 [compareWith]=\"compareWith\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\" >\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n </ng-template>\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]=\"
|
|
1488
|
+
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix><ng-content select=\"[matPrefix]\"></ng-content></div>\n\n <!-- readonly -->\n <ng-container *ngIf=\"_readonly; else writable\">\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <ng-template #writable>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n [compareWith]=\"compareWith\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\" >\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n </ng-template>\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"onClick.emit($event)\"\n (focus)=\"filterInputTextFocusInEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.opened && onDropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [class.cdk-visually-hidden]=\"!searchable\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\" >\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count \" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\" >\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"onDropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content matSuffix select=\"[matSuffix]\"></ng-content>\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 </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n\n</ion-grid>\n",
|
|
1460
1489
|
providers: [DEFAULT_VALUE_ACCESSOR$6],
|
|
1461
1490
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1462
1491
|
styles: [":host{display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}.fact-scroll-viewport{height:100%;width:100%}.fact-item{height:54px;display:flex}.fact-item .fact-date{min-width:100px;text-align:center;font-size:24pt}.fact-item .fact-date,.fact-item .fact-text{height:100%;align-items:center;justify-content:center;display:flex}.fact-item .fact-text{border-radius:10px}cdk-virtual-scroll-viewport{border:1px solid #000}cdk-virtual-scroll-viewport li{list-style:none}"]
|
|
@@ -1506,9 +1535,12 @@ MatAutocompleteField.propDecorators = {
|
|
|
1506
1535
|
onBlur: [{ type: Output, args: ['blur',] }],
|
|
1507
1536
|
onFocus: [{ type: Output, args: ['focus',] }],
|
|
1508
1537
|
onDropButtonClick: [{ type: Output, args: ['dropButtonClick',] }],
|
|
1538
|
+
onKeydownEscape: [{ type: Output, args: ['keydown.escape',] }],
|
|
1539
|
+
onKeyupEnter: [{ type: Output, args: ['keyup.enter',] }],
|
|
1509
1540
|
matSelect: [{ type: ViewChild, args: ['matSelect',] }],
|
|
1510
1541
|
matInputText: [{ type: ViewChild, args: ['matInputText',] }],
|
|
1511
|
-
|
|
1542
|
+
matAutocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
|
|
1543
|
+
matAutocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }]
|
|
1512
1544
|
};
|
|
1513
1545
|
|
|
1514
1546
|
class DateFormatPipe {
|
|
@@ -8532,7 +8564,7 @@ class LocalSettingsService {
|
|
|
8532
8564
|
.then(() => {
|
|
8533
8565
|
this.data.mobile = isNotNil(this.data.mobile) ? this.data.mobile : this.platform.is('mobile');
|
|
8534
8566
|
this.data.touchUi = this.data.mobile || this.platform.is('phablet') || this.platform.is('tablet');
|
|
8535
|
-
this.data.usageMode = this.
|
|
8567
|
+
this.data.usageMode = this.platform.is('android') ? 'FIELD' : 'DESK'; // FIELD by default if Android
|
|
8536
8568
|
})
|
|
8537
8569
|
.then(() => this.restoreLocally())
|
|
8538
8570
|
.then(data => {
|
|
@@ -14654,6 +14686,7 @@ class InMemoryEntitiesService extends EntitiesService {
|
|
|
14654
14686
|
return { data: [], total: 0 };
|
|
14655
14687
|
}
|
|
14656
14688
|
// Apply sort
|
|
14689
|
+
console.log("TODO: before sort");
|
|
14657
14690
|
let data = this._sortFn(this.data || [], sortBy, sortDirection);
|
|
14658
14691
|
if (this._onLoad) {
|
|
14659
14692
|
const promiseOrData = this._onLoad(data);
|
|
@@ -15288,7 +15321,7 @@ class AutocompleteTestPage {
|
|
|
15288
15321
|
AutocompleteTestPage.decorators = [
|
|
15289
15322
|
{ type: Component, args: [{
|
|
15290
15323
|
selector: 'app-autocomplete-test',
|
|
15291
|
-
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 class=\"ion-padding\">\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><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></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><pre>mobile: true, suggestFn: (searchText, filter) => 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-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><pre>mobile: true, 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 [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><pre>mobile: true, 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=\"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><pre></pre></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><pre>class=\"min-width-large\"</pre></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-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col><ion-text><h4>Desktop mode</h4></ion-text></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></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 [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><pre>items: [], value: {{stringify(form.controls.entity.value)}}</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-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><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\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><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=\"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><pre>class: 'mat-autocomplete-panel-full-size'</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 [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\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>\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><pre>class=\"mat-autocomplete-panel-full-size\"</pre></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><pre>panelWidth: string</pre></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 </ion-row>\n\n\n\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
15324
|
+
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 class=\"ion-padding\">\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><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></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><pre>mobile: true, suggestFn: (searchText, filter) => 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-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><pre>mobile: true, 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 [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><pre>mobile: true, 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=\"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><pre></pre></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><pre>class=\"min-width-large\"</pre></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-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col><ion-text><h4>Desktop mode</h4></ion-text></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></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 [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><pre>items: [], value: {{stringify(form.controls.entity.value)}}</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-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><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\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><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=\"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><pre>class: 'mat-autocomplete-panel-full-size'</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 [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><pre>class=\"mat-autocomplete-panel-full-size\"</pre></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><pre>panelWidth: string</pre></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 </ion-row>\n\n\n\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
15292
15325
|
},] }
|
|
15293
15326
|
];
|
|
15294
15327
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -15628,7 +15661,7 @@ function adaptValueToControl(source, control, path) {
|
|
|
15628
15661
|
}
|
|
15629
15662
|
// Skip if value is not an array
|
|
15630
15663
|
if (!(source instanceof Array) || control.length === 0) {
|
|
15631
|
-
if (
|
|
15664
|
+
if (isNotEmptyArray(source))
|
|
15632
15665
|
console.warn(`WARN: please resize the FormArray '${path}' to the same length of the input array`);
|
|
15633
15666
|
return [];
|
|
15634
15667
|
}
|
|
@@ -17474,6 +17507,7 @@ class FormButtonsBarComponent {
|
|
|
17474
17507
|
.subscribe((event) => this.onCancel.emit(event)));
|
|
17475
17508
|
// Escape
|
|
17476
17509
|
this._subscription.add(hotkeys.addShortcut({ keys: 'escape', description: 'COMMON.BTN_CLOSE', preventDefault: false })
|
|
17510
|
+
.pipe(filter(e => !e.defaultPrevented))
|
|
17477
17511
|
.subscribe((event) => this.onBack.emit(event)));
|
|
17478
17512
|
}
|
|
17479
17513
|
ngOnDestroy() {
|
|
@@ -18234,7 +18268,13 @@ class AppListForm extends AppForm {
|
|
|
18234
18268
|
}
|
|
18235
18269
|
markAsTouched(opts) {
|
|
18236
18270
|
AppFormUtils.markAsTouched(this.formArray, opts);
|
|
18237
|
-
|
|
18271
|
+
if (!opts || opts.emitEvent !== false)
|
|
18272
|
+
this.markForCheck();
|
|
18273
|
+
}
|
|
18274
|
+
markAllAsTouched(opts) {
|
|
18275
|
+
AppFormUtils.markAllAsTouched(this.formArray, opts);
|
|
18276
|
+
if (!opts || opts.emitEvent !== false)
|
|
18277
|
+
this.markForCheck();
|
|
18238
18278
|
}
|
|
18239
18279
|
ngOnInit() {
|
|
18240
18280
|
this.options = Object.assign({ allowEmptyArray: true, allowMultipleSelection: true, buttons: [] }, this.options);
|
|
@@ -18265,6 +18305,9 @@ class AppListForm extends AppForm {
|
|
|
18265
18305
|
this.helper.resize(data.length);
|
|
18266
18306
|
this.helper.formArray.patchValue(data, { emitEvent: false });
|
|
18267
18307
|
}
|
|
18308
|
+
else {
|
|
18309
|
+
console.warn('TODO: cannot applyied setValue() on fromArray, because formArrayHelper not exists yet !');
|
|
18310
|
+
}
|
|
18268
18311
|
this.selection.clear();
|
|
18269
18312
|
this.markAsPristine();
|
|
18270
18313
|
this.loading = false;
|
|
@@ -18605,7 +18648,7 @@ class AppInstallUpgradeCard {
|
|
|
18605
18648
|
AppInstallUpgradeCard.decorators = [
|
|
18606
18649
|
{ type: Component, args: [{
|
|
18607
18650
|
selector: 'app-install-upgrade-card',
|
|
18608
|
-
template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n <!-- Waiting spinner -->\n <ng-template #waitingSpinner>\n <ion-spinner *ngIf=\"waitingNetwork\" color=\"light\"></ion-spinner>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n\n <!-- Download button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"
|
|
18651
|
+
template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n <!-- Waiting spinner -->\n <ng-template #waitingSpinner>\n <ion-spinner *ngIf=\"waitingNetwork\" color=\"light\"></ion-spinner>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n\n <!-- Download button -->\n <ion-button *ngIf=\"link.downloadFilename; else redirectButton\"\n [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Download button -->\n <ion-button *ngIf=\"link.downloadFilename; else redirectButton\"\n [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n",
|
|
18609
18652
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
18610
18653
|
animations: [slideUpDownAnimation],
|
|
18611
18654
|
styles: ["ion-text small{font-size:85%}"]
|
|
@@ -20046,13 +20089,6 @@ class AppTable {
|
|
|
20046
20089
|
get saving$() {
|
|
20047
20090
|
return this.savingSubject.asObservable();
|
|
20048
20091
|
}
|
|
20049
|
-
// Focus manager
|
|
20050
|
-
set focusColumn(name) {
|
|
20051
|
-
this._focusColumn = name;
|
|
20052
|
-
}
|
|
20053
|
-
get focusColumn() {
|
|
20054
|
-
return this._focusColumn;
|
|
20055
|
-
}
|
|
20056
20092
|
get firstUserColumn() {
|
|
20057
20093
|
return this.displayedColumns[RESERVED_START_COLUMNS.length];
|
|
20058
20094
|
}
|
|
@@ -20131,10 +20167,11 @@ class AppTable {
|
|
|
20131
20167
|
}
|
|
20132
20168
|
}
|
|
20133
20169
|
markAsUntouched(opts) {
|
|
20170
|
+
var _a;
|
|
20134
20171
|
if (this.dirtySubject.value !== false || (this.editedRow && this.editedRow.id !== this.previouslyEditedRowId)) {
|
|
20135
20172
|
// Cancel the current editing row only if editing and if it was not previously saved
|
|
20136
20173
|
this.dirtySubject.next(false);
|
|
20137
|
-
if (this.editedRow
|
|
20174
|
+
if ((_a = this.editedRow) === null || _a === void 0 ? void 0 : _a.editing) {
|
|
20138
20175
|
this.dataSource.cancelOrDelete(this.editedRow);
|
|
20139
20176
|
}
|
|
20140
20177
|
this.editedRow = null;
|
|
@@ -20149,17 +20186,19 @@ class AppTable {
|
|
|
20149
20186
|
* @param opts
|
|
20150
20187
|
*/
|
|
20151
20188
|
markAsTouched(opts) {
|
|
20189
|
+
var _a, _b;
|
|
20152
20190
|
console.warn('TODO: Replace this call by markAllAsTouched() - because of changes in ngx-components >= 0.16.0');
|
|
20153
|
-
if (this.editedRow
|
|
20154
|
-
this.editedRow.validator.markAllAsTouched();
|
|
20191
|
+
if ((_a = this.editedRow) === null || _a === void 0 ? void 0 : _a.editing) {
|
|
20192
|
+
(_b = this.editedRow.validator) === null || _b === void 0 ? void 0 : _b.markAllAsTouched();
|
|
20155
20193
|
if (!opts || opts.emitEvent !== false) {
|
|
20156
20194
|
this.markForCheck();
|
|
20157
20195
|
}
|
|
20158
20196
|
}
|
|
20159
20197
|
}
|
|
20160
20198
|
markAllAsTouched(opts) {
|
|
20161
|
-
|
|
20162
|
-
|
|
20199
|
+
var _a, _b;
|
|
20200
|
+
if ((_a = this.editedRow) === null || _a === void 0 ? void 0 : _a.editing) {
|
|
20201
|
+
(_b = this.editedRow.validator) === null || _b === void 0 ? void 0 : _b.markAllAsTouched();
|
|
20163
20202
|
if (!opts || opts.emitEvent !== false) {
|
|
20164
20203
|
this.markForCheck();
|
|
20165
20204
|
}
|
|
@@ -20840,13 +20879,15 @@ class AppTable {
|
|
|
20840
20879
|
row = row || this.editedRow;
|
|
20841
20880
|
if (!row || !row.editing)
|
|
20842
20881
|
return;
|
|
20882
|
+
// DEBUG
|
|
20883
|
+
//console.debug('[app-table] Cancel the row (keydown.escape)');
|
|
20843
20884
|
if (event) {
|
|
20844
20885
|
// Avoid to cancel the editor
|
|
20845
20886
|
event.preventDefault();
|
|
20846
20887
|
event.stopPropagation();
|
|
20847
20888
|
}
|
|
20848
|
-
// If new row: delete silently
|
|
20849
|
-
if (row.id === -1) {
|
|
20889
|
+
// If new row is invalid: delete silently
|
|
20890
|
+
if (row.id === -1 && row.validator.invalid) {
|
|
20850
20891
|
this.deleteNewRow(event, row);
|
|
20851
20892
|
}
|
|
20852
20893
|
// If exists
|
|
@@ -20873,7 +20914,7 @@ class AppTable {
|
|
|
20873
20914
|
return false;
|
|
20874
20915
|
}
|
|
20875
20916
|
if (!row.editing && !this.loading) {
|
|
20876
|
-
this.
|
|
20917
|
+
this.focusColumn = opts && opts.focusColumn || this.focusColumn;
|
|
20877
20918
|
this._dataSource.startEdit(row);
|
|
20878
20919
|
}
|
|
20879
20920
|
this.editedRow = row;
|
|
@@ -22253,12 +22294,7 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
22253
22294
|
event.preventDefault();
|
|
22254
22295
|
event.stopPropagation();
|
|
22255
22296
|
}
|
|
22256
|
-
|
|
22257
|
-
yield this.toolbar.goBack();
|
|
22258
|
-
}
|
|
22259
|
-
else if (this.defaultBackHref) {
|
|
22260
|
-
yield this.router.navigateByUrl(this.defaultBackHref);
|
|
22261
|
-
}
|
|
22297
|
+
return this.goBack();
|
|
22262
22298
|
});
|
|
22263
22299
|
}
|
|
22264
22300
|
save(event, options) {
|
|
@@ -22389,6 +22425,22 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
22389
22425
|
yield this.load(this.data && this.data.id);
|
|
22390
22426
|
});
|
|
22391
22427
|
}
|
|
22428
|
+
goBack(event) {
|
|
22429
|
+
var _a;
|
|
22430
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22431
|
+
// Go back
|
|
22432
|
+
if ((_a = this.toolbar) === null || _a === void 0 ? void 0 : _a.canGoBack) {
|
|
22433
|
+
return this.toolbar.goBack();
|
|
22434
|
+
}
|
|
22435
|
+
else if (this.defaultBackHref) {
|
|
22436
|
+
return this.router.navigateByUrl(this.defaultBackHref);
|
|
22437
|
+
}
|
|
22438
|
+
else {
|
|
22439
|
+
// Back to home
|
|
22440
|
+
return this.router.navigateByUrl('/');
|
|
22441
|
+
}
|
|
22442
|
+
});
|
|
22443
|
+
}
|
|
22392
22444
|
setError(err) {
|
|
22393
22445
|
console.error('[data-editor] ' + err && err.message || err, err);
|
|
22394
22446
|
let userMessage = err && err.message && this.translate.instant(err.message) || err;
|