@sumaris-net/ngx-components 0.26.4 → 0.27.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.
Files changed (30) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +170 -159
  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/esm2015/src/app/core/form/entity-editor.class.js +4 -5
  6. package/esm2015/src/app/core/form/form-buttons-bar.component.js +2 -1
  7. package/esm2015/src/app/core/form/form.class.js +3 -3
  8. package/esm2015/src/app/core/graphql/graphql.service.js +1 -2
  9. package/esm2015/src/app/core/services/config.service.js +1 -1
  10. package/esm2015/src/app/core/services/platform.service.js +67 -83
  11. package/esm2015/src/app/core/table/table.class.js +3 -3
  12. package/esm2015/src/app/shared/help/help.modal.js +1 -1
  13. package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +2 -2
  14. package/esm2015/src/app/shared/material/badge/badge-icon.directive.js +9 -7
  15. package/esm2015/src/app/shared/pipes/form.pipes.js +3 -3
  16. package/esm2015/src/app/shared/services/startable-service.class.js +12 -5
  17. package/esm2015/src/app/shared/toolbar/modal-toolbar.js +6 -1
  18. package/esm2015/src/app/shared/validator/form-error-adapter.class.js +5 -5
  19. package/fesm2015/sumaris-net.ngx-components.js +97 -102
  20. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/app/core/form/entity-editor.class.d.ts +2 -2
  23. package/src/app/core/form/form.class.d.ts +2 -2
  24. package/src/app/core/services/platform.service.d.ts +3 -15
  25. package/src/app/core/table/table.class.d.ts +2 -2
  26. package/src/app/shared/help/help.modal.d.ts +7 -1
  27. package/src/app/shared/pipes/form.pipes.d.ts +2 -2
  28. package/src/app/shared/services/startable-service.class.d.ts +2 -1
  29. package/src/app/shared/validator/form-error-adapter.class.d.ts +1 -1
  30. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -1832,7 +1832,7 @@
1832
1832
  { type: i0.Component, args: [{
1833
1833
  // eslint-disable-next-line @angular-eslint/component-selector
1834
1834
  selector: 'mat-autocomplete-field',
1835
- template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- readonly -->\n <ng-container>\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n [compareWith]=\"compareWith\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"onClick.emit($event)\"\n (focus)=\"filterInputTextFocusInEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.opened && onDropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [class.cdk-visually-hidden]=\"!searchable\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count \" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"onDropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1835
+ template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- readonly -->\n <ng-container>\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n [compareWith]=\"compareWith\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"onClick.emit($event)\"\n (focus)=\"filterInputTextFocusInEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"onKeydownEscape.emit($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.opened && onDropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [class.cdk-visually-hidden]=\"!searchable\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count \" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"onDropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1836
1836
  providers: [DEFAULT_VALUE_ACCESSOR$6],
1837
1837
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
1838
1838
  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}"]
@@ -3983,12 +3983,12 @@
3983
3983
  }());
3984
3984
 
3985
3985
  var APP_FORM_ERROR_I18N_KEYS = new i0.InjectionToken('appFormErrorKeys');
3986
- var FormErrorAdapter = /** @class */ (function () {
3987
- function FormErrorAdapter(translate, errorI18nKeys) {
3986
+ var FormErrorTranslator = /** @class */ (function () {
3987
+ function FormErrorTranslator(translate, errorI18nKeys) {
3988
3988
  this.translate = translate;
3989
3989
  this.errorI18nKeys = Object.assign(Object.assign({}, SharedValidators.I18N_ERROR_KEYS), errorI18nKeys);
3990
3990
  }
3991
- FormErrorAdapter.prototype.translateErrors = function (control, opts) {
3991
+ FormErrorTranslator.prototype.translateErrors = function (control, opts) {
3992
3992
  var _this = this;
3993
3993
  if (!control || !control.invalid)
3994
3994
  return '';
@@ -4017,14 +4017,14 @@
4017
4017
  return res + (res.length ? separator : '') + formError;
4018
4018
  }, "");
4019
4019
  };
4020
- FormErrorAdapter.prototype.translateControlPath = function (path, opts) {
4020
+ FormErrorTranslator.prototype.translateControlPath = function (path, opts) {
4021
4021
  if (opts === null || opts === void 0 ? void 0 : opts.controlPathTranslator) {
4022
4022
  return opts === null || opts === void 0 ? void 0 : opts.controlPathTranslator.translateControlPath(path);
4023
4023
  }
4024
4024
  var i18nKey = (opts && opts.i18nPrefix || '') + changeCaseToUnderscore(path).toUpperCase();
4025
4025
  return this.translate.instant(i18nKey);
4026
4026
  };
4027
- FormErrorAdapter.prototype.translateError = function (errorKey, errorContent) {
4027
+ FormErrorTranslator.prototype.translateError = function (errorKey, errorContent) {
4028
4028
  var i18nKey = this.errorI18nKeys[errorKey]
4029
4029
  // Try to generate a standard error key, like 'ERROR.FIELD_xxx_xxx'
4030
4030
  || ('ERROR.FIELD_' + changeCaseToUnderscore(errorKey).toUpperCase());
@@ -4041,13 +4041,13 @@
4041
4041
  console.error("[form-error-adapter] Cannot translate error key '" + errorKey + "'. Please add more formErrorsKey into APP_FORM_ERROR_I18N_KEYS injection token");
4042
4042
  return errorKey;
4043
4043
  };
4044
- return FormErrorAdapter;
4044
+ return FormErrorTranslator;
4045
4045
  }());
4046
- FormErrorAdapter.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function FormErrorAdapter_Factory() { return new FormErrorAdapter(i0__namespace.ɵɵinject(i1__namespace$1.TranslateService), i0__namespace.ɵɵinject(APP_FORM_ERROR_I18N_KEYS, 8)); }, token: FormErrorAdapter, providedIn: "root" });
4047
- FormErrorAdapter.decorators = [
4046
+ FormErrorTranslator.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function FormErrorTranslator_Factory() { return new FormErrorTranslator(i0__namespace.ɵɵinject(i1__namespace$1.TranslateService), i0__namespace.ɵɵinject(APP_FORM_ERROR_I18N_KEYS, 8)); }, token: FormErrorTranslator, providedIn: "root" });
4047
+ FormErrorTranslator.decorators = [
4048
4048
  { type: i0.Injectable, args: [{ providedIn: 'root' },] }
4049
4049
  ];
4050
- FormErrorAdapter.ctorParameters = function () { return [
4050
+ FormErrorTranslator.ctorParameters = function () { return [
4051
4051
  { type: i1$2.TranslateService },
4052
4052
  { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [APP_FORM_ERROR_I18N_KEYS,] }] }
4053
4053
  ]; };
@@ -4067,7 +4067,7 @@
4067
4067
  },] }
4068
4068
  ];
4069
4069
  FormErrorTranslatePipe.ctorParameters = function () { return [
4070
- { type: FormErrorAdapter }
4070
+ { type: FormErrorTranslator }
4071
4071
  ]; };
4072
4072
 
4073
4073
  var SharedPipesModule = /** @class */ (function () {
@@ -7785,19 +7785,21 @@
7785
7785
  badge.style.display = 'flex';
7786
7786
  badge.style.alignItems = 'center';
7787
7787
  badge.style.justifyContent = 'center';
7788
- if (this.fill !== 'clear') {
7789
- badge.style.background = "var(--ion-color-" + this.color + ")";
7790
- badge.style.color = "var(--ion-color-" + this.color + "-contrast)";
7791
- }
7792
- else {
7788
+ // fill: 'clear'
7789
+ if (this.fill === 'clear') {
7793
7790
  badge.style.color = "var(--ion-color-" + this.color + ")";
7794
7791
  badge.style.background = 'transparent';
7795
7792
  }
7793
+ // fill: 'solid' (default value)
7794
+ else {
7795
+ badge.style.background = "var(--ion-color-" + this.color + ")";
7796
+ badge.style.color = "var(--ion-color-" + this.color + "-contrast)";
7797
+ }
7796
7798
  if (this.matIcon) {
7797
7799
  badge.innerHTML = "<i class=\"material-icons\" style=\"font-size: " + fontSize + ";\">" + this.matIcon + "</i>";
7798
7800
  }
7799
7801
  else if (this.ionIcon) {
7800
- badge.innerHTML = "<ion-icon style=\"font-size: " + fontSize + ";\" name=\"" + this.ionIcon + "\"></ion-icon>";
7802
+ badge.innerHTML = "<ion-icon style=\"font-size: " + fontSize + "; pointer-events: none;\" name=\"" + this.ionIcon + "\"></ion-icon>";
7801
7803
  }
7802
7804
  };
7803
7805
  return MatBadgeIconDirective;
@@ -8535,13 +8537,14 @@
8535
8537
  };
8536
8538
 
8537
8539
  var StartableService = /** @class */ (function () {
8538
- function StartableService(platform) {
8540
+ function StartableService(prerequisiteService) {
8539
8541
  this.onStart = new rxjs.Subject();
8540
8542
  this._debug = false;
8543
+ this._startByReadyFunction = true; // should start when calling ready() ?
8541
8544
  this._data = null;
8542
8545
  this._started = false;
8543
- this._startPrerequisite = platform
8544
- ? function () { return platform.ready(); }
8546
+ this._startPrerequisite = prerequisiteService
8547
+ ? function () { return prerequisiteService.ready(); }
8545
8548
  : function () { return Promise.resolve(); };
8546
8549
  }
8547
8550
  StartableService.prototype.start = function () {
@@ -8626,9 +8629,15 @@
8626
8629
  configurable: true
8627
8630
  });
8628
8631
  StartableService.prototype.ready = function () {
8632
+ var _this = this;
8629
8633
  if (this._started)
8630
8634
  return Promise.resolve(this._data);
8631
- return this.start();
8635
+ if (this._startPromise)
8636
+ return this._startPromise;
8637
+ if (this._startByReadyFunction)
8638
+ return this.start();
8639
+ return waitFor(function () { return _this._started; })
8640
+ .then(function () { return _this._data; });
8632
8641
  };
8633
8642
  StartableService.prototype.ngOnStop = function () {
8634
8643
  return __awaiter(this, void 0, void 0, function () {
@@ -9316,6 +9325,10 @@
9316
9325
  ModalToolbarComponent.prototype.ngOnInit = function () {
9317
9326
  var _this = this;
9318
9327
  this.canValidate = toBoolean(this.canValidate, this.validate.observers.length > 0);
9328
+ // Ctrl+S
9329
+ this._subscription.add(this.hotkeys.addShortcut({ keys: 'control.s', description: 'COMMON.BTN_VALIDATE', elementName: this.modalName })
9330
+ .pipe(operators.filter(function () { return _this.canValidate; }))
9331
+ .subscribe(function (event) { return _this.validate.emit(event); }));
9319
9332
  // Escape
9320
9333
  this._subscription.add(this.hotkeys.addShortcut({ keys: 'escape', description: 'COMMON.BTN_CLOSE', elementName: this.modalName })
9321
9334
  .subscribe(function (event) { return _this.cancel.emit(event); }));
@@ -14072,7 +14085,6 @@
14072
14085
  .append('Authorization', authorization);
14073
14086
  //.append('X-App-Name', environment.name)
14074
14087
  //.append('X-App-Version', environment.version)
14075
- ;
14076
14088
  // Use the setContext method to set the HTTP headers.
14077
14089
  operation.setContext(Object.assign(Object.assign({}, operation.getContext()), { headers: headers }));
14078
14090
  // Call the next link in the middleware chain.
@@ -16458,41 +16470,38 @@
16458
16470
  var templateObject_1$3, templateObject_2$3, templateObject_3$2, templateObject_4$2, templateObject_5$1;
16459
16471
 
16460
16472
  var moment$2 = momentImported__namespace;
16461
- var PlatformService = /** @class */ (function () {
16473
+ var PlatformService = /** @class */ (function (_super) {
16474
+ __extends(PlatformService, _super);
16462
16475
  function PlatformService(platform, cdkPlatform, toastController, translate, dateAdapter, entitiesStorage, settings, networkService, accountService, configService, cache, storage, audioProvider, environment, statusBar, keyboard, splashScreen, browser, downloader) {
16463
- this.platform = platform;
16464
- this.cdkPlatform = cdkPlatform;
16465
- this.toastController = toastController;
16466
- this.translate = translate;
16467
- this.dateAdapter = dateAdapter;
16468
- this.entitiesStorage = entitiesStorage;
16469
- this.settings = settings;
16470
- this.networkService = networkService;
16471
- this.accountService = accountService;
16472
- this.configService = configService;
16473
- this.cache = cache;
16474
- this.storage = storage;
16475
- this.audioProvider = audioProvider;
16476
- this.environment = environment;
16477
- this.statusBar = statusBar;
16478
- this.keyboard = keyboard;
16479
- this.splashScreen = splashScreen;
16480
- this.browser = browser;
16481
- this.downloader = downloader;
16482
- this._started = false;
16483
- this._downloadingJobs = new Map();
16484
- this._debug = !environment.production;
16485
- if (this._debug)
16476
+ var _this = _super.call(this, platform) || this;
16477
+ _this.platform = platform;
16478
+ _this.cdkPlatform = cdkPlatform;
16479
+ _this.toastController = toastController;
16480
+ _this.translate = translate;
16481
+ _this.dateAdapter = dateAdapter;
16482
+ _this.entitiesStorage = entitiesStorage;
16483
+ _this.settings = settings;
16484
+ _this.networkService = networkService;
16485
+ _this.accountService = accountService;
16486
+ _this.configService = configService;
16487
+ _this.cache = cache;
16488
+ _this.storage = storage;
16489
+ _this.audioProvider = audioProvider;
16490
+ _this.environment = environment;
16491
+ _this.statusBar = statusBar;
16492
+ _this.keyboard = keyboard;
16493
+ _this.splashScreen = splashScreen;
16494
+ _this.browser = browser;
16495
+ _this.downloader = downloader;
16496
+ _this._downloadingJobs = new Map();
16497
+ _this._debug = !environment.production;
16498
+ if (_this._debug)
16486
16499
  console.debug('[platform] Creating service');
16487
- this.start();
16500
+ _this.start()
16501
+ // Manage error
16502
+ .catch(function (err) { return _this.onStartupError(err); });
16503
+ return _this;
16488
16504
  }
16489
- Object.defineProperty(PlatformService.prototype, "started", {
16490
- get: function () {
16491
- return this._started;
16492
- },
16493
- enumerable: false,
16494
- configurable: true
16495
- });
16496
16505
  Object.defineProperty(PlatformService.prototype, "mobile", {
16497
16506
  get: function () {
16498
16507
  return isNotNil(this._mobile) ? this._mobile : this.platform.is('mobile');
@@ -16526,80 +16535,81 @@
16526
16535
  PlatformService.prototype.height = function () {
16527
16536
  return this.platform.height();
16528
16537
  };
16529
- PlatformService.prototype.start = function () {
16530
- var _this = this;
16531
- if (this._startPromise)
16532
- return this._startPromise;
16533
- if (this._started)
16534
- return Promise.resolve();
16535
- this._started = false;
16536
- var now = Date.now();
16537
- this.accountService.tokenType = undefined;
16538
- console.info('[platform] Starting platform...');
16539
- this._startPromise = this.platform.ready()
16540
- .then(function () {
16541
- _this._mobile = _this.platform.is('mobile');
16542
- _this._cordova = _this.platform.is('cordova');
16543
- _this._android = _this.platform.is('android');
16544
- _this.configureCordovaPlugins(_this._mobile);
16545
- _this.touchUi = _this._mobile || _this.platform.is('tablet') || _this.platform.is('phablet');
16546
- // Force mobile in settings
16547
- if (_this._mobile) {
16548
- _this.settings.mobile = _this._mobile;
16549
- _this.settings.touchUi = _this.touchUi;
16550
- }
16551
- _this.configureTranslate();
16552
- })
16553
- .then(function () { return _this.storageReady(); })
16554
- .then(function (forage) { return _this.migrateStorage(forage); })
16555
- .then(function () { return Promise.all([
16556
- _this.entitiesStorage.ready(),
16557
- _this.cache.ready().then(function () { return _this.configureCache(); }),
16558
- _this.settings.ready(),
16559
- _this.networkService.ready(),
16560
- _this.audioProvider.ready()
16561
- ]); })
16562
- .then(function () {
16563
- _this._started = true;
16564
- _this._startPromise = undefined;
16565
- console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + ", canDownload: " + _this.canDownload + "} in " + (Date.now() - now) + "ms");
16566
- // Update cache configuration when network changed
16567
- _this.networkService.onNetworkStatusChanges.subscribe(function (type) { return _this.configureCache(type !== 'none'); });
16568
- // Update authentication type
16569
- _this.configService.config
16570
- .pipe(operators.map(function (config) { return config === null || config === void 0 ? void 0 : config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE); }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged())
16571
- .subscribe(function (tokenType) {
16572
- console.info("[platform] Using auth token type {" + tokenType + "}");
16573
- _this.accountService.tokenType = tokenType;
16574
- });
16575
- // Wait 1 more seconds, before hiding the splash screen
16576
- setTimeout(function () {
16577
- if (_this.splashScreen)
16578
- _this.splashScreen.hide();
16579
- // Play startup sound
16580
- _this.audioProvider.playStartupSound();
16581
- }, 1000);
16582
- })
16583
- // Manage error
16584
- .catch(function (err) { return _this.onStartupError(err); });
16585
- return this._startPromise;
16586
- };
16587
- /**
16588
- * Wait platform is ready.<br/>
16589
- * Important: this will NOT start the platform, has it should be started by the AppComponent
16590
- *
16591
- * @param opts
16592
- */
16593
- PlatformService.prototype.ready = function (opts) {
16594
- var _this = this;
16595
- var period = opts && opts.checkPeriod || 300;
16596
- if (this._started)
16597
- return Promise.resolve();
16598
- return rxjs.timer(period, period)
16599
- .pipe(
16600
- // For DEBUG :
16601
- //tap(() => this._debug && console.debug("Waiting platform ready...")),
16602
- operators.filter(function () { return _this._started; }), operators.first()).toPromise();
16538
+ PlatformService.prototype.ngOnStart = function () {
16539
+ return __awaiter(this, void 0, void 0, function () {
16540
+ var now, forage, err_1;
16541
+ var _this = this;
16542
+ return __generator(this, function (_b) {
16543
+ switch (_b.label) {
16544
+ case 0:
16545
+ now = Date.now();
16546
+ this.accountService.tokenType = undefined;
16547
+ console.info('[platform] Starting platform...');
16548
+ _b.label = 1;
16549
+ case 1:
16550
+ _b.trys.push([1, 6, , 7]);
16551
+ this._mobile = this.platform.is('mobile');
16552
+ this._cordova = this.platform.is('cordova');
16553
+ this._android = this.platform.is('android');
16554
+ this.configureCordovaPlugins(this._mobile);
16555
+ this.touchUi = this._mobile || this.platform.is('tablet') || this.platform.is('phablet');
16556
+ // Force mobile in settings
16557
+ if (this._mobile) {
16558
+ this.settings.mobile = this._mobile;
16559
+ this.settings.touchUi = this.touchUi;
16560
+ }
16561
+ // Configure translation
16562
+ return [4 /*yield*/, this.configureTranslate()];
16563
+ case 2:
16564
+ // Configure translation
16565
+ _b.sent();
16566
+ return [4 /*yield*/, this.storageReady()];
16567
+ case 3:
16568
+ forage = _b.sent();
16569
+ return [4 /*yield*/, this.migrateStorage(forage)];
16570
+ case 4:
16571
+ _b.sent();
16572
+ // Start root services
16573
+ return [4 /*yield*/, Promise.all([
16574
+ this.entitiesStorage.ready(),
16575
+ this.cache.ready().then(function () { return _this.configureCache(); }),
16576
+ this.settings.ready(),
16577
+ this.networkService.ready(),
16578
+ this.audioProvider.ready()
16579
+ ])];
16580
+ case 5:
16581
+ // Start root services
16582
+ _b.sent();
16583
+ console.info("[platform] Starting platform [OK] {mobile: " + this._mobile + ", touchUi: " + this.touchUi + ", downloader: " + this.canDownload + "} in " + (Date.now() - now) + "ms");
16584
+ // Update cache configuration when network changed
16585
+ this.networkService.onNetworkStatusChanges
16586
+ .pipe(operators.skip(1)) // Skip the first event (behavior subject send event immediately)
16587
+ .subscribe(function (type) { return _this.configureCache(type !== 'none'); });
16588
+ // Update authentication type
16589
+ this.configService.config
16590
+ .pipe(operators.map(function (config) { return config === null || config === void 0 ? void 0 : config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE); }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged())
16591
+ .subscribe(function (tokenType) {
16592
+ console.info("[platform] Using auth token type {" + tokenType + "}");
16593
+ _this.accountService.tokenType = tokenType;
16594
+ });
16595
+ // Hide the splashscreen (if mobile) - after 1s
16596
+ if (this.mobile) {
16597
+ setTimeout(function () {
16598
+ var _a;
16599
+ (_a = _this.splashScreen) === null || _a === void 0 ? void 0 : _a.hide();
16600
+ // Play startup sound
16601
+ _this.audioProvider.playStartupSound();
16602
+ }, 1000);
16603
+ }
16604
+ return [3 /*break*/, 7];
16605
+ case 6:
16606
+ err_1 = _b.sent();
16607
+ // Manage startup error
16608
+ return [2 /*return*/, this.onStartupError(err_1)];
16609
+ case 7: return [2 /*return*/];
16610
+ }
16611
+ });
16612
+ });
16603
16613
  };
16604
16614
  PlatformService.prototype.open = function (url, target, features, replace) {
16605
16615
  console.info("[platform] Opening link: " + url);
@@ -16712,22 +16722,22 @@
16712
16722
  });
16713
16723
  };
16714
16724
  PlatformService.prototype.configureCache = function (online) {
16715
- online = isNotNil(online) ? online : this.cache.isOnline();
16725
+ online = toBoolean(online, this.cache.isOnline());
16716
16726
  var cacheTTL = online ? 3600 /* 1h */ : 3600 * 24 * 30; /* 1 month */
16717
- console.info("[platform] Configuring cache [OK] {online: " + online + "}, {timeToLive: " + cacheTTL / 3600 + "h}, {offlineInvalidate: false}");
16727
+ console.info("[platform] Configuring cache [OK] {online: " + online + ", timeToLive: " + cacheTTL / 3600 + "h, offlineInvalidate: false}");
16718
16728
  this.cache.setDefaultTTL(cacheTTL);
16719
16729
  this.cache.setOfflineInvalidate(false); // Do not invalidate cache when offline
16720
16730
  };
16721
16731
  PlatformService.prototype.storageReady = function () {
16722
16732
  return __awaiter(this, void 0, void 0, function () {
16723
16733
  var forage, driver;
16724
- return __generator(this, function (_a) {
16725
- switch (_a.label) {
16734
+ return __generator(this, function (_b) {
16735
+ switch (_b.label) {
16726
16736
  case 0:
16727
16737
  console.info("[platform] Starting storage...");
16728
16738
  return [4 /*yield*/, this.storage.ready()];
16729
16739
  case 1:
16730
- forage = _a.sent();
16740
+ forage = _b.sent();
16731
16741
  driver = forage.driver();
16732
16742
  if (isNil(driver)) {
16733
16743
  console.error('[platform] NO DRIVER DEFINED IN STORAGE. Local storage cannot be used !');
@@ -16742,9 +16752,9 @@
16742
16752
  };
16743
16753
  PlatformService.prototype.migrateStorage = function (forage) {
16744
16754
  return __awaiter(this, void 0, void 0, function () {
16745
- var canMigrate, oldForage, keys, now, toast_1, duration, err_1;
16746
- return __generator(this, function (_a) {
16747
- switch (_a.label) {
16755
+ var canMigrate, oldForage, keys, now, toast_1, duration, err_2;
16756
+ return __generator(this, function (_b) {
16757
+ switch (_b.label) {
16748
16758
  case 0:
16749
16759
  canMigrate = forage &&
16750
16760
  ((forage.driver() === 'cordovaSQLiteDriver' && (forage.supports(forage.INDEXEDDB) || forage.supports(forage.WEBSQL))) ||
@@ -16758,13 +16768,13 @@
16758
16768
  });
16759
16769
  return [4 /*yield*/, oldForage.keys()];
16760
16770
  case 1:
16761
- keys = _a.sent();
16771
+ keys = _b.sent();
16762
16772
  if (!isEmptyArray(keys)) return [3 /*break*/, 3];
16763
16773
  // Drop the old instance (not need anymore)
16764
16774
  console.debug("[platform] Old storage is empty: dropping unused instance {name: '" + forage.config().name + "', driver: '" + oldForage.driver() + "'}");
16765
16775
  return [4 /*yield*/, oldForage.dropInstance()];
16766
16776
  case 2:
16767
- _a.sent();
16777
+ _b.sent();
16768
16778
  return [3 /*break*/, 12];
16769
16779
  case 3:
16770
16780
  now = Date.now();
@@ -16772,13 +16782,13 @@
16772
16782
  return [4 /*yield*/, this.showToast({ message: 'INFO.DATA_MIGRATION_STARTED',
16773
16783
  duration: 30000 })];
16774
16784
  case 4:
16775
- toast_1 = _a.sent();
16776
- _a.label = 5;
16785
+ toast_1 = _b.sent();
16786
+ _b.label = 5;
16777
16787
  case 5:
16778
- _a.trys.push([5, 9, , 12]);
16788
+ _b.trys.push([5, 9, , 12]);
16779
16789
  return [4 /*yield*/, StorageUtils.copy(oldForage, forage, { keys: keys, deleteAfterCopy: false })];
16780
16790
  case 6:
16781
- _a.sent();
16791
+ _b.sent();
16782
16792
  duration = Date.now() - now;
16783
16793
  setTimeout(function () { return toast_1.dismiss(); }, Math.max(2000 - duration, 0));
16784
16794
  return [4 /*yield*/, this.showToast({ message: 'INFO.DATA_MIGRATION_SUCCEED',
@@ -16786,26 +16796,26 @@
16786
16796
  showCloseButton: true
16787
16797
  })];
16788
16798
  case 7:
16789
- _a.sent();
16799
+ _b.sent();
16790
16800
  console.info('[platform] Starting storage migration [OK]');
16791
16801
  // Drop the old instance
16792
16802
  console.info("[platform] Drop old storage {name: '" + forage.config().name + "', driver: '" + oldForage.driver() + "'}");
16793
16803
  return [4 /*yield*/, oldForage.dropInstance()];
16794
16804
  case 8:
16795
- _a.sent();
16805
+ _b.sent();
16796
16806
  return [3 /*break*/, 12];
16797
16807
  case 9:
16798
- err_1 = _a.sent();
16799
- console.error(err_1 && err_1.message || err_1, err_1);
16808
+ err_2 = _b.sent();
16809
+ console.error(err_2 && err_2.message || err_2, err_2);
16800
16810
  return [4 /*yield*/, toast_1.dismiss()];
16801
16811
  case 10:
16802
- _a.sent();
16812
+ _b.sent();
16803
16813
  return [4 /*yield*/, this.showToast({ message: 'ERROR.DATA_MIGRATION_FAILED',
16804
16814
  type: 'error',
16805
16815
  showCloseButton: true
16806
16816
  })];
16807
16817
  case 11:
16808
- _a.sent();
16818
+ _b.sent();
16809
16819
  return [3 /*break*/, 12];
16810
16820
  case 12: return [2 /*return*/];
16811
16821
  }
@@ -16821,8 +16831,8 @@
16821
16831
  PlatformService.prototype.onStartupError = function (err) {
16822
16832
  return __awaiter(this, void 0, void 0, function () {
16823
16833
  var message, detailsMessage;
16824
- return __generator(this, function (_a) {
16825
- switch (_a.label) {
16834
+ return __generator(this, function (_b) {
16835
+ switch (_b.label) {
16826
16836
  case 0:
16827
16837
  console.error('[platform] Failed starting the platform! ', err);
16828
16838
  message = err && err.message || err;
@@ -16834,14 +16844,14 @@
16834
16844
  if (!this.translate) return [3 /*break*/, 2];
16835
16845
  return [4 /*yield*/, this.translate.get(message).toPromise()];
16836
16846
  case 1:
16837
- message = _a.sent();
16847
+ message = _b.sent();
16838
16848
  if (err && err.code) {
16839
16849
  message += " {code: " + err.code + "}";
16840
16850
  }
16841
16851
  return [3 /*break*/, 3];
16842
16852
  case 2:
16843
16853
  message = "Fatal error: Please contact your administrator.\n\n{code: " + (err && err.code || 'null') + ", message: \"" + message + "\"}";
16844
- _a.label = 3;
16854
+ _b.label = 3;
16845
16855
  case 3:
16846
16856
  if (!this.toastController) return [3 /*break*/, 5];
16847
16857
  if (detailsMessage) {
@@ -16854,7 +16864,7 @@
16854
16864
  message: message
16855
16865
  })];
16856
16866
  case 4:
16857
- _a.sent();
16867
+ _b.sent();
16858
16868
  return [3 /*break*/, 6];
16859
16869
  case 5:
16860
16870
  if (window) {
@@ -16868,14 +16878,14 @@
16868
16878
  if (err && err.details)
16869
16879
  console.error('cause', err.details);
16870
16880
  }
16871
- _a.label = 6;
16881
+ _b.label = 6;
16872
16882
  case 6: return [2 /*return*/];
16873
16883
  }
16874
16884
  });
16875
16885
  });
16876
16886
  };
16877
16887
  return PlatformService;
16878
- }());
16888
+ }(StartableService));
16879
16889
  PlatformService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function PlatformService_Factory() { return new PlatformService(i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(i2__namespace$4.Platform), i0__namespace.ɵɵinject(i1__namespace$4.ToastController), i0__namespace.ɵɵinject(i1__namespace$1.TranslateService), i0__namespace.ɵɵinject(i1__namespace.MomentDateAdapter), i0__namespace.ɵɵinject(EntitiesStorage), i0__namespace.ɵɵinject(LocalSettingsService), i0__namespace.ɵɵinject(NetworkService), i0__namespace.ɵɵinject(AccountService), i0__namespace.ɵɵinject(ConfigService), i0__namespace.ɵɵinject(i6__namespace.CacheService), i0__namespace.ɵɵinject(i3__namespace$1.Storage), i0__namespace.ɵɵinject(AudioProvider), i0__namespace.ɵɵinject(ENVIRONMENT), i0__namespace.ɵɵinject(i14__namespace.StatusBar, 8), i0__namespace.ɵɵinject(i15__namespace.Keyboard, 8), i0__namespace.ɵɵinject(i10__namespace.SplashScreen, 8), i0__namespace.ɵɵinject(i17__namespace.InAppBrowser, 8), i0__namespace.ɵɵinject(i18__namespace.Downloader, 8)); }, token: PlatformService, providedIn: "root" });
16880
16890
  PlatformService.decorators = [
16881
16891
  { type: i0.Injectable, args: [{ providedIn: 'root' },] }
@@ -19021,7 +19031,7 @@
19021
19031
  if (form)
19022
19032
  this.setForm(form);
19023
19033
  this.settings = injector.get(LocalSettingsService);
19024
- this.errorTranslator = injector.get(FormErrorAdapter);
19034
+ this.errorTranslator = injector.get(FormErrorTranslator);
19025
19035
  this.autocompleteHelper = new MatAutocompleteConfigHolder(this.settings && {
19026
19036
  getUserAttributes: function (a, b) { return _this.settings.getFieldDisplayAttributes(a, b); }
19027
19037
  });
@@ -20335,6 +20345,7 @@
20335
20345
  this.onSave = new i0.EventEmitter();
20336
20346
  this.onNext = new i0.EventEmitter();
20337
20347
  this.onBack = new i0.EventEmitter();
20348
+ // Ctrl+S
20338
20349
  this._subscription.add(hotkeys.addShortcut({ keys: 'control.s', description: 'COMMON.BTN_SAVE' })
20339
20350
  .pipe(operators.filter(function (e) { return !_this.disabled; }))
20340
20351
  .subscribe(function (event) { return _this.onSave.emit(event); }));
@@ -23518,7 +23529,7 @@
23518
23529
  this._paginator = null;
23519
23530
  this.mobile = this.platform.is('mobile');
23520
23531
  this.translate = injector === null || injector === void 0 ? void 0 : injector.get(i1$2.TranslateService);
23521
- this.formErrorAdapter = injector === null || injector === void 0 ? void 0 : injector.get(FormErrorAdapter);
23532
+ this.formErrorAdapter = injector === null || injector === void 0 ? void 0 : injector.get(FormErrorTranslator);
23522
23533
  this.alertCtrl = injector === null || injector === void 0 ? void 0 : injector.get(i1$5.AlertController);
23523
23534
  this.toastController = injector === null || injector === void 0 ? void 0 : injector.get(i1$5.ToastController);
23524
23535
  this._autocompleteConfigHolder = new MatAutocompleteConfigHolder({
@@ -25868,7 +25879,7 @@
25868
25879
  enableListenChanges: (injector.get(ENVIRONMENT).listenRemoteChanges === true), pathIdAttribute: 'id', autoLoad: true, autoUpdateRoute: true, i18nPrefix: ''
25869
25880
  }, options);
25870
25881
  _this.settings = injector.get(LocalSettingsService);
25871
- _this.formErrorAdapter = injector.get(FormErrorAdapter);
25882
+ _this.formErrorAdapter = injector.get(FormErrorTranslator);
25872
25883
  _this.cd = injector.get(i0.ChangeDetectorRef);
25873
25884
  _this.dateFormat = injector.get(DateFormatPipe);
25874
25885
  _this.toastController = injector.get(i1$5.ToastController);
@@ -27895,8 +27906,8 @@
27895
27906
  exports.FormArrayHelper = FormArrayHelper;
27896
27907
  exports.FormButtonsBarComponent = FormButtonsBarComponent;
27897
27908
  exports.FormButtonsBarToken = FormButtonsBarToken;
27898
- exports.FormErrorAdapter = FormErrorAdapter;
27899
27909
  exports.FormErrorTranslatePipe = FormErrorTranslatePipe;
27910
+ exports.FormErrorTranslator = FormErrorTranslator;
27900
27911
  exports.FormFieldValuesHolder = FormFieldValuesHolder;
27901
27912
  exports.Fragments = Fragments;
27902
27913
  exports.GraphqlService = GraphqlService;