@sumaris-net/ngx-components 1.4.0 → 1.4.4

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.
@@ -1368,14 +1368,14 @@
1368
1368
  });
1369
1369
  Object.defineProperty(MatAutocompleteField.prototype, "disabled", {
1370
1370
  get: function () {
1371
- return this.readonly || this.formControl.disabled;
1371
+ return this._readonly || this.formControl.disabled;
1372
1372
  },
1373
1373
  enumerable: false,
1374
1374
  configurable: true
1375
1375
  });
1376
1376
  Object.defineProperty(MatAutocompleteField.prototype, "enabled", {
1377
1377
  get: function () {
1378
- return !this.readonly && this.formControl.enabled;
1378
+ return !this._readonly && this.formControl.enabled;
1379
1379
  },
1380
1380
  enumerable: false,
1381
1381
  configurable: true
@@ -1476,7 +1476,7 @@
1476
1476
  this._reload$,
1477
1477
  // Search text (no distinctUntilChanged() because of the debounceTime() pipe)
1478
1478
  this.formControl.valueChanges
1479
- .pipe(operators.filter(function (value) { return _this.searchable && isNotNilString(value); }),
1479
+ .pipe(operators.filter(function (value) { return _this.enabled && _this.searchable && isNotNilString(value); }),
1480
1480
  // Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
1481
1481
  operators.tap(function (value) {
1482
1482
  if (_this.showLoadingSpinner) {
@@ -1486,10 +1486,12 @@
1486
1486
  // Filter if not enough character
1487
1487
  operators.filter(function (value) { return value.length >= _this.suggestLengthThreshold; }),
1488
1488
  // Wait a debounce time
1489
- operators.debounceTime(this.debounceTime)),
1489
+ operators.debounceTime(this.debounceTime),
1490
+ // DEBUG
1491
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Search text changes:', value); })),
1490
1492
  // Object set: use it (no distinctUntilChanged() pipe need)
1491
1493
  this.formControl.valueChanges
1492
- .pipe(operators.startWith(this.formControl.value), operators.filter(function (value) { return _this.searchable && (typeof value === 'object'); }), operators.tap(function (value) {
1494
+ .pipe(operators.startWith(this.formControl.value), operators.filter(function (value) { return (_this.searchable && isNotNil(value) && typeof value === 'object'); }), operators.tap(function (value) {
1493
1495
  // DEBUG
1494
1496
  //console.debug(this.logPrefix + ' object changes:', value)
1495
1497
  // Update the display value (if need)
@@ -1501,24 +1503,28 @@
1501
1503
  _this.matInputText.nativeElement.value = _this.displayValue;
1502
1504
  }
1503
1505
  }
1504
- })),
1506
+ }),
1507
+ // DEBUG
1508
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Received an object value: ', value); })),
1505
1509
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
1506
1510
  rxjs.merge(
1507
1511
  // Focus or click => Load all
1508
1512
  rxjs.merge(this.onFocus, this.onClick)
1509
- .pipe(operators.filter(function (_) { return _this.searchable && _this.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })),
1513
+ .pipe(operators.filter(function (_) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })),
1510
1514
  // On dropdown button click
1511
1515
  this.onDropButtonClick
1512
- .pipe(operators.filter(function (event) { return _this.searchable && (!event || !event.defaultPrevented) && _this.formControl.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })), rxjs.merge(this.$inputItems, this._filter$)
1513
- .pipe(operators.map(function (_) { return _this.searchable && _this.formControl.value; })))
1516
+ .pipe(operators.filter(function (event) { return _this.enabled && _this.searchable && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })), rxjs.merge(this.$inputItems, this._filter$)
1517
+ .pipe(operators.filter(function (event) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.formControl.value; }),
1518
+ // DEBUG
1519
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Received $inputItems or filter event: ', value); })))
1514
1520
  .pipe(
1515
1521
  // If value is a string (and is not = '*'), filter if not enough character
1516
1522
  operators.filter(function (value) { return value === '*' || !(typeof value === 'string') || value.length >= _this.suggestLengthThreshold; }),
1517
1523
  // Distinguish changes
1518
- operators.distinctUntilChanged()))
1519
- .pipe(
1524
+ operators.distinctUntilChanged(),
1520
1525
  // DEBUG
1521
- //tap(value => console.debug(this.logPrefix + ' Received update event: ', value)),
1526
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Received update event: ', value); })))
1527
+ .pipe(
1522
1528
  // Suggest values
1523
1529
  operators.mergeMap(function (value) { return _this.suggest(value, _this.filter); }),
1524
1530
  // DEBUG
@@ -1577,7 +1583,9 @@
1577
1583
  }));
1578
1584
  // Listen form control status change
1579
1585
  this._subscription.add(this.formControl.statusChanges
1580
- .pipe(operators.distinctUntilChanged())
1586
+ .pipe(
1587
+ //filter(() => this.enabled),
1588
+ operators.distinctUntilChanged())
1581
1589
  // Update component state
1582
1590
  .subscribe(function () { return _this.checkIfTouched(); }));
1583
1591
  this._subscription.add(this.onKeydownEscape.subscribe(function (event) {
@@ -3794,7 +3802,7 @@
3794
3802
  Object.keys(control.errors).forEach(function (error) { return console.warn(logPrefix + " -> " + (path || '') + " (" + error + ")"); });
3795
3803
  }
3796
3804
  if (control.controls) {
3797
- Object.keys(control.controls).forEach(function (child) { return logFormErrors(control.controls[child], logPrefix, (path ? path + "/" + child : child)); } // Recursive call
3805
+ Object.keys(control.controls).forEach(function (child) { return logFormErrors(control.controls[child], logPrefix, (path ? path + "." + child : child)); } // Recursive call
3798
3806
  );
3799
3807
  }
3800
3808
  }
@@ -3804,7 +3812,7 @@
3804
3812
  Object.keys(control.errors).forEach(function (error) { return console.warn(logPrefix + " -> " + (path || '') + " (" + error + ")"); });
3805
3813
  }
3806
3814
  control.controls.forEach(function (child, index) {
3807
- logFormErrors(child, logPrefix, (path ? path + "#" + index : "#" + index)); // Recursive call
3815
+ logFormErrors(child, logPrefix, (path ? path + "." + index : "" + index)); // Recursive call
3808
3816
  });
3809
3817
  }
3810
3818
  // Other control's errors
@@ -5312,6 +5320,7 @@
5312
5320
  this.compact = false;
5313
5321
  this.placeholderChar = DEFAULT_PLACEHOLDER_CHAR;
5314
5322
  this.autofocus = false;
5323
+ this.startDate = null;
5315
5324
  this.clearable = false;
5316
5325
  this.locale = (translate.currentLang || translate.defaultLang).substr(0, 2);
5317
5326
  }
@@ -5679,19 +5688,19 @@
5679
5688
  { type: i1.FormGroupDirective, decorators: [{ type: i0.Optional }] }
5680
5689
  ]; };
5681
5690
  MatDateTime.propDecorators = {
5682
- mobile: [{ type: i0.Input }],
5683
5691
  formControl: [{ type: i0.Input }],
5684
5692
  formControlName: [{ type: i0.Input }],
5685
5693
  placeholder: [{ type: i0.Input }],
5686
5694
  floatLabel: [{ type: i0.Input }],
5687
5695
  required: [{ type: i0.Input }],
5696
+ mobile: [{ type: i0.Input }],
5688
5697
  compact: [{ type: i0.Input }],
5689
5698
  placeholderChar: [{ type: i0.Input }],
5690
5699
  autofocus: [{ type: i0.Input }],
5691
- readonly: [{ type: i0.Input }],
5692
- tabindex: [{ type: i0.Input }],
5693
5700
  startDate: [{ type: i0.Input }],
5694
5701
  clearable: [{ type: i0.Input }],
5702
+ readonly: [{ type: i0.Input }],
5703
+ tabindex: [{ type: i0.Input }],
5695
5704
  datePicker: [{ type: i0.ViewChild, args: ['datePicker',] }],
5696
5705
  timePicker: [{ type: i0.ViewChild, args: ['timePicker',] }],
5697
5706
  matInputs: [{ type: i0.ViewChildren, args: ['matInput',] }]
@@ -6411,17 +6420,6 @@
6411
6420
  this.showRadio = this.showRadio || this.floatLabel === 'always';
6412
6421
  this.updateTabIndex();
6413
6422
  };
6414
- MatBooleanField.prototype.ngAfterViewInit = function () {
6415
- var _this = this;
6416
- // Inject suffix elements, into the first injection point found
6417
- if (this.suffixDiv) {
6418
- this.suffixInjections.find(function (item) {
6419
- item.nativeElement.append(_this.suffixDiv.nativeElement);
6420
- _this.suffixDiv.nativeElement.classList.remove('cdk-visually-hidden');
6421
- return true; // take only the first injection point
6422
- });
6423
- }
6424
- };
6425
6423
  MatBooleanField.prototype.writeValue = function (value, event) {
6426
6424
  var _this = this;
6427
6425
  if (this._writing)
@@ -6540,7 +6538,7 @@
6540
6538
  MatBooleanField.decorators = [
6541
6539
  { type: i0.Component, args: [{
6542
6540
  selector: 'mat-boolean-field',
6543
- template: "<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled {{classList}}\">\n <input matInput hidden type=\"text\" readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{(formControl.value == null && 'COMMON.EMPTY_OPTION' || (formControl.value === true && yesLabel) || noLabel) | translate }}</ion-text>\n</mat-form-field>\n\n<ng-template #writable>\n <ng-container [ngSwitch]=\"style\">\n\n <!-- Radio -->\n <mat-form-field *ngSwitchCase=\"'radio'\"\n [floatLabel]=\"showRadio && (!floatLabel || floatLabel === 'auto') ? 'always': floatLabel\"\n class=\"mat-boolean-field mat-boolean-field-radio {{classList}}\">\n <mat-label *ngIf=\"placeholder && floatLabel!=='never'\">\n {{placeholder}}\n <span [hidden]=\"showRadio\">({{yesLabel|translate}}/{{'COMMON.NO'|translate}})</span>\n </mat-label>\n\n <input matInput #fakeInput type=\"text\" readonly=\"true\"\n [formControl]=\"formControl\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showRadio\"\n [tabindex]=\"tabindex\">\n\n <!-- radio button -->\n <mat-radio-group [hidden]=\"!showRadio\"\n [formControl]=\"formControl\"\n (change)=\"onRadioValueChanged($event)\">\n <mat-radio-button #yesButton [value]=\"true\">\n <span>{{yesLabel|translate}}</span>\n </mat-radio-button>&nbsp;\n <mat-radio-button #noButton [value]=\"false\">\n <span>{{noLabel|translate}}</span>\n </mat-radio-button>\n </mat-radio-group>\n\n <div matSuffix #injectMatSuffix></div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Checkbox -->\n <mat-form-field *ngSwitchCase=\"'checkbox'\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-boolean-field mat-boolean-field-checkbox {{classList}}\">\n <mat-label *ngIf=\"placeholder && !showRadio\">\n {{placeholder}}\n </mat-label>\n\n <input matInput #matInput\n [formControl]=\"formControl\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showRadio\"\n [tabindex]=\"tabindex\">\n\n <ion-label>&nbsp;</ion-label>\n\n <!-- checkbox, when compact -->\n <mat-checkbox #checkboxButton\n [formControl]=\"formControl\"\n (change)=\"onCheckboxValueChanged($event)\"\n [indeterminate]=\"value===undefined\"\n [hidden]=\"!showRadio\"\n [tabindex]=\"tabindex\">\n </mat-checkbox>\n\n <div matSuffix #injectMatSuffix></div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- Buttons -->\n <mat-form-field *ngSwitchCase=\"'button'\"\n [floatLabel]=\"floatLabel === 'never' ? 'never' : 'always'\"\n class=\"mat-boolean-field mat-boolean-field-button {{classList}}\">\n <input matInput type=\"text\" hidden\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\">\n <div class=\"mat-form-field-buttons\"\n [style.--buttons-col-count]=\"buttonsColCount\"\n *ngIf=\"!formControl.disabled; else disabledLabel\">\n <!-- yes -->\n <ion-button class=\"mat-form-field-button\"\n [tabindex]=\"_tabindex\"\n (click)=\"writeValue(true, $event)\"\n (keyup.enter)=\"writeValue(true, $event)\"\n [color]=\"_value == null ? 'tertiary' : (_value === true) ? 'accent' : 'light'\">\n <ion-icon *ngIf=\"showButtonIcons && yesIcon; let icon\" slot=\"start\" [name]=\"icon\"></ion-icon>\n {{yesLabel|translate}}\n </ion-button>\n\n <!-- No button -->\n <ion-button class=\"mat-form-field-button\"\n [tabindex]=\"_tabindex !== undefined ? (_tabindex + 1) : undefined\"\n (click)=\"writeValue(false, $event)\"\n (keyup.enter)=\"writeValue(false, $event)\"\n [color]=\"_value == null ? 'tertiary' : (_value === false) ? 'accent' : 'light'\">\n <ion-icon *ngIf=\"showButtonIcons && noIcon; let icon\" slot=\"start\" [name]=\"icon\"></ion-icon>\n {{noLabel|translate}}\n </ion-button>\n </div>\n <ng-template #disabledLabel>\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ng-template>\n\n <div matSuffix #injectMatSuffix></div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ng-container>\n\n <div class=\"cdk-visually-hidden\">\n <div #suffix><ng-content select=\"[matSuffix]\"></ng-content></div>\n </div>\n\n</ng-template>\n\n\n",
6541
+ template: "<mat-form-field *ngIf=\"readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-form-field-disabled {{classList}}\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <input matInput hidden type=\"text\" readonly\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\">\n <ion-text>{{(formControl.value == null && 'COMMON.EMPTY_OPTION' || (formControl.value === true && yesLabel) || noLabel) | translate }}</ion-text>\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n</mat-form-field>\n\n<ng-template #writable>\n <ng-container [ngSwitch]=\"style\">\n\n <!-- Radio -->\n <mat-form-field *ngSwitchCase=\"'radio'\"\n [floatLabel]=\"showRadio && (!floatLabel || floatLabel === 'auto') ? 'always': floatLabel\"\n class=\"mat-boolean-field mat-boolean-field-radio {{classList}}\">\n <mat-label *ngIf=\"placeholder && floatLabel!=='never'\">\n {{placeholder}}\n <span [hidden]=\"showRadio\">({{yesLabel|translate}}/{{'COMMON.NO'|translate}})</span>\n </mat-label>\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <input matInput #fakeInput type=\"text\" readonly=\"true\"\n [formControl]=\"formControl\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showRadio\"\n [tabindex]=\"tabindex\">\n\n <!-- radio button -->\n <mat-radio-group [hidden]=\"!showRadio\"\n [formControl]=\"formControl\"\n (change)=\"onRadioValueChanged($event)\">\n <mat-radio-button #yesButton [value]=\"true\">\n <span>{{yesLabel|translate}}</span>\n </mat-radio-button>&nbsp;\n <mat-radio-button #noButton [value]=\"false\">\n <span>{{noLabel|translate}}</span>\n </mat-radio-button>\n </mat-radio-group>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Checkbox -->\n <mat-form-field *ngSwitchCase=\"'checkbox'\"\n [floatLabel]=\"floatLabel\"\n class=\"mat-boolean-field mat-boolean-field-checkbox {{classList}}\">\n <mat-label *ngIf=\"placeholder && !showRadio\">\n {{placeholder}}\n </mat-label>\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <input matInput #matInput\n [formControl]=\"formControl\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showRadio\"\n [tabindex]=\"tabindex\">\n\n <ion-label>&nbsp;</ion-label>\n\n <!-- checkbox, when compact -->\n <mat-checkbox #checkboxButton\n [formControl]=\"formControl\"\n (change)=\"onCheckboxValueChanged($event)\"\n [indeterminate]=\"value===undefined\"\n [hidden]=\"!showRadio\"\n [tabindex]=\"tabindex\">\n </mat-checkbox>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n\n <!-- Buttons -->\n <mat-form-field *ngSwitchCase=\"'button'\"\n [floatLabel]=\"floatLabel === 'never' ? 'never' : 'always'\"\n class=\"mat-boolean-field mat-boolean-field-button {{classList}}\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <input matInput type=\"text\" hidden\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\">\n <div class=\"mat-form-field-buttons\"\n [style.--buttons-col-count]=\"buttonsColCount\"\n *ngIf=\"!formControl.disabled; else disabledLabel\">\n <!-- yes -->\n <ion-button class=\"mat-form-field-button\"\n [tabindex]=\"_tabindex\"\n (click)=\"writeValue(true, $event)\"\n (keyup.enter)=\"writeValue(true, $event)\"\n [color]=\"_value == null ? 'tertiary' : (_value === true) ? 'accent' : 'light'\">\n <ion-icon *ngIf=\"showButtonIcons && yesIcon; let icon\" slot=\"start\" [name]=\"icon\"></ion-icon>\n {{yesLabel|translate}}\n </ion-button>\n\n <!-- No button -->\n <ion-button class=\"mat-form-field-button\"\n [tabindex]=\"_tabindex !== undefined ? (_tabindex + 1) : undefined\"\n (click)=\"writeValue(false, $event)\"\n (keyup.enter)=\"writeValue(false, $event)\"\n [color]=\"_value == null ? 'tertiary' : (_value === false) ? 'accent' : 'light'\">\n <ion-icon *ngIf=\"showButtonIcons && noIcon; let icon\" slot=\"start\" [name]=\"icon\"></ion-icon>\n {{noLabel|translate}}\n </ion-button>\n </div>\n <ng-template #disabledLabel>\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ng-template>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n </ng-container>\n\n <div class=\"cdk-visually-hidden\">\n <div #suffix><ng-content select=\"[matSuffix]\"></ng-content></div>\n </div>\n\n</ng-template>\n\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n<ng-template #matSuffixTemplate>\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
6544
6542
  providers: [
6545
6543
  DEFAULT_VALUE_ACCESSOR$1
6546
6544
  ],
@@ -6579,8 +6577,7 @@
6579
6577
  noButton: [{ type: i0.ViewChild, args: ['noButton',] }],
6580
6578
  checkboxButton: [{ type: i0.ViewChild, args: ['checkboxButton',] }],
6581
6579
  fakeInput: [{ type: i0.ViewChild, args: ['fakeInput',] }],
6582
- suffixDiv: [{ type: i0.ViewChild, args: ['suffix', { static: false },] }],
6583
- suffixInjections: [{ type: i0.ViewChildren, args: ['injectMatSuffix',] }]
6580
+ suffixDiv: [{ type: i0.ViewChild, args: ['suffix', { static: false },] }]
6584
6581
  };
6585
6582
 
6586
6583
  var SharedMatBooleanModule = /** @class */ (function () {
@@ -8345,7 +8342,9 @@
8345
8342
  return [3 /*break*/, 7];
8346
8343
  case 4:
8347
8344
  if (!this._defaultBackHref) return [3 /*break*/, 6];
8348
- return [4 /*yield*/, this.router.navigateByUrl(this._defaultBackHref)];
8345
+ return [4 /*yield*/, this.router.navigateByUrl(this._defaultBackHref, {
8346
+ replaceUrl: true
8347
+ })];
8349
8348
  case 5:
8350
8349
  _a.sent();
8351
8350
  return [3 /*break*/, 7];
@@ -10876,7 +10875,7 @@
10876
10875
  });
10877
10876
  };
10878
10877
  LocalSettingsService.prototype.setProperty = function (keyOrDef, value) {
10879
- if (!this._data)
10878
+ if (!this._data || !keyOrDef)
10880
10879
  return;
10881
10880
  if (typeof keyOrDef === 'object') {
10882
10881
  this.setProperty(keyOrDef.key, value);
@@ -10999,8 +10998,9 @@
10999
10998
  var feature = this._data.offlineFeatures.find(function (f) {
11000
10999
  if (typeof f === 'string')
11001
11000
  return f.toLowerCase().startsWith(featurePrefix);
11002
- if (typeof f === 'object' && f.name)
11001
+ if (f && typeof f === 'object' && f.name)
11003
11002
  return f.name === featureName;
11003
+ return false;
11004
11004
  });
11005
11005
  if (!feature)
11006
11006
  return; // Not found
@@ -11031,8 +11031,9 @@
11031
11031
  var existingIndex = this._data.offlineFeatures.findIndex(function (f) {
11032
11032
  if (typeof f === 'string')
11033
11033
  return f.toLowerCase().startsWith(featurePrefix);
11034
- if (typeof f === 'object' && f.name)
11034
+ if (f && typeof f === 'object' && f.name)
11035
11035
  return f.name === feature.name;
11036
+ return false;
11036
11037
  });
11037
11038
  if (existingIndex !== -1) {
11038
11039
  this._data.offlineFeatures[existingIndex] = feature;