@sumaris-net/ngx-components 0.25.20 → 0.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +180 -54
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +7 -0
  6. package/esm2015/src/app/core/account/account.js +5 -7
  7. package/esm2015/src/app/core/auth/form/form-auth.js +6 -7
  8. package/esm2015/src/app/core/form/entity-editor.class.js +25 -16
  9. package/esm2015/src/app/core/form/form.class.js +29 -12
  10. package/esm2015/src/app/core/form/list.form.js +2 -2
  11. package/esm2015/src/app/core/form/properties.form.js +2 -3
  12. package/esm2015/src/app/core/settings/settings.page.js +5 -7
  13. package/esm2015/src/app/core/table/table.class.js +4 -4
  14. package/esm2015/src/app/shared/material/badge/badge-icon.directive.js +62 -0
  15. package/esm2015/src/app/shared/material/badge/badge-icon.module.js +23 -0
  16. package/esm2015/src/app/shared/material/badge/badge-icon.test.js +10 -0
  17. package/esm2015/src/app/shared/material/material.module.js +4 -2
  18. package/esm2015/src/app/shared/material/testing/material.testing.module.js +9 -2
  19. package/esm2015/src/app/shared/material/testing/material.testing.page.js +2 -2
  20. package/esm2015/src/app/shared/pipes/form.pipes.js +1 -1
  21. package/esm2015/src/app/shared/validator/form-error-adapter.class.js +3 -3
  22. package/esm2015/sumaris-net.ngx-components.js +10 -7
  23. package/fesm2015/sumaris-net.ngx-components.js +164 -49
  24. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/app/core/account/account.d.ts +2 -5
  27. package/src/app/core/auth/form/form-auth.d.ts +2 -4
  28. package/src/app/core/form/entity-editor.class.d.ts +13 -2
  29. package/src/app/core/form/form.class.d.ts +15 -12
  30. package/src/app/core/form/properties.form.d.ts +0 -1
  31. package/src/app/core/settings/settings.page.d.ts +2 -5
  32. package/src/app/core/table/table.class.d.ts +4 -7
  33. package/src/app/shared/material/badge/badge-icon.directive.d.ts +15 -0
  34. package/src/app/shared/material/badge/badge-icon.module.d.ts +2 -0
  35. package/src/app/shared/material/badge/badge-icon.test.d.ts +2 -0
  36. package/src/app/shared/pipes/form.pipes.d.ts +2 -2
  37. package/src/app/shared/validator/form-error-adapter.class.d.ts +6 -6
  38. package/sumaris-net.ngx-components.d.ts +9 -6
  39. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -3503,8 +3503,8 @@ class FormErrorAdapter {
3503
3503
  }, "");
3504
3504
  }
3505
3505
  translateControlPath(path, opts) {
3506
- if (opts === null || opts === void 0 ? void 0 : opts.pathTranslateService) {
3507
- return opts === null || opts === void 0 ? void 0 : opts.pathTranslateService.translateControlPath(path);
3506
+ if (opts === null || opts === void 0 ? void 0 : opts.controlPathTranslator) {
3507
+ return opts === null || opts === void 0 ? void 0 : opts.controlPathTranslator.translateControlPath(path);
3508
3508
  }
3509
3509
  const i18nKey = (opts && opts.i18nPrefix || '') + changeCaseToUnderscore(path).toUpperCase();
3510
3510
  return this.translate.instant(i18nKey);
@@ -6908,6 +6908,85 @@ MaterialChipsModule.decorators = [
6908
6908
  },] }
6909
6909
  ];
6910
6910
 
6911
+ class MatBadgeIconDirective {
6912
+ constructor(el) {
6913
+ this.el = el;
6914
+ }
6915
+ ngOnInit() {
6916
+ this.size = this.size || 'medium';
6917
+ this.color = this.color || 'primary';
6918
+ if (this.color === 'warn')
6919
+ this.color = 'warning';
6920
+ let fontSize;
6921
+ switch (this.size) {
6922
+ case 'large':
6923
+ fontSize = '24px';
6924
+ break;
6925
+ case 'medium':
6926
+ fontSize = '22px';
6927
+ break;
6928
+ case 'small':
6929
+ fontSize = '16px';
6930
+ break;
6931
+ }
6932
+ const badge = this.el.nativeElement.querySelector('.mat-badge-content');
6933
+ badge.style.display = 'flex';
6934
+ badge.style.alignItems = 'center';
6935
+ badge.style.justifyContent = 'center';
6936
+ if (this.color !== 'accent') {
6937
+ if (this.fill !== 'clear') {
6938
+ badge.style.background = `var(--ion-color-${this.color})`;
6939
+ badge.style.color = `var(--ion-color-${this.color}-contrast)`;
6940
+ }
6941
+ else {
6942
+ badge.style.color = `var(--ion-color-${this.color})`;
6943
+ badge.style.background = 'transparent';
6944
+ }
6945
+ }
6946
+ if (this.matIcon) {
6947
+ badge.innerHTML = `<i class="material-icons" style="font-size: ${fontSize};">${this.matIcon}</i>`;
6948
+ }
6949
+ else if (this.ionIcon) {
6950
+ badge.innerHTML = `<ion-icon style="font-size: ${fontSize};" name="${this.ionIcon}"></ion-icon>`;
6951
+ }
6952
+ }
6953
+ }
6954
+ MatBadgeIconDirective.decorators = [
6955
+ { type: Directive, args: [{
6956
+ selector: '[matBadgeIcon], [ionBadgeIcon]',
6957
+ inputs: [
6958
+ 'size: matBadgeSize',
6959
+ 'color: matBadgeColor',
6960
+ 'fill: matBadgeFill',
6961
+ ]
6962
+ },] }
6963
+ ];
6964
+ MatBadgeIconDirective.ctorParameters = () => [
6965
+ { type: ElementRef }
6966
+ ];
6967
+ MatBadgeIconDirective.propDecorators = {
6968
+ matIcon: [{ type: Input, args: ['matBadgeIcon',] }],
6969
+ ionIcon: [{ type: Input, args: ['ionBadgeIcon',] }]
6970
+ };
6971
+
6972
+ class SharedMatBadgeIconModule {
6973
+ }
6974
+ SharedMatBadgeIconModule.decorators = [
6975
+ { type: NgModule, args: [{
6976
+ imports: [
6977
+ CommonModule,
6978
+ IonicModule,
6979
+ MatBadgeModule,
6980
+ ],
6981
+ exports: [
6982
+ MatBadgeIconDirective
6983
+ ],
6984
+ declarations: [
6985
+ MatBadgeIconDirective
6986
+ ]
6987
+ },] }
6988
+ ];
6989
+
6911
6990
  const modules = [
6912
6991
  // Angular material components
6913
6992
  MatCommonModule,
@@ -6949,7 +7028,8 @@ const modules = [
6949
7028
  SharedMatBooleanModule,
6950
7029
  SharedMatNumpadModule,
6951
7030
  SharedMatSwipeModule,
6952
- MaterialChipsModule
7031
+ MaterialChipsModule,
7032
+ SharedMatBadgeIconModule
6953
7033
  ];
6954
7034
  class SharedMaterialModule {
6955
7035
  }
@@ -16067,7 +16147,7 @@ class MaterialTestingPage {
16067
16147
  MaterialTestingPage.decorators = [
16068
16148
  { type: Component, args: [{
16069
16149
  selector: 'app-material-testing',
16070
- template: "\n<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>Material components</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <ion-list>\n\n <ion-item-divider>Shared Material components</ion-item-divider>\n\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./datetime')\">\n Date/Time field\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./autocomplete')\">\n Autocomplete field\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./latlong')\">\n Lat/Long field\n </ion-item>\n<!-- <ion-item tappable class=\"text-1x\" (click)=\"openPage('./numpad')\">-->\n<!-- Numeric pad component-->\n<!-- </ion-item>-->\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./swipe')\">\n Swipe component\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./chips')\">\n Chips component\n </ion-item>\n\n <ng-container *ngIf=\"pages && pages.length\">\n <ion-item-divider>Other components</ion-item-divider>\n\n <ion-item *ngFor=\"let item of pages\"\n tappable class=\"text-1x\"\n (click)=\"openPage(item.page)\">{{item.label}}</ion-item>\n\n </ng-container>\n </ion-list>\n\n</ion-content>\n"
16150
+ template: "\n<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>Material components</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <ion-list>\n\n <ion-item-divider>Shared Material components</ion-item-divider>\n\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./datetime')\">\n Date/Time field\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./autocomplete')\">\n Autocomplete field\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./latlong')\">\n Lat/Long field\n </ion-item>\n<!-- <ion-item tappable class=\"text-1x\" (click)=\"openPage('./numpad')\">-->\n<!-- Numeric pad component-->\n<!-- </ion-item>-->\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./swipe')\">\n Swipe component\n </ion-item>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./chips')\">\n Chips component\n </ion-item>\n\n <ion-item-divider>Directive</ion-item-divider>\n <ion-item tappable class=\"text-1x\" (click)=\"openPage('./badge-icon')\">\n Badge icon directive\n </ion-item>\n\n <ng-container *ngIf=\"pages && pages.length\">\n <ion-item-divider>Other components</ion-item-divider>\n\n <ion-item *ngFor=\"let item of pages\"\n tappable class=\"text-1x\"\n (click)=\"openPage(item.page)\">{{item.label}}</ion-item>\n\n </ng-container>\n </ion-list>\n\n</ion-content>\n"
16071
16151
  },] }
16072
16152
  ];
16073
16153
  MaterialTestingPage.ctorParameters = () => [
@@ -16323,6 +16403,15 @@ ChipsTestPage.ctorParameters = () => [
16323
16403
  { type: FormBuilder }
16324
16404
  ];
16325
16405
 
16406
+ class MatBadgeIconTestPage {
16407
+ }
16408
+ MatBadgeIconTestPage.decorators = [
16409
+ { type: Component, args: [{
16410
+ selector: 'mat-badge-icon-test',
16411
+ template: "\n<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>matBadgeIcon directive</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <!-- small badge -->\n <p>\n <ion-text color=\"tertiary\">\n <span matBadge matIcon=\"check\"\n matBadgeSize=\"small\"\n matBadgeColor=\"accent\"\n matBadgeOverlap=\"false\">Small badge</span>\n </ion-text>\n </p>\n\n <!-- medium badge -->\n <p>\n <ion-text matBadge matBadgeIcon=\"check\"\n matBadgeSize=\"medium\"\n matBadgeColor=\"tertiary\"\n matBadgeOverlap=\"false\"\n >Medium badge</ion-text>\n </p>\n\n <!-- small badge -->\n <p>\n <ion-label matBadge matBadgeIcon=\"close\" matBadgeSize=\"large\"\n matBadgeOverlap=\"false\">Large badge</ion-label>\n </p>\n\n <!-- default size badge -->\n <p>\n <ion-label matBadge matBadgeIcon=\"check\" matBadgeColor=\"success\"\n matBadgeOverlap=\"false\">Badge (no size, no color)\n </ion-label>\n </p>\n\n <!-- ion icon -->\n <p>\n <ion-label matBadge\n ionBadgeIcon=\"checkmark\"\n matBadgeColor=\"success\"\n matBadgeOverlap=\"false\">Badge with ion-icon\n </ion-label>\n </p>\n\n <!-- ion icon clear -->\n <p>\n <ion-label matBadge\n ionBadgeIcon=\"checkmark-circle\"\n matBadgeColor=\"tertiary\"\n matBadgeFill=\"clear\"\n matBadgeOverlap=\"false\">Badge with clear icon\n </ion-label>\n </p>\n\n\n</ion-content>\n"
16412
+ },] }
16413
+ ];
16414
+
16326
16415
  const routes$1 = [
16327
16416
  {
16328
16417
  path: '',
@@ -16358,6 +16447,11 @@ const routes$1 = [
16358
16447
  path: 'chips',
16359
16448
  pathMatch: 'full',
16360
16449
  component: ChipsTestPage
16450
+ },
16451
+ {
16452
+ path: 'badge-icon',
16453
+ pathMatch: 'full',
16454
+ component: MatBadgeIconTestPage
16361
16455
  }
16362
16456
  ];
16363
16457
  class MaterialTestingModule {
@@ -16379,7 +16473,8 @@ MaterialTestingModule.decorators = [
16379
16473
  LatLongTestPage,
16380
16474
  // NumpadTestPage,
16381
16475
  SwipeTestPage,
16382
- ChipsTestPage
16476
+ ChipsTestPage,
16477
+ MatBadgeIconTestPage
16383
16478
  ],
16384
16479
  exports: [
16385
16480
  SharedMaterialModule,
@@ -16463,20 +16558,21 @@ RegisterModal.propDecorators = {
16463
16558
 
16464
16559
  // eslint-disable-next-line @angular-eslint/directive-class-suffix
16465
16560
  class AppForm {
16466
- constructor(dateAdapter, form, settings) {
16467
- this.dateAdapter = dateAdapter;
16468
- this.settings = settings;
16469
- this._subscription = new Subscription();
16561
+ constructor(injector, form) {
16562
+ this.error = null;
16470
16563
  this._enable = false;
16471
16564
  this._loading = true;
16472
- this.error = null;
16565
+ this.i18nFieldPrefix = null;
16566
+ this._subscription = new Subscription();
16473
16567
  this.debug = false;
16474
16568
  this.onCancel = new EventEmitter();
16475
16569
  this.onSubmit = new EventEmitter();
16476
16570
  if (form)
16477
16571
  this.setForm(form);
16478
- this.autocompleteHelper = new MatAutocompleteConfigHolder(settings && {
16479
- getUserAttributes: (a, b) => settings.getFieldDisplayAttributes(a, b)
16572
+ this.settings = injector.get(LocalSettingsService);
16573
+ this.errorTranslator = injector.get(FormErrorAdapter);
16574
+ this.autocompleteHelper = new MatAutocompleteConfigHolder(this.settings && {
16575
+ getUserAttributes: (a, b) => this.settings.getFieldDisplayAttributes(a, b)
16480
16576
  });
16481
16577
  this.autocompleteFields = this.autocompleteHelper.fields;
16482
16578
  }
@@ -16536,6 +16632,9 @@ class AppForm {
16536
16632
  }
16537
16633
  ngOnInit() {
16538
16634
  this._enable ? this.enable() : this.disable();
16635
+ this.errorTranslatorOptions = this.errorTranslatorOptions || {
16636
+ controlPathTranslator: this
16637
+ };
16539
16638
  }
16540
16639
  ngOnDestroy() {
16541
16640
  this._subscription.unsubscribe();
@@ -16644,7 +16743,18 @@ class AppForm {
16644
16743
  if (!opts || opts.emitEvent !== false)
16645
16744
  this.markForCheck();
16646
16745
  }
16746
+ translateControlPath(path) {
16747
+ return this.getFieldName(path);
16748
+ }
16647
16749
  /* -- protected methods -- */
16750
+ getFormError(form, opts) {
16751
+ if (!form || !this.errorTranslator)
16752
+ return undefined;
16753
+ return this.errorTranslator.translateErrors(this.form, Object.assign({ controlPathTranslator: this }, opts));
16754
+ }
16755
+ getFieldName(path) {
16756
+ return (this.i18nFieldPrefix || '') + changeCaseToUnderscore(path).toUpperCase();
16757
+ }
16648
16758
  registerSubscription(sub) {
16649
16759
  return this._subscription.add(sub);
16650
16760
  }
@@ -16660,25 +16770,25 @@ AppForm.decorators = [
16660
16770
  { type: Directive }
16661
16771
  ];
16662
16772
  AppForm.ctorParameters = () => [
16663
- { type: undefined },
16664
- { type: FormGroup },
16665
- { type: LocalSettingsService }
16773
+ { type: Injector },
16774
+ { type: FormGroup }
16666
16775
  ];
16667
16776
  AppForm.propDecorators = {
16668
16777
  debug: [{ type: Input }],
16669
16778
  tabindex: [{ type: Input }],
16779
+ errorTranslatorOptions: [{ type: Input }],
16670
16780
  form: [{ type: Input }],
16671
16781
  onCancel: [{ type: Output }],
16672
16782
  onSubmit: [{ type: Output }]
16673
16783
  };
16674
16784
 
16675
16785
  class AuthForm extends AppForm {
16676
- constructor(platform, dateAdapter, formBuilder, settings, configService, modalCtrl, network, cd, environment) {
16677
- super(dateAdapter, formBuilder.group({
16786
+ constructor(injector, platform, formBuilder, settings, configService, modalCtrl, network, cd, environment) {
16787
+ super(injector, formBuilder.group({
16678
16788
  username: [null, Validators.required],
16679
16789
  password: [null, Validators.required],
16680
16790
  offline: [network.offline]
16681
- }), settings);
16791
+ }));
16682
16792
  this.configService = configService;
16683
16793
  this.modalCtrl = modalCtrl;
16684
16794
  this.network = network;
@@ -16770,8 +16880,8 @@ AuthForm.decorators = [
16770
16880
  },] }
16771
16881
  ];
16772
16882
  AuthForm.ctorParameters = () => [
16883
+ { type: Injector },
16773
16884
  { type: PlatformService },
16774
- { type: DateAdapter },
16775
16885
  { type: FormBuilder },
16776
16886
  { type: LocalSettingsService },
16777
16887
  { type: ConfigService },
@@ -17367,9 +17477,8 @@ AccountValidatorService.ctorParameters = () => [
17367
17477
  ];
17368
17478
 
17369
17479
  class AccountPage extends AppForm {
17370
- constructor(dateAdapter, router, formBuilder, accountService, validatorService, settingsValidatorService, translate, settings, cd, locales) {
17371
- super(dateAdapter, validatorService.getFormGroup(accountService.account), settings);
17372
- this.dateAdapter = dateAdapter;
17480
+ constructor(injector, router, formBuilder, accountService, validatorService, settingsValidatorService, translate, settings, cd, locales) {
17481
+ super(injector, validatorService.getFormGroup(accountService.account));
17373
17482
  this.router = router;
17374
17483
  this.formBuilder = formBuilder;
17375
17484
  this.accountService = accountService;
@@ -17534,7 +17643,7 @@ AccountPage.decorators = [
17534
17643
  },] }
17535
17644
  ];
17536
17645
  AccountPage.ctorParameters = () => [
17537
- { type: DateAdapter },
17646
+ { type: Injector },
17538
17647
  { type: Router },
17539
17648
  { type: FormBuilder },
17540
17649
  { type: AccountService },
@@ -17901,9 +18010,8 @@ LocalSettingsValidatorService.ctorParameters = () => [
17901
18010
  ];
17902
18011
 
17903
18012
  class SettingsPage extends AppForm {
17904
- constructor(dateAdapter, platform, router, validatorService, alertCtrl, translate, formBuilder, accountService, settings, cd, network, locales) {
17905
- super(dateAdapter, validatorService.getFormGroup(), settings);
17906
- this.dateAdapter = dateAdapter;
18013
+ constructor(injector, platform, router, validatorService, alertCtrl, translate, formBuilder, accountService, settings, cd, network, locales) {
18014
+ super(injector, validatorService.getFormGroup());
17907
18015
  this.platform = platform;
17908
18016
  this.router = router;
17909
18017
  this.validatorService = validatorService;
@@ -18169,7 +18277,7 @@ SettingsPage.decorators = [
18169
18277
  },] }
18170
18278
  ];
18171
18279
  SettingsPage.ctorParameters = () => [
18172
- { type: DateAdapter },
18280
+ { type: Injector },
18173
18281
  { type: PlatformService },
18174
18282
  { type: Router },
18175
18283
  { type: LocalSettingsValidatorService },
@@ -18185,8 +18293,7 @@ SettingsPage.ctorParameters = () => [
18185
18293
 
18186
18294
  class AppPropertiesForm extends AppForm {
18187
18295
  constructor(injector, formBuilder, dateAdapter, settings, cd, formGroupDir) {
18188
- super(dateAdapter, null, settings);
18189
- this.injector = injector;
18296
+ super(injector, null);
18190
18297
  this.formBuilder = formBuilder;
18191
18298
  this.dateAdapter = dateAdapter;
18192
18299
  this.settings = settings;
@@ -18298,7 +18405,7 @@ AppPropertiesForm.propDecorators = {
18298
18405
 
18299
18406
  class AppListForm extends AppForm {
18300
18407
  constructor(injector, formBuilder, dateAdapter, settings, cd, formGroupDir) {
18301
- super(dateAdapter, null, settings);
18408
+ super(injector, null);
18302
18409
  this.injector = injector;
18303
18410
  this.formBuilder = formBuilder;
18304
18411
  this.dateAdapter = dateAdapter;
@@ -20489,7 +20596,7 @@ class AppTable {
20489
20596
  this.saveBeforeSort = toBoolean(this.saveBeforeSort, !this.readOnly); // force to false when readonly
20490
20597
  this.saveBeforeFilter = toBoolean(this.saveBeforeFilter, !this.readOnly); // force to false when readonly
20491
20598
  this.keepEditedRowOnSave = toBoolean(this.keepEditedRowOnSave, this.inlineEdition);
20492
- this.translateErrorOptions = this.translateErrorOptions || { separator: ', ', pathTranslateService: this }; // Can be override in subclasses constructors
20599
+ this.errorTranslatorOptions = this.errorTranslatorOptions || { separator: ', ', controlPathTranslator: this }; // Can be override in subclasses constructors
20493
20600
  // Check ask user confirmation is possible
20494
20601
  if (this.confirmBeforeDelete && !this.alertCtrl)
20495
20602
  throw Error('Missing \'alertCtrl\' or \'injector\' in component\'s constructor.');
@@ -21394,7 +21501,7 @@ class AppTable {
21394
21501
  return this._autocompleteConfigHolder.add(fieldName, options);
21395
21502
  }
21396
21503
  getI18nColumnName(columnName) {
21397
- return this.i18nColumnPrefix + changeCaseToUnderscore(columnName).toUpperCase();
21504
+ return (this.i18nColumnPrefix || '') + changeCaseToUnderscore(columnName).toUpperCase();
21398
21505
  }
21399
21506
  generateTableId() {
21400
21507
  return this.location.path(true).replace(/[?].*$/g, '').replace(/\/[\d]+/g, '_id') + '_' + this.constructor.name;
@@ -21497,7 +21604,7 @@ class AppTable {
21497
21604
  row = row || this.editedRow;
21498
21605
  if (!row || !this.formErrorAdapter)
21499
21606
  return undefined;
21500
- return this.formErrorAdapter.translateErrors(row.validator, Object.assign(Object.assign({}, this.translateErrorOptions), opts));
21607
+ return this.formErrorAdapter.translateErrors(row.validator, Object.assign(Object.assign({}, this.errorTranslatorOptions), opts));
21501
21608
  }
21502
21609
  setError(value, opts) {
21503
21610
  if (this.errorSubject.value !== value) {
@@ -22218,6 +22325,7 @@ class AppEntityEditor extends AppTabEditor {
22218
22325
  // Default options
22219
22326
  enableListenChanges: (injector.get(ENVIRONMENT).listenRemoteChanges === true), pathIdAttribute: 'id', autoLoad: true, autoUpdateRoute: true, i18nPrefix: '' }, options);
22220
22327
  this.settings = injector.get(LocalSettingsService);
22328
+ this.formErrorAdapter = injector.get(FormErrorAdapter);
22221
22329
  this.cd = injector.get(ChangeDetectorRef);
22222
22330
  this.dateFormat = injector.get(DateFormatPipe);
22223
22331
  this.toastController = injector.get(ToastController);
@@ -22297,7 +22405,6 @@ class AppEntityEditor extends AppTabEditor {
22297
22405
  /**
22298
22406
  * Load data from the snapshot route
22299
22407
  *
22300
- * @param route
22301
22408
  * @protected
22302
22409
  */
22303
22410
  loadFromRoute() {
@@ -22386,7 +22493,7 @@ class AppEntityEditor extends AppTabEditor {
22386
22493
  const idChanged = isNotNil(data.id)
22387
22494
  && this.previousDataId !== undefined // Ignore if first loading (=undefined)
22388
22495
  && this.previousDataId !== data.id;
22389
- opts = Object.assign({ updateRoute: this._autoUpdateRoute && idChanged && !this.loading, openTabIndex: this._autoOpenNextTab && idChanged && this.computeNextTabIndex() }, opts);
22496
+ opts = Object.assign({ updateRoute: this._autoUpdateRoute && idChanged && !this.loading, openTabIndex: this._autoOpenNextTab && idChanged && isNil(this.previousDataId) && this.computeNextTabIndex() }, opts);
22390
22497
  this.data = data;
22391
22498
  this.previousDataId = data.id || null;
22392
22499
  const promiseOrVoid = this.setValue(data);
@@ -22403,7 +22510,7 @@ class AppEntityEditor extends AppTabEditor {
22403
22510
  .then(() => this.updateTitle(data));
22404
22511
  }
22405
22512
  else {
22406
- // Update the tag group index
22513
+ // Update the next tab
22407
22514
  this.updateTabIndex(opts.openTabIndex);
22408
22515
  // Update the title.
22409
22516
  this.updateTitle(data);
@@ -22431,7 +22538,7 @@ class AppEntityEditor extends AppTabEditor {
22431
22538
  updateTabAndRoute(data, opts) {
22432
22539
  return __awaiter(this, void 0, void 0, function* () {
22433
22540
  this.queryParams = this.queryParams || {};
22434
- // Open the tab group
22541
+ // Open the next tab
22435
22542
  this.updateTabIndex(opts && opts.openTabIndex);
22436
22543
  // Save the opened tab into the queryParams
22437
22544
  this.queryParams.tab = this.selectedTabIndex;
@@ -22457,12 +22564,9 @@ class AppEntityEditor extends AppTabEditor {
22457
22564
  * Update the route location, and open the next tab
22458
22565
  */
22459
22566
  updateTabIndex(tabIndex) {
22460
- // Open the second tab
22461
- if (isNotNil(tabIndex)) {
22462
- if (this.selectedTabIndex !== tabIndex) {
22463
- this.selectedTabIndex = tabIndex;
22464
- this.markForCheck();
22465
- }
22567
+ if (isNotNil(tabIndex) && tabIndex > this.selectedTabIndex) {
22568
+ this.selectedTabIndex = tabIndex;
22569
+ this.markForCheck();
22466
22570
  }
22467
22571
  }
22468
22572
  saveAndClose(event, options) {
@@ -22485,7 +22589,13 @@ class AppEntityEditor extends AppTabEditor {
22485
22589
  return this.goBack();
22486
22590
  });
22487
22591
  }
22488
- save(event, options) {
22592
+ /**
22593
+ * Save the editor, by calling the dataService.save().
22594
+ * Ensure that editor if valid. If not, display an error
22595
+ * @param event
22596
+ * @param opts
22597
+ */
22598
+ save(event, opts) {
22489
22599
  return __awaiter(this, void 0, void 0, function* () {
22490
22600
  if (this.loading || this.saving) {
22491
22601
  console.debug('[data-editor] Skip save: editor is busy (loading or saving)');
@@ -22514,10 +22624,10 @@ class AppEntityEditor extends AppTabEditor {
22514
22624
  const data = yield this.getValue();
22515
22625
  this.disable();
22516
22626
  // Save form
22517
- const updatedData = yield this.dataService.save(data, options);
22627
+ const updatedData = yield this.dataService.save(data, opts);
22518
22628
  yield this.onEntitySaved(updatedData);
22519
22629
  // Update the view (e.g metadata)
22520
- yield this.updateView(updatedData, options);
22630
+ yield this.updateView(updatedData, opts);
22521
22631
  // Subscribe to remote changes
22522
22632
  if (!this.hasRemoteListener)
22523
22633
  this.startListenRemoteChanges();
@@ -22630,7 +22740,7 @@ class AppEntityEditor extends AppTabEditor {
22630
22740
  });
22631
22741
  }
22632
22742
  setError(err) {
22633
- console.error('[data-editor] ' + err && err.message || err, err);
22743
+ console.error('[entity-editor] Error: ' + err && err.message || '', err);
22634
22744
  let userMessage = err && err.message && this.translate.instant(err.message) || err;
22635
22745
  // Add details error (if any) under the main message
22636
22746
  const detailMessage = err && err.details && (err.details.message || err.details) || undefined;
@@ -22642,8 +22752,13 @@ class AppEntityEditor extends AppTabEditor {
22642
22752
  this.error = userMessage;
22643
22753
  }
22644
22754
  /* -- protected methods -- */
22755
+ /**
22756
+ * Return undefined to keep same tab
22757
+ * @protected
22758
+ */
22645
22759
  computeNextTabIndex() {
22646
- return this.selectedTabIndex + 1 < this.tabCount ? this.selectedTabIndex + 1 : undefined;
22760
+ const nextTabIndex = this.selectedTabIndex + 1;
22761
+ return nextTabIndex < this.tabCount ? nextTabIndex : undefined;
22647
22762
  }
22648
22763
  unload() {
22649
22764
  return __awaiter(this, void 0, void 0, function* () {
@@ -23897,5 +24012,5 @@ const ErrorCodes = {
23897
24012
  * Generated bundle index. Do not edit.
23898
24013
  */
23899
24014
 
23900
- 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, 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, FormErrorAdapter, FormErrorTranslatePipe, 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, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalsePromise, firstNotNil, firstNotNilPromise, 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, waitIdle, waitWhilePending, ɵ0$5 as ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh };
24015
+ 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, 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, FormErrorAdapter, FormErrorTranslatePipe, 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, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalsePromise, firstNotNil, firstNotNilPromise, 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, waitIdle, waitWhilePending, ɵ0$5 as ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk };
23901
24016
  //# sourceMappingURL=sumaris-net.ngx-components.js.map