@sumaris-net/ngx-components 0.24.0 → 0.25.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 (50) hide show
  1. package/bundles/{ngx-sumaris-components.umd.js → sumaris-net.ngx-components.umd.js} +898 -872
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -0
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +25 -0
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -0
  5. package/esm2015/public_api.js +2 -1
  6. package/esm2015/src/app/admin/services/filter/person.filter.js +4 -2
  7. package/esm2015/src/app/admin/services/person.service.js +3 -2
  8. package/esm2015/src/app/admin/users/list/users.js +6 -4
  9. package/esm2015/src/app/core/graphql/graphql.service.js +17 -63
  10. package/esm2015/src/app/core/graphql/graphql.utils.js +1 -1
  11. package/esm2015/src/app/core/install/install-upgrade-card.component.js +14 -8
  12. package/esm2015/src/app/core/services/account.service.js +146 -149
  13. package/esm2015/src/app/core/services/config.service.js +21 -14
  14. package/esm2015/src/app/core/services/local-settings.service.js +72 -87
  15. package/esm2015/src/app/core/services/network.service.js +135 -170
  16. package/esm2015/src/app/core/services/platform.service.js +26 -14
  17. package/esm2015/src/app/core/services/storage/entities-storage.service.js +59 -63
  18. package/esm2015/src/app/shared/audio/audio.js +10 -39
  19. package/esm2015/src/app/shared/functions.js +6 -7
  20. package/esm2015/src/app/shared/material/boolean/material.boolean.js +1 -1
  21. package/esm2015/src/app/shared/services/startable-service.class.js +74 -0
  22. package/esm2015/src/environments/environment.class.js +1 -1
  23. package/esm2015/src/environments/environment.js +5 -1
  24. package/esm2015/sumaris-net.ngx-components.js +13 -0
  25. package/fesm2015/{ngx-sumaris-components.js → sumaris-net.ngx-components.js} +585 -618
  26. package/fesm2015/sumaris-net.ngx-components.js.map +1 -0
  27. package/package.json +13 -9
  28. package/public_api.d.ts +1 -0
  29. package/src/app/admin/services/filter/person.filter.d.ts +1 -0
  30. package/src/app/admin/users/list/users.d.ts +1 -0
  31. package/src/app/core/graphql/graphql.service.d.ts +5 -13
  32. package/src/app/core/graphql/graphql.utils.d.ts +2 -1
  33. package/src/app/core/services/account.service.d.ts +11 -10
  34. package/src/app/core/services/config.service.d.ts +6 -5
  35. package/src/app/core/services/local-settings.service.d.ts +4 -9
  36. package/src/app/core/services/network.service.d.ts +27 -38
  37. package/src/app/core/services/platform.service.d.ts +1 -1
  38. package/src/app/core/services/storage/entities-storage.service.d.ts +13 -13
  39. package/src/app/shared/audio/audio.d.ts +4 -8
  40. package/src/app/shared/functions.d.ts +1 -1
  41. package/src/app/shared/services/startable-service.class.d.ts +25 -0
  42. package/src/environments/environment.class.d.ts +1 -0
  43. package/{ngx-sumaris-components.d.ts → sumaris-net.ngx-components.d.ts} +0 -0
  44. package/sumaris-net.ngx-components.metadata.json +1 -0
  45. package/bundles/ngx-sumaris-components.umd.js.map +0 -1
  46. package/bundles/ngx-sumaris-components.umd.min.js +0 -25
  47. package/bundles/ngx-sumaris-components.umd.min.js.map +0 -1
  48. package/esm2015/ngx-sumaris-components.js +0 -13
  49. package/fesm2015/ngx-sumaris-components.js.map +0 -1
  50. package/ngx-sumaris-components.metadata.json +0 -1
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@angular/cdk/table'), require('@angular/cdk/a11y'), require('@angular/cdk/overlay'), require('@angular/cdk/scrolling'), require('@angular/material/core'), require('@angular/material/table'), require('@angular/material/sort'), require('@angular/material/paginator'), require('@angular/material/form-field'), require('@angular/material/input'), require('@angular/material/checkbox'), require('@angular/material/expansion'), require('@angular/material/toolbar'), require('@angular/material/icon'), require('@angular/material/button'), require('@angular/material/menu'), require('@angular/material/select'), require('@angular/material/card'), require('@angular/material/tabs'), require('@angular/material/stepper'), require('@angular/material/list'), require('@angular/material/button-toggle'), require('@angular/material/progress-spinner'), require('@angular/material/progress-bar'), require('@angular/material/radio'), require('@angular/material/badge'), require('@angular/material/slide-toggle'), require('@angular/material/dialog'), require('@angular/material/autocomplete'), require('@angular/forms'), require('rxjs'), require('rxjs/operators'), require('@ngx-translate/core'), require('@ionic/angular'), require('moment'), require('@angular/material-moment-adapter'), require('@ionic-native/keyboard/ngx'), require('angular2-text-mask'), require('ngx-material-timepicker'), require('@angular/material/datepicker'), require('@angular/animations'), require('@angular/material/divider'), require('@angular/material/tooltip'), require('@angular/material/chips'), require('@angular/router'), require('@angular/platform-browser'), require('@angular/common/http'), require('ngx-color-picker'), require('@ionic-native/native-audio/ngx'), require('@ionic-native/vibration/ngx'), require('@ionic-native/audio-management/ngx'), require('@ionic-native/native-audio/ngx/index'), require('@ionic-native/vibration/ngx/index'), require('@ionic-native/audio-management/ngx/index'), require('uuid/v4'), require('@angular/cdk/drag-drop'), require('ngx-markdown'), require('tweetnacl'), require('@ionic/storage'), require('zone.js/dist/zone-error'), require('@ionic-native/splash-screen/ngx'), require('@ionic-native/network/ngx'), require('ionic-cache'), require('ionic-cache/dist/cache.service'), require('@ionic-native/network/ngx/index'), require('@ionic-native/splash-screen/ngx/index'), require('@ionic-native/status-bar/ngx'), require('@angular/cdk/platform'), require('@ionic-native/in-app-browser/ngx'), require('@apollo/client/core'), require('apollo-angular'), require('@apollo/client/link/ws'), require('@apollo/client/utilities'), require('@apollo/client/link/retry'), require('apollo-link-queue'), require('apollo-link-serialize'), require('apollo-link-logger'), require('apollo-angular/http'), require('apollo3-cache-persist'), require('@ionic-native/downloader/ngx'), require('@ionic-native/status-bar/ngx/index'), require('@ionic-native/keyboard/ngx/index'), require('@ionic-native/in-app-browser/ngx/index'), require('@ionic-native/downloader/ngx/index'), require('@e-is/ngx-material-table'), require('@angular/cdk/collections'), require('ngx-jdenticon'), require('tweetnacl-util'), require('scrypt-async'), require('hammerjs')) :
3
3
  typeof define === 'function' && define.amd ? define('@sumaris-net/ngx-components', ['exports', '@angular/core', '@angular/common', '@angular/cdk/table', '@angular/cdk/a11y', '@angular/cdk/overlay', '@angular/cdk/scrolling', '@angular/material/core', '@angular/material/table', '@angular/material/sort', '@angular/material/paginator', '@angular/material/form-field', '@angular/material/input', '@angular/material/checkbox', '@angular/material/expansion', '@angular/material/toolbar', '@angular/material/icon', '@angular/material/button', '@angular/material/menu', '@angular/material/select', '@angular/material/card', '@angular/material/tabs', '@angular/material/stepper', '@angular/material/list', '@angular/material/button-toggle', '@angular/material/progress-spinner', '@angular/material/progress-bar', '@angular/material/radio', '@angular/material/badge', '@angular/material/slide-toggle', '@angular/material/dialog', '@angular/material/autocomplete', '@angular/forms', 'rxjs', 'rxjs/operators', '@ngx-translate/core', '@ionic/angular', 'moment', '@angular/material-moment-adapter', '@ionic-native/keyboard/ngx', 'angular2-text-mask', 'ngx-material-timepicker', '@angular/material/datepicker', '@angular/animations', '@angular/material/divider', '@angular/material/tooltip', '@angular/material/chips', '@angular/router', '@angular/platform-browser', '@angular/common/http', 'ngx-color-picker', '@ionic-native/native-audio/ngx', '@ionic-native/vibration/ngx', '@ionic-native/audio-management/ngx', '@ionic-native/native-audio/ngx/index', '@ionic-native/vibration/ngx/index', '@ionic-native/audio-management/ngx/index', 'uuid/v4', '@angular/cdk/drag-drop', 'ngx-markdown', 'tweetnacl', '@ionic/storage', 'zone.js/dist/zone-error', '@ionic-native/splash-screen/ngx', '@ionic-native/network/ngx', 'ionic-cache', 'ionic-cache/dist/cache.service', '@ionic-native/network/ngx/index', '@ionic-native/splash-screen/ngx/index', '@ionic-native/status-bar/ngx', '@angular/cdk/platform', '@ionic-native/in-app-browser/ngx', '@apollo/client/core', 'apollo-angular', '@apollo/client/link/ws', '@apollo/client/utilities', '@apollo/client/link/retry', 'apollo-link-queue', 'apollo-link-serialize', 'apollo-link-logger', 'apollo-angular/http', 'apollo3-cache-persist', '@ionic-native/downloader/ngx', '@ionic-native/status-bar/ngx/index', '@ionic-native/keyboard/ngx/index', '@ionic-native/in-app-browser/ngx/index', '@ionic-native/downloader/ngx/index', '@e-is/ngx-material-table', '@angular/cdk/collections', 'ngx-jdenticon', 'tweetnacl-util', 'scrypt-async', 'hammerjs'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global['sumaris-net'] = global['sumaris-net'] || {}, global['sumaris-net']['ngx-components'] = {}), global.ng.core, global.ng.common, global.ng.cdk.table, global.ng.cdk.a11y, global.ng.cdk.overlay, global.ng.cdk.scrolling, global.ng.material.core, global.ng.material.table, global.ng.material.sort, global.ng.material.paginator, global.ng.material.formField, global.ng.material.input, global.ng.material.checkbox, global.ng.material.expansion, global.ng.material.toolbar, global.ng.material.icon, global.ng.material.button, global.ng.material.menu, global.ng.material.select, global.ng.material.card, global.ng.material.tabs, global.ng.material.stepper, global.ng.material.list, global.ng.material.buttonToggle, global.ng.material.progressSpinner, global.ng.material.progressBar, global.ng.material.radio, global.ng.material.badge, global.ng.material.slideToggle, global.ng.material.dialog, global.ng.material.autocomplete, global.ng.forms, global.rxjs, global.rxjs.operators, global['ngx-translate'].core, global.ionic.angular, global.moment, global.ng.materialMomentAdapter, global['ionic-native'].keyboard.ngx, global['angular2-text-mask'], global['ngx-material-timepicker'], global.ng.material.datepicker, global.ng.animations, global.ng.material.divider, global.ng.material.tooltip, global.ng.material.chips, global.ng.router, global.ng.platformBrowser, global.ng.common.http, global['ngx-color-picker'], global['ionic-native']['native-audio'].ngx, global['ionic-native'].vibration.ngx, global['ionic-native']['audio-management'].ngx, global['ionic-native']['native-audio'].ngx.index, global['ionic-native'].vibration.ngx.index, global['ionic-native']['audio-management'].ngx.index, global.uuid.v4, global.ng.cdk.dragDrop, global['ngx-markdown'], global.tweetnacl, global.ionic.storage, null, global['ionic-native']['splash-screen'].ngx, global['ionic-native'].network.ngx, global['ionic-cache'], global['ionic-cache/dist/cache'].service, global['ionic-native'].network.ngx.index, global['ionic-native']['splash-screen'].ngx.index, global['ionic-native']['status-bar'].ngx, global.ng.cdk.platform, global['ionic-native']['in-app-browser'].ngx, global.apollo.client.core, global['apollo-angular'], global.apollo.client.link.ws, global.apollo.client.utilities, global.apollo.client.link.retry, global['apollo-link-queue'], global['apollo-link-serialize'], global['apollo-link-logger'], global['apollo-angular'].http, global['apollo3-cache-persist'], global.ngx$6, global['ionic-native']['status-bar'].ngx.index, global['ionic-native'].keyboard.ngx.index, global['ionic-native']['in-app-browser'].ngx.index, global.i18, global['e-is']['ngx-material-table'], global.ng.cdk.collections, global['ngx-jdenticon']));
5
- }(this, (function (exports, i0, i1$4, table$1, a11y, overlay, scrolling, i1$3, table, sort$1, paginator, formField, input, checkbox, expansion, toolbar, icon, button, menu, select, card, tabs, stepper, list, buttonToggle, progressSpinner, progressBar, radio, badge, slideToggle, i2, autocomplete, i1, rxjs, operators, i1$2, i1$5, momentImported, i1$1, ngx, angular2TextMask, ngxMaterialTimepicker, datepicker, animations, divider, tooltip, chips, i3, i1$6, i2$1, ngxColorPicker, ngx$2, ngx$3, ngx$1, i2$2, i3$1, i4, uuidv4Imported, dragDrop, ngxMarkdown, tweetnacl, i3$2, zoneError, ngx$5, ngx$4, ionicCache, i6, i9, i10, ngx$7, i2$4, ngx$8, core, i2$3, ws, utilities, retry, QueueLink, SerializingLink, loggerLink, i3$3, apollo3CachePersist, ngx$6, i14, i15, i17, i18, ngxMaterialTable, collections, ngxJdenticon) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global["sumaris-net"] = global["sumaris-net"] || {}, global["sumaris-net"]["ngx-components"] = {}), global.ng.core, global.ng.common, global.ng.cdk.table, global.ng.cdk.a11y, global.ng.cdk.overlay, global.ng.cdk.scrolling, global.ng.material.core, global.ng.material.table, global.ng.material.sort, global.ng.material.paginator, global.ng.material.formField, global.ng.material.input, global.ng.material.checkbox, global.ng.material.expansion, global.ng.material.toolbar, global.ng.material.icon, global.ng.material.button, global.ng.material.menu, global.ng.material.select, global.ng.material.card, global.ng.material.tabs, global.ng.material.stepper, global.ng.material.list, global.ng.material.buttonToggle, global.ng.material.progressSpinner, global.ng.material.progressBar, global.ng.material.radio, global.ng.material.badge, global.ng.material.slideToggle, global.ng.material.dialog, global.ng.material.autocomplete, global.ng.forms, global.rxjs, global.rxjs.operators, global["ngx-translate"].core, global.ionic.angular, global.moment, global.ng.materialMomentAdapter, global["ionic-native"].keyboard.ngx, global["angular2-text-mask"], global["ngx-material-timepicker"], global.ng.material.datepicker, global.ng.animations, global.ng.material.divider, global.ng.material.tooltip, global.ng.material.chips, global.ng.router, global.ng.platformBrowser, global.ng.common.http, global["ngx-color-picker"], global["ionic-native"]["native-audio"].ngx, global["ionic-native"].vibration.ngx, global["ionic-native"]["audio-management"].ngx, global["ionic-native"]["native-audio"].ngx.index, global["ionic-native"].vibration.ngx.index, global["ionic-native"]["audio-management"].ngx.index, global.uuid.v4, global.ng.cdk.dragDrop, global["ngx-markdown"], global.tweetnacl, global.ionic.storage, null, global["ionic-native"]["splash-screen"].ngx, global["ionic-native"].network.ngx, global["ionic-cache"], global["ionic-cache/dist/cache"].service, global["ionic-native"].network.ngx.index, global["ionic-native"]["splash-screen"].ngx.index, global["ionic-native"]["status-bar"].ngx, global.ng.cdk.platform, global["ionic-native"]["in-app-browser"].ngx, global.apollo.client.core, global["apollo-angular"], global.apollo.client.link.ws, global.apollo.client.utilities, global.apollo.client.link.retry, global["apollo-link-queue"], global["apollo-link-serialize"], global["apollo-link-logger"], global["apollo-angular"].http, global["apollo3-cache-persist"], global.ngx$6, global["ionic-native"]["status-bar"].ngx.index, global["ionic-native"].keyboard.ngx.index, global["ionic-native"]["in-app-browser"].ngx.index, global.i18, global["e-is"]["ngx-material-table"], global.ng.cdk.collections, global["ngx-jdenticon"]));
5
+ })(this, (function (exports, i0, i1$4, table$1, a11y, overlay, scrolling, i1$3, table, sort$1, paginator, formField, input, checkbox, expansion, toolbar, icon, button, menu, select, card, tabs, stepper, list, buttonToggle, progressSpinner, progressBar, radio, badge, slideToggle, i2, autocomplete, i1, rxjs, operators, i1$2, i1$5, momentImported, i1$1, ngx, angular2TextMask, ngxMaterialTimepicker, datepicker, animations, divider, tooltip, chips, i3, i1$6, i2$1, ngxColorPicker, ngx$2, ngx$3, ngx$1, i2$2, i3$1, i4, uuidv4Imported, dragDrop, ngxMarkdown, tweetnacl, i3$2, zoneError, ngx$5, ngx$4, ionicCache, i6, i9, i10, ngx$7, i2$4, ngx$8, core, i2$3, ws, utilities, retry, QueueLink, SerializingLink, loggerLink, i3$3, apollo3CachePersist, ngx$6, i14, i15, i17, i18, ngxMaterialTable, collections, ngxJdenticon) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -15,14 +15,12 @@
15
15
  var d = Object.getOwnPropertyDescriptor(e, k);
16
16
  Object.defineProperty(n, k, d.get ? d : {
17
17
  enumerable: true,
18
- get: function () {
19
- return e[k];
20
- }
18
+ get: function () { return e[k]; }
21
19
  });
22
20
  }
23
21
  });
24
22
  }
25
- n['default'] = e;
23
+ n["default"] = e;
26
24
  return Object.freeze(n);
27
25
  }
28
26
 
@@ -607,16 +605,15 @@
607
605
  // Stop if not equals, otherwise continue with the next key
608
606
  .find(function (res) { return res !== 0; }) || 0; };
609
607
  }
610
- function sort(array, attribute) {
608
+ function sort(array, attribute, opts) {
611
609
  if (isEmptyArray(array))
612
610
  return array;
611
+ var compareFn = opts
612
+ ? new Intl.Collator(undefined, opts).compare
613
+ : function (v1, v2) { return v1 === v2 ? 0 : v1 > v2 ? 1 : -1; };
613
614
  return array
614
615
  .slice() // copy
615
- .sort(function (a, b) {
616
- var valueA = a[attribute];
617
- var valueB = b[attribute];
618
- return valueA === valueB ? 0 : (valueA > valueB ? 1 : -1);
619
- });
616
+ .sort(function (a, b) { return compareFn(a[attribute], b[attribute]); });
620
617
  }
621
618
  var INTEGER_REGEXP = /^[-]?\d+$/;
622
619
  function isInt(value) {
@@ -5584,7 +5581,7 @@
5584
5581
  DEFAULT_VALUE_ACCESSOR$1
5585
5582
  ],
5586
5583
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
5587
- styles: [":host{width:100%}.mat-form-field.mat-boolean-field-radio{margin-top:-2px}.mat-form-field.mat-boolean-field-button{margin-top:-4px}.mat-form-field .mat-form-field-buttons{width:100%;display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}.mat-form-field .mat-form-field-buttons .mat-form-field-button{--flex-basis:calc(100% / var(--buttons-col-count, 2));flex:0 1 var(--flex-basis);max-width:calc(min(var(--flex-basis), 150px));white-space:normal;padding:0 2px;height:40px}"]
5584
+ styles: [":host{width:100%}.mat-form-field.mat-boolean-field-radio{margin-top:-2px}.mat-form-field.mat-boolean-field-button{margin-top:-4px}.mat-form-field .mat-form-field-buttons{width:100%;display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}.mat-form-field .mat-form-field-buttons .mat-form-field-button{--flex-basis:calc(100% / var(--buttons-col-count, 2));flex:0 1 var(--flex-basis);max-width:min(var(--flex-basis),150px);white-space:normal;padding:0 2px;height:40px}"]
5588
5585
  },] }
5589
5586
  ];
5590
5587
  MatBooleanField.ctorParameters = function () { return [
@@ -7735,39 +7732,127 @@
7735
7732
  matInput: [{ type: i0.ViewChild, args: ['matInput',] }]
7736
7733
  };
7737
7734
 
7738
- var SYSTEM_SOUNDS = [
7739
- { id: 'beep-confirm', assetPath: 'assets/audio/beep-confirm.mp3', vibration: 250 },
7740
- { id: 'beep-error', assetPath: 'assets/audio/beep-error.mp3', vibration: 1000 },
7741
- { id: 'startup', assetPath: 'assets/audio/unfa-ping.mp3', vibration: [1, 500, 250, 750] },
7742
- ];
7743
- var AudioProvider = /** @class */ (function () {
7744
- function AudioProvider(platform, nativeAudio, vibration, audioManagement) {
7745
- this.platform = platform;
7746
- this.nativeAudio = nativeAudio;
7747
- this.vibration = vibration;
7748
- this.audioManagement = audioManagement;
7749
- this._started = false;
7750
- this._audioMode = ngx$1.AudioManagement.AudioMode.NORMAL;
7751
- this._preloadedSounds = {};
7752
- this._htmlAudioCache = {};
7735
+ var StartableService = /** @class */ (function () {
7736
+ function StartableService(platform) {
7753
7737
  this.onStart = new rxjs.Subject();
7754
- this.start();
7738
+ this._debug = false;
7739
+ this._data = null;
7740
+ this._started = false;
7741
+ this._startPrerequisite = platform
7742
+ ? function () { return platform.ready(); }
7743
+ : function () { return Promise.resolve(); };
7755
7744
  }
7756
- AudioProvider.prototype.ready = function () {
7745
+ StartableService.prototype.start = function () {
7746
+ var _this = this;
7747
+ if (this._startPromise)
7748
+ return this._startPromise;
7749
+ if (this._started)
7750
+ return Promise.resolve(this._data);
7751
+ this._startPromise = this._startPrerequisite()
7752
+ .then(function () { return _this.ngOnStart(); })
7753
+ .then(function (data) {
7754
+ _this._data = data;
7755
+ _this._started = true;
7756
+ _this._startPromise = undefined;
7757
+ _this.onStart.next(_this._data);
7758
+ return _this._data;
7759
+ })
7760
+ .catch(function (err) {
7761
+ console.error('Failed to start a service: ' + (err && err.message || err), err);
7762
+ _this._started = false;
7763
+ _this._startPromise = null;
7764
+ return null;
7765
+ });
7766
+ return this._startPromise;
7767
+ };
7768
+ StartableService.prototype.stop = function () {
7757
7769
  return __awaiter(this, void 0, void 0, function () {
7770
+ var err_1;
7758
7771
  return __generator(this, function (_a) {
7759
7772
  switch (_a.label) {
7760
7773
  case 0:
7761
- if (this._started)
7762
- return [2 /*return*/, Promise.resolve()];
7763
- return [4 /*yield*/, this.start()];
7774
+ _a.trys.push([0, 2, , 3]);
7775
+ return [4 /*yield*/, this.ngOnStop()];
7764
7776
  case 1:
7765
7777
  _a.sent();
7766
- return [2 /*return*/];
7778
+ this._started = false;
7779
+ this._startPromise = undefined;
7780
+ return [3 /*break*/, 3];
7781
+ case 2:
7782
+ err_1 = _a.sent();
7783
+ console.error('Failed to stop a service: ' + (err_1 && err_1.message || err_1), err_1);
7784
+ return [3 /*break*/, 3];
7785
+ case 3: return [2 /*return*/];
7786
+ }
7787
+ });
7788
+ });
7789
+ };
7790
+ StartableService.prototype.restart = function () {
7791
+ return __awaiter(this, void 0, void 0, function () {
7792
+ return __generator(this, function (_a) {
7793
+ switch (_a.label) {
7794
+ case 0:
7795
+ if (!this._startPromise) return [3 /*break*/, 2];
7796
+ return [4 /*yield*/, this._startPromise];
7797
+ case 1:
7798
+ _a.sent(); // Wait end of previous loading
7799
+ _a.label = 2;
7800
+ case 2:
7801
+ if (!this._started) return [3 /*break*/, 4];
7802
+ return [4 /*yield*/, this.stop()];
7803
+ case 3:
7804
+ _a.sent(); // Then stop if started
7805
+ _a.label = 4;
7806
+ case 4: // Then stop if started
7807
+ return [2 /*return*/, this.start()]; // Then start again
7767
7808
  }
7768
7809
  });
7769
7810
  });
7770
7811
  };
7812
+ Object.defineProperty(StartableService.prototype, "started", {
7813
+ get: function () {
7814
+ return this._started;
7815
+ },
7816
+ enumerable: false,
7817
+ configurable: true
7818
+ });
7819
+ StartableService.prototype.ready = function () {
7820
+ if (this._started)
7821
+ return Promise.resolve(this._data);
7822
+ return this.start();
7823
+ };
7824
+ StartableService.prototype.ngOnStop = function () {
7825
+ return __awaiter(this, void 0, void 0, function () {
7826
+ return __generator(this, function (_a) {
7827
+ return [2 /*return*/];
7828
+ });
7829
+ });
7830
+ };
7831
+ return StartableService;
7832
+ }());
7833
+ StartableService.ctorParameters = function () { return [
7834
+ { type: undefined, decorators: [{ type: i0.Optional }] }
7835
+ ]; };
7836
+
7837
+ var SYSTEM_SOUNDS = [
7838
+ { id: 'beep-confirm', assetPath: 'assets/audio/beep-confirm.mp3', vibration: 250 },
7839
+ { id: 'beep-error', assetPath: 'assets/audio/beep-error.mp3', vibration: 1000 },
7840
+ { id: 'startup', assetPath: 'assets/audio/unfa-ping.mp3', vibration: [1, 500, 250, 750] },
7841
+ ];
7842
+ var AudioProvider = /** @class */ (function (_super) {
7843
+ __extends(AudioProvider, _super);
7844
+ function AudioProvider(platform, nativeAudio, vibration, audioManagement) {
7845
+ var _this = _super.call(this, platform) || this;
7846
+ _this.platform = platform;
7847
+ _this.nativeAudio = nativeAudio;
7848
+ _this.vibration = vibration;
7849
+ _this.audioManagement = audioManagement;
7850
+ _this._audioMode = ngx$1.AudioManagement.AudioMode.NORMAL;
7851
+ _this._preloadedSounds = {};
7852
+ _this._htmlAudioCache = {};
7853
+ _this.start();
7854
+ return _this;
7855
+ }
7771
7856
  AudioProvider.prototype.playBeepConfirm = function () {
7772
7857
  return this.play('beep-confirm', {
7773
7858
  // Vibrate only if in vibration mode
@@ -7831,7 +7916,7 @@
7831
7916
  return __generator(this, function (_a) {
7832
7917
  switch (_a.label) {
7833
7918
  case 0:
7834
- if (!!this._started) return [3 /*break*/, 2];
7919
+ if (!!this.started) return [3 /*break*/, 2];
7835
7920
  return [4 /*yield*/, this.ready()];
7836
7921
  case 1:
7837
7922
  _a.sent();
@@ -7915,7 +8000,7 @@
7915
8000
  return __generator(this, function (_a) {
7916
8001
  switch (_a.label) {
7917
8002
  case 0:
7918
- if (!!this._started) return [3 /*break*/, 2];
8003
+ if (!!this.started) return [3 /*break*/, 2];
7919
8004
  return [4 /*yield*/, this.ready()];
7920
8005
  case 1:
7921
8006
  _a.sent();
@@ -7930,15 +8015,10 @@
7930
8015
  });
7931
8016
  };
7932
8017
  /* -- protected methods -- */
7933
- AudioProvider.prototype.start = function () {
7934
- var _this = this;
7935
- if (this._startPromise)
7936
- return this._startPromise;
7937
- if (this._started)
7938
- return Promise.resolve();
7939
- var cordova;
7940
- this._startPromise = this.platform.ready()
7941
- .then(function () { return __awaiter(_this, void 0, void 0, function () {
8018
+ AudioProvider.prototype.ngOnStart = function () {
8019
+ return __awaiter(this, void 0, void 0, function () {
8020
+ var cordova;
8021
+ var _this = this;
7942
8022
  return __generator(this, function (_a) {
7943
8023
  switch (_a.label) {
7944
8024
  case 0:
@@ -7950,33 +8030,21 @@
7950
8030
  case 1:
7951
8031
  _a.sent();
7952
8032
  _a.label = 2;
7953
- case 2: return [2 /*return*/];
8033
+ case 2:
8034
+ // Pre-loading system sounds
8035
+ console.debug('[audio] Preloading audio sounds...');
8036
+ return [4 /*yield*/, Promise.all(SYSTEM_SOUNDS.map(function (s) {
8037
+ // Disable vibration is cordova not enabled
8038
+ if (!cordova)
8039
+ s.vibration = undefined;
8040
+ return _this.preload(s);
8041
+ }))];
8042
+ case 3:
8043
+ _a.sent();
8044
+ return [2 /*return*/];
7954
8045
  }
7955
8046
  });
7956
- }); })
7957
- // Pre-loading system sounds
7958
- .then(function () {
7959
- console.debug('[audio] Preloading audio sounds...');
7960
- return Promise.all(SYSTEM_SOUNDS.map(function (s) {
7961
- // Disable vibration is cordova not enabled
7962
- if (!cordova)
7963
- s.vibration = undefined;
7964
- return _this.preload(s);
7965
- }));
7966
- })
7967
- .then(function () {
7968
- _this._started = true;
7969
- _this._startPromise = null;
7970
- console.info('[audio] Audio provider started');
7971
- // Emit event
7972
- _this.onStart.next();
7973
- })
7974
- .catch(function (err) {
7975
- console.error('[audio] Unable to start audio provider: ' + (err && err.message || err), err);
7976
- _this._started = false;
7977
- _this._startPromise = null;
7978
8047
  });
7979
- return this._startPromise;
7980
8048
  };
7981
8049
  AudioProvider.prototype.readAudioMode = function () {
7982
8050
  return __awaiter(this, void 0, void 0, function () {
@@ -7994,7 +8062,7 @@
7994
8062
  });
7995
8063
  };
7996
8064
  return AudioProvider;
7997
- }());
8065
+ }(StartableService));
7998
8066
  AudioProvider.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function AudioProvider_Factory() { return new AudioProvider(i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(i2__namespace.NativeAudio, 8), i0__namespace.ɵɵinject(i3__namespace.Vibration, 8), i0__namespace.ɵɵinject(i4__namespace.AudioManagement, 8)); }, token: AudioProvider, providedIn: "root" });
7999
8067
  AudioProvider.decorators = [
8000
8068
  { type: i0.Injectable, args: [{ providedIn: 'root' },] }
@@ -8980,6 +9048,10 @@
8980
9048
  {
8981
9049
  host: 'sih.sfa.sc',
8982
9050
  port: 80
9051
+ },
9052
+ {
9053
+ host: 'test.sumaris.net',
9054
+ port: 443
8983
9055
  }
8984
9056
  ],
8985
9057
  defaultAppName: 'SUMARiS',
@@ -9592,110 +9664,87 @@
9592
9664
  };
9593
9665
  var APP_LOCAL_SETTINGS = new i0.InjectionToken('DefaultLocalSettings');
9594
9666
  var APP_LOCAL_SETTINGS_OPTIONS = new i0.InjectionToken('LocalSettingsOptions');
9595
- var LocalSettingsService = /** @class */ (function () {
9667
+ var LocalSettingsService = /** @class */ (function (_super) {
9668
+ __extends(LocalSettingsService, _super);
9596
9669
  function LocalSettingsService(translate, platform, storage, environment, defaultSettings, defaultOptionsMap) {
9597
- this.translate = translate;
9598
- this.platform = platform;
9599
- this.storage = storage;
9600
- this.environment = environment;
9601
- this.defaultSettings = defaultSettings;
9602
- this._started = false;
9603
- this.onChange = new rxjs.Subject();
9604
- this.defaultSettings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), this.defaultSettings);
9605
- this._optionDefs = Object.values(defaultOptionsMap);
9606
- this.resetData();
9607
- this._debug = !environment.production;
9608
- if (this._debug)
9670
+ var _this = _super.call(this, platform) || this;
9671
+ _this.translate = translate;
9672
+ _this.platform = platform;
9673
+ _this.storage = storage;
9674
+ _this.environment = environment;
9675
+ _this.defaultSettings = defaultSettings;
9676
+ _this.onChange = new rxjs.Subject();
9677
+ _this.defaultSettings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), _this.defaultSettings);
9678
+ _this._optionDefs = Object.values(defaultOptionsMap);
9679
+ _this.resetData();
9680
+ _this._debug = !environment.production;
9681
+ if (_this._debug)
9609
9682
  console.debug('[settings] Creating service');
9683
+ return _this;
9610
9684
  }
9611
9685
  Object.defineProperty(LocalSettingsService.prototype, "settings", {
9612
9686
  get: function () {
9613
- return this.data || this.defaultSettings;
9687
+ return this._data || this.defaultSettings;
9614
9688
  },
9615
9689
  enumerable: false,
9616
9690
  configurable: true
9617
9691
  });
9618
9692
  Object.defineProperty(LocalSettingsService.prototype, "locale", {
9619
9693
  get: function () {
9620
- return this.data && this.data.locale || this.translate.currentLang || this.translate.defaultLang;
9694
+ return this._data && this._data.locale || this.translate.currentLang || this.translate.defaultLang;
9621
9695
  },
9622
9696
  enumerable: false,
9623
9697
  configurable: true
9624
9698
  });
9625
9699
  Object.defineProperty(LocalSettingsService.prototype, "latLongFormat", {
9626
9700
  get: function () {
9627
- return this.data && this.data.latLongFormat || 'DDMM';
9701
+ return this._data && this._data.latLongFormat || 'DDMM';
9628
9702
  },
9629
9703
  enumerable: false,
9630
9704
  configurable: true
9631
9705
  });
9632
9706
  Object.defineProperty(LocalSettingsService.prototype, "usageMode", {
9633
9707
  get: function () {
9634
- return (this.data && this.data.usageMode || (this.mobile ? 'FIELD' : 'DESK'));
9708
+ return (this._data && this._data.usageMode || (this.mobile ? 'FIELD' : 'DESK'));
9635
9709
  },
9636
9710
  enumerable: false,
9637
9711
  configurable: true
9638
9712
  });
9639
9713
  Object.defineProperty(LocalSettingsService.prototype, "mobile", {
9640
9714
  get: function () {
9641
- return this.data && toBoolean(this.data.mobile, this.platform.is('mobile'));
9715
+ return this._data && toBoolean(this._data.mobile, this.platform.is('mobile'));
9642
9716
  },
9643
9717
  set: function (value) {
9644
- this.data.mobile = value;
9718
+ this._data.mobile = value;
9645
9719
  },
9646
9720
  enumerable: false,
9647
9721
  configurable: true
9648
9722
  });
9649
9723
  Object.defineProperty(LocalSettingsService.prototype, "touchUi", {
9650
9724
  get: function () {
9651
- return this.data.touchUi;
9725
+ return this._data.touchUi;
9652
9726
  },
9653
9727
  set: function (value) {
9654
- this.data.touchUi = value;
9728
+ this._data.touchUi = value;
9655
9729
  },
9656
9730
  enumerable: false,
9657
9731
  configurable: true
9658
9732
  });
9659
9733
  Object.defineProperty(LocalSettingsService.prototype, "pageHistory", {
9660
9734
  get: function () {
9661
- return (this.data && this.data.pageHistory || []);
9735
+ return (this._data && this._data.pageHistory || []);
9662
9736
  },
9663
9737
  enumerable: false,
9664
9738
  configurable: true
9665
9739
  });
9666
- LocalSettingsService.prototype.start = function () {
9667
- var _this = this;
9668
- if (this._startPromise)
9669
- return this._startPromise;
9670
- if (this._started)
9671
- return Promise.resolve(this.data);
9672
- console.info('[settings] Starting settings...');
9740
+ LocalSettingsService.prototype.ngOnStart = function () {
9741
+ console.info('[settings] Starting service...');
9673
9742
  // Restoring local settings
9674
- this._startPromise = this.platform.ready()
9675
- .then(function () {
9676
- _this.data.mobile = isNotNil(_this.data.mobile) ? _this.data.mobile : _this.platform.is('mobile');
9677
- _this.data.touchUi = _this.data.mobile || _this.platform.is('phablet') || _this.platform.is('tablet');
9678
- _this.data.usageMode = _this.platform.is('android') ? 'FIELD' : 'DESK'; // FIELD by default if Android
9679
- })
9680
- .then(function () { return _this.restoreLocally(); })
9681
- .then(function (data) {
9682
- _this._started = true;
9683
- _this._startPromise = undefined;
9684
- return data;
9685
- });
9686
- return this._startPromise;
9687
- };
9688
- Object.defineProperty(LocalSettingsService.prototype, "started", {
9689
- get: function () {
9690
- return this._started;
9691
- },
9692
- enumerable: false,
9693
- configurable: true
9694
- });
9695
- LocalSettingsService.prototype.ready = function () {
9696
- if (this._started)
9697
- return Promise.resolve(this.data);
9698
- return this.start();
9743
+ this._data.mobile = isNotNil(this._data.mobile) ? this._data.mobile : this.platform.is('mobile');
9744
+ this._data.touchUi = this._data.mobile || this.platform.is('phablet') || this.platform.is('tablet');
9745
+ this._data.usageMode = this.platform.is('android') ? 'FIELD' : 'DESK'; // FIELD by default if Android
9746
+ // Restoring local settings
9747
+ return this.restoreLocally();
9699
9748
  };
9700
9749
  LocalSettingsService.prototype.isUsageMode = function (mode) {
9701
9750
  return this.usageMode === mode;
@@ -9705,10 +9754,12 @@
9705
9754
  };
9706
9755
  LocalSettingsService.prototype.restoreLocally = function () {
9707
9756
  return __awaiter(this, void 0, void 0, function () {
9708
- var settingsStr, restoredData_1;
9757
+ var data, settingsStr, restoredData_1;
9709
9758
  return __generator(this, function (_a) {
9710
9759
  switch (_a.label) {
9711
- case 0: return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
9760
+ case 0:
9761
+ data = this._data || {};
9762
+ return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
9712
9763
  case 1:
9713
9764
  settingsStr = _a.sent();
9714
9765
  // Restore local settings (or keep old settings)
@@ -9719,30 +9770,31 @@
9719
9770
  SETTINGS_TRANSIENT_PROPERTIES.forEach(function (transientKey) {
9720
9771
  delete restoredData_1[transientKey];
9721
9772
  });
9722
- this.data = Object.assign(this.data, restoredData_1);
9773
+ // Merge into existing data
9774
+ data = Object.assign(data, restoredData_1);
9723
9775
  }
9724
9776
  // Emit event
9725
- this.onChange.next(this.data);
9726
- return [2 /*return*/, this.data];
9777
+ this.onChange.next(data);
9778
+ return [2 /*return*/, data];
9727
9779
  }
9728
9780
  });
9729
9781
  });
9730
9782
  };
9731
9783
  LocalSettingsService.prototype.setProperty = function (keyOrDef, value) {
9732
- if (!this.data)
9784
+ if (!this._data)
9733
9785
  return;
9734
9786
  if (typeof keyOrDef === 'object') {
9735
9787
  this.setProperty(keyOrDef.key, value);
9736
9788
  return;
9737
9789
  }
9738
- this.data.properties = this.data.properties || {};
9739
- this.data.properties[keyOrDef] = isNil(value) ? undefined : value.toString();
9790
+ this._data.properties = this._data.properties || {};
9791
+ this._data.properties[keyOrDef] = isNil(value) ? undefined : value.toString();
9740
9792
  };
9741
9793
  LocalSettingsService.prototype.getProperty = function (keyOrDef, defaultValue) {
9742
9794
  if (typeof keyOrDef === 'object') {
9743
9795
  return this.getProperty(keyOrDef.key, isNil(defaultValue) ? keyOrDef.defaultValue : defaultValue);
9744
9796
  }
9745
- var value = this.data && this.data.properties && this.data.properties[keyOrDef];
9797
+ var value = this._data && this._data.properties && this._data.properties[keyOrDef];
9746
9798
  return isNotNil(value) ? value : defaultValue;
9747
9799
  };
9748
9800
  LocalSettingsService.prototype.getPropertyAsBoolean = function (definition, defaultValue) {
@@ -9768,19 +9820,25 @@
9768
9820
  return __generator(this, function (_a) {
9769
9821
  switch (_a.label) {
9770
9822
  case 0:
9771
- this.data = Object.assign(Object.assign({}, this.data), settings);
9772
- if (!(opts && opts.persistImmediate)) return [3 /*break*/, 2];
9773
- return [4 /*yield*/, this.persistLocally(true)];
9823
+ if (!!this.started) return [3 /*break*/, 2];
9824
+ return [4 /*yield*/, this.ready()];
9774
9825
  case 1:
9775
9826
  _a.sent();
9776
- return [3 /*break*/, 3];
9827
+ _a.label = 2;
9777
9828
  case 2:
9778
- this.persistLocally(); // No AWAIT
9779
- _a.label = 3;
9829
+ this._data = Object.assign(Object.assign({}, this._data), settings);
9830
+ if (!(opts && opts.persistImmediate)) return [3 /*break*/, 4];
9831
+ return [4 /*yield*/, this.persistLocally(true)];
9780
9832
  case 3:
9833
+ _a.sent();
9834
+ return [3 /*break*/, 5];
9835
+ case 4:
9836
+ this.persistLocally(); // No AWAIT
9837
+ _a.label = 5;
9838
+ case 5:
9781
9839
  // Emit event
9782
9840
  if (!opts || opts.emitEvent !== false) {
9783
- this.onChange.next(this.data);
9841
+ this.onChange.next(this._data);
9784
9842
  }
9785
9843
  return [2 /*return*/];
9786
9844
  }
@@ -9804,27 +9862,27 @@
9804
9862
  });
9805
9863
  };
9806
9864
  LocalSettingsService.prototype.getPageSettings = function (pageId, propertyName) {
9807
- if (!this.data || !this.data.pages)
9865
+ if (!this._data || !this._data.pages)
9808
9866
  return undefined;
9809
9867
  var key = pageId.replace(/[/]/g, '__');
9810
9868
  if (isNotNilOrBlank(propertyName)) {
9811
- return getPropertyByPath(this.data.pages, key + '.' + propertyName);
9869
+ return getPropertyByPath(this._data.pages, key + '.' + propertyName);
9812
9870
  }
9813
- return this.data.pages[key];
9871
+ return this._data.pages[key];
9814
9872
  };
9815
9873
  LocalSettingsService.prototype.savePageSetting = function (pageId, value, propertyName) {
9816
9874
  return __awaiter(this, void 0, void 0, function () {
9817
9875
  var key;
9818
9876
  return __generator(this, function (_a) {
9819
- this.data = this.data || this.defaultSettings;
9820
- this.data.pages = this.data.pages || {};
9877
+ this._data = this._data || this.defaultSettings;
9878
+ this._data.pages = this._data.pages || {};
9821
9879
  key = pageId.replace(/[/]/g, '__');
9822
9880
  if (propertyName) {
9823
- this.data.pages[key] = this.data.pages[key] || {};
9824
- this.data.pages[key][propertyName] = value;
9881
+ this._data.pages[key] = this._data.pages[key] || {};
9882
+ this._data.pages[key][propertyName] = value;
9825
9883
  }
9826
9884
  else {
9827
- this.data.pages[key] = value;
9885
+ this._data.pages[key] = value;
9828
9886
  }
9829
9887
  // Update local settings
9830
9888
  this.persistLocally();
@@ -9833,13 +9891,13 @@
9833
9891
  });
9834
9892
  };
9835
9893
  LocalSettingsService.prototype.getOfflineFeature = function (featureName) {
9836
- if (!this.data || !this.data.offlineFeatures || isEmptyArray(this.data.offlineFeatures))
9894
+ if (!this._data || !this._data.offlineFeatures || isEmptyArray(this._data.offlineFeatures))
9837
9895
  return undefined;
9838
9896
  if (!featureName)
9839
9897
  throw Error('Missing \'featureName\' argument');
9840
9898
  featureName = featureName.toLowerCase();
9841
9899
  var featurePrefix = featureName + '#';
9842
- var feature = this.data.offlineFeatures.find(function (f) {
9900
+ var feature = this._data.offlineFeatures.find(function (f) {
9843
9901
  if (typeof f === 'string')
9844
9902
  return f.toLowerCase().startsWith(featurePrefix);
9845
9903
  if (typeof f === 'object' && f.name)
@@ -9862,24 +9920,24 @@
9862
9920
  LocalSettingsService.prototype.hasOfflineFeature = function (featureName) {
9863
9921
  if (featureName)
9864
9922
  return isNotNil(this.getOfflineFeature(featureName));
9865
- return this.data && isNotEmptyArray(this.data.offlineFeatures);
9923
+ return this._data && isNotEmptyArray(this._data.offlineFeatures);
9866
9924
  };
9867
9925
  LocalSettingsService.prototype.saveOfflineFeature = function (feature) {
9868
- this.data = this.data || this.defaultSettings;
9869
- this.data.offlineFeatures = this.data.offlineFeatures || [];
9926
+ this._data = this._data || this.defaultSettings;
9927
+ this._data.offlineFeatures = this._data.offlineFeatures || [];
9870
9928
  feature.name = feature.name.toLowerCase();
9871
9929
  var featurePrefix = feature.name + '#';
9872
- var existingIndex = this.data.offlineFeatures.findIndex(function (f) {
9930
+ var existingIndex = this._data.offlineFeatures.findIndex(function (f) {
9873
9931
  if (typeof f === 'string')
9874
9932
  return f.toLowerCase().startsWith(featurePrefix);
9875
9933
  if (typeof f === 'object' && f.name)
9876
9934
  return f.name === feature.name;
9877
9935
  });
9878
9936
  if (existingIndex !== -1) {
9879
- this.data.offlineFeatures[existingIndex] = feature;
9937
+ this._data.offlineFeatures[existingIndex] = feature;
9880
9938
  }
9881
9939
  else {
9882
- this.data.offlineFeatures.push(feature);
9940
+ this._data.offlineFeatures.push(feature);
9883
9941
  }
9884
9942
  // Update local settings
9885
9943
  this.persistLocally();
@@ -9898,14 +9956,14 @@
9898
9956
  this.saveOfflineFeature(feature);
9899
9957
  };
9900
9958
  LocalSettingsService.prototype.removeOfflineFeatures = function () {
9901
- if (this.data && this.data.offlineFeatures) {
9902
- this.data.offlineFeatures = [];
9959
+ if (this._data && this._data.offlineFeatures) {
9960
+ this._data.offlineFeatures = [];
9903
9961
  // Update local settings
9904
9962
  this.persistLocally();
9905
9963
  }
9906
9964
  };
9907
9965
  LocalSettingsService.prototype.getFieldDisplayAttributes = function (fieldName, defaultAttributes) {
9908
- var value = this.data && this.data.properties && this.data.properties["sumaris.field." + fieldName + ".attributes"];
9966
+ var value = this._data && this._data.properties && this._data.properties["sumaris.field." + fieldName + ".attributes"];
9909
9967
  // Nothing found in settings: return defaults
9910
9968
  if (!value)
9911
9969
  return defaultAttributes || ['label', 'name'];
@@ -9943,7 +10001,7 @@
9943
10001
  // If not inside recursive call: fill page history defaults
9944
10002
  if (!pageHistory)
9945
10003
  this.fillPageHistoryDefaults(page, opts);
9946
- pageHistory = pageHistory || this.data.pageHistory;
10004
+ pageHistory = pageHistory || this._data.pageHistory;
9947
10005
  index = pageHistory.findIndex(function (p) { return (
9948
10006
  // same path
9949
10007
  p.path === page.path
@@ -9978,10 +10036,10 @@
9978
10036
  _a.sent();
9979
10037
  _a.label = 4;
9980
10038
  case 4:
9981
- if (!(pageHistory === this.data.pageHistory)) return [3 /*break*/, 6];
10039
+ if (!(pageHistory === this._data.pageHistory)) return [3 /*break*/, 6];
9982
10040
  // If max has been reached, remove old pages
9983
- if (this.data.pageHistory.length > this.data.pageHistoryMaxSize) {
9984
- removedPages = pageHistory.splice(this.data.pageHistoryMaxSize, pageHistory.length - this.data.pageHistoryMaxSize);
10041
+ if (this._data.pageHistory.length > this._data.pageHistoryMaxSize) {
10042
+ removedPages = pageHistory.splice(this._data.pageHistoryMaxSize, pageHistory.length - this._data.pageHistoryMaxSize);
9985
10043
  console.debug('[settings] Pages removed from history: ', removedPages);
9986
10044
  }
9987
10045
  // Apply new value
@@ -10003,7 +10061,7 @@
10003
10061
  return __generator(this, function (_a) {
10004
10062
  switch (_a.label) {
10005
10063
  case 0:
10006
- pageHistory = pageHistory || this.data.pageHistory;
10064
+ pageHistory = pageHistory || this._data.pageHistory;
10007
10065
  index = pageHistory.findIndex(function (p) { return p.path === path; });
10008
10066
  found = index !== -1;
10009
10067
  if (found) {
@@ -10018,9 +10076,9 @@
10018
10076
  .filter(isNotEmptyArray)
10019
10077
  .findIndex(function (children) { return _this.removePageHistory(path, opts, children); }) !== -1;
10020
10078
  }
10021
- if (!(found && pageHistory === this.data.pageHistory)) return [3 /*break*/, 2];
10079
+ if (!(found && pageHistory === this._data.pageHistory)) return [3 /*break*/, 2];
10022
10080
  // Apply changes
10023
- return [4 /*yield*/, this.applyProperty('pageHistory', this.data.pageHistory)];
10081
+ return [4 /*yield*/, this.applyProperty('pageHistory', this._data.pageHistory)];
10024
10082
  case 1:
10025
10083
  // Apply changes
10026
10084
  _a.sent();
@@ -10047,27 +10105,27 @@
10047
10105
  };
10048
10106
  /* -- Protected methods -- */
10049
10107
  LocalSettingsService.prototype.resetData = function () {
10050
- this.data = Object.assign(Object.assign({}, this.data), this.defaultSettings);
10051
- this.data.locale = this.translate.currentLang || this.translate.defaultLang;
10052
- this.data.mobile = undefined;
10053
- this.data.usageMode = undefined;
10054
- this.data.pageHistory = [];
10108
+ this._data = Object.assign(Object.assign({}, this._data), this.defaultSettings);
10109
+ this._data.locale = this.translate.currentLang || this.translate.defaultLang;
10110
+ this._data.mobile = undefined;
10111
+ this._data.usageMode = undefined;
10112
+ this._data.pageHistory = [];
10055
10113
  var defaultPeer = this.environment.defaultPeer && exports.Peer.fromObject(this.environment.defaultPeer);
10056
- this.data.peerUrl = defaultPeer && defaultPeer.url || undefined;
10057
- if (this._started)
10058
- this.onChange.next(this.data);
10114
+ this._data.peerUrl = defaultPeer && defaultPeer.url || undefined;
10115
+ if (this.started)
10116
+ this.onChange.next(this._data);
10059
10117
  };
10060
10118
  LocalSettingsService.prototype.persistLocally = function (immediate) {
10061
10119
  var _this = this;
10062
10120
  // Execute immediate
10063
10121
  if (immediate) {
10064
- if (!this.data) {
10122
+ if (!this._data) {
10065
10123
  console.debug('[settings] Removing local settings from storage');
10066
10124
  return this.storage.remove(SETTINGS_STORAGE_KEY);
10067
10125
  }
10068
10126
  else {
10069
- console.debug('[settings] Store local settings', this.data);
10070
- return this.storage.set(SETTINGS_STORAGE_KEY, JSON.stringify(this.data));
10127
+ console.debug('[settings] Store local settings', this._data);
10128
+ return this.storage.set(SETTINGS_STORAGE_KEY, JSON.stringify(this._data));
10071
10129
  }
10072
10130
  }
10073
10131
  // Execute with delay
@@ -10077,7 +10135,7 @@
10077
10135
  this._$persist = new i0.EventEmitter(true);
10078
10136
  this._$persist
10079
10137
  .pipe(operators.debounceTime(2000), // add a delay of 2s
10080
- operators.filter(function () { return _this._started; }))
10138
+ operators.filter(function () { return _this.started; }))
10081
10139
  .subscribe(function () { return _this.persistLocally(true); });
10082
10140
  }
10083
10141
  this._$persist.emit();
@@ -10103,7 +10161,7 @@
10103
10161
  return page;
10104
10162
  };
10105
10163
  return LocalSettingsService;
10106
- }());
10164
+ }(StartableService));
10107
10165
  LocalSettingsService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function LocalSettingsService_Factory() { return new LocalSettingsService(i0__namespace.ɵɵinject(i1__namespace$1.TranslateService), i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(i3__namespace$1.Storage), i0__namespace.ɵɵinject(ENVIRONMENT), i0__namespace.ɵɵinject(APP_LOCAL_SETTINGS, 8), i0__namespace.ɵɵinject(APP_LOCAL_SETTINGS_OPTIONS, 8)); }, token: LocalSettingsService, providedIn: "root" });
10108
10166
  LocalSettingsService.decorators = [
10109
10167
  { type: i0.Injectable, args: [{
@@ -10250,6 +10308,8 @@
10250
10308
  switch (type) {
10251
10309
  case ngx$4.Connection.NONE:
10252
10310
  return 'none';
10311
+ case ngx$4.Connection.ETHERNET:
10312
+ return 'ethernet';
10253
10313
  case ngx$4.Connection.WIFI:
10254
10314
  return 'wifi';
10255
10315
  case ngx$4.Connection.CELL:
@@ -10257,8 +10317,6 @@
10257
10317
  case ngx$4.Connection.CELL_3G:
10258
10318
  case ngx$4.Connection.CELL_4G:
10259
10319
  return 'cell';
10260
- case ngx$4.Connection.ETHERNET:
10261
- return 'ethernet';
10262
10320
  case ngx$4.Connection.UNKNOWN:
10263
10321
  return 'unknown';
10264
10322
  default:
@@ -10274,41 +10332,42 @@
10274
10332
  MOBILE: 1000,
10275
10333
  DESKTOP: 1000
10276
10334
  }*/
10277
- var NetworkService = /** @class */ (function () {
10335
+ var NetworkService = /** @class */ (function (_super) {
10336
+ __extends(NetworkService, _super);
10278
10337
  function NetworkService(_document, platform, modalCtrl, cryptoService, storage, settings, cache, http, environment, network, splashScreen, translate, toastController) {
10279
- var _this = this;
10280
- this._document = _document;
10281
- this.platform = platform;
10282
- this.modalCtrl = modalCtrl;
10283
- this.cryptoService = cryptoService;
10284
- this.storage = storage;
10285
- this.settings = settings;
10286
- this.cache = cache;
10287
- this.http = http;
10288
- this.environment = environment;
10289
- this.network = network;
10290
- this.splashScreen = splashScreen;
10291
- this.translate = translate;
10292
- this.toastController = toastController;
10293
- this._started = false;
10294
- this._subscription = new rxjs.Subscription();
10295
- this._listeners = {};
10296
- this.onStart = new rxjs.Subject();
10297
- this.onPeerChanges = this.onStart.pipe(operators.map(function (peer) { return peer && peer.url; }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged());
10298
- this.onNetworkStatusChanges = new rxjs.BehaviorSubject(null);
10299
- this.onResetNetworkCache = new i0.EventEmitter(true);
10300
- this._mobile = this.platform.is('mobile');
10301
- if (this._mobile) {
10302
- this._timerRefreshPeriod = NetworkRefreshTimerPeriod.MOBILE;
10303
- this._timerRefreshCondition = function () { return _this.online; }; // Check only when online, and stop when offline
10338
+ var _this = _super.call(this, platform) || this;
10339
+ _this._document = _document;
10340
+ _this.platform = platform;
10341
+ _this.modalCtrl = modalCtrl;
10342
+ _this.cryptoService = cryptoService;
10343
+ _this.storage = storage;
10344
+ _this.settings = settings;
10345
+ _this.cache = cache;
10346
+ _this.http = http;
10347
+ _this.environment = environment;
10348
+ _this.network = network;
10349
+ _this.splashScreen = splashScreen;
10350
+ _this.translate = translate;
10351
+ _this.toastController = toastController;
10352
+ _this.onPeerChanges = _this.onStart.pipe(operators.map(function (peer) { return peer && peer.url; }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged());
10353
+ _this.onNetworkStatusChanges = new rxjs.BehaviorSubject(null);
10354
+ _this.onResetNetworkCache = new i0.EventEmitter(true);
10355
+ _this._subscription = new rxjs.Subscription();
10356
+ _this._listeners = {};
10357
+ _this._mobile = _this.platform.is('mobile');
10358
+ if (_this._mobile) {
10359
+ _this._timerRefreshPeriod = NetworkRefreshTimerPeriod.MOBILE;
10360
+ _this._timerRefreshCondition = function () { return _this.online; }; // Check only when online, and stop when offline
10304
10361
  }
10305
10362
  else {
10306
- this._timerRefreshPeriod = NetworkRefreshTimerPeriod.DESKTOP;
10307
- this._timerRefreshCondition = function () { return true; }; // Always check
10363
+ _this._timerRefreshPeriod = NetworkRefreshTimerPeriod.DESKTOP;
10364
+ _this._timerRefreshCondition = function () { return true; }; // Always check
10308
10365
  }
10309
- this.resetData();
10366
+ _this.resetData();
10367
+ _this.onStart.subscribe(function () { return _this.ngOnAfterStart(); });
10310
10368
  // For DEV only
10311
- this._debug = !environment.production;
10369
+ _this._debug = !environment.production;
10370
+ return _this;
10312
10371
  }
10313
10372
  Object.defineProperty(NetworkService.prototype, "online", {
10314
10373
  get: function () {
@@ -10329,24 +10388,18 @@
10329
10388
  // If force offline: return 'none'
10330
10389
  return this._forceOffline && 'none'
10331
10390
  // Else, return device connection type (or unknown)
10332
- || (this._started && this._deviceConnectionType || 'unknown');
10391
+ || (this.started && this._deviceConnectionType || 'unknown');
10333
10392
  },
10334
10393
  enumerable: false,
10335
10394
  configurable: true
10336
10395
  });
10337
10396
  Object.defineProperty(NetworkService.prototype, "peer", {
10338
10397
  get: function () {
10339
- return this._peer && this._peer.clone();
10398
+ return this._data && this._data.clone();
10340
10399
  },
10341
10400
  set: function (peer) {
10342
- this.restart(peer);
10343
- },
10344
- enumerable: false,
10345
- configurable: true
10346
- });
10347
- Object.defineProperty(NetworkService.prototype, "started", {
10348
- get: function () {
10349
- return this._started;
10401
+ this._startingPeer = peer;
10402
+ this.restart();
10350
10403
  },
10351
10404
  enumerable: false,
10352
10405
  configurable: true
@@ -10371,170 +10424,72 @@
10371
10424
  return this.addListener(eventType, callback);
10372
10425
  }
10373
10426
  };
10374
- NetworkService.prototype.start = function (peer) {
10375
- return __awaiter(this, void 0, void 0, function () {
10376
- var _this = this;
10377
- return __generator(this, function (_a) {
10378
- if (this._startPromise)
10379
- return [2 /*return*/, this._startPromise];
10380
- if (this._started)
10381
- return [2 /*return*/];
10382
- console.info('[network] Starting network...');
10383
- // Restoring local settings
10384
- this._startPromise = (!peer && this.restoreLocally() || Promise.resolve(peer))
10385
- .then(function (peer) { return __awaiter(_this, void 0, void 0, function () {
10386
- return __generator(this, function (_a) {
10387
- switch (_a.label) {
10388
- case 0:
10389
- // Make sure to hide the splashscreen, before open the modal
10390
- if (!peer && this.splashScreen)
10391
- this.splashScreen.hide();
10392
- _a.label = 1;
10393
- case 1:
10394
- if (!!peer) return [3 /*break*/, 3];
10395
- console.debug('[network] No peer defined. Asking user to choose a peer.');
10396
- return [4 /*yield*/, this.showSelectPeerModal({ allowSelectDownPeer: false })];
10397
- case 2:
10398
- peer = _a.sent();
10399
- return [3 /*break*/, 1];
10400
- case 3:
10401
- this._peer = peer;
10402
- this._started = true;
10403
- this._startPromise = undefined;
10404
- this.onStart.next(peer);
10405
- console.info("[platform] Starting network [OK] {online: " + this.online + "}");
10406
- return [2 /*return*/];
10407
- }
10408
- });
10409
- }); })
10410
- .catch(function (err) {
10411
- console.error(err && err.message || err, err);
10412
- _this._started = false;
10413
- _this._startPromise = undefined;
10414
- })
10415
- // Wait settings starts, then save peer in settings
10416
- .then(function () { return _this.settings.ready(); })
10417
- .then(function () { return _this.settings.apply({ peerUrl: _this._peer.url }); })
10418
- .then(function () { return _this.onDeviceConnectionChanged(_this.network && _this.network.type || 'unknown'); })
10419
- // Start the refresh timer
10420
- .then(function () { return _this.startRefreshTimer(); });
10421
- // Listen for device network changes
10422
- if (this.network) {
10423
- this._subscription.add(this.network.onDisconnect().subscribe(function () { return _this.onDeviceConnectionChanged('none'); }));
10424
- this._subscription.add(this.network.onConnect().subscribe(function () { return _this.onDeviceConnectionChanged(_this.network.type); }));
10425
- }
10426
- return [2 /*return*/, this._startPromise];
10427
- });
10428
- });
10429
- };
10430
- NetworkService.prototype.ready = function () {
10431
- if (this._started)
10432
- return Promise.resolve();
10433
- return this.start();
10434
- };
10435
- NetworkService.prototype.stop = function () {
10436
- return __awaiter(this, void 0, void 0, function () {
10437
- return __generator(this, function (_a) {
10438
- this.resetData();
10439
- this._started = false;
10440
- this._startPromise = undefined;
10441
- // Stop timer if cannot refresh anymore
10442
- if (this._timerRefreshCondition() === false) {
10443
- this.stopRefreshTimer();
10444
- }
10445
- this._subscription.unsubscribe();
10446
- this._subscription = new rxjs.Subscription();
10447
- return [2 /*return*/];
10448
- });
10449
- });
10450
- };
10451
- NetworkService.prototype.restart = function (peer) {
10427
+ NetworkService.prototype.tryOnline = function (opts) {
10452
10428
  return __awaiter(this, void 0, void 0, function () {
10453
- var _this = this;
10454
- return __generator(this, function (_a) {
10455
- switch (_a.label) {
10429
+ var now, showLoadingToast, loadingToast, settings, peer, peerInfo, peerAliveAndCompatible, _b, err_1, online;
10430
+ return __generator(this, function (_c) {
10431
+ switch (_c.label) {
10456
10432
  case 0:
10457
- if (!this._started) return [3 /*break*/, 2];
10458
- return [4 /*yield*/, this.stop()
10459
- .then(function () { return _this.start(peer); })];
10433
+ // If offline mode not forced, and device says there is no connection: skip
10434
+ if (!this._forceOffline || this._deviceConnectionType === 'none')
10435
+ return [2 /*return*/, false];
10436
+ now = Date.now();
10437
+ showLoadingToast = !opts || opts.showLoadingToast !== false;
10438
+ if (!showLoadingToast) return [3 /*break*/, 2];
10439
+ return [4 /*yield*/, this.showToast({ message: 'NETWORK.INFO.RETRY_TO_CONNECT',
10440
+ duration: 10000, onWillPresent: function (t) { return loadingToast = t; } })];
10460
10441
  case 1:
10461
- _a.sent();
10462
- return [3 /*break*/, 4];
10463
- case 2: return [4 /*yield*/, this.start(peer)];
10464
- case 3:
10465
- _a.sent();
10466
- _a.label = 4;
10467
- case 4: return [2 /*return*/];
10468
- }
10469
- });
10470
- });
10471
- };
10472
- NetworkService.prototype.tryOnline = function (opts) {
10473
- return __awaiter(this, void 0, void 0, function () {
10474
- var now, showLoadingToast, loadingToast, settings, peer, peerInfo, peerAliveAndCompatible, _a, err_1, online;
10475
- return __generator(this, function (_b) {
10476
- switch (_b.label) {
10477
- case 0:
10478
- // If offline mode not forced, and device says there is no connection: skip
10479
- if (!this._forceOffline || this._deviceConnectionType === 'none')
10480
- return [2 /*return*/, false];
10481
- now = Date.now();
10482
- showLoadingToast = !opts || opts.showLoadingToast !== false;
10483
- if (!showLoadingToast) return [3 /*break*/, 2];
10484
- return [4 /*yield*/, this.showToast({ message: 'NETWORK.INFO.RETRY_TO_CONNECT',
10485
- duration: 10000, onWillPresent: function (t) { return loadingToast = t; } })];
10486
- case 1:
10487
- _b.sent();
10488
- _b.label = 2;
10442
+ _c.sent();
10443
+ _c.label = 2;
10489
10444
  case 2:
10490
- _b.trys.push([2, 10, , 11]);
10445
+ _c.trys.push([2, 10, , 11]);
10491
10446
  console.info('[network] Checking connection to pod...');
10492
10447
  return [4 /*yield*/, this.settings.ready()];
10493
10448
  case 3:
10494
- settings = _b.sent();
10449
+ settings = _c.sent();
10495
10450
  if (!settings.peerUrl)
10496
10451
  return [2 /*return*/, false]; // No peer define. Skip
10497
10452
  peer = exports.Peer.parseUrl(settings.peerUrl);
10498
10453
  return [4 /*yield*/, this.checkPeerAlive(peer)];
10499
10454
  case 4:
10500
- peerInfo = _b.sent();
10501
- _a = peerInfo;
10502
- if (!_a) return [3 /*break*/, 6];
10455
+ peerInfo = _c.sent();
10456
+ _b = peerInfo;
10457
+ if (!_b) return [3 /*break*/, 6];
10503
10458
  return [4 /*yield*/, this.checkPeerCompatible(peerInfo)];
10504
10459
  case 5:
10505
- _a = (_b.sent());
10506
- _b.label = 6;
10460
+ _b = (_c.sent());
10461
+ _c.label = 6;
10507
10462
  case 6:
10508
- peerAliveAndCompatible = _a;
10463
+ peerAliveAndCompatible = _b;
10509
10464
  if (!peerAliveAndCompatible) return [3 /*break*/, 9];
10510
10465
  // Disable the offline mode
10511
10466
  this.setForceOffline(false);
10512
10467
  // Restart
10513
- return [4 /*yield*/, this.restart(peer)];
10468
+ this._startingPeer = peer;
10469
+ return [4 /*yield*/, this.restart()];
10514
10470
  case 7:
10515
- // Restart
10516
- _b.sent();
10471
+ _c.sent();
10517
10472
  // Wait a promise, before recheck
10518
10473
  return [4 /*yield*/, this.emit('beforeTryOnlineFinish', this.online)];
10519
10474
  case 8:
10520
10475
  // Wait a promise, before recheck
10521
- _b.sent();
10522
- _b.label = 9;
10476
+ _c.sent();
10477
+ _c.label = 9;
10523
10478
  case 9: return [3 /*break*/, 11];
10524
10479
  case 10:
10525
- err_1 = _b.sent();
10480
+ err_1 = _c.sent();
10526
10481
  console.error(err_1 && err_1.message || err_1);
10527
10482
  return [3 /*break*/, 11];
10528
10483
  case 11:
10529
10484
  if (!showLoadingToast) return [3 /*break*/, 14];
10530
10485
  return [4 /*yield*/, sleep(2000 - (Date.now() - now))];
10531
10486
  case 12:
10532
- _b.sent();
10487
+ _c.sent();
10533
10488
  if (!loadingToast) return [3 /*break*/, 14];
10534
10489
  return [4 /*yield*/, loadingToast.dismiss()];
10535
10490
  case 13:
10536
- _b.sent();
10537
- _b.label = 14;
10491
+ _c.sent();
10492
+ _c.label = 14;
10538
10493
  case 14:
10539
10494
  online = this.online;
10540
10495
  // Display a toast to user
@@ -10548,7 +10503,7 @@
10548
10503
  // Display toast (without await, because not need to wait toast close event)
10549
10504
  return [2 /*return*/, this.showOfflineToast({ showRetryButton: false })];
10550
10505
  }
10551
- return [2 /*return*/, this._started && online];
10506
+ return [2 /*return*/, this.started && online];
10552
10507
  }
10553
10508
  });
10554
10509
  });
@@ -10556,8 +10511,8 @@
10556
10511
  NetworkService.prototype.showOfflineToast = function (opts) {
10557
10512
  return __awaiter(this, void 0, void 0, function () {
10558
10513
  var toastResult, online;
10559
- return __generator(this, function (_a) {
10560
- switch (_a.label) {
10514
+ return __generator(this, function (_b) {
10515
+ switch (_b.label) {
10561
10516
  case 0:
10562
10517
  if (this.online)
10563
10518
  return [2 /*return*/]; // Skip if online
@@ -10576,7 +10531,7 @@
10576
10531
  ]
10577
10532
  })];
10578
10533
  case 1:
10579
- toastResult = _a.sent();
10534
+ toastResult = _b.sent();
10580
10535
  // User don't click reconnect: return
10581
10536
  if (!toastResult || toastResult.role !== 'refresh')
10582
10537
  return [2 /*return*/, false];
@@ -10589,7 +10544,7 @@
10589
10544
  showLoadingToast: toBoolean(opts && opts.showRetryLoadingToast, true)
10590
10545
  })];
10591
10546
  case 2:
10592
- online = _a.sent();
10547
+ online = _b.sent();
10593
10548
  if (online) {
10594
10549
  // Call success callback (async)
10595
10550
  if (opts && opts.onRetrySuccess) {
@@ -10598,7 +10553,7 @@
10598
10553
  return [2 /*return*/, true];
10599
10554
  }
10600
10555
  opts = Object.assign(Object.assign({}, opts), { showRetryButton: false, showCloseButton: true });
10601
- _a.label = 3;
10556
+ _b.label = 3;
10602
10557
  case 3:
10603
10558
  // Simple toast, without 'await', because not need to wait toast's dismiss
10604
10559
  this.showToast(Object.assign({ message: 'ERROR.NETWORK_REQUIRED', type: 'error' }, opts));
@@ -10607,97 +10562,6 @@
10607
10562
  });
10608
10563
  });
10609
10564
  };
10610
- /**
10611
- * Try to restore peer from the local storage
10612
- */
10613
- NetworkService.prototype.restoreLocally = function () {
10614
- return __awaiter(this, void 0, void 0, function () {
10615
- var settingsStr, settings, location, hostname, detectedPeer;
10616
- return __generator(this, function (_a) {
10617
- switch (_a.label) {
10618
- case 0: return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
10619
- case 1:
10620
- settingsStr = _a.sent();
10621
- settings = settingsStr && JSON.parse(settingsStr) || undefined;
10622
- if (settings && settings.peerUrl) {
10623
- console.debug("[network] Use peer {" + settings.peerUrl + "} (found in the local storage)");
10624
- return [2 /*return*/, exports.Peer.parseUrl(settings.peerUrl)];
10625
- }
10626
- // Else, use default peer in env, if exists
10627
- if (this.environment.defaultPeer) {
10628
- return [2 /*return*/, exports.Peer.fromObject(this.environment.defaultPeer)];
10629
- }
10630
- location = this._document && this._document.location;
10631
- if (!(location && location.protocol && location.protocol.startsWith('http'))) return [3 /*break*/, 3];
10632
- hostname = this._document.location.host;
10633
- detectedPeer = exports.Peer.parseUrl("" + this._document.location.protocol + hostname + this.environment.baseUrl);
10634
- return [4 /*yield*/, this.checkPeerAlive(detectedPeer)];
10635
- case 2:
10636
- if (_a.sent()) {
10637
- return [2 /*return*/, detectedPeer];
10638
- }
10639
- _a.label = 3;
10640
- case 3: return [2 /*return*/, undefined];
10641
- }
10642
- });
10643
- });
10644
- };
10645
- /**
10646
- * Refresh network state, using a ping to pod
10647
- */
10648
- NetworkService.prototype.refreshPeerState = function (opts) {
10649
- return __awaiter(this, void 0, void 0, function () {
10650
- return __generator(this, function (_a) {
10651
- return [2 /*return*/];
10652
- });
10653
- });
10654
- };
10655
- /**
10656
- * Stop to network state
10657
- *
10658
- * @protected
10659
- */
10660
- NetworkService.prototype.stopRefreshTimer = function () {
10661
- if (this._timerSubscription) {
10662
- this._timerSubscription.unsubscribe();
10663
- this._timerSubscription = undefined;
10664
- }
10665
- };
10666
- /**
10667
- * Refresh the network state
10668
- *
10669
- * @protected
10670
- */
10671
- NetworkService.prototype.startRefreshTimer = function () {
10672
- var _this = this;
10673
- if (this._timerSubscription)
10674
- return; // Already running: skip
10675
- console.info("[network] Starting refresh timer, every " + this._timerRefreshPeriod + "ms...");
10676
- var lastInfo;
10677
- this._timerSubscription = rxjs.timer(this._timerRefreshPeriod, this._timerRefreshPeriod)
10678
- .pipe(
10679
- // Skip some timer event (see constructor)
10680
- operators.filter(this._timerRefreshCondition),
10681
- // Checkin if peer alive
10682
- operators.tap(function () { return console.debug('[network] Checking connection to pod...'); }), operators.mergeMap(function () { return _this.checkPeerAlive(_this.peer); }),
10683
- // Filter to keep only changes
10684
- operators.filter(function (info) { return !!info !== !!lastInfo; }), operators.tap(function (info) { return lastInfo = info; }),
10685
- // Check compatibility
10686
- operators.mergeMap(function (info) { return _this.checkPeerCompatible(info, { showToast: true }); }))
10687
- .subscribe(function (alive) {
10688
- if (alive && _this.offline) {
10689
- _this.setForceOffline(false);
10690
- // Restart the service (to force re auth)
10691
- _this.restart();
10692
- }
10693
- else if (!alive && _this.online) {
10694
- _this.setForceOffline(true);
10695
- // Stop the service
10696
- _this.stop();
10697
- }
10698
- });
10699
- this._timerSubscription.add(function () { return console.debug('[network] Refresh timer stopped'); });
10700
- };
10701
10565
  /**
10702
10566
  * Check if the peer is alive
10703
10567
  *
@@ -10706,24 +10570,24 @@
10706
10570
  NetworkService.prototype.checkPeerAlive = function (peer, opts) {
10707
10571
  return __awaiter(this, void 0, void 0, function () {
10708
10572
  var settings, err_2;
10709
- return __generator(this, function (_a) {
10710
- switch (_a.label) {
10573
+ return __generator(this, function (_b) {
10574
+ switch (_b.label) {
10711
10575
  case 0:
10712
10576
  peer = peer || this.peer;
10713
10577
  if (!!peer) return [3 /*break*/, 2];
10714
10578
  return [4 /*yield*/, this.settings.ready()];
10715
10579
  case 1:
10716
- settings = _a.sent();
10580
+ settings = _b.sent();
10717
10581
  if (!settings.peerUrl)
10718
10582
  return [2 /*return*/, undefined]; // No peer define. Skip
10719
10583
  peer = exports.Peer.parseUrl(settings.peerUrl);
10720
- _a.label = 2;
10584
+ _b.label = 2;
10721
10585
  case 2:
10722
- _a.trys.push([2, 4, , 5]);
10586
+ _b.trys.push([2, 4, , 5]);
10723
10587
  return [4 /*yield*/, this.getNodeInfo(peer)];
10724
- case 3: return [2 /*return*/, _a.sent()];
10588
+ case 3: return [2 /*return*/, _b.sent()];
10725
10589
  case 4:
10726
- err_2 = _a.sent();
10590
+ err_2 = _b.sent();
10727
10591
  console.debug('[network] Cannot get /api/node/info from peer: ' + (err_2 && err_2.message || err_2), err_2);
10728
10592
  return [2 /*return*/, undefined];
10729
10593
  case 5: return [2 /*return*/];
@@ -10734,8 +10598,8 @@
10734
10598
  NetworkService.prototype.checkPeerCompatible = function (peerInfo, opts) {
10735
10599
  return __awaiter(this, void 0, void 0, function () {
10736
10600
  var isCompatible;
10737
- return __generator(this, function (_a) {
10738
- switch (_a.label) {
10601
+ return __generator(this, function (_b) {
10602
+ switch (_b.label) {
10739
10603
  case 0:
10740
10604
  if (!this.environment.peerMinVersion)
10741
10605
  return [2 /*return*/, true]; // Skip compatibility check
@@ -10750,8 +10614,8 @@
10750
10614
  showCloseButton: true
10751
10615
  })];
10752
10616
  case 1:
10753
- _a.sent();
10754
- _a.label = 2;
10617
+ _b.sent();
10618
+ _b.label = 2;
10755
10619
  case 2: return [2 /*return*/, isCompatible];
10756
10620
  }
10757
10621
  });
@@ -10791,8 +10655,8 @@
10791
10655
  return __awaiter(this, void 0, void 0, function () {
10792
10656
  var $onRefresh, peers$, modal, data;
10793
10657
  var _this = this;
10794
- return __generator(this, function (_a) {
10795
- switch (_a.label) {
10658
+ return __generator(this, function (_b) {
10659
+ switch (_b.label) {
10796
10660
  case 0:
10797
10661
  opts = opts || {};
10798
10662
  $onRefresh = new i0.EventEmitter();
@@ -10809,14 +10673,14 @@
10809
10673
  showBackdrop: true
10810
10674
  })];
10811
10675
  case 1:
10812
- modal = _a.sent();
10676
+ modal = _b.sent();
10813
10677
  return [4 /*yield*/, modal.present()];
10814
10678
  case 2:
10815
- _a.sent();
10679
+ _b.sent();
10816
10680
  $onRefresh.emit();
10817
10681
  return [4 /*yield*/, modal.onWillDismiss()];
10818
10682
  case 3:
10819
- data = (_a.sent()).data;
10683
+ data = (_b.sent()).data;
10820
10684
  $onRefresh.complete();
10821
10685
  return [2 /*return*/, data && data || undefined];
10822
10686
  }
@@ -10827,7 +10691,7 @@
10827
10691
  return __awaiter(this, void 0, void 0, function () {
10828
10692
  var now;
10829
10693
  var _this = this;
10830
- return __generator(this, function (_a) {
10694
+ return __generator(this, function (_b) {
10831
10695
  now = this._debug && Date.now();
10832
10696
  console.info('[network] Clearing all caches...');
10833
10697
  return [2 /*return*/, this.cache.clearAll()
@@ -10846,10 +10710,164 @@
10846
10710
  });
10847
10711
  });
10848
10712
  };
10713
+ /* -- protected functions -- */
10714
+ NetworkService.prototype.ngOnStart = function () {
10715
+ return __awaiter(this, void 0, void 0, function () {
10716
+ var peer, _b;
10717
+ return __generator(this, function (_c) {
10718
+ switch (_c.label) {
10719
+ case 0:
10720
+ console.info('[network] Starting network...', this._startingPeer);
10721
+ _b = this._startingPeer;
10722
+ if (_b) return [3 /*break*/, 2];
10723
+ return [4 /*yield*/, this.restoreLocally()];
10724
+ case 1:
10725
+ _b = (_c.sent());
10726
+ _c.label = 2;
10727
+ case 2:
10728
+ peer = _b;
10729
+ // Make sure to hide the splashscreen, before open the modal
10730
+ if (!peer && this.splashScreen)
10731
+ this.splashScreen.hide();
10732
+ _c.label = 3;
10733
+ case 3:
10734
+ if (!!peer) return [3 /*break*/, 5];
10735
+ console.debug('[network] No peer defined. Asking user to choose a peer.');
10736
+ return [4 /*yield*/, this.showSelectPeerModal({ allowSelectDownPeer: false })];
10737
+ case 4:
10738
+ peer = _c.sent();
10739
+ return [3 /*break*/, 3];
10740
+ case 5:
10741
+ console.info("[network] Starting service [OK] {peer: '" + peer.url + "', online: " + this.online + "}");
10742
+ return [2 /*return*/, peer];
10743
+ }
10744
+ });
10745
+ });
10746
+ };
10747
+ NetworkService.prototype.ngOnAfterStart = function () {
10748
+ var _a;
10749
+ return __awaiter(this, void 0, void 0, function () {
10750
+ var _this = this;
10751
+ return __generator(this, function (_b) {
10752
+ switch (_b.label) {
10753
+ case 0:
10754
+ // Wait settings starts, then save peer in settings
10755
+ return [4 /*yield*/, this.settings.apply({ peerUrl: this._data.url })];
10756
+ case 1:
10757
+ // Wait settings starts, then save peer in settings
10758
+ _b.sent();
10759
+ this.onDeviceConnectionChanged(((_a = this.network) === null || _a === void 0 ? void 0 : _a.type) || 'unknown');
10760
+ // Start the refresh timer
10761
+ this.startRefreshTimer();
10762
+ // Listen for device network changes
10763
+ if (this.network) {
10764
+ this._subscription.add(this.network.onDisconnect().subscribe(function () { return _this.onDeviceConnectionChanged('none'); }));
10765
+ this._subscription.add(this.network.onConnect().subscribe(function () { return _this.onDeviceConnectionChanged(_this.network.type); }));
10766
+ }
10767
+ return [2 /*return*/];
10768
+ }
10769
+ });
10770
+ });
10771
+ };
10772
+ NetworkService.prototype.ngOnStop = function () {
10773
+ return __awaiter(this, void 0, void 0, function () {
10774
+ return __generator(this, function (_b) {
10775
+ this.resetData();
10776
+ // Stop timer if cannot refresh anymore
10777
+ if (this._timerRefreshCondition() === false) {
10778
+ this.stopRefreshTimer();
10779
+ }
10780
+ this._subscription.unsubscribe();
10781
+ this._subscription = new rxjs.Subscription();
10782
+ return [2 /*return*/];
10783
+ });
10784
+ });
10785
+ };
10786
+ /**
10787
+ * Try to restore peer from the local storage
10788
+ */
10789
+ NetworkService.prototype.restoreLocally = function () {
10790
+ return __awaiter(this, void 0, void 0, function () {
10791
+ var settingsStr, settings, location, hostname, detectedPeer;
10792
+ return __generator(this, function (_b) {
10793
+ switch (_b.label) {
10794
+ case 0: return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
10795
+ case 1:
10796
+ settingsStr = _b.sent();
10797
+ settings = settingsStr && JSON.parse(settingsStr) || undefined;
10798
+ if (settings && settings.peerUrl) {
10799
+ console.debug("[network] Use peer {" + settings.peerUrl + "} (found in the local storage)");
10800
+ return [2 /*return*/, exports.Peer.parseUrl(settings.peerUrl)];
10801
+ }
10802
+ // Else, use default peer in env, if exists
10803
+ if (this.environment.defaultPeer) {
10804
+ return [2 /*return*/, exports.Peer.fromObject(this.environment.defaultPeer)];
10805
+ }
10806
+ location = this._document && this._document.location;
10807
+ if (!(location && location.protocol && location.protocol.startsWith('http'))) return [3 /*break*/, 3];
10808
+ hostname = this._document.location.host;
10809
+ detectedPeer = exports.Peer.parseUrl("" + this._document.location.protocol + hostname + this.environment.baseUrl);
10810
+ return [4 /*yield*/, this.checkPeerAlive(detectedPeer)];
10811
+ case 2:
10812
+ if (_b.sent()) {
10813
+ return [2 /*return*/, detectedPeer];
10814
+ }
10815
+ _b.label = 3;
10816
+ case 3: return [2 /*return*/, undefined];
10817
+ }
10818
+ });
10819
+ });
10820
+ };
10821
+ /**
10822
+ * Stop to network state
10823
+ *
10824
+ * @protected
10825
+ */
10826
+ NetworkService.prototype.stopRefreshTimer = function () {
10827
+ if (this._timerSubscription) {
10828
+ this._timerSubscription.unsubscribe();
10829
+ this._timerSubscription = undefined;
10830
+ }
10831
+ };
10832
+ /**
10833
+ * Refresh the network state
10834
+ *
10835
+ * @protected
10836
+ */
10837
+ NetworkService.prototype.startRefreshTimer = function () {
10838
+ var _this = this;
10839
+ if (this._timerSubscription)
10840
+ return; // Already running: skip
10841
+ console.info("[network] Starting refresh timer, every " + this._timerRefreshPeriod + "ms...");
10842
+ var lastInfo;
10843
+ this._timerSubscription = rxjs.timer(this._timerRefreshPeriod, this._timerRefreshPeriod)
10844
+ .pipe(
10845
+ // Skip some timer event (see constructor)
10846
+ operators.filter(this._timerRefreshCondition),
10847
+ // Checkin if peer alive
10848
+ operators.tap(function () { return console.debug('[network] Checking connection to pod...'); }), operators.mergeMap(function () { return _this.checkPeerAlive(_this.peer); }),
10849
+ // Filter to keep only changes
10850
+ operators.filter(function (info) { return !!info !== !!lastInfo; }), operators.tap(function (info) { return lastInfo = info; }),
10851
+ // Check compatibility
10852
+ operators.mergeMap(function (info) { return _this.checkPeerCompatible(info, { showToast: true }); }))
10853
+ .subscribe(function (alive) {
10854
+ if (alive && _this.offline) {
10855
+ _this.setForceOffline(false);
10856
+ // Restart the service (to force re auth)
10857
+ _this.restart();
10858
+ }
10859
+ else if (!alive && _this.online) {
10860
+ _this.setForceOffline(true);
10861
+ // Stop the service
10862
+ _this.stop();
10863
+ }
10864
+ });
10865
+ this._timerSubscription.add(function () { return console.debug('[network] Refresh timer stopped'); });
10866
+ };
10849
10867
  NetworkService.prototype.get = function (path, opts) {
10850
10868
  return __awaiter(this, void 0, void 0, function () {
10851
10869
  var uri, peerUrl;
10852
- return __generator(this, function (_a) {
10870
+ return __generator(this, function (_b) {
10853
10871
  uri = path;
10854
10872
  // If path is not an URI: prepend with peer URL
10855
10873
  if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
@@ -10900,7 +10918,7 @@
10900
10918
  }
10901
10919
  };
10902
10920
  NetworkService.prototype.resetData = function () {
10903
- this._peer = null;
10921
+ this._data = null;
10904
10922
  };
10905
10923
  /**
10906
10924
  * Get default peers, from environment
@@ -10908,7 +10926,7 @@
10908
10926
  NetworkService.prototype.getDefaultPeers = function () {
10909
10927
  return __awaiter(this, void 0, void 0, function () {
10910
10928
  var peers;
10911
- return __generator(this, function (_a) {
10929
+ return __generator(this, function (_b) {
10912
10930
  peers = (this.environment.defaultPeers || []).map(exports.Peer.fromObject);
10913
10931
  return [2 /*return*/, Promise.resolve(peers)];
10914
10932
  });
@@ -10932,7 +10950,7 @@
10932
10950
  NetworkService.prototype.emit = function (name, data) {
10933
10951
  return __awaiter(this, void 0, void 0, function () {
10934
10952
  var hooks;
10935
- return __generator(this, function (_a) {
10953
+ return __generator(this, function (_b) {
10936
10954
  hooks = this._listeners[name];
10937
10955
  if (isNotEmptyArray(hooks)) {
10938
10956
  console.info("[network-service] Trigger " + name + " hook: Executing " + hooks.length + " callbacks...");
@@ -10948,7 +10966,7 @@
10948
10966
  });
10949
10967
  };
10950
10968
  return NetworkService;
10951
- }());
10969
+ }(StartableService));
10952
10970
  NetworkService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function NetworkService_Factory() { return new NetworkService(i0__namespace.ɵɵinject(i1__namespace$3.DOCUMENT), i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(i1__namespace$4.ModalController), i0__namespace.ɵɵinject(CryptoService), i0__namespace.ɵɵinject(i3__namespace$1.Storage), i0__namespace.ɵɵinject(LocalSettingsService), i0__namespace.ɵɵinject(i6__namespace.CacheService), i0__namespace.ɵɵinject(i2__namespace$2.HttpClient), i0__namespace.ɵɵinject(ENVIRONMENT), i0__namespace.ɵɵinject(i9__namespace.Network, 8), i0__namespace.ɵɵinject(i10__namespace.SplashScreen, 8), i0__namespace.ɵɵinject(i1__namespace$1.TranslateService, 8), i0__namespace.ɵɵinject(i1__namespace$4.ToastController, 8)); }, token: NetworkService, providedIn: "root" });
10953
10971
  NetworkService.decorators = [
10954
10972
  { type: i0.Injectable, args: [{ providedIn: 'root' },] }
@@ -11551,31 +11569,31 @@
11551
11569
  }());
11552
11570
 
11553
11571
  var APP_LOCAL_STORAGE_TYPE_POLICIES = new i0.InjectionToken('localStorageTypePolicies');
11554
- var EntitiesStorage = /** @class */ (function () {
11572
+ ;
11573
+ var EntitiesStorage = /** @class */ (function (_super) {
11574
+ __extends(EntitiesStorage, _super);
11555
11575
  function EntitiesStorage(platform, progressBarService, storage, environment, typePolicies) {
11556
- this.platform = platform;
11557
- this.progressBarService = progressBarService;
11558
- this.storage = storage;
11559
- this.environment = environment;
11560
- this._started = false;
11561
- this._subscription = new rxjs.Subscription();
11562
- this._stores = {};
11563
- this._$save = new i0.EventEmitter(true);
11564
- this._dirty = false;
11565
- this._saving = false;
11566
- this.onStart = new rxjs.Subject();
11567
- this._typePolicies = typePolicies || {};
11576
+ var _this = _super.call(this, platform) || this;
11577
+ _this.platform = platform;
11578
+ _this.progressBarService = progressBarService;
11579
+ _this.storage = storage;
11580
+ _this.environment = environment;
11581
+ _this._subscription = new rxjs.Subscription();
11582
+ _this._$save = new i0.EventEmitter(true);
11583
+ _this._dirty = false;
11584
+ _this._saving = false;
11585
+ _this._typePolicies = typePolicies || {};
11586
+ _this._saveTimerPeriod = environment.storageSavePeriodMs || 10000 /* = 10s */;
11587
+ _this._data = {};
11568
11588
  // For DEV only
11569
- this._debug = !environment.production;
11570
- if (this._debug)
11589
+ _this._debug = !environment.production;
11590
+ if (_this._debug)
11571
11591
  console.debug('[entities-storage] Creating service');
11592
+ return _this;
11572
11593
  }
11573
11594
  Object.defineProperty(EntitiesStorage.prototype, "dirty", {
11574
11595
  get: function () {
11575
- return this._dirty || Object.entries(this._stores).find(function (_a) {
11576
- var _b = __read(_a, 2), _ = _b[0], store = _b[1];
11577
- return store.dirty;
11578
- }) !== undefined;
11596
+ return this._dirty || Object.values(this._data).some(function (store) { return store.dirty; });
11579
11597
  },
11580
11598
  enumerable: false,
11581
11599
  configurable: true
@@ -11583,7 +11601,7 @@
11583
11601
  EntitiesStorage.prototype.watchAll = function (entityName, variables, opts) {
11584
11602
  var _this = this;
11585
11603
  // Make sure store is ready
11586
- if (!this._started) {
11604
+ if (!this.started) {
11587
11605
  return rxjs.defer(function () { return _this.ready(); })
11588
11606
  .pipe(operators.switchMap(function () { return _this.watchAll(entityName, variables, opts); })); // Loop
11589
11607
  }
@@ -11600,7 +11618,7 @@
11600
11618
  return __generator(this, function (_a) {
11601
11619
  switch (_a.label) {
11602
11620
  case 0:
11603
- if (!!this._started) return [3 /*break*/, 2];
11621
+ if (!!this.started) return [3 /*break*/, 2];
11604
11622
  return [4 /*yield*/, this.ready()];
11605
11623
  case 1:
11606
11624
  _a.sent();
@@ -11703,9 +11721,12 @@
11703
11721
  case 0:
11704
11722
  if (!entity)
11705
11723
  return [2 /*return*/]; // skip
11724
+ if (!!this.started) return [3 /*break*/, 2];
11706
11725
  return [4 /*yield*/, this.ready()];
11707
11726
  case 1:
11708
11727
  _a.sent();
11728
+ _a.label = 2;
11729
+ case 2:
11709
11730
  try {
11710
11731
  this.progressBarService.increase();
11711
11732
  this._dirty = true;
@@ -11732,9 +11753,12 @@
11732
11753
  case 0:
11733
11754
  if (isEmptyArray(entities) && (!opts || opts.reset !== true))
11734
11755
  return [2 /*return*/, entities]; // Skip (nothing to save)
11756
+ if (!!this.started) return [3 /*break*/, 2];
11735
11757
  return [4 /*yield*/, this.ready()];
11736
11758
  case 1:
11737
11759
  _a.sent();
11760
+ _a.label = 2;
11761
+ case 2:
11738
11762
  try {
11739
11763
  this.progressBarService.increase();
11740
11764
  this._dirty = true;
@@ -11756,10 +11780,12 @@
11756
11780
  case 0:
11757
11781
  if (!entity)
11758
11782
  return [2 /*return*/, undefined]; // skip
11783
+ if (!!this.started) return [3 /*break*/, 2];
11759
11784
  return [4 /*yield*/, this.ready()];
11760
11785
  case 1:
11761
11786
  _a.sent();
11762
- return [2 /*return*/, this.deleteById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
11787
+ _a.label = 2;
11788
+ case 2: return [2 /*return*/, this.deleteById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
11763
11789
  }
11764
11790
  });
11765
11791
  });
@@ -11769,9 +11795,13 @@
11769
11795
  var entityStore, deletedEntity;
11770
11796
  return __generator(this, function (_a) {
11771
11797
  switch (_a.label) {
11772
- case 0: return [4 /*yield*/, this.ready()];
11798
+ case 0:
11799
+ if (!!this.started) return [3 /*break*/, 2];
11800
+ return [4 /*yield*/, this.ready()];
11773
11801
  case 1:
11774
11802
  _a.sent();
11803
+ _a.label = 2;
11804
+ case 2:
11775
11805
  if (!opts || isNilOrBlank(opts.entityName))
11776
11806
  throw new Error('Missing argument \'opts\' or \'entityName\'');
11777
11807
  //if (id >= 0) throw new Error('Invalid id a local entity (not a negative number): ' + id);
@@ -11803,9 +11833,13 @@
11803
11833
  var entityStore, deletedEntities;
11804
11834
  return __generator(this, function (_a) {
11805
11835
  switch (_a.label) {
11806
- case 0: return [4 /*yield*/, this.ready()];
11836
+ case 0:
11837
+ if (!!this.started) return [3 /*break*/, 2];
11838
+ return [4 /*yield*/, this.ready()];
11807
11839
  case 1:
11808
11840
  _a.sent();
11841
+ _a.label = 2;
11842
+ case 2:
11809
11843
  if (!opts || isNilOrBlank(opts.entityName))
11810
11844
  throw new Error('Missing argument \'opts\' or \'opts.entityName\'');
11811
11845
  try {
@@ -11838,10 +11872,12 @@
11838
11872
  case 0:
11839
11873
  if (!entity)
11840
11874
  return [2 /*return*/, undefined]; // skip
11875
+ if (!!this.started) return [3 /*break*/, 2];
11841
11876
  return [4 /*yield*/, this.ready()];
11842
11877
  case 1:
11843
11878
  _a.sent();
11844
- return [2 /*return*/, this.deleteFromTrashById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
11879
+ _a.label = 2;
11880
+ case 2: return [2 /*return*/, this.deleteFromTrashById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
11845
11881
  }
11846
11882
  });
11847
11883
  });
@@ -11868,9 +11904,12 @@
11868
11904
  case 0:
11869
11905
  if (!entity)
11870
11906
  return [2 /*return*/, undefined]; // skip
11907
+ if (!!this.started) return [3 /*break*/, 2];
11871
11908
  return [4 /*yield*/, this.ready()];
11872
11909
  case 1:
11873
11910
  _a.sent();
11911
+ _a.label = 2;
11912
+ case 2:
11874
11913
  entityName = opts && opts.entityName || this.detectEntityName(entity);
11875
11914
  entityStore = this.getEntityStore(entityName);
11876
11915
  if (entityStore)
@@ -11890,9 +11929,13 @@
11890
11929
  var entityStore, deletedEntities, trashName;
11891
11930
  return __generator(this, function (_a) {
11892
11931
  switch (_a.label) {
11893
- case 0: return [4 /*yield*/, this.ready()];
11932
+ case 0:
11933
+ if (!!this.started) return [3 /*break*/, 2];
11934
+ return [4 /*yield*/, this.ready()];
11894
11935
  case 1:
11895
11936
  _a.sent();
11937
+ _a.label = 2;
11938
+ case 2:
11896
11939
  if (!opts || isNilOrBlank(opts.entityName))
11897
11940
  throw new Error('Missing argument \'opts.entityName\'');
11898
11941
  entityStore = this.getEntityStore(opts.entityName, { create: false });
@@ -11924,9 +11967,12 @@
11924
11967
  case 0:
11925
11968
  if (!entity)
11926
11969
  return [2 /*return*/, undefined]; // skip
11970
+ if (!!this.started) return [3 /*break*/, 2];
11927
11971
  return [4 /*yield*/, this.ready()];
11928
11972
  case 1:
11929
11973
  _a.sent();
11974
+ _a.label = 2;
11975
+ case 2:
11930
11976
  entityName = opts && opts.entityName || this.detectEntityName(entity);
11931
11977
  trashName = EntitiesStorage.TRASH_PREFIX + entityName;
11932
11978
  this.getEntityStore(trashName).save(entity, opts);
@@ -11941,9 +11987,13 @@
11941
11987
  var trashName, entityStore;
11942
11988
  return __generator(this, function (_a) {
11943
11989
  switch (_a.label) {
11944
- case 0: return [4 /*yield*/, this.ready()];
11990
+ case 0:
11991
+ if (!!this.started) return [3 /*break*/, 2];
11992
+ return [4 /*yield*/, this.ready()];
11945
11993
  case 1:
11946
11994
  _a.sent();
11995
+ _a.label = 2;
11996
+ case 2:
11947
11997
  trashName = EntitiesStorage.TRASH_PREFIX + entityName;
11948
11998
  entityStore = this.getEntityStore(trashName, { create: false });
11949
11999
  if (!entityStore)
@@ -11962,79 +12012,58 @@
11962
12012
  }
11963
12013
  return Promise.resolve();
11964
12014
  };
11965
- EntitiesStorage.prototype.ready = function () {
11966
- if (this._started)
11967
- return Promise.resolve();
11968
- return this.start();
11969
- };
11970
- EntitiesStorage.prototype.start = function () {
11971
- var _this = this;
11972
- if (this._startPromise)
11973
- return this._startPromise;
11974
- if (this._started)
11975
- return Promise.resolve();
11976
- var now = Date.now();
11977
- console.info("[entities-storage] Starting entity storage...");
11978
- // Restore sequences
11979
- this._startPromise = this.restoreLocally()
11980
- .then(function () {
11981
- // Start a save timer
11982
- _this._subscription.add(rxjs.merge(_this._$save, rxjs.timer(2000, 10000))
11983
- .pipe(operators.throttleTime(10000))
11984
- .subscribe(function () { return _this.storeLocally(); }));
11985
- _this._started = true;
11986
- _this._startPromise = undefined;
11987
- console.info("[entities-storage] Starting [OK] in " + (Date.now() - now) + "ms");
11988
- // Emit event
11989
- _this.onStart.next();
11990
- });
11991
- return this._startPromise;
11992
- };
11993
- EntitiesStorage.prototype.stop = function () {
12015
+ EntitiesStorage.prototype.ngOnStart = function () {
11994
12016
  return __awaiter(this, void 0, void 0, function () {
12017
+ var now;
12018
+ var _this = this;
11995
12019
  return __generator(this, function (_a) {
11996
12020
  switch (_a.label) {
11997
12021
  case 0:
11998
- this._started = false;
11999
- this._subscription.unsubscribe();
12000
- this._subscription = new rxjs.Subscription();
12001
- if (!this.dirty) return [3 /*break*/, 2];
12002
- return [4 /*yield*/, this.storeLocally()];
12022
+ now = Date.now();
12023
+ console.info("[entities-storage] Starting entity storage...");
12024
+ // Restore sequences
12025
+ return [4 /*yield*/, this.restoreLocally()];
12003
12026
  case 1:
12027
+ // Restore sequences
12004
12028
  _a.sent();
12005
- _a.label = 2;
12006
- case 2: return [2 /*return*/];
12029
+ // Start a save timer
12030
+ this._subscription.add(rxjs.merge(this._$save, rxjs.timer(this._saveTimerPeriod, this._saveTimerPeriod))
12031
+ .pipe(
12032
+ // Avoid to many call (e.g. when $save AND timer are triggered
12033
+ operators.throttleTime(this._saveTimerPeriod))
12034
+ .subscribe(function () { return _this.storeLocally(); }));
12035
+ console.info("[entities-storage] Starting [OK] in " + (Date.now() - now) + "ms");
12036
+ return [2 /*return*/, this._data];
12007
12037
  }
12008
12038
  });
12009
12039
  });
12010
12040
  };
12011
- EntitiesStorage.prototype.restart = function () {
12041
+ EntitiesStorage.prototype.ngOnStop = function () {
12012
12042
  return __awaiter(this, void 0, void 0, function () {
12013
12043
  return __generator(this, function (_a) {
12014
12044
  switch (_a.label) {
12015
12045
  case 0:
12016
- if (!this._started) return [3 /*break*/, 2];
12017
- return [4 /*yield*/, this.stop()];
12046
+ this._subscription.unsubscribe();
12047
+ this._subscription = new rxjs.Subscription();
12048
+ if (!this.dirty) return [3 /*break*/, 2];
12049
+ return [4 /*yield*/, this.storeLocally()];
12018
12050
  case 1:
12019
12051
  _a.sent();
12020
12052
  _a.label = 2;
12021
- case 2: return [4 /*yield*/, this.start()];
12022
- case 3:
12023
- _a.sent();
12024
- return [2 /*return*/];
12053
+ case 2: return [2 /*return*/];
12025
12054
  }
12026
12055
  });
12027
12056
  });
12028
12057
  };
12029
12058
  /* -- protected methods -- */
12030
12059
  EntitiesStorage.prototype.getEntityStore = function (name, opts) {
12031
- var store = this._stores[name];
12060
+ var store = this._data[name];
12032
12061
  if (!store && (!opts || opts.create !== false)) {
12033
12062
  if (this._debug)
12034
12063
  console.debug("[entities-storage] Creating store " + name);
12035
12064
  var typePolicy = this._typePolicies[name];
12036
12065
  store = new EntityStore(name, this.storage, typePolicy);
12037
- this._stores[name] = store;
12066
+ this._data[name] = store;
12038
12067
  }
12039
12068
  return store;
12040
12069
  };
@@ -12091,11 +12120,11 @@
12091
12120
  this._saving = true;
12092
12121
  this._dirty = false;
12093
12122
  this.progressBarService.increase();
12094
- entityNames = this._stores && Object.keys(this._stores) || [];
12123
+ entityNames = this._data && Object.keys(this._data) || [];
12095
12124
  now = Date.now();
12096
12125
  if (this._debug)
12097
12126
  console.debug('[entities-storage] Persisting...');
12098
- return [2 /*return*/, rxjs.concat.apply(void 0, __spread(entityNames.map(function (entityName) { return rxjs.defer(function () {
12127
+ return [2 /*return*/, chainPromises(entityNames.map(function (entityName) { return function () {
12099
12128
  currentEntityName = entityName;
12100
12129
  var entityStore = _this.getEntityStore(entityName, { create: false });
12101
12130
  if (!entityStore) {
@@ -12109,17 +12138,20 @@
12109
12138
  entityNames.splice(entityNames.findIndex(function (e) { return e === entityName; }), 1);
12110
12139
  }
12111
12140
  });
12112
- }); }), [rxjs.defer(function () {
12113
- currentEntityName = undefined;
12114
- return isEmptyArray(entityNames) ?
12115
- _this.storage.remove(ENTITIES_STORAGE_KEY_PREFIX) :
12116
- _this.storage.set(ENTITIES_STORAGE_KEY_PREFIX, entityNames);
12117
- }), rxjs.defer(function () {
12118
- if (_this._debug)
12119
- console.debug("[entities-storage] Persisting [OK] " + entityNames.length + " stores saved in " + (Date.now() - now) + "ms...");
12120
- _this._saving = false;
12121
- _this.progressBarService.decrease();
12122
- })])).pipe(operators.catchError(function (err) {
12141
+ }; }))
12142
+ .then(function () {
12143
+ currentEntityName = undefined;
12144
+ return isEmptyArray(entityNames) ?
12145
+ _this.storage.remove(ENTITIES_STORAGE_KEY_PREFIX) :
12146
+ _this.storage.set(ENTITIES_STORAGE_KEY_PREFIX, entityNames);
12147
+ })
12148
+ .then(function () {
12149
+ if (_this._debug)
12150
+ console.debug("[entities-storage] Persisting [OK] " + entityNames.length + " stores saved in " + (Date.now() - now) + "ms...");
12151
+ _this._saving = false;
12152
+ _this.progressBarService.decrease();
12153
+ })
12154
+ .catch(function (err) {
12123
12155
  _this._saving = false;
12124
12156
  _this.progressBarService.decrease();
12125
12157
  if (currentEntityName) {
@@ -12128,13 +12160,13 @@
12128
12160
  else {
12129
12161
  console.error("[entities-storage] Error while persisting: " + (err && err.message || err), err);
12130
12162
  }
12131
- return err;
12132
- })).toPromise()];
12163
+ throw err;
12164
+ })];
12133
12165
  });
12134
12166
  });
12135
12167
  };
12136
12168
  return EntitiesStorage;
12137
- }());
12169
+ }(StartableService));
12138
12170
  EntitiesStorage.TRASH_PREFIX = 'Trash#';
12139
12171
  EntitiesStorage.REMOTE_PREFIX = 'Remote#';
12140
12172
  EntitiesStorage.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function EntitiesStorage_Factory() { return new EntitiesStorage(i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(ProgressBarService), i0__namespace.ɵɵinject(i3__namespace$1.Storage), i0__namespace.ɵɵinject(ENVIRONMENT), i0__namespace.ɵɵinject(APP_LOCAL_STORAGE_TYPE_POLICIES, 8)); }, token: EntitiesStorage, providedIn: "root" });
@@ -12145,7 +12177,7 @@
12145
12177
  { type: i1$5.Platform },
12146
12178
  { type: ProgressBarService },
12147
12179
  { type: i3$2.Storage },
12148
- { type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] },
12180
+ { type: Environment, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] },
12149
12181
  { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [APP_LOCAL_STORAGE_TYPE_POLICIES,] }] }
12150
12182
  ]; };
12151
12183
 
@@ -12670,29 +12702,28 @@
12670
12702
  }
12671
12703
 
12672
12704
  var APP_GRAPHQL_TYPE_POLICIES = new i0.InjectionToken('graphqlTypePolicies');
12673
- var GraphqlService = /** @class */ (function () {
12705
+ var GraphqlService = /** @class */ (function (_super) {
12706
+ __extends(GraphqlService, _super);
12674
12707
  function GraphqlService(platform, apollo, httpLink, network, storage, cryptoService, environment, typePolicies) {
12675
- var _this = this;
12676
- this.platform = platform;
12677
- this.apollo = apollo;
12678
- this.httpLink = httpLink;
12679
- this.network = network;
12680
- this.storage = storage;
12681
- this.cryptoService = cryptoService;
12682
- this.environment = environment;
12683
- this.typePolicies = typePolicies;
12684
- this._started = false;
12685
- this._subscription = new rxjs.Subscription();
12686
- this.connectionParams = {};
12687
- this.onNetworkError = new rxjs.Subject();
12688
- this.customErrors = {};
12689
- this.onStart = new rxjs.Subject();
12690
- this._debug = !environment.production;
12691
- this._defaultFetchPolicy = environment.apolloFetchPolicy;
12708
+ var _this = _super.call(this, network) || this;
12709
+ _this.platform = platform;
12710
+ _this.apollo = apollo;
12711
+ _this.httpLink = httpLink;
12712
+ _this.network = network;
12713
+ _this.storage = storage;
12714
+ _this.cryptoService = cryptoService;
12715
+ _this.environment = environment;
12716
+ _this.typePolicies = typePolicies;
12717
+ _this._subscription = new rxjs.Subscription();
12718
+ _this.connectionParams = {};
12719
+ _this.onNetworkError = new rxjs.Subject();
12720
+ _this.customErrors = {};
12721
+ _this._debug = !environment.production;
12722
+ _this._defaultFetchPolicy = environment.apolloFetchPolicy;
12692
12723
  // Restart if network restart
12693
- this.network.on('start', function () { return _this.restart(); });
12724
+ _this.network.on('start', function () { return _this.restart(); });
12694
12725
  // Clear cache
12695
- this.network.on('resetCache', function () { return __awaiter(_this, void 0, void 0, function () {
12726
+ _this.network.on('resetCache', function () { return __awaiter(_this, void 0, void 0, function () {
12696
12727
  return __generator(this, function (_a) {
12697
12728
  switch (_a.label) {
12698
12729
  case 0: return [4 /*yield*/, this.ready()];
@@ -12706,23 +12737,17 @@
12706
12737
  });
12707
12738
  }); });
12708
12739
  // Listen network status
12709
- this._networkStatusChanged$ = network.onNetworkStatusChanges
12740
+ _this._networkStatusChanged$ = network.onNetworkStatusChanges
12710
12741
  .pipe(operators.filter(isNotNil), operators.distinctUntilChanged());
12711
12742
  // When getting network error: try to ping peer, and toggle to offline
12712
- this.onNetworkError
12743
+ _this.onNetworkError
12713
12744
  .pipe(operators.throttleTime(300), operators.filter(function () { return _this.network.online; }), operators.mergeMap(function () { return _this.network.checkPeerAlive(); }), operators.filter(function (alive) { return !alive; }))
12714
12745
  .subscribe(function () { return _this.network.setForceOffline(true, { showToast: true }); });
12746
+ return _this;
12715
12747
  }
12716
- Object.defineProperty(GraphqlService.prototype, "started", {
12717
- get: function () {
12718
- return this._started;
12719
- },
12720
- enumerable: false,
12721
- configurable: true
12722
- });
12723
12748
  Object.defineProperty(GraphqlService.prototype, "client", {
12724
12749
  get: function () {
12725
- return this.apollo.client;
12750
+ return this._data;
12726
12751
  },
12727
12752
  enumerable: false,
12728
12753
  configurable: true
@@ -12741,34 +12766,6 @@
12741
12766
  enumerable: false,
12742
12767
  configurable: true
12743
12768
  });
12744
- GraphqlService.prototype.ready = function () {
12745
- if (this._started)
12746
- return Promise.resolve();
12747
- return this.start();
12748
- };
12749
- GraphqlService.prototype.start = function () {
12750
- var _this = this;
12751
- if (this._startPromise)
12752
- return this._startPromise;
12753
- if (this._started)
12754
- return Promise.resolve();
12755
- console.info('[graphql] Starting graphql...');
12756
- // Waiting for network service
12757
- this._startPromise = this.network.ready()
12758
- .then(function () { return _this.initApollo(); })
12759
- .then(function () {
12760
- _this._started = true;
12761
- _this._startPromise = undefined;
12762
- // Emit event
12763
- _this.onStart.next();
12764
- console.info('[graphql] Starting graphql [OK]');
12765
- })
12766
- .catch(function (err) {
12767
- console.error(err && err.message || err, err);
12768
- _this._startPromise = undefined;
12769
- });
12770
- return this._startPromise;
12771
- };
12772
12769
  GraphqlService.prototype.setAuthToken = function (token) {
12773
12770
  if (token) {
12774
12771
  console.debug('[graphql] Apply token authentication to headers');
@@ -12801,15 +12798,18 @@
12801
12798
  */
12802
12799
  GraphqlService.prototype.addResolver = function (resolvers) {
12803
12800
  return __awaiter(this, void 0, void 0, function () {
12804
- var client;
12805
- var _this = this;
12806
12801
  return __generator(this, function (_a) {
12807
- if (!this._started) {
12808
- this.onStart.toPromise().then(function () { return _this.addResolver(resolvers); }); // Loop
12802
+ switch (_a.label) {
12803
+ case 0:
12804
+ if (!!this.started) return [3 /*break*/, 2];
12805
+ return [4 /*yield*/, this.ready()];
12806
+ case 1:
12807
+ _a.sent();
12808
+ _a.label = 2;
12809
+ case 2:
12810
+ this.apollo.client.addResolvers(resolvers);
12811
+ return [2 /*return*/];
12809
12812
  }
12810
- client = this.apollo.getClient();
12811
- client.addResolvers(resolvers);
12812
- return [2 /*return*/];
12813
12813
  });
12814
12814
  });
12815
12815
  };
@@ -12819,21 +12819,26 @@
12819
12819
  return __generator(this, function (_a) {
12820
12820
  switch (_a.label) {
12821
12821
  case 0:
12822
- _a.trys.push([0, 3, , 4]);
12823
- return [4 /*yield*/, this.getApollo()];
12824
- case 1: return [4 /*yield*/, (_a.sent()).query({
12825
- query: opts.query,
12826
- variables: opts.variables,
12827
- fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined
12828
- }).toPromise()];
12822
+ if (!!this.started) return [3 /*break*/, 2];
12823
+ return [4 /*yield*/, this.ready()];
12824
+ case 1:
12825
+ _a.sent();
12826
+ _a.label = 2;
12829
12827
  case 2:
12830
- res = _a.sent();
12831
- return [3 /*break*/, 4];
12828
+ _a.trys.push([2, 4, , 5]);
12829
+ return [4 /*yield*/, this.client.query({
12830
+ query: opts.query,
12831
+ variables: opts.variables,
12832
+ fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined
12833
+ })];
12832
12834
  case 3:
12835
+ res = _a.sent();
12836
+ return [3 /*break*/, 5];
12837
+ case 4:
12833
12838
  err_1 = _a.sent();
12834
12839
  res = this.toApolloError(err_1, opts.error);
12835
- return [3 /*break*/, 4];
12836
- case 4:
12840
+ return [3 /*break*/, 5];
12841
+ case 5:
12837
12842
  if (res.errors) {
12838
12843
  throw res.errors[0];
12839
12844
  }
@@ -13210,13 +13215,14 @@
13210
13215
  this.customErrors = Object.assign(Object.assign({}, this.customErrors), error);
13211
13216
  };
13212
13217
  /* -- protected methods -- */
13213
- GraphqlService.prototype.initApollo = function () {
13218
+ GraphqlService.prototype.ngOnStart = function () {
13214
13219
  return __awaiter(this, void 0, void 0, function () {
13215
13220
  var mobile, enableTrackMutationQueries, peer, uri, wsUri, storage, client, wsLink, retryLink, authLink, httpLink, cache, mutationLinks, serializingLink, trackerLink, queueLink_1, err_2;
13216
13221
  var _this = this;
13217
13222
  return __generator(this, function (_a) {
13218
13223
  switch (_a.label) {
13219
13224
  case 0:
13225
+ console.info('[graphql] Starting graphql...');
13220
13226
  mobile = this.platform.is('mobile') || this.platform.is('mobileweb');
13221
13227
  enableTrackMutationQueries = !mobile;
13222
13228
  peer = this.network.peer;
@@ -13277,14 +13283,14 @@
13277
13283
  mutationLinks = void 0;
13278
13284
  // Add queue to store tracked queries, when offline
13279
13285
  if (enableTrackMutationQueries) {
13280
- serializingLink = new SerializingLink__default['default']();
13286
+ serializingLink = new SerializingLink__default["default"]();
13281
13287
  trackerLink = createTrackerLink({
13282
13288
  storage: storage,
13283
13289
  onNetworkStatusChange: this._networkStatusChanged$,
13284
13290
  debounce: 1000,
13285
13291
  debug: true
13286
13292
  });
13287
- queueLink_1 = new QueueLink__default['default']();
13293
+ queueLink_1 = new QueueLink__default["default"]();
13288
13294
  this._subscription.add(this._networkStatusChanged$
13289
13295
  .subscribe(function (type) {
13290
13296
  // Network is offline: start buffering into queue
@@ -13299,7 +13305,7 @@
13299
13305
  }
13300
13306
  }));
13301
13307
  mutationLinks = [
13302
- loggerLink__default['default'],
13308
+ loggerLink__default["default"],
13303
13309
  queueLink_1,
13304
13310
  trackerLink,
13305
13311
  queueLink_1,
@@ -13351,12 +13357,14 @@
13351
13357
  err_2 = _a.sent();
13352
13358
  console.error('[graphql] Failed to restore tracked queries from storage: ' + (err_2 && err_2.message || err_2), err_2);
13353
13359
  return [3 /*break*/, 7];
13354
- case 7: return [2 /*return*/];
13360
+ case 7:
13361
+ console.info('[graphql] Starting graphql [OK]');
13362
+ return [2 /*return*/, client];
13355
13363
  }
13356
13364
  });
13357
13365
  });
13358
13366
  };
13359
- GraphqlService.prototype.stop = function () {
13367
+ GraphqlService.prototype.ngOnStop = function () {
13360
13368
  return __awaiter(this, void 0, void 0, function () {
13361
13369
  return __generator(this, function (_a) {
13362
13370
  switch (_a.label) {
@@ -13367,24 +13375,11 @@
13367
13375
  return [4 /*yield*/, this.resetClient()];
13368
13376
  case 1:
13369
13377
  _a.sent();
13370
- this._started = false;
13371
- this._startPromise = undefined;
13372
13378
  return [2 /*return*/];
13373
13379
  }
13374
13380
  });
13375
13381
  });
13376
13382
  };
13377
- GraphqlService.prototype.restart = function () {
13378
- return __awaiter(this, void 0, void 0, function () {
13379
- var _this = this;
13380
- return __generator(this, function (_a) {
13381
- if (this.started) {
13382
- return [2 /*return*/, this.stop().then(function () { return _this.start(); })];
13383
- }
13384
- return [2 /*return*/, this.start()];
13385
- });
13386
- });
13387
- };
13388
13383
  GraphqlService.prototype.resetClient = function (client) {
13389
13384
  return __awaiter(this, void 0, void 0, function () {
13390
13385
  return __generator(this, function (_a) {
@@ -13486,24 +13481,8 @@
13486
13481
  }
13487
13482
  return undefined;
13488
13483
  };
13489
- GraphqlService.prototype.getApollo = function () {
13490
- return __awaiter(this, void 0, void 0, function () {
13491
- return __generator(this, function (_a) {
13492
- switch (_a.label) {
13493
- case 0:
13494
- if (!!this._started) return [3 /*break*/, 2];
13495
- console.debug('[graphql] Waiting apollo client... ');
13496
- return [4 /*yield*/, this.onStart.toPromise()];
13497
- case 1:
13498
- _a.sent();
13499
- _a.label = 2;
13500
- case 2: return [2 /*return*/, this.apollo];
13501
- }
13502
- });
13503
- });
13504
- };
13505
13484
  return GraphqlService;
13506
- }());
13485
+ }(StartableService));
13507
13486
  GraphqlService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function GraphqlService_Factory() { return new GraphqlService(i0__namespace.ɵɵinject(i1__namespace$4.Platform), i0__namespace.ɵɵinject(i2__namespace$3.Apollo), i0__namespace.ɵɵinject(i3__namespace$2.HttpLink), i0__namespace.ɵɵinject(NetworkService), i0__namespace.ɵɵinject(i3__namespace$1.Storage), i0__namespace.ɵɵinject(CryptoService), i0__namespace.ɵɵinject(ENVIRONMENT), i0__namespace.ɵɵinject(APP_GRAPHQL_TYPE_POLICIES, 8)); }, token: GraphqlService, providedIn: "root" });
13508
13487
  GraphqlService.decorators = [
13509
13488
  { type: i0.Injectable, args: [{
@@ -13786,7 +13765,12 @@
13786
13765
  _this.storage = storage;
13787
13766
  _this.file = file;
13788
13767
  _this.environment = environment;
13789
- _this.data = {
13768
+ _this.onLogin = new rxjs.Subject();
13769
+ _this.onLogout = new rxjs.Subject();
13770
+ _this.onChange = new rxjs.Subject();
13771
+ _this.onAuthTokenChange = new rxjs.Subject();
13772
+ _this.onAuthBasicChange = new rxjs.Subject();
13773
+ _this._data = {
13790
13774
  loaded: false,
13791
13775
  keypair: null,
13792
13776
  authToken: null,
@@ -13800,11 +13784,6 @@
13800
13784
  _this._started = false;
13801
13785
  _this._$additionalFields = new rxjs.BehaviorSubject([]);
13802
13786
  _this._tokenType$ = new rxjs.BehaviorSubject(undefined);
13803
- _this.onLogin = new rxjs.Subject();
13804
- _this.onLogout = new rxjs.Subject();
13805
- _this.onChange = new rxjs.Subject();
13806
- _this.onAuthTokenChange = new rxjs.Subject();
13807
- _this.onAuthBasicChange = new rxjs.Subject();
13808
13787
  _this._debug = !environment.production;
13809
13788
  if (_this._debug)
13810
13789
  console.debug('[account-service] Creating service');
@@ -13812,7 +13791,7 @@
13812
13791
  // Send auth token to the graphql layer, when changed
13813
13792
  _this.onAuthTokenChange.subscribe(function (token) { return _this.graphql.setAuthToken(token); });
13814
13793
  _this.onAuthBasicChange.subscribe(function (basic) { return _this.graphql.setAuthBasic(basic); });
13815
- // Listen network restart
13794
+ // Listen graphql start (or restart)
13816
13795
  _this.graphql.onStart.subscribe(function () { return __awaiter(_this, void 0, void 0, function () {
13817
13796
  return __generator(this, function (_b) {
13818
13797
  if (!this._started) {
@@ -13846,27 +13825,27 @@
13846
13825
  }
13847
13826
  Object.defineProperty(AccountService.prototype, "account", {
13848
13827
  get: function () {
13849
- return this.data.loaded ? this.data.account : undefined;
13828
+ return this._data.loaded ? this._data.account : undefined;
13850
13829
  },
13851
13830
  enumerable: false,
13852
13831
  configurable: true
13853
13832
  });
13854
13833
  Object.defineProperty(AccountService.prototype, "person", {
13855
13834
  get: function () {
13856
- if (this.data.loaded && !this.data.person) {
13857
- this.data.person = this.data.loaded ? this.data.account.asPerson() : undefined;
13835
+ if (this._data.loaded && !this._data.person) {
13836
+ this._data.person = this._data.loaded ? this._data.account.asPerson() : undefined;
13858
13837
  }
13859
- return this.data.person;
13838
+ return this._data.person;
13860
13839
  },
13861
13840
  enumerable: false,
13862
13841
  configurable: true
13863
13842
  });
13864
13843
  Object.defineProperty(AccountService.prototype, "department", {
13865
13844
  get: function () {
13866
- if (this.data.loaded && !this.data.department) {
13867
- this.data.department = this.data.loaded ? this.data.account.asPerson().department : undefined;
13845
+ if (this._data.loaded && !this._data.department) {
13846
+ this._data.department = this._data.loaded ? this._data.account.asPerson().department : undefined;
13868
13847
  }
13869
- return this.data.department;
13848
+ return this._data.department;
13870
13849
  },
13871
13850
  enumerable: false,
13872
13851
  configurable: true
@@ -13880,32 +13859,21 @@
13880
13859
  console.info('[account] Using authentication token type: ' + value);
13881
13860
  this._tokenType$.next(value);
13882
13861
  // Reset values
13883
- this.data.authToken = undefined;
13862
+ this._data.authToken = undefined;
13884
13863
  this.onAuthTokenChange.next(undefined);
13885
- this.data.authBasic = undefined;
13864
+ this._data.authBasic = undefined;
13886
13865
  this.onAuthBasicChange.next(undefined);
13887
13866
  }
13888
13867
  },
13889
13868
  enumerable: false,
13890
13869
  configurable: true
13891
13870
  });
13892
- AccountService.prototype.resetData = function () {
13893
- this.data.loaded = false;
13894
- this.data.keypair = null;
13895
- this.data.authToken = null;
13896
- this.data.authBasic = null;
13897
- this.data.pubkey = null;
13898
- this.data.mainProfile = null;
13899
- this.data.account = new exports.Account();
13900
- this.data.person = null;
13901
- this.data.department = null;
13902
- };
13903
13871
  AccountService.prototype.start = function () {
13904
13872
  var _this = this;
13905
13873
  if (this._startPromise)
13906
13874
  return this._startPromise;
13907
13875
  if (this._started)
13908
- return Promise.resolve();
13876
+ return Promise.resolve(this.account);
13909
13877
  // Restoring local settings
13910
13878
  this._startPromise = Promise.all([
13911
13879
  this.settings.ready(),
@@ -13916,6 +13884,7 @@
13916
13884
  .then(function () {
13917
13885
  _this._started = true;
13918
13886
  _this._startPromise = undefined;
13887
+ return _this.account;
13919
13888
  });
13920
13889
  return this._startPromise;
13921
13890
  };
@@ -13933,8 +13902,8 @@
13933
13902
  if (this._started || this._startPromise) {
13934
13903
  this._started = false;
13935
13904
  this._startPromise = undefined;
13936
- hadAuthToken = this.data.authToken && true;
13937
- hadAuthBasic = this.data.authBasic && true;
13905
+ hadAuthToken = this._data.authToken && true;
13906
+ hadAuthBasic = this._data.authBasic && true;
13938
13907
  hadAuth = hadAuthToken || hadAuthBasic;
13939
13908
  this.resetData();
13940
13909
  if (hadAuth) {
@@ -13964,35 +13933,35 @@
13964
13933
  };
13965
13934
  AccountService.prototype.ready = function () {
13966
13935
  if (this._started)
13967
- return Promise.resolve();
13936
+ return Promise.resolve(this.account);
13968
13937
  return this.start();
13969
13938
  };
13970
13939
  AccountService.prototype.isLogin = function () {
13971
- return !!(this.data.pubkey && this.data.loaded);
13940
+ return !!(this._data.pubkey && this._data.loaded);
13972
13941
  };
13973
13942
  AccountService.prototype.isAuth = function () {
13974
- return !!(this.data.pubkey && this.data.keypair && this.data.keypair.secretKey);
13943
+ return !!(this._data.pubkey && this._data.keypair && this._data.keypair.secretKey);
13975
13944
  };
13976
13945
  AccountService.prototype.hasMinProfile = function (userProfile) {
13977
13946
  // should be login, and status ENABLE or TEMPORARY
13978
- if (!this.data.account || !this.data.account.pubkey ||
13979
- (this.data.account.statusId !== StatusIds.ENABLE && this.data.account.statusId !== StatusIds.TEMPORARY)) {
13947
+ if (!this._data.account || !this._data.account.pubkey ||
13948
+ (this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY)) {
13980
13949
  return false;
13981
13950
  }
13982
- return PersonUtils.hasUpperOrEqualsProfile(this.data.account.profiles, userProfile);
13951
+ return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, userProfile);
13983
13952
  };
13984
13953
  AccountService.prototype.hasExactProfile = function (label) {
13985
13954
  // should be login, and status ENABLE or TEMPORARY
13986
- if (!this.data.account || !this.data.account.pubkey ||
13987
- (this.data.account.statusId !== StatusIds.ENABLE && this.data.account.statusId !== StatusIds.TEMPORARY))
13955
+ if (!this._data.account || !this._data.account.pubkey ||
13956
+ (this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY))
13988
13957
  return false;
13989
- return this.data.account.profiles.some(function (profile) { return profile === label; });
13958
+ return this._data.account.profiles.some(function (profile) { return profile === label; });
13990
13959
  };
13991
13960
  AccountService.prototype.hasProfileAndIsEnable = function (userProfile) {
13992
13961
  // should be login, and status ENABLE
13993
- if (!this.data.account || !this.data.account.pubkey || this.data.account.statusId !== StatusIds.ENABLE)
13962
+ if (!this._data.account || !this._data.account.pubkey || this._data.account.statusId !== StatusIds.ENABLE)
13994
13963
  return false;
13995
- return PersonUtils.hasUpperOrEqualsProfile(this.data.account.profiles, userProfile);
13964
+ return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, userProfile);
13996
13965
  };
13997
13966
  AccountService.prototype.isAdmin = function () {
13998
13967
  return this.hasProfileAndIsEnable('ADMIN');
@@ -14012,11 +13981,11 @@
14012
13981
  };
14013
13982
  AccountService.prototype.isOnlyGuest = function () {
14014
13983
  // Should be login, and status ENABLE or TEMPORARY
14015
- if (!this.data.account || !this.data.account.pubkey ||
14016
- (this.data.account.statusId !== StatusIds.ENABLE && this.data.account.statusId !== StatusIds.TEMPORARY))
13984
+ if (!this._data.account || !this._data.account.pubkey ||
13985
+ (this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY))
14017
13986
  return false;
14018
13987
  // Profile less then user
14019
- return !PersonUtils.hasUpperOrEqualsProfile(this.data.account.profiles, 'USER');
13988
+ return !PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, 'USER');
14020
13989
  };
14021
13990
  AccountService.prototype.canUserWriteDataForDepartment = function (recorderDepartment) {
14022
13991
  if (ReferentialUtils.isEmpty(recorderDepartment)) {
@@ -14025,17 +13994,17 @@
14025
13994
  return this.isAdmin();
14026
13995
  }
14027
13996
  // Should be login, and status ENABLE
14028
- if (!this.data.account || !this.data.account.pubkey || this.data.account.statusId !== StatusIds.ENABLE)
13997
+ if (!this._data.account || !this._data.account.pubkey || this._data.account.statusId !== StatusIds.ENABLE)
14029
13998
  return false;
14030
- if (!this.data.account.department || !this.data.account.department.id) {
13999
+ if (!this._data.account.department || !this._data.account.department.id) {
14031
14000
  console.warn('User account has no department ! Unable to check write right against recorderDepartment');
14032
14001
  return false;
14033
14002
  }
14034
14003
  // Same recorder department: OK, user can write
14035
- if (this.data.account.department.id === recorderDepartment.id)
14004
+ if (this._data.account.department.id === recorderDepartment.id)
14036
14005
  return true;
14037
14006
  // Else, check if supervisor (or more)
14038
- return PersonUtils.hasUpperOrEqualsProfile(this.data.account.profiles, 'SUPERVISOR');
14007
+ return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, 'SUPERVISOR');
14039
14008
  };
14040
14009
  AccountService.prototype.register = function (data) {
14041
14010
  return __awaiter(this, void 0, void 0, function () {
@@ -14050,7 +14019,7 @@
14050
14019
  throw new Error('Missing required username or password');
14051
14020
  if (this._debug)
14052
14021
  console.debug('[account] Register new user account...', data.account);
14053
- this.data.loaded = false;
14022
+ this._data.loaded = false;
14054
14023
  now = Date.now();
14055
14024
  _b.label = 1;
14056
14025
  case 1:
@@ -14064,29 +14033,29 @@
14064
14033
  data.account.settings.locale = this.settings.locale;
14065
14034
  data.account.settings.latLongFormat = this.settings.latLongFormat;
14066
14035
  data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;
14067
- this.data.keypair = keypair;
14036
+ this._data.keypair = keypair;
14068
14037
  return [4 /*yield*/, this.saveRemotely(data.account, keypair)];
14069
14038
  case 3:
14070
14039
  account = _b.sent();
14071
14040
  // Default values
14072
14041
  account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
14073
- this.data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14074
- this.data.account = account;
14075
- this.data.pubkey = account.pubkey;
14042
+ this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14043
+ this._data.account = account;
14044
+ this._data.pubkey = account.pubkey;
14076
14045
  // Try to auth on pod
14077
14046
  return [4 /*yield*/, this.authenticate(data)];
14078
14047
  case 4:
14079
14048
  // Try to auth on pod
14080
14049
  _b.sent();
14081
- this.data.loaded = true;
14050
+ this._data.loaded = true;
14082
14051
  return [4 /*yield*/, this.saveLocally()];
14083
14052
  case 5:
14084
14053
  _b.sent();
14085
14054
  console.debug("[account] Account successfully registered in " + (Date.now() - now) + "ms");
14086
14055
  // Emit events
14087
- this.onLogin.next(this.data.account);
14088
- this.onChange.next(this.data.account);
14089
- return [2 /*return*/, this.data.account];
14056
+ this.onLogin.next(this._data.account);
14057
+ this.onChange.next(this._data.account);
14058
+ return [2 /*return*/, this._data.account];
14090
14059
  case 6:
14091
14060
  error_1 = _b.sent();
14092
14061
  console.error(error_1 && error_1.message || error_1);
@@ -14108,22 +14077,22 @@
14108
14077
  // Basic auth
14109
14078
  if (tokenType === 'basic' || tokenType === 'basic-and-token') {
14110
14079
  // Generate the authBasic, if used
14111
- if (!this.data.authBasic) {
14080
+ if (!this._data.authBasic) {
14112
14081
  // Skip if token already provided
14113
- if (!(this.data.authToken && tokenType === 'basic-and-token')) {
14082
+ if (!(this._data.authToken && tokenType === 'basic-and-token')) {
14114
14083
  if (!data || !data.username || !data.password)
14115
14084
  throw new Error('Missing username and password');
14116
- this.data.authBasic = this.cryptoService.encodeBase64(data.username + ":" + data.password);
14085
+ this._data.authBasic = this.cryptoService.encodeBase64(data.username + ":" + data.password);
14117
14086
  }
14118
14087
  }
14119
- this.onAuthBasicChange.next(this.data.authBasic);
14088
+ this.onAuthBasicChange.next(this._data.authBasic);
14120
14089
  }
14121
14090
  if (!(tokenType === 'token' || tokenType === 'basic-and-token')) return [3 /*break*/, 5];
14122
14091
  _c.label = 2;
14123
14092
  case 2:
14124
14093
  _c.trys.push([2, 4, , 5]);
14125
- _b = this.data;
14126
- return [4 /*yield*/, this.authenticateAndGetToken(this.data.authToken)];
14094
+ _b = this._data;
14095
+ return [4 /*yield*/, this.authenticateAndGetToken(this._data.authToken)];
14127
14096
  case 3:
14128
14097
  _b.authToken = _c.sent();
14129
14098
  return [3 /*break*/, 5];
@@ -14136,7 +14105,7 @@
14136
14105
  case 5:
14137
14106
  // Forget authBasic, to switch to authToken
14138
14107
  if (tokenType === 'basic-and-token') {
14139
- this.data.authBasic = undefined;
14108
+ this._data.authBasic = undefined;
14140
14109
  this.onAuthBasicChange.next(undefined);
14141
14110
  }
14142
14111
  return [2 /*return*/];
@@ -14167,18 +14136,18 @@
14167
14136
  throw { code: ErrorCodes$2.UNKNOWN_ERROR, message: 'ERROR.SCRYPT_ERROR' };
14168
14137
  case 4:
14169
14138
  // Store pubkey+keypair
14170
- this.data.pubkey = Base58.encode(keypair.publicKey);
14171
- this.data.keypair = keypair;
14139
+ this._data.pubkey = Base58.encode(keypair.publicKey);
14140
+ this._data.keypair = keypair;
14172
14141
  return [4 /*yield*/, this.storage.get(TOKEN_STORAGE_KEY)];
14173
14142
  case 5:
14174
14143
  previousToken = _b.sent();
14175
- previousToken = previousToken && previousToken.startsWith(this.data.pubkey) && previousToken || null;
14144
+ previousToken = previousToken && previousToken.startsWith(this._data.pubkey) && previousToken || null;
14176
14145
  offline = this.settings.hasOfflineFeature() && (this.network.offline || data.offline === true);
14177
14146
  if (!offline) return [3 /*break*/, 6];
14178
- this.data.authToken = previousToken;
14147
+ this._data.authToken = previousToken;
14179
14148
  // Make sure network if set as offline
14180
14149
  this.network.setForceOffline(true, { showToast: false });
14181
- console.info("[account] Login [OK] {pubkey: " + this.data.pubkey.substr(0, 8) + "}, {offline: true}");
14150
+ console.info("[account] Login [OK] {pubkey: " + this._data.pubkey.substr(0, 8) + "}, {offline: true}");
14182
14151
  return [3 /*break*/, 9];
14183
14152
  case 6:
14184
14153
  _b.trys.push([6, 8, , 9]);
@@ -14238,9 +14207,9 @@
14238
14207
  throw error_5;
14239
14208
  case 21:
14240
14209
  // Emit event to observers
14241
- this.onLogin.next(this.data.account);
14242
- this.onChange.next(this.data.account);
14243
- return [2 /*return*/, this.data.account];
14210
+ this.onLogin.next(this._data.account);
14211
+ this.onChange.next(this._data.account);
14212
+ return [2 /*return*/, this._data.account];
14244
14213
  }
14245
14214
  });
14246
14215
  });
@@ -14250,7 +14219,7 @@
14250
14219
  return __generator(this, function (_b) {
14251
14220
  switch (_b.label) {
14252
14221
  case 0:
14253
- if (!this.data.pubkey)
14222
+ if (!this._data.pubkey)
14254
14223
  throw new Error('User not logged');
14255
14224
  if (this.network.offline)
14256
14225
  throw new Error('Cannot check account in offline mode');
@@ -14262,9 +14231,9 @@
14262
14231
  _b.sent();
14263
14232
  console.debug('[account] Successfully reload account');
14264
14233
  // Emit login event to subscribers
14265
- this.onLogin.next(this.data.account);
14266
- this.onChange.next(this.data.account);
14267
- return [2 /*return*/, this.data.account];
14234
+ this.onLogin.next(this._data.account);
14235
+ this.onChange.next(this._data.account);
14236
+ return [2 /*return*/, this._data.account];
14268
14237
  }
14269
14238
  });
14270
14239
  });
@@ -14279,27 +14248,27 @@
14279
14248
  return __generator(this, function (_b) {
14280
14249
  switch (_b.label) {
14281
14250
  case 0:
14282
- if (!this.data.pubkey)
14251
+ if (!this._data.pubkey)
14283
14252
  return [2 /*return*/, Promise.reject('User not logged')];
14284
- if (this.data.pubkey !== account.pubkey)
14253
+ if (this._data.pubkey !== account.pubkey)
14285
14254
  return [2 /*return*/, Promise.reject('Not user account')];
14286
- return [4 /*yield*/, this.saveRemotely(account, this.data.keypair)];
14255
+ return [4 /*yield*/, this.saveRemotely(account, this._data.keypair)];
14287
14256
  case 1:
14288
14257
  account = _b.sent();
14289
14258
  // Set defaults
14290
14259
  account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
14291
- this.data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14292
- this.data.account = account;
14293
- this.data.loaded = true;
14260
+ this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14261
+ this._data.account = account;
14262
+ this._data.loaded = true;
14294
14263
  // Save locally (in storage)
14295
14264
  return [4 /*yield*/, this.saveLocally()];
14296
14265
  case 2:
14297
14266
  // Save locally (in storage)
14298
14267
  _b.sent();
14299
14268
  // Send event
14300
- this.onLogin.next(this.data.account);
14301
- this.onChange.next(this.data.account);
14302
- return [2 /*return*/, this.data.account];
14269
+ this.onLogin.next(this._data.account);
14270
+ this.onChange.next(this._data.account);
14271
+ return [2 /*return*/, this._data.account];
14303
14272
  }
14304
14273
  });
14305
14274
  });
@@ -14310,9 +14279,9 @@
14310
14279
  return __generator(this, function (_b) {
14311
14280
  switch (_b.label) {
14312
14281
  case 0:
14313
- hadAuthToken = this.data.authToken && true;
14314
- hadAuthBasic = this.data.authBasic && true;
14315
- pubkey = this.data && this.data.pubkey;
14282
+ hadAuthToken = this._data.authToken && true;
14283
+ hadAuthBasic = this._data.authBasic && true;
14284
+ pubkey = this._data && this._data.pubkey;
14316
14285
  this.resetData();
14317
14286
  if (!!this.settings.hasOfflineFeature()) return [3 /*break*/, 2];
14318
14287
  // Remove all data from the local storage
@@ -14384,9 +14353,9 @@
14384
14353
  case 1:
14385
14354
  json = _b.sent();
14386
14355
  json = json && (typeof json === 'string') && JSON.parse(json) || json;
14387
- json = json && this.data.pubkey && (json.pubkey === this.data.pubkey) && json || null;
14388
- if (!(!json && this.data.pubkey)) return [3 /*break*/, 3];
14389
- return [4 /*yield*/, this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this.data.pubkey)];
14356
+ json = json && this._data.pubkey && (json.pubkey === this._data.pubkey) && json || null;
14357
+ if (!(!json && this._data.pubkey)) return [3 /*break*/, 3];
14358
+ return [4 /*yield*/, this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this._data.pubkey)];
14390
14359
  case 2:
14391
14360
  json = _b.sent();
14392
14361
  json = json && (typeof json === 'string') && JSON.parse(json) || json;
@@ -14517,7 +14486,8 @@
14517
14486
  });
14518
14487
  };
14519
14488
  AccountService.prototype.listenChanges = function () {
14520
- if (!this.data.pubkey)
14489
+ var _this = this;
14490
+ if (!this._data.pubkey)
14521
14491
  return rxjs.Subscription.EMPTY;
14522
14492
  var self = this;
14523
14493
  console.debug('[account] [WS] Listening account changes');
@@ -14533,15 +14503,14 @@
14533
14503
  }).subscribe({
14534
14504
  next: function (_b) {
14535
14505
  var data = _b.data;
14536
- var _a;
14537
- return __awaiter(this, void 0, void 0, function () {
14538
- var existingUpdateDate;
14506
+ return __awaiter(_this, void 0, void 0, function () {
14507
+ var _a, existingUpdateDate;
14539
14508
  return __generator(this, function (_b) {
14540
14509
  switch (_b.label) {
14541
14510
  case 0:
14542
14511
  if (!data)
14543
14512
  return [2 /*return*/];
14544
- existingUpdateDate = toDateISOString((_a = self.data.account) === null || _a === void 0 ? void 0 : _a.updateDate);
14513
+ existingUpdateDate = toDateISOString((_a = self._data.account) === null || _a === void 0 ? void 0 : _a.updateDate);
14545
14514
  if (!(existingUpdateDate !== data.updateDate)) return [3 /*break*/, 2];
14546
14515
  console.debug("[account] [WS] Detected update on {" + data.updateDate + "}");
14547
14516
  return [4 /*yield*/, self.refresh()];
@@ -14553,32 +14522,30 @@
14553
14522
  });
14554
14523
  });
14555
14524
  },
14556
- error: function (err) {
14557
- return __awaiter(this, void 0, void 0, function () {
14558
- return __generator(this, function (_b) {
14559
- switch (_b.label) {
14560
- case 0:
14561
- if (!(err && +err.code === ServerErrorCodes.NOT_FOUND)) return [3 /*break*/, 2];
14562
- console.info('[account] Account not exists anymore: force user to logout...', err);
14563
- return [4 /*yield*/, self.logout()];
14564
- case 1:
14565
- _b.sent();
14566
- return [3 /*break*/, 5];
14567
- case 2:
14568
- if (!(err && +err.code === ServerErrorCodes.UNAUTHORIZED)) return [3 /*break*/, 4];
14569
- console.info('[account] Account not authorized: force user to logout...', err);
14570
- return [4 /*yield*/, self.logout()];
14571
- case 3:
14572
- _b.sent();
14573
- return [3 /*break*/, 5];
14574
- case 4:
14575
- console.warn('[account] [WS] Received error:', err);
14576
- _b.label = 5;
14577
- case 5: return [2 /*return*/];
14578
- }
14579
- });
14525
+ error: function (err) { return __awaiter(_this, void 0, void 0, function () {
14526
+ return __generator(this, function (_b) {
14527
+ switch (_b.label) {
14528
+ case 0:
14529
+ if (!(err && +err.code === ServerErrorCodes.NOT_FOUND)) return [3 /*break*/, 2];
14530
+ console.info('[account] Account not exists anymore: force user to logout...', err);
14531
+ return [4 /*yield*/, self.logout()];
14532
+ case 1:
14533
+ _b.sent();
14534
+ return [3 /*break*/, 5];
14535
+ case 2:
14536
+ if (!(err && +err.code === ServerErrorCodes.UNAUTHORIZED)) return [3 /*break*/, 4];
14537
+ console.info('[account] Account not authorized: force user to logout...', err);
14538
+ return [4 /*yield*/, self.logout()];
14539
+ case 3:
14540
+ _b.sent();
14541
+ return [3 /*break*/, 5];
14542
+ case 4:
14543
+ console.warn('[account] [WS] Received error:', err);
14544
+ _b.label = 5;
14545
+ case 5: return [2 /*return*/];
14546
+ }
14580
14547
  });
14581
- },
14548
+ }); },
14582
14549
  complete: function () {
14583
14550
  console.debug('[account] [WS] Completed');
14584
14551
  }
@@ -14635,15 +14602,26 @@
14635
14602
  this._$additionalFields.next(values.concat(field));
14636
14603
  };
14637
14604
  /* -- protected method -- */
14605
+ AccountService.prototype.resetData = function () {
14606
+ this._data.loaded = false;
14607
+ this._data.keypair = null;
14608
+ this._data.authToken = null;
14609
+ this._data.authBasic = null;
14610
+ this._data.pubkey = null;
14611
+ this._data.mainProfile = null;
14612
+ this._data.account = new exports.Account();
14613
+ this._data.person = null;
14614
+ this._data.department = null;
14615
+ };
14638
14616
  AccountService.prototype.loadData = function (opts) {
14639
14617
  return __awaiter(this, void 0, void 0, function () {
14640
14618
  var account, error_6;
14641
14619
  return __generator(this, function (_b) {
14642
14620
  switch (_b.label) {
14643
14621
  case 0:
14644
- if (!this.data.pubkey)
14622
+ if (!this._data.pubkey)
14645
14623
  throw new Error('User not logged');
14646
- this.data.loaded = false;
14624
+ this._data.loaded = false;
14647
14625
  _b.label = 1;
14648
14626
  case 1:
14649
14627
  _b.trys.push([1, 3, , 4]);
@@ -14656,16 +14634,16 @@
14656
14634
  account.settings.locale = account.settings.locale || this.settings.locale;
14657
14635
  account.settings.latLongFormat = account.settings.latLongFormat || this.settings.latLongFormat || 'DDMM';
14658
14636
  // Read main profile
14659
- this.data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14637
+ this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14660
14638
  // Update, instead of replace it
14661
- if (this.data.account) {
14662
- this.data.account.fromObject(account);
14639
+ if (this._data.account) {
14640
+ this._data.account.fromObject(account);
14663
14641
  }
14664
14642
  else {
14665
- this.data.account = account;
14643
+ this._data.account = account;
14666
14644
  }
14667
- this.data.loaded = true;
14668
- return [2 /*return*/, this.data.account];
14645
+ this._data.loaded = true;
14646
+ return [2 /*return*/, this._data.account];
14669
14647
  case 3:
14670
14648
  error_6 = _b.sent();
14671
14649
  this.resetData();
@@ -14704,9 +14682,9 @@
14704
14682
  return [2 /*return*/];
14705
14683
  if (this._debug)
14706
14684
  console.debug("[account] Account restoration...");
14707
- this.data.authToken = token;
14708
- this.data.pubkey = pubkey;
14709
- this.data.keypair = seckey && {
14685
+ this._data.authToken = token;
14686
+ this._data.pubkey = pubkey;
14687
+ this._data.keypair = seckey && {
14710
14688
  publicKey: Base58.decode(pubkey),
14711
14689
  secretKey: Base58.decode(seckey)
14712
14690
  } || null;
@@ -14717,7 +14695,7 @@
14717
14695
  return [4 /*yield*/, this.authenticate()];
14718
14696
  case 3:
14719
14697
  _b.sent();
14720
- if (!this.data.authToken && !this.data.authBasic)
14698
+ if (!this._data.authToken && !this._data.authBasic)
14721
14699
  throw new Error('Authentication failed');
14722
14700
  return [3 /*break*/, 5];
14723
14701
  case 4:
@@ -14750,14 +14728,14 @@
14750
14728
  return [2 /*return*/];
14751
14729
  account = exports.Account.fromObject(jsonAccount);
14752
14730
  // Update data
14753
- this.data.account = account;
14754
- this.data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14755
- this.data.loaded = true;
14731
+ this._data.account = account;
14732
+ this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
14733
+ this._data.loaded = true;
14756
14734
  // Emit event
14757
- this.onLogin.next(this.data.account);
14758
- this.onChange.next(this.data.account);
14735
+ this.onLogin.next(this._data.account);
14736
+ this.onChange.next(this._data.account);
14759
14737
  if (this._debug)
14760
- console.debug("[account] Account restoration [OK] {pubkey: " + pubkey.substr(0, 8) + "}, {profile: " + this.data.mainProfile + "}");
14738
+ console.debug("[account] Account restoration [OK] {pubkey: " + pubkey.substr(0, 8) + "}, {profile: " + this._data.mainProfile + "}");
14761
14739
  return [2 /*return*/, account];
14762
14740
  }
14763
14741
  });
@@ -14773,12 +14751,12 @@
14773
14751
  return __generator(this, function (_b) {
14774
14752
  switch (_b.label) {
14775
14753
  case 0:
14776
- if (!this.data.pubkey)
14754
+ if (!this._data.pubkey)
14777
14755
  throw new Error('User not logged');
14778
14756
  if (this._debug)
14779
- console.debug("[account] Saving account {" + this.data.pubkey.substring(0, 6) + "} in local storage...");
14780
- json = this.data.account.asObject({ keepTypename: true });
14781
- seckey = this.data.keypair && this.data.keypair.secretKey && Base58.encode(this.data.keypair.secretKey) || null;
14757
+ console.debug("[account] Saving account {" + this._data.pubkey.substring(0, 6) + "} in local storage...");
14758
+ json = this._data.account.asObject({ keepTypename: true });
14759
+ seckey = this._data.keypair && this._data.keypair.secretKey && Base58.encode(this._data.keypair.secretKey) || null;
14782
14760
  hasAvatarUrl = json.avatar && !json.avatar.endsWith(DEFAULT_AVATAR_IMAGE) &&
14783
14761
  (json.avatar.startsWith('http://') || (json.avatar.startsWith('https://')));
14784
14762
  if (!(hasAvatarUrl && this.network.online)) return [3 /*break*/, 2];
@@ -14801,9 +14779,9 @@
14801
14779
  case 2:
14802
14780
  _b.trys.push([2, 4, , 5]);
14803
14781
  return [4 /*yield*/, Promise.all([
14804
- this.storage.set(PUBKEY_STORAGE_KEY, this.data.pubkey),
14805
- this.storage.set(TOKEN_STORAGE_KEY, this.data.authToken),
14806
- this.storage.set(ACCOUNT_STORAGE_KEY + "#" + this.data.pubkey, json),
14782
+ this.storage.set(PUBKEY_STORAGE_KEY, this._data.pubkey),
14783
+ this.storage.set(TOKEN_STORAGE_KEY, this._data.authToken),
14784
+ this.storage.set(ACCOUNT_STORAGE_KEY + "#" + this._data.pubkey, json),
14807
14785
  // Secret key (optional)
14808
14786
  seckey && this.storage.set(SECKEY_STORAGE_KEY, seckey) || this.storage.remove(SECKEY_STORAGE_KEY),
14809
14787
  // Remove old storage key
@@ -14880,7 +14858,7 @@
14880
14858
  return __generator(this, function (_b) {
14881
14859
  switch (_b.label) {
14882
14860
  case 0:
14883
- if (!this.data.pubkey)
14861
+ if (!this._data.pubkey)
14884
14862
  throw new Error('User not logged');
14885
14863
  if (!counter)
14886
14864
  console.info('[account] Authentication on pod...');
@@ -14907,7 +14885,7 @@
14907
14885
  if (data_1 && data_1.authenticate) {
14908
14886
  // Store the token
14909
14887
  this.onAuthTokenChange.next(token);
14910
- console.info("[account] Authentication on pod [OK] {pubkey: '" + this.data.pubkey.substr(0, 8) + "'}");
14888
+ console.info("[account] Authentication on pod [OK] {pubkey: '" + this._data.pubkey.substr(0, 8) + "'}");
14911
14889
  return [2 /*return*/, token]; // return the token
14912
14890
  }
14913
14891
  _b.label = 2;
@@ -14933,10 +14911,10 @@
14933
14911
  if (!signatureOK) {
14934
14912
  console.warn('FIXME: Bad peer signature on auth challenge !', data.authChallenge);
14935
14913
  }
14936
- return [4 /*yield*/, this.cryptoService.sign(data.authChallenge.challenge, this.data.keypair)];
14914
+ return [4 /*yield*/, this.cryptoService.sign(data.authChallenge.challenge, this._data.keypair)];
14937
14915
  case 5:
14938
14916
  signature = _b.sent();
14939
- newToken = this.data.pubkey + ":" + data.authChallenge.challenge + "|" + signature;
14917
+ newToken = this._data.pubkey + ":" + data.authChallenge.challenge + "|" + signature;
14940
14918
  return [4 /*yield*/, this.authenticateAndGetToken(newToken, (counter || 1) + 1 /* increment */)];
14941
14919
  case 6:
14942
14920
  // iterate with the new token
@@ -15266,9 +15244,8 @@
15266
15244
  Object.defineProperty(ConfigService.prototype, "config", {
15267
15245
  get: function () {
15268
15246
  // If first call: start loading
15269
- if (!this._started) {
15247
+ if (!this._started)
15270
15248
  this.start();
15271
- }
15272
15249
  return this.$data.pipe(operators.filter(isNotNil));
15273
15250
  },
15274
15251
  enumerable: false,
@@ -15283,30 +15260,49 @@
15283
15260
  console.info('[config] Starting configuration...');
15284
15261
  this._startPromise = this.graphql.ready()
15285
15262
  .then(function () { return _this.loadOrRestoreLocally(); })
15286
- .then(function () {
15263
+ .then(function (data) {
15287
15264
  _this._started = true;
15288
15265
  _this._startPromise = undefined;
15266
+ _this.$data.next(data);
15267
+ return data;
15289
15268
  })
15290
15269
  .catch(function (err) {
15291
15270
  console.error(err && err.message || err, err);
15271
+ _this._started = false;
15292
15272
  _this._startPromise = undefined;
15273
+ return null;
15293
15274
  });
15294
15275
  return this._startPromise;
15295
15276
  };
15296
15277
  ConfigService.prototype.stop = function () {
15297
- this._subscription.unsubscribe();
15298
- this._subscription = new rxjs.Subscription();
15299
- this._started = false;
15300
- this._startPromise = undefined;
15278
+ return __awaiter(this, void 0, void 0, function () {
15279
+ return __generator(this, function (_a) {
15280
+ this._subscription.unsubscribe();
15281
+ this._subscription = new rxjs.Subscription();
15282
+ this._started = false;
15283
+ this._startPromise = undefined;
15284
+ return [2 /*return*/];
15285
+ });
15286
+ });
15301
15287
  };
15302
15288
  ConfigService.prototype.restart = function () {
15303
- if (this.started)
15304
- this.stop();
15305
- return this.start();
15289
+ return __awaiter(this, void 0, void 0, function () {
15290
+ return __generator(this, function (_a) {
15291
+ switch (_a.label) {
15292
+ case 0:
15293
+ if (!this.started) return [3 /*break*/, 2];
15294
+ return [4 /*yield*/, this.stop()];
15295
+ case 1:
15296
+ _a.sent();
15297
+ _a.label = 2;
15298
+ case 2: return [2 /*return*/, this.start()];
15299
+ }
15300
+ });
15301
+ });
15306
15302
  };
15307
15303
  ConfigService.prototype.ready = function () {
15308
15304
  if (this._started)
15309
- return Promise.resolve();
15305
+ return Promise.resolve(this.$data.value);
15310
15306
  if (this._startPromise)
15311
15307
  return this._startPromise;
15312
15308
  return this.start();
@@ -15377,7 +15373,7 @@
15377
15373
  return [4 /*yield*/, this.loadDefault({ fetchPolicy: 'network-only' })];
15378
15374
  case 2:
15379
15375
  reloadedConfig = _a.sent();
15380
- defaultConfig = this.$data.getValue();
15376
+ defaultConfig = this.$data.value;
15381
15377
  if (isNotNil(defaultConfig) && reloadedConfig.label === defaultConfig.label) {
15382
15378
  // Emit update event when is default config
15383
15379
  this.$data.next(reloadedConfig);
@@ -15486,8 +15482,7 @@
15486
15482
  if (wasJustLoaded) {
15487
15483
  // TODO
15488
15484
  }
15489
- this.$data.next(data);
15490
- return [2 /*return*/];
15485
+ return [2 /*return*/, data];
15491
15486
  }
15492
15487
  });
15493
15488
  });
@@ -15740,7 +15735,7 @@
15740
15735
  .then(function () {
15741
15736
  _this._started = true;
15742
15737
  _this._startPromise = undefined;
15743
- console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + "} in " + (Date.now() - now) + "ms");
15738
+ console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + ", downloader: " + !!_this.downloader + " in " + (Date.now() - now) + "ms");
15744
15739
  // Update cache configuration when network changed
15745
15740
  _this.networkService.onNetworkStatusChanges.subscribe(function (type) { return _this.configureCache(type !== 'none'); });
15746
15741
  // Update authentication type
@@ -15789,18 +15784,37 @@
15789
15784
  }
15790
15785
  };
15791
15786
  PlatformService.prototype.download = function (request) {
15792
- if (!request || !request.uri)
15793
- throw new Error('Missing argument \'request\' or \'request.uri\'');
15794
- if (this._android && this._cordova) {
15795
- request = Object.assign(Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted, title: request.filename || '' }, request), { destinationInExternalFilesDir: Object.assign({ dirType: 'Downloads', subPath: request.filename || request.title || '' }, request.destinationInExternalFilesDir) });
15796
- this.downloader.download(request)
15797
- .then(function (location) { return console.info('[platform] File successfully downloaded at:' + location); })
15798
- .catch(function (error) { return console.error(error); });
15799
- }
15800
- // Web mode: open URI using the browser
15801
- else {
15802
- this.open(request.uri, '_system', 'location=yes');
15803
- }
15787
+ return __awaiter(this, void 0, void 0, function () {
15788
+ var downloader, location, err_1;
15789
+ return __generator(this, function (_a) {
15790
+ switch (_a.label) {
15791
+ case 0:
15792
+ if (!request || !request.uri)
15793
+ throw new Error('Missing argument \'request\' or \'request.uri\'');
15794
+ downloader = this.downloader || window.plugins.Downloader;
15795
+ if (!(downloader && this._android && this._cordova)) return [3 /*break*/, 5];
15796
+ request = Object.assign(Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted, title: request.filename || '' }, request), { destinationInExternalFilesDir: Object.assign({ dirType: 'Downloads', subPath: request.filename || request.title || '' }, request.destinationInExternalFilesDir) });
15797
+ _a.label = 1;
15798
+ case 1:
15799
+ _a.trys.push([1, 3, , 4]);
15800
+ return [4 /*yield*/, downloader.download(request)];
15801
+ case 2:
15802
+ location = _a.sent();
15803
+ console.info('[platform] File successfully downloaded at:' + location);
15804
+ return [2 /*return*/, location];
15805
+ case 3:
15806
+ err_1 = _a.sent();
15807
+ console.error('[platform] Error while downloading: ' + (err_1 && err_1.message || err_1), err_1);
15808
+ throw err_1;
15809
+ case 4: return [3 /*break*/, 6];
15810
+ case 5:
15811
+ console.warn('[platform] Cannot use Cordova downloader: using browser open()');
15812
+ this.open(request.uri, '_system', 'location=no', true);
15813
+ return [2 /*return*/, undefined];
15814
+ case 6: return [2 /*return*/];
15815
+ }
15816
+ });
15817
+ });
15804
15818
  };
15805
15819
  /* -- protected methods -- */
15806
15820
  PlatformService.prototype.configureCordovaPlugins = function (mobile) {
@@ -15896,7 +15910,7 @@
15896
15910
  };
15897
15911
  PlatformService.prototype.migrateStorage = function (forage) {
15898
15912
  return __awaiter(this, void 0, void 0, function () {
15899
- var canMigrate, oldForage, keys, now, toast_1, duration, err_1;
15913
+ var canMigrate, oldForage, keys, now, toast_1, duration, err_2;
15900
15914
  return __generator(this, function (_a) {
15901
15915
  switch (_a.label) {
15902
15916
  case 0:
@@ -15949,8 +15963,8 @@
15949
15963
  _a.sent();
15950
15964
  return [3 /*break*/, 12];
15951
15965
  case 9:
15952
- err_1 = _a.sent();
15953
- console.error(err_1 && err_1.message || err_1, err_1);
15966
+ err_2 = _a.sent();
15967
+ console.error(err_2 && err_2.message || err_2, err_2);
15954
15968
  return [4 /*yield*/, toast_1.dismiss()];
15955
15969
  case 10:
15956
15970
  _a.sent();
@@ -21333,6 +21347,7 @@
21333
21347
  AppInstallUpgradeCard.prototype.downloadLink = function (event, link) {
21334
21348
  if (!link || !link.url)
21335
21349
  return; // Skip
21350
+ console.info("[install-upgrade-card] Downloading '" + link.url + "' ...");
21336
21351
  this.platform.download({
21337
21352
  uri: link.url,
21338
21353
  filename: link.downloadFilename,
@@ -21379,15 +21394,20 @@
21379
21394
  };
21380
21395
  AppInstallUpgradeCard.prototype.getCompatibleUpgradeLinks = function (installLinks, config) {
21381
21396
  var _this = this;
21382
- var appMinVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21383
- var needUpgrade = appMinVersion && !VersionUtils.isCompatible(appMinVersion, this.environment.version);
21397
+ var appVersion = this.environment.version;
21398
+ var appMinVersionFromPod = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21399
+ if (!appVersion) {
21400
+ console.error('Missing value for \'environment.version\': cannot check app compatibility!');
21401
+ return undefined;
21402
+ }
21403
+ var needUpgrade = appMinVersionFromPod && !VersionUtils.isCompatible(appMinVersionFromPod, appVersion);
21384
21404
  if (!needUpgrade)
21385
21405
  return undefined;
21386
21406
  var upgradeLinks = installLinks
21387
21407
  .filter(function (link) { return _this.platform.is('mobileweb') || (link.platform && _this.platform.is(link.platform)); });
21388
21408
  // Use min version as default version
21389
21409
  upgradeLinks.forEach(function (link) {
21390
- link.version = link.version || appMinVersion;
21410
+ link.version = link.version || appMinVersionFromPod;
21391
21411
  });
21392
21412
  return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
21393
21413
  };
@@ -21399,6 +21419,7 @@
21399
21419
  var url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
21400
21420
  if (isNilOrBlank(url))
21401
21421
  url = this.environment.defaultAndroidInstallUrl || null;
21422
+ var minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21402
21423
  // Compute App name
21403
21424
  var name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
21404
21425
  if (url) {
@@ -21407,7 +21428,7 @@
21407
21428
  var mimeType = void 0;
21408
21429
  // Get file name
21409
21430
  var filename = this.getFilename(url);
21410
- version = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21431
+ version = minVersion || 'latest';
21411
21432
  // OK, this is a downloadable APK file (e.g. NOT a link to a playstore)
21412
21433
  if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.apk')) {
21413
21434
  // Define mime type
@@ -21417,13 +21438,12 @@
21417
21438
  version = versionMatches && versionMatches[1] || version;
21418
21439
  // Compute a new file name, with the version
21419
21440
  if (isNotNilOrBlank(name)) {
21420
- downloadFilename = name + "-" + version + ".apk";
21441
+ downloadFilename = (name + "-v" + version + ".apk").toLowerCase();
21421
21442
  }
21422
21443
  else {
21423
21444
  downloadFilename = filename;
21424
- // Replace 'latest' with the app min version
21445
+ // Replace 'latest' with the app version, if present
21425
21446
  if (downloadFilename.indexOf('latest')) {
21426
- version = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21427
21447
  downloadFilename = downloadFilename.replace('latest', version);
21428
21448
  }
21429
21449
  }
@@ -26905,6 +26925,7 @@
26905
26925
  this.userProfiles = source.userProfiles;
26906
26926
  this.excludedIds = source.excludedIds;
26907
26927
  this.searchAttribute = source.searchAttribute;
26928
+ this.searchAttributes = source.searchAttributes;
26908
26929
  };
26909
26930
  PersonFilter.prototype.asObject = function (opts) {
26910
26931
  var target = _super.prototype.asObject.call(this, opts);
@@ -26915,6 +26936,7 @@
26915
26936
  target.userProfiles = this.userProfiles;
26916
26937
  target.excludedIds = this.excludedIds;
26917
26938
  target.searchAttribute = this.searchAttribute;
26939
+ target.searchAttributes = this.searchAttributes;
26918
26940
  return target;
26919
26941
  };
26920
26942
  PersonFilter.prototype.buildFilter = function () {
@@ -26929,7 +26951,7 @@
26929
26951
  filterFns.push(function (e) { return isNil(e.id) || !_this.excludedIds.includes(e.id); });
26930
26952
  }
26931
26953
  // Search text
26932
- var searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || ['lastName', 'firstName', 'department.name'], this.searchText);
26954
+ var searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
26933
26955
  if (searchTextFilter)
26934
26956
  filterFns.push(searchTextFilter);
26935
26957
  return filterFns;
@@ -27018,7 +27040,8 @@
27018
27040
  if (ReferentialUtils.isNotEmpty(value))
27019
27041
  return [2 /*return*/, { data: [value] }];
27020
27042
  value = (typeof value === 'string' && value !== '*') && value || undefined;
27021
- return [2 /*return*/, this.loadAll(0, !value ? 30 : 10, sortBy || (filter === null || filter === void 0 ? void 0 : filter.searchAttribute), sortDirection, Object.assign(Object.assign({}, filter), { searchText: value, statusIds: filter && filter.statusIds || [StatusIds.ENABLE], userProfiles: filter && filter.userProfiles }), { withTotal: true /* need by autocomplete */ })];
27043
+ sortBy = sortBy || filter.searchAttribute || (filter.searchAttributes && filter.searchAttributes[0]);
27044
+ return [2 /*return*/, this.loadAll(0, !value ? 30 : 10, sortBy, sortDirection, Object.assign(Object.assign({}, filter), { searchText: value, statusIds: filter && filter.statusIds || [StatusIds.ENABLE], userProfiles: filter && filter.userProfiles }), { withTotal: true /* need by autocomplete */ })];
27022
27045
  });
27023
27046
  });
27024
27047
  };
@@ -27154,6 +27177,7 @@
27154
27177
  _this.filterCriteriaCount = 0;
27155
27178
  _this.statusList = StatusList;
27156
27179
  _this.statusById = StatusById;
27180
+ _this.useSticky = false;
27157
27181
  _this.referentialToString = referentialToString;
27158
27182
  _this.inlineEdition = accountService.isAdmin(); // Allow inline edition only if admin
27159
27183
  _this.canEdit = accountService.isAdmin();
@@ -27272,13 +27296,13 @@
27272
27296
  UsersPage.decorators = [
27273
27297
  { type: i0.Component, args: [{
27274
27298
  selector: 'app-users-table',
27275
- template: "<app-toolbar [title]=\"'USER.LIST.TITLE'|translate\"\n color=\"primary\"\n [canGoBack]=\"false\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\">\n <ion-buttons slot=\"end\">\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\"\n [title]=\"'COMMON.BTN_REFRESH'|translate\"\n (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt</mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n </ng-container>\n\n <ng-template #hasSelection>\n <!-- delete -->\n <button mat-icon-button\n class=\"hidden-xs hidden-sm\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"errorSubject|async ; let error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"ion-no-padding filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding\" [formGroup]=\"filterForm\" (ngSubmit)=\"onRefresh.emit()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.LIST.FILTER.SEARCH'|translate\" formControlName=\"searchText\">\n\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <!-- status -->\n <mat-form-field>\n <mat-select formControlName=\"statusId\" [placeholder]=\"'USER.STATUS'|translate\" >\n <mat-option [value]=\"null\"><i><span translate>COMMON.EMPTY_OPTION</span></i></mat-option>\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.statusId)\"\n [hidden]=\"filterForm.controls.statusId.disabled || !filterForm.controls.statusId.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {count: (totalRowCount |\n numberFormat)} }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"table-container\">\n <table #table mat-table matSort\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\" [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- avatar Column -->\n <ng-container matColumnDef=\"avatar\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let row\">\n <div class=\"avatar\" *ngIf=\"row.currentData.avatar; else generateIcon\"\n [ngStyle]=\"{'background-image':'url('+row.currentData.avatar+')'}\"></div>\n <ng-template #generateIcon>\n <div class=\"avatar\">\n <svg width=\"38\" width=\"38\" [data-jdenticon-value]=\"row.currentData.id\"></svg>\n </div>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- lastName -->\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.LAST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['lastName']\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n [readonly]=\"!row.editing\" [appAutofocus]=\"row == -1 && row.editing\">\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('minlength')\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n </td>\n\n </ng-container>\n\n <!-- firstname -->\n <ng-container matColumnDef=\"firstName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.FIRST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['firstName']\" [placeholder]=\"'USER.FIRST_NAME'|translate\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('minlength')\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- email -->\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.EMAIL</span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['email']\" [placeholder]=\"'USER.EMAIL'|translate\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('email')\">\n <span translate>ERROR.FIELD_NOT_VALID_EMAIL</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\" [matColumnDef]=\"definition.key\">\n <th mat-header-cell *matHeaderCellDef>\n <span>{{definition.label|translate}}</span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <app-form-field floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"row.validator.controls[definition.key]\"\n [required]=\"definition.extra?.account?.required\">\n </app-form-field>\n </td>\n </ng-container>\n\n <!-- profile column -->\n <ng-container matColumnDef=\"profile\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.PROFILE</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field floatLabel=\"never\">\n <mat-select [formControl]=\"row.validator.controls['mainProfile']\" [placeholder]=\"'USER.PROFILE'|translate\">\n <mat-option *ngFor=\"let item of profiles\" [value]=\"item\">\n {{ ('USER.PROFILE_ENUM.' + item) | uppercase |translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['mainProfile'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field floatLabel=\"never\">\n <ion-icon matPrefix *ngIf=\"row.validator.controls['statusId'].value &gt;=0\" [name]=\"statusById[row.validator.controls['statusId'].value]?.icon\"></ion-icon>\n\n <mat-select [formControl]=\"row.validator.controls['statusId']\" [placeholder]=\"'REFERENTIAL.STATUS'|translate\">\n <mat-select-trigger>\n <span *ngIf=\"row.validator.controls['statusId'].value &gt;=0\">\n {{ statusById[row.validator.controls['statusId'].value]?.label | translate}}</span>\n </mat-select-trigger>\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- username -->\n <ng-container matColumnDef=\"username\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls.username\" [placeholder]=\"'USER.USERNAME'|translate\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls.username.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- username extranet -->\n <ng-container matColumnDef=\"usernameExtranet\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME_EXTRANET</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls.usernameExtranet\" [placeholder]=\"'USER.USERNAME_EXTRANET'|translate\"\n [readonly]=\"!row.editing\">\n <mat-error *ngIf=\"row.validator.controls.usernameExtranet.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- pubkey -->\n <ng-container matColumnDef=\"pubkey\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.PUBKEY</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.mat-form-field-disabled]=\"!row.editing\" [title]=\"row.validator.controls['pubkey'].value\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['pubkey']\" [placeholder]=\"'USER.PUBKEY'|translate\"\n [readonly]=\"!row.editing\" autocomplete=\"off\">\n <mat-error *ngIf=\"row.validator.controls['pubkey'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['pubkey'].hasError('pubkey')\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"true\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\">\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-error]=\"row.validator.invalid\"\n [class.mat-row-dirty]=\"row.currentData.dirty\"\n [class.mat-row-disabled]=\"!row.editing\"\n (click)=\"clickRow($event, row)\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-footer>\n <mat-paginator class=\"mat-paginator-footer\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"!mobile && inlineEdition\"\n (onCancel)=\"onRefresh.emit()\" (onSave)=\"save()\" [disabled]=\"(loadingSubject|async) || !dirty\"></app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow()\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n",
27299
+ template: "<app-toolbar [title]=\"'USER.LIST.TITLE'|translate\"\n color=\"primary\"\n [canGoBack]=\"false\"\n [hasValidate]=\"!(loadingSubject|async) && dirty\"\n (onValidate)=\"save()\">\n <ion-buttons slot=\"end\">\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n <!-- Add -->\n <button mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD'|translate\"\n (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\"\n [title]=\"'COMMON.BTN_REFRESH'|translate\"\n (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\"\n *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold;\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\">filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n </ng-container>\n\n <ng-template #hasSelection>\n <!-- delete -->\n <button mat-icon-button\n class=\"hidden-xs hidden-sm\"\n [title]=\"'COMMON.BTN_DELETE'|translate\"\n (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n\n <!-- error -->\n <ion-item *ngIf=\"errorSubject|async ; let error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"ion-no-padding filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding\" [formGroup]=\"filterForm\" (ngSubmit)=\"onRefresh.emit()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.LIST.FILTER.SEARCH'|translate\" formControlName=\"searchText\">\n\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <!-- status -->\n <mat-form-field>\n <mat-select formControlName=\"statusId\" [placeholder]=\"'USER.STATUS'|translate\">\n <mat-option [value]=\"null\"><i><span translate>COMMON.EMPTY_OPTION</span></i></mat-option>\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button matSuffix tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.statusId)\"\n [hidden]=\"filterForm.controls.statusId.disabled || !filterForm.controls.statusId.value\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label [hidden]=\"(loadingSubject|async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\">\n {{ (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {\n count: (totalRowCount |\n numberFormat)\n } }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject|async\">\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"table-container\">\n <table #table mat-table matSort\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\" [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- avatar Column -->\n <ng-container matColumnDef=\"avatar\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let row\">\n <div class=\"avatar\" *ngIf=\"row.currentData.avatar; else generateIcon\"\n [ngStyle]=\"{'background-image':'url('+row.currentData.avatar+')'}\"></div>\n <ng-template #generateIcon>\n <div class=\"avatar\">\n <svg width=\"38\" width=\"38\" [data-jdenticon-value]=\"row.currentData.id\"></svg>\n </div>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- lastName -->\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.LAST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='lastName'\">\n <mat-form-field floatLabel=\"never\">\n <input matInput\n [formControl]=\"row.validator.controls['lastName']\"\n [placeholder]=\"'USER.LAST_NAME'|translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn==='lastName'\">\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('minlength')\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n </td>\n\n </ng-container>\n\n <!-- firstname -->\n <ng-container matColumnDef=\"firstName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.FIRST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n\n (click)=\"focusColumn='firstName'\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['firstName']\"\n [placeholder]=\"'USER.FIRST_NAME'|translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn==='firstName'\">\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('minlength')\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- email -->\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.EMAIL</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn='email'\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls['email']\"\n [placeholder]=\"'USER.EMAIL'|translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn==='email'\">\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('email')\">\n <span translate>ERROR.FIELD_NOT_VALID_EMAIL</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\" [matColumnDef]=\"definition.key\">\n <th mat-header-cell *matHeaderCellDef>\n <span>{{definition.label|translate}}</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn=definition.key\">\n <app-form-field floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"row.validator.controls[definition.key]\"\n [required]=\"definition.extra?.account?.required\"\n [autofocus]=\"row.editing && focusColumn===definition.ke\">\n </app-form-field>\n </td>\n </ng-container>\n\n <!-- profile column -->\n <ng-container matColumnDef=\"profile\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.PROFILE</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='profile'\">\n <mat-form-field floatLabel=\"never\">\n <mat-select [formControl]=\"row.validator.controls['mainProfile']\"\n [placeholder]=\"'USER.PROFILE'|translate\">\n <mat-option *ngFor=\"let item of profiles\" [value]=\"item\">\n {{ ('USER.PROFILE_ENUM.' + item) | uppercase |translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['mainProfile'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='status'\">\n <mat-form-field floatLabel=\"never\">\n <ion-icon matPrefix *ngIf=\"row.validator.controls['statusId'].value &gt;=0\" [name]=\"statusById[row.validator.controls['statusId'].value]?.icon\"></ion-icon>\n\n <mat-select [formControl]=\"row.validator.controls['statusId']\"\n [placeholder]=\"'REFERENTIAL.STATUS'|translate\">\n <mat-select-trigger>\n <span *ngIf=\"row.validator.controls['statusId'].value &gt;=0\">\n {{ statusById[row.validator.controls['statusId'].value]?.label | translate}}</span>\n </mat-select-trigger>\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['statusId'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- username -->\n <ng-container matColumnDef=\"username\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='username'\">\n <mat-form-field floatLabel=\"never\" >\n <input matInput [formControl]=\"row.validator.controls.username\"\n [placeholder]=\"'USER.USERNAME'|translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn==='username'\">\n <mat-error *ngIf=\"row.validator.controls.username.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- username extranet -->\n <ng-container matColumnDef=\"usernameExtranet\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME_EXTRANET</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n (click)=\"focusColumn='usernameExtranet'\">\n <mat-form-field floatLabel=\"never\">\n <input matInput [formControl]=\"row.validator.controls.usernameExtranet\"\n [placeholder]=\"'USER.USERNAME_EXTRANET'|translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn==='usernameExtranet'\">\n <mat-error *ngIf=\"row.validator.controls.usernameExtranet.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- pubkey -->\n <ng-container matColumnDef=\"pubkey\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.PUBKEY</span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n [title]=\"row.validator.controls['pubkey'].value\"\n (click)=\"focusColumn='pubkey'\">\n <mat-form-field floatLabel=\"never\" >\n <input matInput [formControl]=\"row.validator.controls['pubkey']\" [placeholder]=\"'USER.PUBKEY'|translate\"\n [readonly]=\"!row.editing\" autocomplete=\"off\">\n <mat-error *ngIf=\"row.validator.controls['pubkey'].hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"row.validator.controls['pubkey'].hasError('pubkey')\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column [stickyEnd]=\"useSticky\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\">\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n [class.mat-row-error]=\"row.validator.invalid\"\n [class.mat-row-dirty]=\"row.currentData.dirty\"\n [class.mat-row-disabled]=\"!row.editing\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator.invalid\"></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-footer>\n <mat-paginator class=\"mat-paginator-footer\"\n [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n\n <app-form-buttons-bar *ngIf=\"!mobile && inlineEdition\"\n (onCancel)=\"onRefresh.emit()\" (onSave)=\"save()\" [disabled]=\"(loadingSubject|async) || !dirty\"></app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow()\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n",
27276
27300
  providers: [
27277
27301
  { provide: ngxMaterialTable.ValidatorService, useExisting: PersonValidatorService }
27278
27302
  ],
27279
27303
  animations: [slideUpDownAnimation],
27280
27304
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
27281
- styles: [".mat-expansion-panel{margin-bottom:5px}.mat-expansion-panel .form-container mat-form-field{width:100%}.mat-expansion-panel mat-action-row ion-label{line-height:36px}.table-container{height:calc(100%)}.mat-table .mat-cell .avatar{height:40px;width:40px;margin:2px 0 0;background-size:cover;background-repeat:no-repeat;background-position:50%}.mat-table .mat-column-avatar{min-width:50px}.mat-table .mat-column-profile{min-width:110px}.mat-table .mat-column-status{min-width:130px}.mat-table .mat-column-department{min-width:150px}"]
27305
+ styles: [".mat-expansion-panel{margin-bottom:5px}.mat-expansion-panel .form-container mat-form-field{width:100%}.mat-expansion-panel mat-action-row ion-label{line-height:36px}.table-container{height:100%}.mat-table .mat-cell .avatar{height:40px;width:40px;margin:2px 0 0;background-size:cover;background-repeat:no-repeat;background-position:50%}.mat-table .mat-column-id{width:30px}.mat-table .mat-column-avatar{width:50px}.mat-table .mat-column-avatar .avatar{border-radius:5px;border:1px solid rgba(var(--ion-color-secondary-rgb),.5)}.mat-table .mat-column-firstName,.mat-table .mat-column-lastName{min-width:80px}.mat-table .mat-column-email{min-width:120px}.mat-table .mat-column-profile{min-width:110px}.mat-table .mat-column-status{min-width:130px}.mat-table .mat-column-department{min-width:150px}"]
27282
27306
  },] }
27283
27307
  ];
27284
27308
  UsersPage.ctorParameters = function () { return [
@@ -27298,6 +27322,7 @@
27298
27322
  { type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] }
27299
27323
  ]; };
27300
27324
  UsersPage.propDecorators = {
27325
+ useSticky: [{ type: i0.Input }],
27301
27326
  filterExpansionPanel: [{ type: i0.ViewChild, args: [expansion.MatExpansionPanel, { static: true },] }]
27302
27327
  };
27303
27328
 
@@ -27571,6 +27596,7 @@
27571
27596
  exports.SharedTestingModule = SharedTestingModule;
27572
27597
  exports.SharedValidators = SharedValidators;
27573
27598
  exports.SocialModule = SocialModule;
27599
+ exports.StartableService = StartableService;
27574
27600
  exports.StatusById = StatusById;
27575
27601
  exports.StatusIds = StatusIds;
27576
27602
  exports.StatusList = StatusList;
@@ -27719,17 +27745,17 @@
27719
27745
  exports.waitFor = waitFor;
27720
27746
  exports.waitIdle = waitIdle;
27721
27747
  exports.waitWhilePending = waitWhilePending;
27722
- exports0 = ɵ0$5;
27723
- exports.ɵa = CustomReuseStrategy;
27724
- exports.ɵb = MatNumpadDomService;
27725
- exports.ɵc = isFocusableElement;
27726
- exports.ɵd = RegisterForm;
27727
- exports.ɵe = AccountValidatorService;
27728
- exports.ɵf = RegisterModal;
27729
- exports.ɵg = UserSettingsValidatorService;
27730
- exports.ɵh = LocalSettingsValidatorService;
27748
+ exports["ɵ0"] = ɵ0$5;
27749
+ exports["ɵa"] = CustomReuseStrategy;
27750
+ exports["ɵb"] = MatNumpadDomService;
27751
+ exports["ɵc"] = isFocusableElement;
27752
+ exports["ɵd"] = RegisterForm;
27753
+ exports["ɵe"] = AccountValidatorService;
27754
+ exports["ɵf"] = RegisterModal;
27755
+ exports["ɵg"] = UserSettingsValidatorService;
27756
+ exports["ɵh"] = LocalSettingsValidatorService;
27731
27757
 
27732
27758
  Object.defineProperty(exports, '__esModule', { value: true });
27733
27759
 
27734
- })));
27735
- //# sourceMappingURL=ngx-sumaris-components.umd.js.map
27760
+ }));
27761
+ //# sourceMappingURL=sumaris-net.ngx-components.umd.js.map