@sumaris-net/ngx-components 1.13.0 → 1.14.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 (40) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +257 -82
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +5 -0
  6. package/esm2015/src/app/core/auth/form/form-auth.js +2 -2
  7. package/esm2015/src/app/core/install/install-upgrade-card.component.js +3 -3
  8. package/esm2015/src/app/core/services/account.service.js +1 -3
  9. package/esm2015/src/app/core/services/base-entity-service.class.js +6 -3
  10. package/esm2015/src/app/core/services/config/core.config.js +7 -1
  11. package/esm2015/src/app/core/services/network.service.js +53 -4
  12. package/esm2015/src/app/core/services/network.utils.js +1 -1
  13. package/esm2015/src/app/core/services/platform.service.js +95 -8
  14. package/esm2015/src/app/shared/http/http.utils.js +14 -2
  15. package/esm2015/src/app/shared/observables.js +2 -12
  16. package/esm2015/src/app/shared/upload-file/upload-file.component.js +12 -7
  17. package/esm2015/src/app/shared/upload-file/upload-file.model.js +8 -1
  18. package/esm2015/src/app/shared/validator/validators.js +12 -21
  19. package/esm2015/src/app/shared/version/versions.js +5 -1
  20. package/esm2015/src/environments/environment.class.js +1 -1
  21. package/fesm2015/sumaris-net.ngx-components.js +199 -48
  22. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/app/core/services/config/core.config.d.ts +1 -0
  25. package/src/app/core/services/network.service.d.ts +10 -1
  26. package/src/app/core/services/network.utils.d.ts +15 -0
  27. package/src/app/core/services/platform.service.d.ts +6 -0
  28. package/src/app/shared/http/http.utils.d.ts +1 -0
  29. package/src/app/shared/observables.d.ts +0 -1
  30. package/src/app/shared/upload-file/upload-file.model.d.ts +5 -3
  31. package/src/app/shared/validator/validators.d.ts +0 -5
  32. package/src/app/shared/version/versions.d.ts +2 -0
  33. package/src/assets/i18n/en-US.json +2 -5
  34. package/src/assets/i18n/en.json +2 -5
  35. package/src/assets/i18n/fr.json +2 -1
  36. package/src/assets/manifest.json +5 -5
  37. package/src/environments/environment.class.d.ts +1 -0
  38. package/src/theme/_responsive.scss +7 -3
  39. package/sumaris-net.ngx-components.metadata.json +1 -1
  40. package/src/assets/manifest.sumaris.json +0 -17
@@ -1187,16 +1187,6 @@
1187
1187
  });
1188
1188
  });
1189
1189
  }
1190
- function fromPromise(promise) {
1191
- var $observable = new rxjs.Subject();
1192
- promise
1193
- .then(function (errors) {
1194
- $observable.next(errors);
1195
- $observable.complete();
1196
- })
1197
- .catch(function (err) { return $observable.error(err); });
1198
- return $observable;
1199
- }
1200
1190
 
1201
1191
  function createPromiseEventEmitter() {
1202
1192
  return new i0.EventEmitter(true);
@@ -3599,21 +3589,6 @@
3599
3589
  var SharedAsyncValidators = /** @class */ (function () {
3600
3590
  function SharedAsyncValidators() {
3601
3591
  }
3602
- /**
3603
- * Create an observable validator function. Will execute the validator, then cnvert the result into an observable
3604
- * @param validatorFn any validator
3605
- */
3606
- SharedAsyncValidators.of = function (validatorFn) {
3607
- return function (control) {
3608
- var res = validatorFn(control);
3609
- if (rxjs.isObservable(res)) {
3610
- return res;
3611
- } // Already an observable
3612
- if (res instanceof Promise)
3613
- return fromPromise(res);
3614
- return rxjs.of(res);
3615
- };
3616
- };
3617
3592
  /**
3618
3593
  * Add a debounce time to a validator.
3619
3594
  * @param form
@@ -3631,8 +3606,6 @@
3631
3606
  var $disposeSubject = new rxjs.Subject();
3632
3607
  var disposeEvent$ = (opts === null || opts === void 0 ? void 0 : opts.dispose) ? rxjs.merge($disposeSubject, opts === null || opts === void 0 ? void 0 : opts.dispose)
3633
3608
  : $disposeSubject;
3634
- // Make sure validator will return an Observable - This is need by the switchMap()
3635
- var asyncValidatorFn = SharedAsyncValidators.of(validatorFn);
3636
3609
  // DEBUG
3637
3610
  if (debug && (opts === null || opts === void 0 ? void 0 : opts.dispose)) {
3638
3611
  opts === null || opts === void 0 ? void 0 : opts.dispose.pipe(operators.first()).subscribe(function () {
@@ -3654,7 +3627,16 @@
3654
3627
  console.debug(logPrefix + 'Executing...');
3655
3628
  now = Date.now();
3656
3629
  }
3657
- }), operators.switchMap(function (_) { return asyncValidatorFn(control); }),
3630
+ }), operators.switchMap(function (_) {
3631
+ // Call the validator
3632
+ var res = validatorFn(control);
3633
+ // Make sure to return an Observable
3634
+ if (rxjs.isObservable(res))
3635
+ return res;
3636
+ if (res instanceof Promise)
3637
+ return rxjs.from(res);
3638
+ return rxjs.of(res);
3639
+ }),
3658
3640
  // DEBUG
3659
3641
  operators.tap(function (res) { return debug && console.debug(logPrefix + ("Finished in " + (Date.now() - now) + "ms (" + (res ? 'with errors' : 'no error') + ")"), res); }), operators.catchError(function (error) {
3660
3642
  console.error('[debounceTime-validator] Error while executing validator. Stopping job', error);
@@ -11224,7 +11206,18 @@
11224
11206
  switch (_a.label) {
11225
11207
  case 0:
11226
11208
  // Add headers
11227
- opts = Object.assign({}, opts);
11209
+ opts = Object.assign({}, opts
11210
+ //headers: new HttpHeaders(),
11211
+ //.append('X-App-Name', environment.name)
11212
+ //.append('X-App-Version', environment.version),
11213
+ );
11214
+ // Force no cache
11215
+ if (opts.nocache === true) {
11216
+ opts.headers = (opts.headers instanceof i2$1.HttpHeaders ? opts.headers : new i2$1.HttpHeaders(opts.headers));
11217
+ opts.headers
11218
+ .append('Cache-Control', 'no-cache')
11219
+ .append('Pragma', 'no-cache');
11220
+ }
11228
11221
  _a.label = 1;
11229
11222
  case 1:
11230
11223
  _a.trys.push([1, 3, , 4]);
@@ -11282,6 +11275,7 @@
11282
11275
  }());
11283
11276
  VersionUtils.compare = compareVersionNumbers;
11284
11277
  VersionUtils.isCompatible = isVersionCompatible;
11278
+ VersionUtils.isSame = isSameVersion;
11285
11279
  /**
11286
11280
  * Compare two software version numbers (e.g. 1.7.1)
11287
11281
  * Returns:
@@ -11350,6 +11344,9 @@
11350
11344
  //console.debug(`[http] Checking actual version {${actualVersion}} is compatible with min expected version {${minVersion}}`);
11351
11345
  return compareVersionNumbers(minVersion, actualVersion) <= 0;
11352
11346
  }
11347
+ function isSameVersion(v1, v2) {
11348
+ return compareVersionNumbers(v1, v2) === 0;
11349
+ }
11353
11350
 
11354
11351
  var SelectPeerModal = /** @class */ (function () {
11355
11352
  function SelectPeerModal(viewCtrl, cd, http, environment) {
@@ -12488,15 +12485,81 @@
12488
12485
  });
12489
12486
  };
12490
12487
  NetworkService.prototype.getNodeInfo = function (peer) {
12488
+ var path = this.computePeerPath(peer, '/api/node/info');
12489
+ return this.get(path);
12490
+ };
12491
+ NetworkService.prototype.getAppManifest = function (peer, opts) {
12492
+ return __awaiter(this, void 0, void 0, function () {
12493
+ var path, err_3;
12494
+ return __generator(this, function (_b) {
12495
+ switch (_b.label) {
12496
+ case 0:
12497
+ _b.trys.push([0, 2, , 3]);
12498
+ path = this.computePeerPath(peer, 'manifest.json');
12499
+ if (opts === null || opts === void 0 ? void 0 : opts.nocache) {
12500
+ path += '?t=' + Date.now();
12501
+ }
12502
+ return [4 /*yield*/, this.get(path, opts)];
12503
+ case 1: return [2 /*return*/, _b.sent()];
12504
+ case 2:
12505
+ err_3 = _b.sent();
12506
+ if (this.environment.production)
12507
+ console.error('[network] Cannot load file \'manifest.json\'. Please make sure webserver config allow CORS access', err_3);
12508
+ else
12509
+ console.error('[network] Cannot load file \'manifest.json\'.', err_3);
12510
+ return [3 /*break*/, 3];
12511
+ case 3: return [2 /*return*/];
12512
+ }
12513
+ });
12514
+ });
12515
+ };
12516
+ NetworkService.prototype.getAppVersion = function (peer, opts) {
12517
+ return __awaiter(this, void 0, void 0, function () {
12518
+ var path, appVersion, err_4, manifest;
12519
+ return __generator(this, function (_b) {
12520
+ switch (_b.label) {
12521
+ case 0:
12522
+ _b.trys.push([0, 2, , 3]);
12523
+ path = this.computePeerPath(peer, 'version.appup');
12524
+ if (opts === null || opts === void 0 ? void 0 : opts.nocache) {
12525
+ path += '?t=' + Date.now();
12526
+ }
12527
+ return [4 /*yield*/, this.get(path, opts)];
12528
+ case 1:
12529
+ appVersion = _b.sent();
12530
+ if (isNotNilOrBlank(appVersion))
12531
+ return [2 /*return*/, appVersion];
12532
+ return [3 /*break*/, 3];
12533
+ case 2:
12534
+ err_4 = _b.sent();
12535
+ if (this.environment.production)
12536
+ console.error('[network] Cannot load file \'version.appup\'. Please make sure webserver config allow CORS access');
12537
+ else
12538
+ console.error('[network] Cannot load file \'version.appup\'.', err_4);
12539
+ return [3 /*break*/, 3];
12540
+ case 3: return [4 /*yield*/, this.getAppManifest(peer, opts)];
12541
+ case 4:
12542
+ manifest = _b.sent();
12543
+ return [2 /*return*/, manifest === null || manifest === void 0 ? void 0 : manifest.version];
12544
+ }
12545
+ });
12546
+ });
12547
+ };
12548
+ NetworkService.prototype.computePeerPath = function (peer, path) {
12491
12549
  peer = peer || this.peer;
12492
12550
  if (!peer)
12493
12551
  return undefined;
12494
- var peerUrl = isInstanceOf(peer, exports.Peer) ? peer.url : peer;
12552
+ var peerUrl = (peer instanceof exports.Peer) ? peer.url : peer;
12495
12553
  // Remove trailing slash
12496
12554
  if (peerUrl.endsWith('/')) {
12497
12555
  peerUrl = peerUrl.substr(0, peerUrl.length - 1);
12498
12556
  }
12499
- return this.get(peerUrl + '/api/node/info');
12557
+ // Add first path
12558
+ if (!path.startsWith('/')) {
12559
+ path = '/' + path;
12560
+ }
12561
+ // Concat peer URL and path
12562
+ return peerUrl + path;
12500
12563
  };
12501
12564
  /**
12502
12565
  * Allow to force offline mode
@@ -15878,8 +15941,6 @@
15878
15941
  };
15879
15942
  AccountService.prototype.canUserWriteDataForDepartment = function (recorderDepartment) {
15880
15943
  if (ReferentialUtils.isEmpty(recorderDepartment)) {
15881
- if (!this.isAdmin())
15882
- console.warn('Unable to check if user has right: invalid recorderDepartment', recorderDepartment);
15883
15944
  return this.isAdmin();
15884
15945
  }
15885
15946
  // Should be login, and status ENABLE
@@ -17185,6 +17246,12 @@
17185
17246
  key: 'sumaris.android.install.url',
17186
17247
  label: 'CONFIGURATION.OPTIONS.ANDROID_INSTALL_URL',
17187
17248
  type: 'string'
17249
+ },
17250
+ DB_TIMEZONE: {
17251
+ key: 'sumaris.persistence.db.timezone',
17252
+ label: 'DB Timezone (readonly)',
17253
+ type: 'string',
17254
+ isTransient: true // ONly on server, cannot be set
17188
17255
  }
17189
17256
  });
17190
17257
 
@@ -17650,6 +17717,9 @@
17650
17717
  PlatformService.prototype.isApp = function () {
17651
17718
  return this._cordova && (this._android || this._ios);
17652
17719
  };
17720
+ PlatformService.prototype.isMobileWeb = function () {
17721
+ return isMobile(window) && this.isWeb();
17722
+ };
17653
17723
  Object.defineProperty(PlatformService.prototype, "canDownload", {
17654
17724
  get: function () {
17655
17725
  return !!this.downloader && this.isAndroidCordova();
@@ -17671,18 +17741,19 @@
17671
17741
  return this.platform.height();
17672
17742
  };
17673
17743
  PlatformService.prototype.ngOnStart = function () {
17744
+ var _a, _b;
17674
17745
  return __awaiter(this, void 0, void 0, function () {
17675
- var now, storage, err_1;
17746
+ var now, storage, intervalMs, err_1;
17676
17747
  var _this = this;
17677
- return __generator(this, function (_b) {
17678
- switch (_b.label) {
17748
+ return __generator(this, function (_d) {
17749
+ switch (_d.label) {
17679
17750
  case 0:
17680
17751
  now = Date.now();
17681
17752
  this.accountService.tokenType = undefined;
17682
17753
  console.info('[platform] Starting platform...');
17683
- _b.label = 1;
17754
+ _d.label = 1;
17684
17755
  case 1:
17685
- _b.trys.push([1, 6, , 7]);
17756
+ _d.trys.push([1, 7, , 8]);
17686
17757
  this._mobile = this.is('mobile');
17687
17758
  this._cordova = this.is('cordova');
17688
17759
  this._android = this.is('android');
@@ -17694,29 +17765,37 @@
17694
17765
  return [4 /*yield*/, this.configureTranslate()];
17695
17766
  case 2:
17696
17767
  // Configure translation
17697
- _b.sent();
17768
+ _d.sent();
17698
17769
  return [4 /*yield*/, this.storageReady()];
17699
17770
  case 3:
17700
- storage = _b.sent();
17771
+ storage = _d.sent();
17701
17772
  return [4 /*yield*/, this.migrateStorage(storage)];
17702
17773
  case 4:
17703
- _b.sent();
17774
+ _d.sent();
17704
17775
  // Start root services
17705
17776
  return [4 /*yield*/, Promise.all([
17706
17777
  this.entitiesStorage.ready(),
17707
- this.cache.ready().then(function () { return _this.configureCache(); }),
17778
+ this.cache.ready(),
17708
17779
  this.settings.ready(),
17709
17780
  this.networkService.ready(),
17710
17781
  this.audioProvider.ready()
17711
17782
  ])];
17712
17783
  case 5:
17713
17784
  // Start root services
17714
- _b.sent();
17715
- console.info("[platform] Starting platform [OK] {mobile: " + this._mobile + ", downloader: " + this.canDownload + ", fileOpener: " + this.canOpenFile + "} in " + (Date.now() - now) + "ms");
17785
+ _d.sent();
17786
+ return [4 /*yield*/, Promise.all([
17787
+ this.configureCache(),
17788
+ this.checkAppVersion({ canReload: true })
17789
+ ])];
17790
+ case 6:
17791
+ _d.sent();
17716
17792
  // Update cache configuration when network changed
17717
17793
  this.networkService.onNetworkStatusChanges
17718
- .pipe(operators.skip(1)) // Skip the first event (behavior subject send event immediately)
17719
- .subscribe(function (type) { return _this.configureCache(type !== 'none'); });
17794
+ .pipe(operators.skip(1), operators.map(function (type) { return type !== 'none'; }), operators.debounceTime(1000), operators.distinctUntilChanged(),
17795
+ // Configure the cache
17796
+ operators.tap(function (online) { return _this.configureCache(online); }))
17797
+ .subscribe();
17798
+ console.info("[platform] Starting platform [OK] {mobile: " + this._mobile + ", web: " + this.isWeb() + ", downloader: " + this.canDownload + ", fileOpener: " + this.canOpenFile + "} in " + (Date.now() - now) + "ms");
17720
17799
  // Update authentication type
17721
17800
  this.configService.config
17722
17801
  .pipe(operators.map(function (config) { return config === null || config === void 0 ? void 0 : config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE); }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged())
@@ -17733,12 +17812,21 @@
17733
17812
  _this.audioProvider.playStartupSound();
17734
17813
  }, 1000);
17735
17814
  }
17736
- return [3 /*break*/, 7];
17737
- case 6:
17738
- err_1 = _b.sent();
17815
+ // Check if new version, every 1 min
17816
+ if (this.isWeb()) {
17817
+ intervalMs = (((_a = this.environment) === null || _a === void 0 ? void 0 : _a.checkAppVersionIntervalInSeconds) || 0) * 1000;
17818
+ if (intervalMs > 0) {
17819
+ (_b = this.checkAppVersionTimer) === null || _b === void 0 ? void 0 : _b.unsubscribe();
17820
+ this.checkAppVersionTimer = rxjs.timer(intervalMs, intervalMs)
17821
+ .subscribe(function (_) { return _this.checkAppVersion({ silent: true, canReload: false /*do NOT auto reload, when app is started*/ }); });
17822
+ }
17823
+ }
17824
+ return [3 /*break*/, 8];
17825
+ case 7:
17826
+ err_1 = _d.sent();
17739
17827
  // Manage startup error
17740
17828
  return [2 /*return*/, this.onStartupError(err_1)];
17741
- case 7: return [2 /*return*/];
17829
+ case 8: return [2 /*return*/];
17742
17830
  }
17743
17831
  });
17744
17832
  });
@@ -17859,16 +17947,88 @@
17859
17947
  this.cache.setDefaultTTL(cacheTTL);
17860
17948
  this.cache.setOfflineInvalidate(false); // Do not invalidate cache when offline
17861
17949
  };
17950
+ PlatformService.prototype.checkAppVersion = function (opts) {
17951
+ var _a, _b, _c;
17952
+ return __awaiter(this, void 0, void 0, function () {
17953
+ var silent, production, actualVersion, peer, remoteVersion, canAutoReload, reloadPath;
17954
+ return __generator(this, function (_d) {
17955
+ switch (_d.label) {
17956
+ case 0:
17957
+ if (this.networkService.offline || !this.isWeb())
17958
+ return [2 /*return*/]; // Skip
17959
+ silent = (opts === null || opts === void 0 ? void 0 : opts.silent) === true;
17960
+ production = this.environment.production;
17961
+ if (!silent)
17962
+ console.info('[platform] Checking remote app version...');
17963
+ actualVersion = this.environment.version;
17964
+ if (isNilOrBlank(actualVersion)) {
17965
+ console.warn('[platform] Missing required value for \'environment.version\'. Cannot check remote app version.');
17966
+ (_a = this.checkAppVersionTimer) === null || _a === void 0 ? void 0 : _a.unsubscribe(); // Stop timer if exists
17967
+ return [2 /*return*/]; // Skip
17968
+ }
17969
+ peer = undefined;
17970
+ return [4 /*yield*/, this.networkService.getAppVersion(peer)];
17971
+ case 1:
17972
+ remoteVersion = _d.sent();
17973
+ if (isNilOrBlank(remoteVersion)) {
17974
+ if (production && !silent)
17975
+ console.error('[platform] Cannot load remote app version. Skipping version check');
17976
+ (_b = this.checkAppVersionTimer) === null || _b === void 0 ? void 0 : _b.unsubscribe(); // Stop timer if exists
17977
+ return [2 /*return*/];
17978
+ }
17979
+ if (VersionUtils.isCompatible(remoteVersion, actualVersion)) {
17980
+ if (!silent)
17981
+ console.info('[platform] Checking remote app version [OK]');
17982
+ return [2 /*return*/];
17983
+ }
17984
+ canAutoReload = !opts || opts.canReload !== false;
17985
+ // Avoid infinite loop, if already reloaded
17986
+ if (location.href.indexOf('?version=' + remoteVersion) !== -1) {
17987
+ if (canAutoReload)
17988
+ console.error("[platform] Reloaded page failed, because version still mismatch! Please check version.appup file (expected app version: " + actualVersion + ")");
17989
+ (_c = this.checkAppVersionTimer) === null || _c === void 0 ? void 0 : _c.unsubscribe();
17990
+ return [2 /*return*/];
17991
+ }
17992
+ console.warn("[platform] More recent version detected (remote: " + remoteVersion + ", actual: " + actualVersion);
17993
+ reloadPath = location.href.replace(/[&?]{1}[a-z_-]=[0-9.]+/gi, '');
17994
+ reloadPath += (reloadPath.indexOf('?') === -1) ? '?' : '&'; // Add query param separator
17995
+ reloadPath += 'version=' + remoteVersion; // Add version (to avoid a reload infinite loop)
17996
+ console.info('[platform] Will reloading at ' + reloadPath);
17997
+ if (!canAutoReload) return [3 /*break*/, 2];
17998
+ location.href = reloadPath;
17999
+ return [3 /*break*/, 4];
18000
+ case 2: return [4 /*yield*/, this.showToast({
18001
+ message: 'CONFIRM.RELOAD_APP',
18002
+ messageParams: { version: remoteVersion, name: this.environment.name },
18003
+ type: 'info', duration: -1,
18004
+ buttons: [
18005
+ // Reload button
18006
+ { text: this.translate.instant('COMMON.BTN_RELOAD'),
18007
+ side: 'end', handler: function () {
18008
+ location.href = reloadPath;
18009
+ return true;
18010
+ }
18011
+ }
18012
+ ]
18013
+ })];
18014
+ case 3:
18015
+ _d.sent();
18016
+ _d.label = 4;
18017
+ case 4: return [2 /*return*/];
18018
+ }
18019
+ });
18020
+ });
18021
+ };
17862
18022
  PlatformService.prototype.storageReady = function () {
17863
18023
  return __awaiter(this, void 0, void 0, function () {
17864
18024
  var forage, driver;
17865
- return __generator(this, function (_b) {
17866
- switch (_b.label) {
18025
+ return __generator(this, function (_d) {
18026
+ switch (_d.label) {
17867
18027
  case 0:
17868
18028
  console.info("[platform] Starting storage...");
17869
18029
  return [4 /*yield*/, this.storage.ready()];
17870
18030
  case 1:
17871
- forage = _b.sent();
18031
+ forage = _d.sent();
17872
18032
  driver = forage.driver();
17873
18033
  if (isNil(driver)) {
17874
18034
  console.error('[platform] NO DRIVER DEFINED IN STORAGE. Local storage cannot be used !');
@@ -17884,8 +18044,8 @@
17884
18044
  PlatformService.prototype.migrateStorage = function (storage) {
17885
18045
  return __awaiter(this, void 0, void 0, function () {
17886
18046
  var canMigrate, oldForage, keys, now, toast_1, duration, err_2;
17887
- return __generator(this, function (_b) {
17888
- switch (_b.label) {
18047
+ return __generator(this, function (_d) {
18048
+ switch (_d.label) {
17889
18049
  case 0:
17890
18050
  canMigrate = storage &&
17891
18051
  ((storage.driver() === 'cordovaSQLiteDriver' && (storage.supports(storage.INDEXEDDB) || storage.supports(storage.WEBSQL))) ||
@@ -17899,26 +18059,26 @@
17899
18059
  });
17900
18060
  return [4 /*yield*/, oldForage.keys()];
17901
18061
  case 1:
17902
- keys = _b.sent();
18062
+ keys = _d.sent();
17903
18063
  if (!isEmptyArray(keys)) return [3 /*break*/, 3];
17904
18064
  // Drop the old instance (not need anymore)
17905
18065
  console.debug("[platform] Old storage is empty: dropping unused instance {name: '" + storage.config().name + "', driver: '" + oldForage.driver() + "'}");
17906
18066
  return [4 /*yield*/, oldForage.dropInstance()];
17907
18067
  case 2:
17908
- _b.sent();
18068
+ _d.sent();
17909
18069
  return [3 /*break*/, 12];
17910
18070
  case 3:
17911
18071
  now = Date.now();
17912
18072
  console.info("[platform] Starting storage migration...");
17913
18073
  return [4 /*yield*/, this.showToast({ message: 'INFO.DATA_MIGRATION_STARTED', type: 'info', duration: 30000 })];
17914
18074
  case 4:
17915
- toast_1 = _b.sent();
17916
- _b.label = 5;
18075
+ toast_1 = _d.sent();
18076
+ _d.label = 5;
17917
18077
  case 5:
17918
- _b.trys.push([5, 9, , 12]);
18078
+ _d.trys.push([5, 9, , 12]);
17919
18079
  return [4 /*yield*/, StorageUtils.copy(oldForage, storage, { keys: keys, deleteAfterCopy: false })];
17920
18080
  case 6:
17921
- _b.sent();
18081
+ _d.sent();
17922
18082
  duration = Date.now() - now;
17923
18083
  setTimeout(function () { return toast_1.dismiss(); }, Math.max(2000 - duration, 0));
17924
18084
  return [4 /*yield*/, this.showToast({ message: 'INFO.DATA_MIGRATION_SUCCEED',
@@ -17926,26 +18086,26 @@
17926
18086
  showCloseButton: true
17927
18087
  })];
17928
18088
  case 7:
17929
- _b.sent();
18089
+ _d.sent();
17930
18090
  console.info('[platform] Starting storage migration [OK]');
17931
18091
  // Drop the old instance
17932
18092
  console.info("[platform] Drop old storage {name: '" + storage.config().name + "', driver: '" + oldForage.driver() + "'}");
17933
18093
  return [4 /*yield*/, oldForage.dropInstance()];
17934
18094
  case 8:
17935
- _b.sent();
18095
+ _d.sent();
17936
18096
  return [3 /*break*/, 12];
17937
18097
  case 9:
17938
- err_2 = _b.sent();
18098
+ err_2 = _d.sent();
17939
18099
  console.error(err_2 && err_2.message || err_2, err_2);
17940
18100
  return [4 /*yield*/, toast_1.dismiss()];
17941
18101
  case 10:
17942
- _b.sent();
18102
+ _d.sent();
17943
18103
  return [4 /*yield*/, this.showToast({ message: 'ERROR.DATA_MIGRATION_FAILED',
17944
18104
  type: 'error',
17945
18105
  showCloseButton: true
17946
18106
  })];
17947
18107
  case 11:
17948
- _b.sent();
18108
+ _d.sent();
17949
18109
  return [3 /*break*/, 12];
17950
18110
  case 12: return [2 /*return*/];
17951
18111
  }
@@ -17961,8 +18121,8 @@
17961
18121
  PlatformService.prototype.onStartupError = function (err) {
17962
18122
  return __awaiter(this, void 0, void 0, function () {
17963
18123
  var message, detailsMessage;
17964
- return __generator(this, function (_b) {
17965
- switch (_b.label) {
18124
+ return __generator(this, function (_d) {
18125
+ switch (_d.label) {
17966
18126
  case 0:
17967
18127
  console.error('[platform] Failed starting the platform! ', err);
17968
18128
  message = err && err.message || err;
@@ -17974,14 +18134,14 @@
17974
18134
  if (!this.translate) return [3 /*break*/, 2];
17975
18135
  return [4 /*yield*/, this.translate.get(message).toPromise()];
17976
18136
  case 1:
17977
- message = _b.sent();
18137
+ message = _d.sent();
17978
18138
  if (err && err.code) {
17979
18139
  message += " {code: " + err.code + "}";
17980
18140
  }
17981
18141
  return [3 /*break*/, 3];
17982
18142
  case 2:
17983
18143
  message = "Fatal error: Please contact your administrator.\n\n{code: " + (err && err.code || 'null') + ", message: \"" + message + "\"}";
17984
- _b.label = 3;
18144
+ _d.label = 3;
17985
18145
  case 3:
17986
18146
  if (!this.toastController) return [3 /*break*/, 5];
17987
18147
  if (detailsMessage) {
@@ -17994,7 +18154,7 @@
17994
18154
  message: message
17995
18155
  })];
17996
18156
  case 4:
17997
- _b.sent();
18157
+ _d.sent();
17998
18158
  return [3 /*break*/, 6];
17999
18159
  case 5:
18000
18160
  if (window) {
@@ -18008,7 +18168,7 @@
18008
18168
  if (err && err.details)
18009
18169
  console.error('cause', err.details);
18010
18170
  }
18011
- _b.label = 6;
18171
+ _d.label = 6;
18012
18172
  case 6: return [2 /*return*/];
18013
18173
  }
18014
18174
  });
@@ -18138,6 +18298,13 @@
18138
18298
  }
18139
18299
  return FileResponse;
18140
18300
  }());
18301
+ function isProgressEvent(event) {
18302
+ return event.type === i2$1.HttpEventType.UploadProgress
18303
+ || event.type === i2$1.HttpEventType.DownloadProgress;
18304
+ }
18305
+ function isResponseEvent(event) {
18306
+ return event.type === i2$1.HttpEventType.Response;
18307
+ }
18141
18308
 
18142
18309
  var UploadFileComponent = /** @class */ (function () {
18143
18310
  function UploadFileComponent(cd, translate) {
@@ -18304,7 +18471,7 @@
18304
18471
  operators.switchMap(function (file) { return _this.uploadFn(file)
18305
18472
  .pipe(operators.map(function (event) {
18306
18473
  // Progress event
18307
- if ((event === null || event === void 0 ? void 0 : event.type) === i2$1.HttpEventType.UploadProgress || event.type === i2$1.HttpEventType.User) {
18474
+ if (isProgressEvent(event)) {
18308
18475
  if (isNotNil(event.loaded) && event.loaded >= 0) {
18309
18476
  file.progress = Math.min(1, event.loaded / (event.total || 1));
18310
18477
  }
@@ -18312,15 +18479,20 @@
18312
18479
  file.progress = -1; // Indeterminate progression
18313
18480
  }
18314
18481
  }
18482
+ // User event
18483
+ else if (event.type === i2$1.HttpEventType.User) {
18484
+ file.progress = -1; // Indeterminate progression
18485
+ }
18315
18486
  // Response event
18316
- else if (event instanceof i2$1.HttpResponse || event instanceof FileResponse) {
18487
+ else if (isResponseEvent(event)) {
18317
18488
  file.progress = 1;
18318
18489
  file.response = event;
18319
18490
  console.debug("[upload-file] " + file.name + ": " + (event.statusText || 'OK'), file.response);
18320
18491
  }
18321
- // Other events
18492
+ // Other events: ignore
18322
18493
  else {
18323
- console.warn('[upload-file] Unknown event, returned by uploadFn\'s observable:', event);
18494
+ // DEBUG
18495
+ console.debug('[upload-file] Ignoring a file event: ', event);
18324
18496
  }
18325
18497
  return file;
18326
18498
  }), operators.catchError(function (err) {
@@ -20485,7 +20657,7 @@
20485
20657
  _this.showPwd = false;
20486
20658
  _this.onCancel = new i0.EventEmitter();
20487
20659
  _this.onSubmit = new i0.EventEmitter();
20488
- _this.mobile = platform.mobile;
20660
+ _this.mobile = settings.mobile;
20489
20661
  _this.canWorkOffline = _this.settings.hasOfflineFeature();
20490
20662
  _this._enable = true;
20491
20663
  return _this;
@@ -22943,10 +23115,10 @@
22943
23115
  };
22944
23116
  AppInstallUpgradeCard.prototype.getCompatibleInstallLinks = function (installLinks) {
22945
23117
  // Cordova already running: not need to install
22946
- if (this.platform.is('cordova'))
23118
+ if (this.platform.isCordova())
22947
23119
  return undefined;
22948
23120
  // If mobile web: return all
22949
- if (this.platform.is('mobileweb')) {
23121
+ if (this.platform.isMobileWeb()) {
22950
23122
  return installLinks;
22951
23123
  }
22952
23124
  return undefined;
@@ -24330,8 +24502,10 @@
24330
24502
  var _this = this;
24331
24503
  if (isNil(id))
24332
24504
  throw Error('Missing argument \'id\' ');
24333
- if (!this.subscriptions.listenChanges)
24334
- throw Error('Not implemented!');
24505
+ if (!this.subscriptions.listenChanges) {
24506
+ console.warn(this.constructor.name + ".listenChanges() not implemented yet. Will empty observable");
24507
+ return rxjs.of();
24508
+ }
24335
24509
  var variables = opts && opts.variables || {
24336
24510
  id: id,
24337
24511
  interval: toNumber(opts && opts.interval, 0) // no timer by default
@@ -31111,7 +31285,6 @@
31111
31285
  exports.formatLatitude = formatLatitude;
31112
31286
  exports.formatLongitude = formatLongitude;
31113
31287
  exports.fromDateISOString = fromDateISOString;
31114
- exports.fromPromise = fromPromise;
31115
31288
  exports.fromScrollEndEvent = fromScrollEndEvent;
31116
31289
  exports.fromUnixMsTimestamp = fromUnixMsTimestamp;
31117
31290
  exports.fromUnixTimestamp = fromUnixTimestamp;
@@ -31150,6 +31323,8 @@
31150
31323
  exports.isNotNilString = isNotNilString;
31151
31324
  exports.isNumber = isNumber;
31152
31325
  exports.isNumberRange = isNumberRange;
31326
+ exports.isProgressEvent = isProgressEvent;
31327
+ exports.isResponseEvent = isResponseEvent;
31153
31328
  exports.isTouchUi = isTouchUi;
31154
31329
  exports.isWindow = isWindow;
31155
31330
  exports.joinProperties = joinProperties;