@sumaris-net/ngx-components 0.24.3 → 0.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/sumaris-net.ngx-components.umd.js +1100 -906
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +4 -0
- package/esm2015/public_api.js +2 -1
- package/esm2015/src/app/admin/users/list/users.js +6 -4
- package/esm2015/src/app/core/graphql/graphql.service.js +26 -74
- package/esm2015/src/app/core/install/install-upgrade-card.component.js +134 -46
- package/esm2015/src/app/core/services/account.service.js +146 -149
- package/esm2015/src/app/core/services/config.service.js +21 -14
- package/esm2015/src/app/core/services/local-settings.service.js +72 -87
- package/esm2015/src/app/core/services/model/peer.model.js +15 -2
- package/esm2015/src/app/core/services/network.service.js +134 -169
- package/esm2015/src/app/core/services/platform.service.js +46 -17
- package/esm2015/src/app/core/services/storage/entities-storage.service.js +59 -63
- package/esm2015/src/app/shared/audio/audio.js +10 -39
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +2 -2
- package/esm2015/src/app/shared/services/startable-service.class.js +77 -0
- package/esm2015/src/environments/environment.class.js +1 -1
- package/esm2015/src/environments/environment.js +5 -1
- package/fesm2015/sumaris-net.ngx-components.js +724 -649
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +1 -0
- package/src/app/admin/users/list/users.d.ts +1 -0
- package/src/app/core/graphql/graphql.service.d.ts +5 -13
- package/src/app/core/install/install-upgrade-card.component.d.ts +14 -7
- package/src/app/core/services/account.service.d.ts +11 -10
- package/src/app/core/services/config.service.d.ts +6 -5
- package/src/app/core/services/local-settings.service.d.ts +4 -9
- package/src/app/core/services/model/peer.model.d.ts +1 -0
- package/src/app/core/services/network.service.d.ts +27 -38
- package/src/app/core/services/platform.service.d.ts +3 -1
- package/src/app/core/services/storage/entities-storage.service.d.ts +13 -13
- package/src/app/shared/audio/audio.d.ts +4 -8
- package/src/app/shared/services/startable-service.class.d.ts +26 -0
- package/src/assets/i18n/fr.json +3 -0
- package/src/environments/environment.class.d.ts +1 -0
- package/sumaris-net.ngx-components.metadata.json +1 -1
|
@@ -7732,39 +7732,134 @@
|
|
|
7732
7732
|
matInput: [{ type: i0.ViewChild, args: ['matInput',] }]
|
|
7733
7733
|
};
|
|
7734
7734
|
|
|
7735
|
-
var
|
|
7736
|
-
|
|
7737
|
-
{ id: 'beep-error', assetPath: 'assets/audio/beep-error.mp3', vibration: 1000 },
|
|
7738
|
-
{ id: 'startup', assetPath: 'assets/audio/unfa-ping.mp3', vibration: [1, 500, 250, 750] },
|
|
7739
|
-
];
|
|
7740
|
-
var AudioProvider = /** @class */ (function () {
|
|
7741
|
-
function AudioProvider(platform, nativeAudio, vibration, audioManagement) {
|
|
7742
|
-
this.platform = platform;
|
|
7743
|
-
this.nativeAudio = nativeAudio;
|
|
7744
|
-
this.vibration = vibration;
|
|
7745
|
-
this.audioManagement = audioManagement;
|
|
7746
|
-
this._started = false;
|
|
7747
|
-
this._audioMode = ngx$1.AudioManagement.AudioMode.NORMAL;
|
|
7748
|
-
this._preloadedSounds = {};
|
|
7749
|
-
this._htmlAudioCache = {};
|
|
7735
|
+
var StartableService = /** @class */ (function () {
|
|
7736
|
+
function StartableService(platform) {
|
|
7750
7737
|
this.onStart = new rxjs.Subject();
|
|
7751
|
-
this.
|
|
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(); };
|
|
7752
7744
|
}
|
|
7753
|
-
|
|
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 () {
|
|
7754
7769
|
return __awaiter(this, void 0, void 0, function () {
|
|
7770
|
+
var err_1;
|
|
7755
7771
|
return __generator(this, function (_a) {
|
|
7756
7772
|
switch (_a.label) {
|
|
7757
7773
|
case 0:
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
return [4 /*yield*/, this.start()];
|
|
7774
|
+
_a.trys.push([0, 2, , 3]);
|
|
7775
|
+
return [4 /*yield*/, this.ngOnStop()];
|
|
7761
7776
|
case 1:
|
|
7762
7777
|
_a.sent();
|
|
7763
|
-
|
|
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
|
|
7764
7808
|
}
|
|
7765
7809
|
});
|
|
7766
7810
|
});
|
|
7767
7811
|
};
|
|
7812
|
+
Object.defineProperty(StartableService.prototype, "started", {
|
|
7813
|
+
get: function () {
|
|
7814
|
+
return this._started;
|
|
7815
|
+
},
|
|
7816
|
+
enumerable: false,
|
|
7817
|
+
configurable: true
|
|
7818
|
+
});
|
|
7819
|
+
Object.defineProperty(StartableService.prototype, "starting", {
|
|
7820
|
+
get: function () {
|
|
7821
|
+
return !!this._startPromise;
|
|
7822
|
+
},
|
|
7823
|
+
enumerable: false,
|
|
7824
|
+
configurable: true
|
|
7825
|
+
});
|
|
7826
|
+
StartableService.prototype.ready = function () {
|
|
7827
|
+
if (this._started)
|
|
7828
|
+
return Promise.resolve(this._data);
|
|
7829
|
+
return this.start();
|
|
7830
|
+
};
|
|
7831
|
+
StartableService.prototype.ngOnStop = function () {
|
|
7832
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
7833
|
+
return __generator(this, function (_a) {
|
|
7834
|
+
return [2 /*return*/];
|
|
7835
|
+
});
|
|
7836
|
+
});
|
|
7837
|
+
};
|
|
7838
|
+
return StartableService;
|
|
7839
|
+
}());
|
|
7840
|
+
StartableService.ctorParameters = function () { return [
|
|
7841
|
+
{ type: undefined, decorators: [{ type: i0.Optional }] }
|
|
7842
|
+
]; };
|
|
7843
|
+
|
|
7844
|
+
var SYSTEM_SOUNDS = [
|
|
7845
|
+
{ id: 'beep-confirm', assetPath: 'assets/audio/beep-confirm.mp3', vibration: 250 },
|
|
7846
|
+
{ id: 'beep-error', assetPath: 'assets/audio/beep-error.mp3', vibration: 1000 },
|
|
7847
|
+
{ id: 'startup', assetPath: 'assets/audio/unfa-ping.mp3', vibration: [1, 500, 250, 750] },
|
|
7848
|
+
];
|
|
7849
|
+
var AudioProvider = /** @class */ (function (_super) {
|
|
7850
|
+
__extends(AudioProvider, _super);
|
|
7851
|
+
function AudioProvider(platform, nativeAudio, vibration, audioManagement) {
|
|
7852
|
+
var _this = _super.call(this, platform) || this;
|
|
7853
|
+
_this.platform = platform;
|
|
7854
|
+
_this.nativeAudio = nativeAudio;
|
|
7855
|
+
_this.vibration = vibration;
|
|
7856
|
+
_this.audioManagement = audioManagement;
|
|
7857
|
+
_this._audioMode = ngx$1.AudioManagement.AudioMode.NORMAL;
|
|
7858
|
+
_this._preloadedSounds = {};
|
|
7859
|
+
_this._htmlAudioCache = {};
|
|
7860
|
+
_this.start();
|
|
7861
|
+
return _this;
|
|
7862
|
+
}
|
|
7768
7863
|
AudioProvider.prototype.playBeepConfirm = function () {
|
|
7769
7864
|
return this.play('beep-confirm', {
|
|
7770
7865
|
// Vibrate only if in vibration mode
|
|
@@ -7828,7 +7923,7 @@
|
|
|
7828
7923
|
return __generator(this, function (_a) {
|
|
7829
7924
|
switch (_a.label) {
|
|
7830
7925
|
case 0:
|
|
7831
|
-
if (!!this.
|
|
7926
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
7832
7927
|
return [4 /*yield*/, this.ready()];
|
|
7833
7928
|
case 1:
|
|
7834
7929
|
_a.sent();
|
|
@@ -7912,7 +8007,7 @@
|
|
|
7912
8007
|
return __generator(this, function (_a) {
|
|
7913
8008
|
switch (_a.label) {
|
|
7914
8009
|
case 0:
|
|
7915
|
-
if (!!this.
|
|
8010
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
7916
8011
|
return [4 /*yield*/, this.ready()];
|
|
7917
8012
|
case 1:
|
|
7918
8013
|
_a.sent();
|
|
@@ -7927,15 +8022,10 @@
|
|
|
7927
8022
|
});
|
|
7928
8023
|
};
|
|
7929
8024
|
/* -- protected methods -- */
|
|
7930
|
-
AudioProvider.prototype.
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
if (this._started)
|
|
7935
|
-
return Promise.resolve();
|
|
7936
|
-
var cordova;
|
|
7937
|
-
this._startPromise = this.platform.ready()
|
|
7938
|
-
.then(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
8025
|
+
AudioProvider.prototype.ngOnStart = function () {
|
|
8026
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8027
|
+
var cordova;
|
|
8028
|
+
var _this = this;
|
|
7939
8029
|
return __generator(this, function (_a) {
|
|
7940
8030
|
switch (_a.label) {
|
|
7941
8031
|
case 0:
|
|
@@ -7947,33 +8037,21 @@
|
|
|
7947
8037
|
case 1:
|
|
7948
8038
|
_a.sent();
|
|
7949
8039
|
_a.label = 2;
|
|
7950
|
-
case 2:
|
|
8040
|
+
case 2:
|
|
8041
|
+
// Pre-loading system sounds
|
|
8042
|
+
console.debug('[audio] Preloading audio sounds...');
|
|
8043
|
+
return [4 /*yield*/, Promise.all(SYSTEM_SOUNDS.map(function (s) {
|
|
8044
|
+
// Disable vibration is cordova not enabled
|
|
8045
|
+
if (!cordova)
|
|
8046
|
+
s.vibration = undefined;
|
|
8047
|
+
return _this.preload(s);
|
|
8048
|
+
}))];
|
|
8049
|
+
case 3:
|
|
8050
|
+
_a.sent();
|
|
8051
|
+
return [2 /*return*/];
|
|
7951
8052
|
}
|
|
7952
8053
|
});
|
|
7953
|
-
}); })
|
|
7954
|
-
// Pre-loading system sounds
|
|
7955
|
-
.then(function () {
|
|
7956
|
-
console.debug('[audio] Preloading audio sounds...');
|
|
7957
|
-
return Promise.all(SYSTEM_SOUNDS.map(function (s) {
|
|
7958
|
-
// Disable vibration is cordova not enabled
|
|
7959
|
-
if (!cordova)
|
|
7960
|
-
s.vibration = undefined;
|
|
7961
|
-
return _this.preload(s);
|
|
7962
|
-
}));
|
|
7963
|
-
})
|
|
7964
|
-
.then(function () {
|
|
7965
|
-
_this._started = true;
|
|
7966
|
-
_this._startPromise = null;
|
|
7967
|
-
console.info('[audio] Audio provider started');
|
|
7968
|
-
// Emit event
|
|
7969
|
-
_this.onStart.next();
|
|
7970
|
-
})
|
|
7971
|
-
.catch(function (err) {
|
|
7972
|
-
console.error('[audio] Unable to start audio provider: ' + (err && err.message || err), err);
|
|
7973
|
-
_this._started = false;
|
|
7974
|
-
_this._startPromise = null;
|
|
7975
8054
|
});
|
|
7976
|
-
return this._startPromise;
|
|
7977
8055
|
};
|
|
7978
8056
|
AudioProvider.prototype.readAudioMode = function () {
|
|
7979
8057
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -7991,7 +8069,7 @@
|
|
|
7991
8069
|
});
|
|
7992
8070
|
};
|
|
7993
8071
|
return AudioProvider;
|
|
7994
|
-
}());
|
|
8072
|
+
}(StartableService));
|
|
7995
8073
|
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" });
|
|
7996
8074
|
AudioProvider.decorators = [
|
|
7997
8075
|
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
|
|
@@ -8977,6 +9055,10 @@
|
|
|
8977
9055
|
{
|
|
8978
9056
|
host: 'sih.sfa.sc',
|
|
8979
9057
|
port: 80
|
|
9058
|
+
},
|
|
9059
|
+
{
|
|
9060
|
+
host: 'test.sumaris.net',
|
|
9061
|
+
port: 443
|
|
8980
9062
|
}
|
|
8981
9063
|
],
|
|
8982
9064
|
defaultAppName: 'SUMARiS',
|
|
@@ -9130,6 +9212,24 @@
|
|
|
9130
9212
|
path: noTrailingSlash(url.pathname)
|
|
9131
9213
|
});
|
|
9132
9214
|
};
|
|
9215
|
+
Peer.path = function (peer) {
|
|
9216
|
+
var _a;
|
|
9217
|
+
var paths = [];
|
|
9218
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
9219
|
+
paths[_i - 1] = arguments[_i];
|
|
9220
|
+
}
|
|
9221
|
+
if (!peer)
|
|
9222
|
+
throw new Error('Missing required argument \'peer\'!');
|
|
9223
|
+
// Remove starting slashes
|
|
9224
|
+
paths = (paths || []).map(function (path) {
|
|
9225
|
+
if (path.startsWith('./'))
|
|
9226
|
+
return path.substring(2);
|
|
9227
|
+
if (path.startsWith('/'))
|
|
9228
|
+
return path.substring(1);
|
|
9229
|
+
return path;
|
|
9230
|
+
}).filter(isNotNilOrBlank);
|
|
9231
|
+
return (_a = [noTrailingSlash(Peer_1.fromObject(peer).url)]).concat.apply(_a, __spread(paths)).join('/');
|
|
9232
|
+
};
|
|
9133
9233
|
Peer.prototype.asObject = function (options) {
|
|
9134
9234
|
return _super.prototype.asObject.call(this, options);
|
|
9135
9235
|
};
|
|
@@ -9589,110 +9689,87 @@
|
|
|
9589
9689
|
};
|
|
9590
9690
|
var APP_LOCAL_SETTINGS = new i0.InjectionToken('DefaultLocalSettings');
|
|
9591
9691
|
var APP_LOCAL_SETTINGS_OPTIONS = new i0.InjectionToken('LocalSettingsOptions');
|
|
9592
|
-
var LocalSettingsService = /** @class */ (function () {
|
|
9692
|
+
var LocalSettingsService = /** @class */ (function (_super) {
|
|
9693
|
+
__extends(LocalSettingsService, _super);
|
|
9593
9694
|
function LocalSettingsService(translate, platform, storage, environment, defaultSettings, defaultOptionsMap) {
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
if (
|
|
9695
|
+
var _this = _super.call(this, platform) || this;
|
|
9696
|
+
_this.translate = translate;
|
|
9697
|
+
_this.platform = platform;
|
|
9698
|
+
_this.storage = storage;
|
|
9699
|
+
_this.environment = environment;
|
|
9700
|
+
_this.defaultSettings = defaultSettings;
|
|
9701
|
+
_this.onChange = new rxjs.Subject();
|
|
9702
|
+
_this.defaultSettings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), _this.defaultSettings);
|
|
9703
|
+
_this._optionDefs = Object.values(defaultOptionsMap);
|
|
9704
|
+
_this.resetData();
|
|
9705
|
+
_this._debug = !environment.production;
|
|
9706
|
+
if (_this._debug)
|
|
9606
9707
|
console.debug('[settings] Creating service');
|
|
9708
|
+
return _this;
|
|
9607
9709
|
}
|
|
9608
9710
|
Object.defineProperty(LocalSettingsService.prototype, "settings", {
|
|
9609
9711
|
get: function () {
|
|
9610
|
-
return this.
|
|
9712
|
+
return this._data || this.defaultSettings;
|
|
9611
9713
|
},
|
|
9612
9714
|
enumerable: false,
|
|
9613
9715
|
configurable: true
|
|
9614
9716
|
});
|
|
9615
9717
|
Object.defineProperty(LocalSettingsService.prototype, "locale", {
|
|
9616
9718
|
get: function () {
|
|
9617
|
-
return this.
|
|
9719
|
+
return this._data && this._data.locale || this.translate.currentLang || this.translate.defaultLang;
|
|
9618
9720
|
},
|
|
9619
9721
|
enumerable: false,
|
|
9620
9722
|
configurable: true
|
|
9621
9723
|
});
|
|
9622
9724
|
Object.defineProperty(LocalSettingsService.prototype, "latLongFormat", {
|
|
9623
9725
|
get: function () {
|
|
9624
|
-
return this.
|
|
9726
|
+
return this._data && this._data.latLongFormat || 'DDMM';
|
|
9625
9727
|
},
|
|
9626
9728
|
enumerable: false,
|
|
9627
9729
|
configurable: true
|
|
9628
9730
|
});
|
|
9629
9731
|
Object.defineProperty(LocalSettingsService.prototype, "usageMode", {
|
|
9630
9732
|
get: function () {
|
|
9631
|
-
return (this.
|
|
9733
|
+
return (this._data && this._data.usageMode || (this.mobile ? 'FIELD' : 'DESK'));
|
|
9632
9734
|
},
|
|
9633
9735
|
enumerable: false,
|
|
9634
9736
|
configurable: true
|
|
9635
9737
|
});
|
|
9636
9738
|
Object.defineProperty(LocalSettingsService.prototype, "mobile", {
|
|
9637
9739
|
get: function () {
|
|
9638
|
-
return this.
|
|
9740
|
+
return this._data && toBoolean(this._data.mobile, this.platform.is('mobile'));
|
|
9639
9741
|
},
|
|
9640
9742
|
set: function (value) {
|
|
9641
|
-
this.
|
|
9743
|
+
this._data.mobile = value;
|
|
9642
9744
|
},
|
|
9643
9745
|
enumerable: false,
|
|
9644
9746
|
configurable: true
|
|
9645
9747
|
});
|
|
9646
9748
|
Object.defineProperty(LocalSettingsService.prototype, "touchUi", {
|
|
9647
9749
|
get: function () {
|
|
9648
|
-
return this.
|
|
9750
|
+
return this._data.touchUi;
|
|
9649
9751
|
},
|
|
9650
9752
|
set: function (value) {
|
|
9651
|
-
this.
|
|
9753
|
+
this._data.touchUi = value;
|
|
9652
9754
|
},
|
|
9653
9755
|
enumerable: false,
|
|
9654
9756
|
configurable: true
|
|
9655
9757
|
});
|
|
9656
9758
|
Object.defineProperty(LocalSettingsService.prototype, "pageHistory", {
|
|
9657
9759
|
get: function () {
|
|
9658
|
-
return (this.
|
|
9760
|
+
return (this._data && this._data.pageHistory || []);
|
|
9659
9761
|
},
|
|
9660
9762
|
enumerable: false,
|
|
9661
9763
|
configurable: true
|
|
9662
9764
|
});
|
|
9663
|
-
LocalSettingsService.prototype.
|
|
9664
|
-
|
|
9665
|
-
if (this._startPromise)
|
|
9666
|
-
return this._startPromise;
|
|
9667
|
-
if (this._started)
|
|
9668
|
-
return Promise.resolve(this.data);
|
|
9669
|
-
console.info('[settings] Starting settings...');
|
|
9765
|
+
LocalSettingsService.prototype.ngOnStart = function () {
|
|
9766
|
+
console.info('[settings] Starting service...');
|
|
9670
9767
|
// Restoring local settings
|
|
9671
|
-
this.
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
})
|
|
9677
|
-
.then(function () { return _this.restoreLocally(); })
|
|
9678
|
-
.then(function (data) {
|
|
9679
|
-
_this._started = true;
|
|
9680
|
-
_this._startPromise = undefined;
|
|
9681
|
-
return data;
|
|
9682
|
-
});
|
|
9683
|
-
return this._startPromise;
|
|
9684
|
-
};
|
|
9685
|
-
Object.defineProperty(LocalSettingsService.prototype, "started", {
|
|
9686
|
-
get: function () {
|
|
9687
|
-
return this._started;
|
|
9688
|
-
},
|
|
9689
|
-
enumerable: false,
|
|
9690
|
-
configurable: true
|
|
9691
|
-
});
|
|
9692
|
-
LocalSettingsService.prototype.ready = function () {
|
|
9693
|
-
if (this._started)
|
|
9694
|
-
return Promise.resolve(this.data);
|
|
9695
|
-
return this.start();
|
|
9768
|
+
this._data.mobile = isNotNil(this._data.mobile) ? this._data.mobile : this.platform.is('mobile');
|
|
9769
|
+
this._data.touchUi = this._data.mobile || this.platform.is('phablet') || this.platform.is('tablet');
|
|
9770
|
+
this._data.usageMode = this.platform.is('android') ? 'FIELD' : 'DESK'; // FIELD by default if Android
|
|
9771
|
+
// Restoring local settings
|
|
9772
|
+
return this.restoreLocally();
|
|
9696
9773
|
};
|
|
9697
9774
|
LocalSettingsService.prototype.isUsageMode = function (mode) {
|
|
9698
9775
|
return this.usageMode === mode;
|
|
@@ -9702,10 +9779,12 @@
|
|
|
9702
9779
|
};
|
|
9703
9780
|
LocalSettingsService.prototype.restoreLocally = function () {
|
|
9704
9781
|
return __awaiter(this, void 0, void 0, function () {
|
|
9705
|
-
var settingsStr, restoredData_1;
|
|
9782
|
+
var data, settingsStr, restoredData_1;
|
|
9706
9783
|
return __generator(this, function (_a) {
|
|
9707
9784
|
switch (_a.label) {
|
|
9708
|
-
case 0:
|
|
9785
|
+
case 0:
|
|
9786
|
+
data = this._data || {};
|
|
9787
|
+
return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
|
|
9709
9788
|
case 1:
|
|
9710
9789
|
settingsStr = _a.sent();
|
|
9711
9790
|
// Restore local settings (or keep old settings)
|
|
@@ -9716,30 +9795,31 @@
|
|
|
9716
9795
|
SETTINGS_TRANSIENT_PROPERTIES.forEach(function (transientKey) {
|
|
9717
9796
|
delete restoredData_1[transientKey];
|
|
9718
9797
|
});
|
|
9719
|
-
|
|
9798
|
+
// Merge into existing data
|
|
9799
|
+
data = Object.assign(data, restoredData_1);
|
|
9720
9800
|
}
|
|
9721
9801
|
// Emit event
|
|
9722
|
-
this.onChange.next(
|
|
9723
|
-
return [2 /*return*/,
|
|
9802
|
+
this.onChange.next(data);
|
|
9803
|
+
return [2 /*return*/, data];
|
|
9724
9804
|
}
|
|
9725
9805
|
});
|
|
9726
9806
|
});
|
|
9727
9807
|
};
|
|
9728
9808
|
LocalSettingsService.prototype.setProperty = function (keyOrDef, value) {
|
|
9729
|
-
if (!this.
|
|
9809
|
+
if (!this._data)
|
|
9730
9810
|
return;
|
|
9731
9811
|
if (typeof keyOrDef === 'object') {
|
|
9732
9812
|
this.setProperty(keyOrDef.key, value);
|
|
9733
9813
|
return;
|
|
9734
9814
|
}
|
|
9735
|
-
this.
|
|
9736
|
-
this.
|
|
9815
|
+
this._data.properties = this._data.properties || {};
|
|
9816
|
+
this._data.properties[keyOrDef] = isNil(value) ? undefined : value.toString();
|
|
9737
9817
|
};
|
|
9738
9818
|
LocalSettingsService.prototype.getProperty = function (keyOrDef, defaultValue) {
|
|
9739
9819
|
if (typeof keyOrDef === 'object') {
|
|
9740
9820
|
return this.getProperty(keyOrDef.key, isNil(defaultValue) ? keyOrDef.defaultValue : defaultValue);
|
|
9741
9821
|
}
|
|
9742
|
-
var value = this.
|
|
9822
|
+
var value = this._data && this._data.properties && this._data.properties[keyOrDef];
|
|
9743
9823
|
return isNotNil(value) ? value : defaultValue;
|
|
9744
9824
|
};
|
|
9745
9825
|
LocalSettingsService.prototype.getPropertyAsBoolean = function (definition, defaultValue) {
|
|
@@ -9765,19 +9845,25 @@
|
|
|
9765
9845
|
return __generator(this, function (_a) {
|
|
9766
9846
|
switch (_a.label) {
|
|
9767
9847
|
case 0:
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
return [4 /*yield*/, this.persistLocally(true)];
|
|
9848
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
9849
|
+
return [4 /*yield*/, this.ready()];
|
|
9771
9850
|
case 1:
|
|
9772
9851
|
_a.sent();
|
|
9773
|
-
|
|
9852
|
+
_a.label = 2;
|
|
9774
9853
|
case 2:
|
|
9775
|
-
this.
|
|
9776
|
-
|
|
9854
|
+
this._data = Object.assign(Object.assign({}, this._data), settings);
|
|
9855
|
+
if (!(opts && opts.persistImmediate)) return [3 /*break*/, 4];
|
|
9856
|
+
return [4 /*yield*/, this.persistLocally(true)];
|
|
9777
9857
|
case 3:
|
|
9858
|
+
_a.sent();
|
|
9859
|
+
return [3 /*break*/, 5];
|
|
9860
|
+
case 4:
|
|
9861
|
+
this.persistLocally(); // No AWAIT
|
|
9862
|
+
_a.label = 5;
|
|
9863
|
+
case 5:
|
|
9778
9864
|
// Emit event
|
|
9779
9865
|
if (!opts || opts.emitEvent !== false) {
|
|
9780
|
-
this.onChange.next(this.
|
|
9866
|
+
this.onChange.next(this._data);
|
|
9781
9867
|
}
|
|
9782
9868
|
return [2 /*return*/];
|
|
9783
9869
|
}
|
|
@@ -9801,27 +9887,27 @@
|
|
|
9801
9887
|
});
|
|
9802
9888
|
};
|
|
9803
9889
|
LocalSettingsService.prototype.getPageSettings = function (pageId, propertyName) {
|
|
9804
|
-
if (!this.
|
|
9890
|
+
if (!this._data || !this._data.pages)
|
|
9805
9891
|
return undefined;
|
|
9806
9892
|
var key = pageId.replace(/[/]/g, '__');
|
|
9807
9893
|
if (isNotNilOrBlank(propertyName)) {
|
|
9808
|
-
return getPropertyByPath(this.
|
|
9894
|
+
return getPropertyByPath(this._data.pages, key + '.' + propertyName);
|
|
9809
9895
|
}
|
|
9810
|
-
return this.
|
|
9896
|
+
return this._data.pages[key];
|
|
9811
9897
|
};
|
|
9812
9898
|
LocalSettingsService.prototype.savePageSetting = function (pageId, value, propertyName) {
|
|
9813
9899
|
return __awaiter(this, void 0, void 0, function () {
|
|
9814
9900
|
var key;
|
|
9815
9901
|
return __generator(this, function (_a) {
|
|
9816
|
-
this.
|
|
9817
|
-
this.
|
|
9902
|
+
this._data = this._data || this.defaultSettings;
|
|
9903
|
+
this._data.pages = this._data.pages || {};
|
|
9818
9904
|
key = pageId.replace(/[/]/g, '__');
|
|
9819
9905
|
if (propertyName) {
|
|
9820
|
-
this.
|
|
9821
|
-
this.
|
|
9906
|
+
this._data.pages[key] = this._data.pages[key] || {};
|
|
9907
|
+
this._data.pages[key][propertyName] = value;
|
|
9822
9908
|
}
|
|
9823
9909
|
else {
|
|
9824
|
-
this.
|
|
9910
|
+
this._data.pages[key] = value;
|
|
9825
9911
|
}
|
|
9826
9912
|
// Update local settings
|
|
9827
9913
|
this.persistLocally();
|
|
@@ -9830,13 +9916,13 @@
|
|
|
9830
9916
|
});
|
|
9831
9917
|
};
|
|
9832
9918
|
LocalSettingsService.prototype.getOfflineFeature = function (featureName) {
|
|
9833
|
-
if (!this.
|
|
9919
|
+
if (!this._data || !this._data.offlineFeatures || isEmptyArray(this._data.offlineFeatures))
|
|
9834
9920
|
return undefined;
|
|
9835
9921
|
if (!featureName)
|
|
9836
9922
|
throw Error('Missing \'featureName\' argument');
|
|
9837
9923
|
featureName = featureName.toLowerCase();
|
|
9838
9924
|
var featurePrefix = featureName + '#';
|
|
9839
|
-
var feature = this.
|
|
9925
|
+
var feature = this._data.offlineFeatures.find(function (f) {
|
|
9840
9926
|
if (typeof f === 'string')
|
|
9841
9927
|
return f.toLowerCase().startsWith(featurePrefix);
|
|
9842
9928
|
if (typeof f === 'object' && f.name)
|
|
@@ -9859,24 +9945,24 @@
|
|
|
9859
9945
|
LocalSettingsService.prototype.hasOfflineFeature = function (featureName) {
|
|
9860
9946
|
if (featureName)
|
|
9861
9947
|
return isNotNil(this.getOfflineFeature(featureName));
|
|
9862
|
-
return this.
|
|
9948
|
+
return this._data && isNotEmptyArray(this._data.offlineFeatures);
|
|
9863
9949
|
};
|
|
9864
9950
|
LocalSettingsService.prototype.saveOfflineFeature = function (feature) {
|
|
9865
|
-
this.
|
|
9866
|
-
this.
|
|
9951
|
+
this._data = this._data || this.defaultSettings;
|
|
9952
|
+
this._data.offlineFeatures = this._data.offlineFeatures || [];
|
|
9867
9953
|
feature.name = feature.name.toLowerCase();
|
|
9868
9954
|
var featurePrefix = feature.name + '#';
|
|
9869
|
-
var existingIndex = this.
|
|
9955
|
+
var existingIndex = this._data.offlineFeatures.findIndex(function (f) {
|
|
9870
9956
|
if (typeof f === 'string')
|
|
9871
9957
|
return f.toLowerCase().startsWith(featurePrefix);
|
|
9872
9958
|
if (typeof f === 'object' && f.name)
|
|
9873
9959
|
return f.name === feature.name;
|
|
9874
9960
|
});
|
|
9875
9961
|
if (existingIndex !== -1) {
|
|
9876
|
-
this.
|
|
9962
|
+
this._data.offlineFeatures[existingIndex] = feature;
|
|
9877
9963
|
}
|
|
9878
9964
|
else {
|
|
9879
|
-
this.
|
|
9965
|
+
this._data.offlineFeatures.push(feature);
|
|
9880
9966
|
}
|
|
9881
9967
|
// Update local settings
|
|
9882
9968
|
this.persistLocally();
|
|
@@ -9895,14 +9981,14 @@
|
|
|
9895
9981
|
this.saveOfflineFeature(feature);
|
|
9896
9982
|
};
|
|
9897
9983
|
LocalSettingsService.prototype.removeOfflineFeatures = function () {
|
|
9898
|
-
if (this.
|
|
9899
|
-
this.
|
|
9984
|
+
if (this._data && this._data.offlineFeatures) {
|
|
9985
|
+
this._data.offlineFeatures = [];
|
|
9900
9986
|
// Update local settings
|
|
9901
9987
|
this.persistLocally();
|
|
9902
9988
|
}
|
|
9903
9989
|
};
|
|
9904
9990
|
LocalSettingsService.prototype.getFieldDisplayAttributes = function (fieldName, defaultAttributes) {
|
|
9905
|
-
var value = this.
|
|
9991
|
+
var value = this._data && this._data.properties && this._data.properties["sumaris.field." + fieldName + ".attributes"];
|
|
9906
9992
|
// Nothing found in settings: return defaults
|
|
9907
9993
|
if (!value)
|
|
9908
9994
|
return defaultAttributes || ['label', 'name'];
|
|
@@ -9940,7 +10026,7 @@
|
|
|
9940
10026
|
// If not inside recursive call: fill page history defaults
|
|
9941
10027
|
if (!pageHistory)
|
|
9942
10028
|
this.fillPageHistoryDefaults(page, opts);
|
|
9943
|
-
pageHistory = pageHistory || this.
|
|
10029
|
+
pageHistory = pageHistory || this._data.pageHistory;
|
|
9944
10030
|
index = pageHistory.findIndex(function (p) { return (
|
|
9945
10031
|
// same path
|
|
9946
10032
|
p.path === page.path
|
|
@@ -9975,10 +10061,10 @@
|
|
|
9975
10061
|
_a.sent();
|
|
9976
10062
|
_a.label = 4;
|
|
9977
10063
|
case 4:
|
|
9978
|
-
if (!(pageHistory === this.
|
|
10064
|
+
if (!(pageHistory === this._data.pageHistory)) return [3 /*break*/, 6];
|
|
9979
10065
|
// If max has been reached, remove old pages
|
|
9980
|
-
if (this.
|
|
9981
|
-
removedPages = pageHistory.splice(this.
|
|
10066
|
+
if (this._data.pageHistory.length > this._data.pageHistoryMaxSize) {
|
|
10067
|
+
removedPages = pageHistory.splice(this._data.pageHistoryMaxSize, pageHistory.length - this._data.pageHistoryMaxSize);
|
|
9982
10068
|
console.debug('[settings] Pages removed from history: ', removedPages);
|
|
9983
10069
|
}
|
|
9984
10070
|
// Apply new value
|
|
@@ -10000,7 +10086,7 @@
|
|
|
10000
10086
|
return __generator(this, function (_a) {
|
|
10001
10087
|
switch (_a.label) {
|
|
10002
10088
|
case 0:
|
|
10003
|
-
pageHistory = pageHistory || this.
|
|
10089
|
+
pageHistory = pageHistory || this._data.pageHistory;
|
|
10004
10090
|
index = pageHistory.findIndex(function (p) { return p.path === path; });
|
|
10005
10091
|
found = index !== -1;
|
|
10006
10092
|
if (found) {
|
|
@@ -10015,9 +10101,9 @@
|
|
|
10015
10101
|
.filter(isNotEmptyArray)
|
|
10016
10102
|
.findIndex(function (children) { return _this.removePageHistory(path, opts, children); }) !== -1;
|
|
10017
10103
|
}
|
|
10018
|
-
if (!(found && pageHistory === this.
|
|
10104
|
+
if (!(found && pageHistory === this._data.pageHistory)) return [3 /*break*/, 2];
|
|
10019
10105
|
// Apply changes
|
|
10020
|
-
return [4 /*yield*/, this.applyProperty('pageHistory', this.
|
|
10106
|
+
return [4 /*yield*/, this.applyProperty('pageHistory', this._data.pageHistory)];
|
|
10021
10107
|
case 1:
|
|
10022
10108
|
// Apply changes
|
|
10023
10109
|
_a.sent();
|
|
@@ -10044,27 +10130,27 @@
|
|
|
10044
10130
|
};
|
|
10045
10131
|
/* -- Protected methods -- */
|
|
10046
10132
|
LocalSettingsService.prototype.resetData = function () {
|
|
10047
|
-
this.
|
|
10048
|
-
this.
|
|
10049
|
-
this.
|
|
10050
|
-
this.
|
|
10051
|
-
this.
|
|
10133
|
+
this._data = Object.assign(Object.assign({}, this._data), this.defaultSettings);
|
|
10134
|
+
this._data.locale = this.translate.currentLang || this.translate.defaultLang;
|
|
10135
|
+
this._data.mobile = undefined;
|
|
10136
|
+
this._data.usageMode = undefined;
|
|
10137
|
+
this._data.pageHistory = [];
|
|
10052
10138
|
var defaultPeer = this.environment.defaultPeer && exports.Peer.fromObject(this.environment.defaultPeer);
|
|
10053
|
-
this.
|
|
10054
|
-
if (this.
|
|
10055
|
-
this.onChange.next(this.
|
|
10139
|
+
this._data.peerUrl = defaultPeer && defaultPeer.url || undefined;
|
|
10140
|
+
if (this.started)
|
|
10141
|
+
this.onChange.next(this._data);
|
|
10056
10142
|
};
|
|
10057
10143
|
LocalSettingsService.prototype.persistLocally = function (immediate) {
|
|
10058
10144
|
var _this = this;
|
|
10059
10145
|
// Execute immediate
|
|
10060
10146
|
if (immediate) {
|
|
10061
|
-
if (!this.
|
|
10147
|
+
if (!this._data) {
|
|
10062
10148
|
console.debug('[settings] Removing local settings from storage');
|
|
10063
10149
|
return this.storage.remove(SETTINGS_STORAGE_KEY);
|
|
10064
10150
|
}
|
|
10065
10151
|
else {
|
|
10066
|
-
console.debug('[settings] Store local settings', this.
|
|
10067
|
-
return this.storage.set(SETTINGS_STORAGE_KEY, JSON.stringify(this.
|
|
10152
|
+
console.debug('[settings] Store local settings', this._data);
|
|
10153
|
+
return this.storage.set(SETTINGS_STORAGE_KEY, JSON.stringify(this._data));
|
|
10068
10154
|
}
|
|
10069
10155
|
}
|
|
10070
10156
|
// Execute with delay
|
|
@@ -10074,7 +10160,7 @@
|
|
|
10074
10160
|
this._$persist = new i0.EventEmitter(true);
|
|
10075
10161
|
this._$persist
|
|
10076
10162
|
.pipe(operators.debounceTime(2000), // add a delay of 2s
|
|
10077
|
-
operators.filter(function () { return _this.
|
|
10163
|
+
operators.filter(function () { return _this.started; }))
|
|
10078
10164
|
.subscribe(function () { return _this.persistLocally(true); });
|
|
10079
10165
|
}
|
|
10080
10166
|
this._$persist.emit();
|
|
@@ -10100,7 +10186,7 @@
|
|
|
10100
10186
|
return page;
|
|
10101
10187
|
};
|
|
10102
10188
|
return LocalSettingsService;
|
|
10103
|
-
}());
|
|
10189
|
+
}(StartableService));
|
|
10104
10190
|
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" });
|
|
10105
10191
|
LocalSettingsService.decorators = [
|
|
10106
10192
|
{ type: i0.Injectable, args: [{
|
|
@@ -10271,41 +10357,42 @@
|
|
|
10271
10357
|
MOBILE: 1000,
|
|
10272
10358
|
DESKTOP: 1000
|
|
10273
10359
|
}*/
|
|
10274
|
-
var NetworkService = /** @class */ (function () {
|
|
10360
|
+
var NetworkService = /** @class */ (function (_super) {
|
|
10361
|
+
__extends(NetworkService, _super);
|
|
10275
10362
|
function NetworkService(_document, platform, modalCtrl, cryptoService, storage, settings, cache, http, environment, network, splashScreen, translate, toastController) {
|
|
10276
|
-
var _this = this;
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
this._timerRefreshPeriod = NetworkRefreshTimerPeriod.MOBILE;
|
|
10300
|
-
this._timerRefreshCondition = function () { return _this.online; }; // Check only when online, and stop when offline
|
|
10363
|
+
var _this = _super.call(this, platform) || this;
|
|
10364
|
+
_this._document = _document;
|
|
10365
|
+
_this.platform = platform;
|
|
10366
|
+
_this.modalCtrl = modalCtrl;
|
|
10367
|
+
_this.cryptoService = cryptoService;
|
|
10368
|
+
_this.storage = storage;
|
|
10369
|
+
_this.settings = settings;
|
|
10370
|
+
_this.cache = cache;
|
|
10371
|
+
_this.http = http;
|
|
10372
|
+
_this.environment = environment;
|
|
10373
|
+
_this.network = network;
|
|
10374
|
+
_this.splashScreen = splashScreen;
|
|
10375
|
+
_this.translate = translate;
|
|
10376
|
+
_this.toastController = toastController;
|
|
10377
|
+
_this.onPeerChanges = _this.onStart.pipe(operators.map(function (peer) { return peer && peer.url; }), operators.filter(isNotNilOrBlank), operators.distinctUntilChanged());
|
|
10378
|
+
_this.onNetworkStatusChanges = new rxjs.BehaviorSubject(null);
|
|
10379
|
+
_this.onResetNetworkCache = new i0.EventEmitter(true);
|
|
10380
|
+
_this._subscription = new rxjs.Subscription();
|
|
10381
|
+
_this._listeners = {};
|
|
10382
|
+
_this._mobile = _this.platform.is('mobile');
|
|
10383
|
+
if (_this._mobile) {
|
|
10384
|
+
_this._timerRefreshPeriod = NetworkRefreshTimerPeriod.MOBILE;
|
|
10385
|
+
_this._timerRefreshCondition = function () { return _this.online; }; // Check only when online, and stop when offline
|
|
10301
10386
|
}
|
|
10302
10387
|
else {
|
|
10303
|
-
|
|
10304
|
-
|
|
10388
|
+
_this._timerRefreshPeriod = NetworkRefreshTimerPeriod.DESKTOP;
|
|
10389
|
+
_this._timerRefreshCondition = function () { return true; }; // Always check
|
|
10305
10390
|
}
|
|
10306
|
-
|
|
10391
|
+
_this.resetData();
|
|
10392
|
+
_this.onStart.subscribe(function () { return _this.ngOnAfterStart(); });
|
|
10307
10393
|
// For DEV only
|
|
10308
|
-
|
|
10394
|
+
_this._debug = !environment.production;
|
|
10395
|
+
return _this;
|
|
10309
10396
|
}
|
|
10310
10397
|
Object.defineProperty(NetworkService.prototype, "online", {
|
|
10311
10398
|
get: function () {
|
|
@@ -10326,24 +10413,18 @@
|
|
|
10326
10413
|
// If force offline: return 'none'
|
|
10327
10414
|
return this._forceOffline && 'none'
|
|
10328
10415
|
// Else, return device connection type (or unknown)
|
|
10329
|
-
|| (this.
|
|
10416
|
+
|| (this.started && this._deviceConnectionType || 'unknown');
|
|
10330
10417
|
},
|
|
10331
10418
|
enumerable: false,
|
|
10332
10419
|
configurable: true
|
|
10333
10420
|
});
|
|
10334
10421
|
Object.defineProperty(NetworkService.prototype, "peer", {
|
|
10335
10422
|
get: function () {
|
|
10336
|
-
return this.
|
|
10423
|
+
return this._data && this._data.clone();
|
|
10337
10424
|
},
|
|
10338
10425
|
set: function (peer) {
|
|
10339
|
-
this.
|
|
10340
|
-
|
|
10341
|
-
enumerable: false,
|
|
10342
|
-
configurable: true
|
|
10343
|
-
});
|
|
10344
|
-
Object.defineProperty(NetworkService.prototype, "started", {
|
|
10345
|
-
get: function () {
|
|
10346
|
-
return this._started;
|
|
10426
|
+
this._startingPeer = peer;
|
|
10427
|
+
this.restart();
|
|
10347
10428
|
},
|
|
10348
10429
|
enumerable: false,
|
|
10349
10430
|
configurable: true
|
|
@@ -10368,109 +10449,11 @@
|
|
|
10368
10449
|
return this.addListener(eventType, callback);
|
|
10369
10450
|
}
|
|
10370
10451
|
};
|
|
10371
|
-
NetworkService.prototype.
|
|
10372
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10373
|
-
var _this = this;
|
|
10374
|
-
return __generator(this, function (_a) {
|
|
10375
|
-
if (this._startPromise)
|
|
10376
|
-
return [2 /*return*/, this._startPromise];
|
|
10377
|
-
if (this._started)
|
|
10378
|
-
return [2 /*return*/];
|
|
10379
|
-
console.info('[network] Starting network...');
|
|
10380
|
-
// Restoring local settings
|
|
10381
|
-
this._startPromise = (!peer && this.restoreLocally() || Promise.resolve(peer))
|
|
10382
|
-
.then(function (peer) { return __awaiter(_this, void 0, void 0, function () {
|
|
10383
|
-
return __generator(this, function (_a) {
|
|
10384
|
-
switch (_a.label) {
|
|
10385
|
-
case 0:
|
|
10386
|
-
// Make sure to hide the splashscreen, before open the modal
|
|
10387
|
-
if (!peer && this.splashScreen)
|
|
10388
|
-
this.splashScreen.hide();
|
|
10389
|
-
_a.label = 1;
|
|
10390
|
-
case 1:
|
|
10391
|
-
if (!!peer) return [3 /*break*/, 3];
|
|
10392
|
-
console.debug('[network] No peer defined. Asking user to choose a peer.');
|
|
10393
|
-
return [4 /*yield*/, this.showSelectPeerModal({ allowSelectDownPeer: false })];
|
|
10394
|
-
case 2:
|
|
10395
|
-
peer = _a.sent();
|
|
10396
|
-
return [3 /*break*/, 1];
|
|
10397
|
-
case 3:
|
|
10398
|
-
this._peer = peer;
|
|
10399
|
-
this._started = true;
|
|
10400
|
-
this._startPromise = undefined;
|
|
10401
|
-
this.onStart.next(peer);
|
|
10402
|
-
console.info("[platform] Starting network [OK] {online: " + this.online + "}");
|
|
10403
|
-
return [2 /*return*/];
|
|
10404
|
-
}
|
|
10405
|
-
});
|
|
10406
|
-
}); })
|
|
10407
|
-
.catch(function (err) {
|
|
10408
|
-
console.error(err && err.message || err, err);
|
|
10409
|
-
_this._started = false;
|
|
10410
|
-
_this._startPromise = undefined;
|
|
10411
|
-
})
|
|
10412
|
-
// Wait settings starts, then save peer in settings
|
|
10413
|
-
.then(function () { return _this.settings.ready(); })
|
|
10414
|
-
.then(function () { return _this.settings.apply({ peerUrl: _this._peer.url }); })
|
|
10415
|
-
.then(function () { return _this.onDeviceConnectionChanged(_this.network && _this.network.type || 'unknown'); })
|
|
10416
|
-
// Start the refresh timer
|
|
10417
|
-
.then(function () { return _this.startRefreshTimer(); });
|
|
10418
|
-
// Listen for device network changes
|
|
10419
|
-
if (this.network) {
|
|
10420
|
-
this._subscription.add(this.network.onDisconnect().subscribe(function () { return _this.onDeviceConnectionChanged('none'); }));
|
|
10421
|
-
this._subscription.add(this.network.onConnect().subscribe(function () { return _this.onDeviceConnectionChanged(_this.network.type); }));
|
|
10422
|
-
}
|
|
10423
|
-
return [2 /*return*/, this._startPromise];
|
|
10424
|
-
});
|
|
10425
|
-
});
|
|
10426
|
-
};
|
|
10427
|
-
NetworkService.prototype.ready = function () {
|
|
10428
|
-
if (this._started)
|
|
10429
|
-
return Promise.resolve();
|
|
10430
|
-
return this.start();
|
|
10431
|
-
};
|
|
10432
|
-
NetworkService.prototype.stop = function () {
|
|
10433
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10434
|
-
return __generator(this, function (_a) {
|
|
10435
|
-
this.resetData();
|
|
10436
|
-
this._started = false;
|
|
10437
|
-
this._startPromise = undefined;
|
|
10438
|
-
// Stop timer if cannot refresh anymore
|
|
10439
|
-
if (this._timerRefreshCondition() === false) {
|
|
10440
|
-
this.stopRefreshTimer();
|
|
10441
|
-
}
|
|
10442
|
-
this._subscription.unsubscribe();
|
|
10443
|
-
this._subscription = new rxjs.Subscription();
|
|
10444
|
-
return [2 /*return*/];
|
|
10445
|
-
});
|
|
10446
|
-
});
|
|
10447
|
-
};
|
|
10448
|
-
NetworkService.prototype.restart = function (peer) {
|
|
10452
|
+
NetworkService.prototype.tryOnline = function (opts) {
|
|
10449
10453
|
return __awaiter(this, void 0, void 0, function () {
|
|
10450
|
-
var
|
|
10451
|
-
return __generator(this, function (
|
|
10452
|
-
switch (
|
|
10453
|
-
case 0:
|
|
10454
|
-
if (!this._started) return [3 /*break*/, 2];
|
|
10455
|
-
return [4 /*yield*/, this.stop()
|
|
10456
|
-
.then(function () { return _this.start(peer); })];
|
|
10457
|
-
case 1:
|
|
10458
|
-
_a.sent();
|
|
10459
|
-
return [3 /*break*/, 4];
|
|
10460
|
-
case 2: return [4 /*yield*/, this.start(peer)];
|
|
10461
|
-
case 3:
|
|
10462
|
-
_a.sent();
|
|
10463
|
-
_a.label = 4;
|
|
10464
|
-
case 4: return [2 /*return*/];
|
|
10465
|
-
}
|
|
10466
|
-
});
|
|
10467
|
-
});
|
|
10468
|
-
};
|
|
10469
|
-
NetworkService.prototype.tryOnline = function (opts) {
|
|
10470
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10471
|
-
var now, showLoadingToast, loadingToast, settings, peer, peerInfo, peerAliveAndCompatible, _a, err_1, online;
|
|
10472
|
-
return __generator(this, function (_b) {
|
|
10473
|
-
switch (_b.label) {
|
|
10454
|
+
var now, showLoadingToast, loadingToast, settings, peer, peerInfo, peerAliveAndCompatible, _b, err_1, online;
|
|
10455
|
+
return __generator(this, function (_c) {
|
|
10456
|
+
switch (_c.label) {
|
|
10474
10457
|
case 0:
|
|
10475
10458
|
// If offline mode not forced, and device says there is no connection: skip
|
|
10476
10459
|
if (!this._forceOffline || this._deviceConnectionType === 'none')
|
|
@@ -10481,57 +10464,57 @@
|
|
|
10481
10464
|
return [4 /*yield*/, this.showToast({ message: 'NETWORK.INFO.RETRY_TO_CONNECT',
|
|
10482
10465
|
duration: 10000, onWillPresent: function (t) { return loadingToast = t; } })];
|
|
10483
10466
|
case 1:
|
|
10484
|
-
|
|
10485
|
-
|
|
10467
|
+
_c.sent();
|
|
10468
|
+
_c.label = 2;
|
|
10486
10469
|
case 2:
|
|
10487
|
-
|
|
10470
|
+
_c.trys.push([2, 10, , 11]);
|
|
10488
10471
|
console.info('[network] Checking connection to pod...');
|
|
10489
10472
|
return [4 /*yield*/, this.settings.ready()];
|
|
10490
10473
|
case 3:
|
|
10491
|
-
settings =
|
|
10474
|
+
settings = _c.sent();
|
|
10492
10475
|
if (!settings.peerUrl)
|
|
10493
10476
|
return [2 /*return*/, false]; // No peer define. Skip
|
|
10494
10477
|
peer = exports.Peer.parseUrl(settings.peerUrl);
|
|
10495
10478
|
return [4 /*yield*/, this.checkPeerAlive(peer)];
|
|
10496
10479
|
case 4:
|
|
10497
|
-
peerInfo =
|
|
10498
|
-
|
|
10499
|
-
if (!
|
|
10480
|
+
peerInfo = _c.sent();
|
|
10481
|
+
_b = peerInfo;
|
|
10482
|
+
if (!_b) return [3 /*break*/, 6];
|
|
10500
10483
|
return [4 /*yield*/, this.checkPeerCompatible(peerInfo)];
|
|
10501
10484
|
case 5:
|
|
10502
|
-
|
|
10503
|
-
|
|
10485
|
+
_b = (_c.sent());
|
|
10486
|
+
_c.label = 6;
|
|
10504
10487
|
case 6:
|
|
10505
|
-
peerAliveAndCompatible =
|
|
10488
|
+
peerAliveAndCompatible = _b;
|
|
10506
10489
|
if (!peerAliveAndCompatible) return [3 /*break*/, 9];
|
|
10507
10490
|
// Disable the offline mode
|
|
10508
10491
|
this.setForceOffline(false);
|
|
10509
10492
|
// Restart
|
|
10510
|
-
|
|
10493
|
+
this._startingPeer = peer;
|
|
10494
|
+
return [4 /*yield*/, this.restart()];
|
|
10511
10495
|
case 7:
|
|
10512
|
-
|
|
10513
|
-
_b.sent();
|
|
10496
|
+
_c.sent();
|
|
10514
10497
|
// Wait a promise, before recheck
|
|
10515
10498
|
return [4 /*yield*/, this.emit('beforeTryOnlineFinish', this.online)];
|
|
10516
10499
|
case 8:
|
|
10517
10500
|
// Wait a promise, before recheck
|
|
10518
|
-
|
|
10519
|
-
|
|
10501
|
+
_c.sent();
|
|
10502
|
+
_c.label = 9;
|
|
10520
10503
|
case 9: return [3 /*break*/, 11];
|
|
10521
10504
|
case 10:
|
|
10522
|
-
err_1 =
|
|
10505
|
+
err_1 = _c.sent();
|
|
10523
10506
|
console.error(err_1 && err_1.message || err_1);
|
|
10524
10507
|
return [3 /*break*/, 11];
|
|
10525
10508
|
case 11:
|
|
10526
10509
|
if (!showLoadingToast) return [3 /*break*/, 14];
|
|
10527
10510
|
return [4 /*yield*/, sleep(2000 - (Date.now() - now))];
|
|
10528
10511
|
case 12:
|
|
10529
|
-
|
|
10512
|
+
_c.sent();
|
|
10530
10513
|
if (!loadingToast) return [3 /*break*/, 14];
|
|
10531
10514
|
return [4 /*yield*/, loadingToast.dismiss()];
|
|
10532
10515
|
case 13:
|
|
10533
|
-
|
|
10534
|
-
|
|
10516
|
+
_c.sent();
|
|
10517
|
+
_c.label = 14;
|
|
10535
10518
|
case 14:
|
|
10536
10519
|
online = this.online;
|
|
10537
10520
|
// Display a toast to user
|
|
@@ -10545,7 +10528,7 @@
|
|
|
10545
10528
|
// Display toast (without await, because not need to wait toast close event)
|
|
10546
10529
|
return [2 /*return*/, this.showOfflineToast({ showRetryButton: false })];
|
|
10547
10530
|
}
|
|
10548
|
-
return [2 /*return*/, this.
|
|
10531
|
+
return [2 /*return*/, this.started && online];
|
|
10549
10532
|
}
|
|
10550
10533
|
});
|
|
10551
10534
|
});
|
|
@@ -10553,8 +10536,8 @@
|
|
|
10553
10536
|
NetworkService.prototype.showOfflineToast = function (opts) {
|
|
10554
10537
|
return __awaiter(this, void 0, void 0, function () {
|
|
10555
10538
|
var toastResult, online;
|
|
10556
|
-
return __generator(this, function (
|
|
10557
|
-
switch (
|
|
10539
|
+
return __generator(this, function (_b) {
|
|
10540
|
+
switch (_b.label) {
|
|
10558
10541
|
case 0:
|
|
10559
10542
|
if (this.online)
|
|
10560
10543
|
return [2 /*return*/]; // Skip if online
|
|
@@ -10573,7 +10556,7 @@
|
|
|
10573
10556
|
]
|
|
10574
10557
|
})];
|
|
10575
10558
|
case 1:
|
|
10576
|
-
toastResult =
|
|
10559
|
+
toastResult = _b.sent();
|
|
10577
10560
|
// User don't click reconnect: return
|
|
10578
10561
|
if (!toastResult || toastResult.role !== 'refresh')
|
|
10579
10562
|
return [2 /*return*/, false];
|
|
@@ -10586,7 +10569,7 @@
|
|
|
10586
10569
|
showLoadingToast: toBoolean(opts && opts.showRetryLoadingToast, true)
|
|
10587
10570
|
})];
|
|
10588
10571
|
case 2:
|
|
10589
|
-
online =
|
|
10572
|
+
online = _b.sent();
|
|
10590
10573
|
if (online) {
|
|
10591
10574
|
// Call success callback (async)
|
|
10592
10575
|
if (opts && opts.onRetrySuccess) {
|
|
@@ -10595,7 +10578,7 @@
|
|
|
10595
10578
|
return [2 /*return*/, true];
|
|
10596
10579
|
}
|
|
10597
10580
|
opts = Object.assign(Object.assign({}, opts), { showRetryButton: false, showCloseButton: true });
|
|
10598
|
-
|
|
10581
|
+
_b.label = 3;
|
|
10599
10582
|
case 3:
|
|
10600
10583
|
// Simple toast, without 'await', because not need to wait toast's dismiss
|
|
10601
10584
|
this.showToast(Object.assign({ message: 'ERROR.NETWORK_REQUIRED', type: 'error' }, opts));
|
|
@@ -10604,97 +10587,6 @@
|
|
|
10604
10587
|
});
|
|
10605
10588
|
});
|
|
10606
10589
|
};
|
|
10607
|
-
/**
|
|
10608
|
-
* Try to restore peer from the local storage
|
|
10609
|
-
*/
|
|
10610
|
-
NetworkService.prototype.restoreLocally = function () {
|
|
10611
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10612
|
-
var settingsStr, settings, location, hostname, detectedPeer;
|
|
10613
|
-
return __generator(this, function (_a) {
|
|
10614
|
-
switch (_a.label) {
|
|
10615
|
-
case 0: return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
|
|
10616
|
-
case 1:
|
|
10617
|
-
settingsStr = _a.sent();
|
|
10618
|
-
settings = settingsStr && JSON.parse(settingsStr) || undefined;
|
|
10619
|
-
if (settings && settings.peerUrl) {
|
|
10620
|
-
console.debug("[network] Use peer {" + settings.peerUrl + "} (found in the local storage)");
|
|
10621
|
-
return [2 /*return*/, exports.Peer.parseUrl(settings.peerUrl)];
|
|
10622
|
-
}
|
|
10623
|
-
// Else, use default peer in env, if exists
|
|
10624
|
-
if (this.environment.defaultPeer) {
|
|
10625
|
-
return [2 /*return*/, exports.Peer.fromObject(this.environment.defaultPeer)];
|
|
10626
|
-
}
|
|
10627
|
-
location = this._document && this._document.location;
|
|
10628
|
-
if (!(location && location.protocol && location.protocol.startsWith('http'))) return [3 /*break*/, 3];
|
|
10629
|
-
hostname = this._document.location.host;
|
|
10630
|
-
detectedPeer = exports.Peer.parseUrl("" + this._document.location.protocol + hostname + this.environment.baseUrl);
|
|
10631
|
-
return [4 /*yield*/, this.checkPeerAlive(detectedPeer)];
|
|
10632
|
-
case 2:
|
|
10633
|
-
if (_a.sent()) {
|
|
10634
|
-
return [2 /*return*/, detectedPeer];
|
|
10635
|
-
}
|
|
10636
|
-
_a.label = 3;
|
|
10637
|
-
case 3: return [2 /*return*/, undefined];
|
|
10638
|
-
}
|
|
10639
|
-
});
|
|
10640
|
-
});
|
|
10641
|
-
};
|
|
10642
|
-
/**
|
|
10643
|
-
* Refresh network state, using a ping to pod
|
|
10644
|
-
*/
|
|
10645
|
-
NetworkService.prototype.refreshPeerState = function (opts) {
|
|
10646
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10647
|
-
return __generator(this, function (_a) {
|
|
10648
|
-
return [2 /*return*/];
|
|
10649
|
-
});
|
|
10650
|
-
});
|
|
10651
|
-
};
|
|
10652
|
-
/**
|
|
10653
|
-
* Stop to network state
|
|
10654
|
-
*
|
|
10655
|
-
* @protected
|
|
10656
|
-
*/
|
|
10657
|
-
NetworkService.prototype.stopRefreshTimer = function () {
|
|
10658
|
-
if (this._timerSubscription) {
|
|
10659
|
-
this._timerSubscription.unsubscribe();
|
|
10660
|
-
this._timerSubscription = undefined;
|
|
10661
|
-
}
|
|
10662
|
-
};
|
|
10663
|
-
/**
|
|
10664
|
-
* Refresh the network state
|
|
10665
|
-
*
|
|
10666
|
-
* @protected
|
|
10667
|
-
*/
|
|
10668
|
-
NetworkService.prototype.startRefreshTimer = function () {
|
|
10669
|
-
var _this = this;
|
|
10670
|
-
if (this._timerSubscription)
|
|
10671
|
-
return; // Already running: skip
|
|
10672
|
-
console.info("[network] Starting refresh timer, every " + this._timerRefreshPeriod + "ms...");
|
|
10673
|
-
var lastInfo;
|
|
10674
|
-
this._timerSubscription = rxjs.timer(this._timerRefreshPeriod, this._timerRefreshPeriod)
|
|
10675
|
-
.pipe(
|
|
10676
|
-
// Skip some timer event (see constructor)
|
|
10677
|
-
operators.filter(this._timerRefreshCondition),
|
|
10678
|
-
// Checkin if peer alive
|
|
10679
|
-
operators.tap(function () { return console.debug('[network] Checking connection to pod...'); }), operators.mergeMap(function () { return _this.checkPeerAlive(_this.peer); }),
|
|
10680
|
-
// Filter to keep only changes
|
|
10681
|
-
operators.filter(function (info) { return !!info !== !!lastInfo; }), operators.tap(function (info) { return lastInfo = info; }),
|
|
10682
|
-
// Check compatibility
|
|
10683
|
-
operators.mergeMap(function (info) { return _this.checkPeerCompatible(info, { showToast: true }); }))
|
|
10684
|
-
.subscribe(function (alive) {
|
|
10685
|
-
if (alive && _this.offline) {
|
|
10686
|
-
_this.setForceOffline(false);
|
|
10687
|
-
// Restart the service (to force re auth)
|
|
10688
|
-
_this.restart();
|
|
10689
|
-
}
|
|
10690
|
-
else if (!alive && _this.online) {
|
|
10691
|
-
_this.setForceOffline(true);
|
|
10692
|
-
// Stop the service
|
|
10693
|
-
_this.stop();
|
|
10694
|
-
}
|
|
10695
|
-
});
|
|
10696
|
-
this._timerSubscription.add(function () { return console.debug('[network] Refresh timer stopped'); });
|
|
10697
|
-
};
|
|
10698
10590
|
/**
|
|
10699
10591
|
* Check if the peer is alive
|
|
10700
10592
|
*
|
|
@@ -10703,24 +10595,24 @@
|
|
|
10703
10595
|
NetworkService.prototype.checkPeerAlive = function (peer, opts) {
|
|
10704
10596
|
return __awaiter(this, void 0, void 0, function () {
|
|
10705
10597
|
var settings, err_2;
|
|
10706
|
-
return __generator(this, function (
|
|
10707
|
-
switch (
|
|
10598
|
+
return __generator(this, function (_b) {
|
|
10599
|
+
switch (_b.label) {
|
|
10708
10600
|
case 0:
|
|
10709
10601
|
peer = peer || this.peer;
|
|
10710
10602
|
if (!!peer) return [3 /*break*/, 2];
|
|
10711
10603
|
return [4 /*yield*/, this.settings.ready()];
|
|
10712
10604
|
case 1:
|
|
10713
|
-
settings =
|
|
10605
|
+
settings = _b.sent();
|
|
10714
10606
|
if (!settings.peerUrl)
|
|
10715
10607
|
return [2 /*return*/, undefined]; // No peer define. Skip
|
|
10716
10608
|
peer = exports.Peer.parseUrl(settings.peerUrl);
|
|
10717
|
-
|
|
10609
|
+
_b.label = 2;
|
|
10718
10610
|
case 2:
|
|
10719
|
-
|
|
10611
|
+
_b.trys.push([2, 4, , 5]);
|
|
10720
10612
|
return [4 /*yield*/, this.getNodeInfo(peer)];
|
|
10721
|
-
case 3: return [2 /*return*/,
|
|
10613
|
+
case 3: return [2 /*return*/, _b.sent()];
|
|
10722
10614
|
case 4:
|
|
10723
|
-
err_2 =
|
|
10615
|
+
err_2 = _b.sent();
|
|
10724
10616
|
console.debug('[network] Cannot get /api/node/info from peer: ' + (err_2 && err_2.message || err_2), err_2);
|
|
10725
10617
|
return [2 /*return*/, undefined];
|
|
10726
10618
|
case 5: return [2 /*return*/];
|
|
@@ -10731,8 +10623,8 @@
|
|
|
10731
10623
|
NetworkService.prototype.checkPeerCompatible = function (peerInfo, opts) {
|
|
10732
10624
|
return __awaiter(this, void 0, void 0, function () {
|
|
10733
10625
|
var isCompatible;
|
|
10734
|
-
return __generator(this, function (
|
|
10735
|
-
switch (
|
|
10626
|
+
return __generator(this, function (_b) {
|
|
10627
|
+
switch (_b.label) {
|
|
10736
10628
|
case 0:
|
|
10737
10629
|
if (!this.environment.peerMinVersion)
|
|
10738
10630
|
return [2 /*return*/, true]; // Skip compatibility check
|
|
@@ -10747,8 +10639,8 @@
|
|
|
10747
10639
|
showCloseButton: true
|
|
10748
10640
|
})];
|
|
10749
10641
|
case 1:
|
|
10750
|
-
|
|
10751
|
-
|
|
10642
|
+
_b.sent();
|
|
10643
|
+
_b.label = 2;
|
|
10752
10644
|
case 2: return [2 /*return*/, isCompatible];
|
|
10753
10645
|
}
|
|
10754
10646
|
});
|
|
@@ -10788,8 +10680,8 @@
|
|
|
10788
10680
|
return __awaiter(this, void 0, void 0, function () {
|
|
10789
10681
|
var $onRefresh, peers$, modal, data;
|
|
10790
10682
|
var _this = this;
|
|
10791
|
-
return __generator(this, function (
|
|
10792
|
-
switch (
|
|
10683
|
+
return __generator(this, function (_b) {
|
|
10684
|
+
switch (_b.label) {
|
|
10793
10685
|
case 0:
|
|
10794
10686
|
opts = opts || {};
|
|
10795
10687
|
$onRefresh = new i0.EventEmitter();
|
|
@@ -10806,14 +10698,14 @@
|
|
|
10806
10698
|
showBackdrop: true
|
|
10807
10699
|
})];
|
|
10808
10700
|
case 1:
|
|
10809
|
-
modal =
|
|
10701
|
+
modal = _b.sent();
|
|
10810
10702
|
return [4 /*yield*/, modal.present()];
|
|
10811
10703
|
case 2:
|
|
10812
|
-
|
|
10704
|
+
_b.sent();
|
|
10813
10705
|
$onRefresh.emit();
|
|
10814
10706
|
return [4 /*yield*/, modal.onWillDismiss()];
|
|
10815
10707
|
case 3:
|
|
10816
|
-
data = (
|
|
10708
|
+
data = (_b.sent()).data;
|
|
10817
10709
|
$onRefresh.complete();
|
|
10818
10710
|
return [2 /*return*/, data && data || undefined];
|
|
10819
10711
|
}
|
|
@@ -10824,7 +10716,7 @@
|
|
|
10824
10716
|
return __awaiter(this, void 0, void 0, function () {
|
|
10825
10717
|
var now;
|
|
10826
10718
|
var _this = this;
|
|
10827
|
-
return __generator(this, function (
|
|
10719
|
+
return __generator(this, function (_b) {
|
|
10828
10720
|
now = this._debug && Date.now();
|
|
10829
10721
|
console.info('[network] Clearing all caches...');
|
|
10830
10722
|
return [2 /*return*/, this.cache.clearAll()
|
|
@@ -10843,10 +10735,164 @@
|
|
|
10843
10735
|
});
|
|
10844
10736
|
});
|
|
10845
10737
|
};
|
|
10738
|
+
/* -- protected functions -- */
|
|
10739
|
+
NetworkService.prototype.ngOnStart = function () {
|
|
10740
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10741
|
+
var peer, _b;
|
|
10742
|
+
return __generator(this, function (_c) {
|
|
10743
|
+
switch (_c.label) {
|
|
10744
|
+
case 0:
|
|
10745
|
+
console.info('[network] Starting network...', this._startingPeer);
|
|
10746
|
+
_b = this._startingPeer;
|
|
10747
|
+
if (_b) return [3 /*break*/, 2];
|
|
10748
|
+
return [4 /*yield*/, this.restoreLocally()];
|
|
10749
|
+
case 1:
|
|
10750
|
+
_b = (_c.sent());
|
|
10751
|
+
_c.label = 2;
|
|
10752
|
+
case 2:
|
|
10753
|
+
peer = _b;
|
|
10754
|
+
// Make sure to hide the splashscreen, before open the modal
|
|
10755
|
+
if (!peer && this.splashScreen)
|
|
10756
|
+
this.splashScreen.hide();
|
|
10757
|
+
_c.label = 3;
|
|
10758
|
+
case 3:
|
|
10759
|
+
if (!!peer) return [3 /*break*/, 5];
|
|
10760
|
+
console.debug('[network] No peer defined. Asking user to choose a peer.');
|
|
10761
|
+
return [4 /*yield*/, this.showSelectPeerModal({ allowSelectDownPeer: false })];
|
|
10762
|
+
case 4:
|
|
10763
|
+
peer = _c.sent();
|
|
10764
|
+
return [3 /*break*/, 3];
|
|
10765
|
+
case 5:
|
|
10766
|
+
console.info("[network] Starting service [OK] {peer: '" + peer.url + "', online: " + this.online + "}");
|
|
10767
|
+
return [2 /*return*/, peer];
|
|
10768
|
+
}
|
|
10769
|
+
});
|
|
10770
|
+
});
|
|
10771
|
+
};
|
|
10772
|
+
NetworkService.prototype.ngOnAfterStart = function () {
|
|
10773
|
+
var _a;
|
|
10774
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10775
|
+
var _this = this;
|
|
10776
|
+
return __generator(this, function (_b) {
|
|
10777
|
+
switch (_b.label) {
|
|
10778
|
+
case 0:
|
|
10779
|
+
// Wait settings starts, then save peer in settings
|
|
10780
|
+
return [4 /*yield*/, this.settings.apply({ peerUrl: this._data.url })];
|
|
10781
|
+
case 1:
|
|
10782
|
+
// Wait settings starts, then save peer in settings
|
|
10783
|
+
_b.sent();
|
|
10784
|
+
this.onDeviceConnectionChanged(((_a = this.network) === null || _a === void 0 ? void 0 : _a.type) || 'unknown');
|
|
10785
|
+
// Start the refresh timer
|
|
10786
|
+
this.startRefreshTimer();
|
|
10787
|
+
// Listen for device network changes
|
|
10788
|
+
if (this.network) {
|
|
10789
|
+
this._subscription.add(this.network.onDisconnect().subscribe(function () { return _this.onDeviceConnectionChanged('none'); }));
|
|
10790
|
+
this._subscription.add(this.network.onConnect().subscribe(function () { return _this.onDeviceConnectionChanged(_this.network.type); }));
|
|
10791
|
+
}
|
|
10792
|
+
return [2 /*return*/];
|
|
10793
|
+
}
|
|
10794
|
+
});
|
|
10795
|
+
});
|
|
10796
|
+
};
|
|
10797
|
+
NetworkService.prototype.ngOnStop = function () {
|
|
10798
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10799
|
+
return __generator(this, function (_b) {
|
|
10800
|
+
this.resetData();
|
|
10801
|
+
// Stop timer if cannot refresh anymore
|
|
10802
|
+
if (this._timerRefreshCondition() === false) {
|
|
10803
|
+
this.stopRefreshTimer();
|
|
10804
|
+
}
|
|
10805
|
+
this._subscription.unsubscribe();
|
|
10806
|
+
this._subscription = new rxjs.Subscription();
|
|
10807
|
+
return [2 /*return*/];
|
|
10808
|
+
});
|
|
10809
|
+
});
|
|
10810
|
+
};
|
|
10811
|
+
/**
|
|
10812
|
+
* Try to restore peer from the local storage
|
|
10813
|
+
*/
|
|
10814
|
+
NetworkService.prototype.restoreLocally = function () {
|
|
10815
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10816
|
+
var settingsStr, settings, location, hostname, detectedPeer;
|
|
10817
|
+
return __generator(this, function (_b) {
|
|
10818
|
+
switch (_b.label) {
|
|
10819
|
+
case 0: return [4 /*yield*/, this.storage.get(SETTINGS_STORAGE_KEY)];
|
|
10820
|
+
case 1:
|
|
10821
|
+
settingsStr = _b.sent();
|
|
10822
|
+
settings = settingsStr && JSON.parse(settingsStr) || undefined;
|
|
10823
|
+
if (settings && settings.peerUrl) {
|
|
10824
|
+
console.debug("[network] Use peer {" + settings.peerUrl + "} (found in the local storage)");
|
|
10825
|
+
return [2 /*return*/, exports.Peer.parseUrl(settings.peerUrl)];
|
|
10826
|
+
}
|
|
10827
|
+
// Else, use default peer in env, if exists
|
|
10828
|
+
if (this.environment.defaultPeer) {
|
|
10829
|
+
return [2 /*return*/, exports.Peer.fromObject(this.environment.defaultPeer)];
|
|
10830
|
+
}
|
|
10831
|
+
location = this._document && this._document.location;
|
|
10832
|
+
if (!(location && location.protocol && location.protocol.startsWith('http'))) return [3 /*break*/, 3];
|
|
10833
|
+
hostname = this._document.location.host;
|
|
10834
|
+
detectedPeer = exports.Peer.parseUrl("" + this._document.location.protocol + hostname + this.environment.baseUrl);
|
|
10835
|
+
return [4 /*yield*/, this.checkPeerAlive(detectedPeer)];
|
|
10836
|
+
case 2:
|
|
10837
|
+
if (_b.sent()) {
|
|
10838
|
+
return [2 /*return*/, detectedPeer];
|
|
10839
|
+
}
|
|
10840
|
+
_b.label = 3;
|
|
10841
|
+
case 3: return [2 /*return*/, undefined];
|
|
10842
|
+
}
|
|
10843
|
+
});
|
|
10844
|
+
});
|
|
10845
|
+
};
|
|
10846
|
+
/**
|
|
10847
|
+
* Stop to network state
|
|
10848
|
+
*
|
|
10849
|
+
* @protected
|
|
10850
|
+
*/
|
|
10851
|
+
NetworkService.prototype.stopRefreshTimer = function () {
|
|
10852
|
+
if (this._timerSubscription) {
|
|
10853
|
+
this._timerSubscription.unsubscribe();
|
|
10854
|
+
this._timerSubscription = undefined;
|
|
10855
|
+
}
|
|
10856
|
+
};
|
|
10857
|
+
/**
|
|
10858
|
+
* Refresh the network state
|
|
10859
|
+
*
|
|
10860
|
+
* @protected
|
|
10861
|
+
*/
|
|
10862
|
+
NetworkService.prototype.startRefreshTimer = function () {
|
|
10863
|
+
var _this = this;
|
|
10864
|
+
if (this._timerSubscription)
|
|
10865
|
+
return; // Already running: skip
|
|
10866
|
+
console.info("[network] Starting refresh timer, every " + this._timerRefreshPeriod + "ms...");
|
|
10867
|
+
var lastInfo;
|
|
10868
|
+
this._timerSubscription = rxjs.timer(this._timerRefreshPeriod, this._timerRefreshPeriod)
|
|
10869
|
+
.pipe(
|
|
10870
|
+
// Skip some timer event (see constructor)
|
|
10871
|
+
operators.filter(this._timerRefreshCondition),
|
|
10872
|
+
// Checkin if peer alive
|
|
10873
|
+
operators.tap(function () { return console.debug('[network] Checking connection to pod...'); }), operators.mergeMap(function () { return _this.checkPeerAlive(_this.peer); }),
|
|
10874
|
+
// Filter to keep only changes
|
|
10875
|
+
operators.filter(function (info) { return !!info !== !!lastInfo; }), operators.tap(function (info) { return lastInfo = info; }),
|
|
10876
|
+
// Check compatibility
|
|
10877
|
+
operators.mergeMap(function (info) { return _this.checkPeerCompatible(info, { showToast: true }); }))
|
|
10878
|
+
.subscribe(function (alive) {
|
|
10879
|
+
if (alive && _this.offline) {
|
|
10880
|
+
_this.setForceOffline(false);
|
|
10881
|
+
// Restart the service (to force re auth)
|
|
10882
|
+
_this.restart();
|
|
10883
|
+
}
|
|
10884
|
+
else if (!alive && _this.online) {
|
|
10885
|
+
_this.setForceOffline(true);
|
|
10886
|
+
// Stop the service
|
|
10887
|
+
_this.stop();
|
|
10888
|
+
}
|
|
10889
|
+
});
|
|
10890
|
+
this._timerSubscription.add(function () { return console.debug('[network] Refresh timer stopped'); });
|
|
10891
|
+
};
|
|
10846
10892
|
NetworkService.prototype.get = function (path, opts) {
|
|
10847
10893
|
return __awaiter(this, void 0, void 0, function () {
|
|
10848
10894
|
var uri, peerUrl;
|
|
10849
|
-
return __generator(this, function (
|
|
10895
|
+
return __generator(this, function (_b) {
|
|
10850
10896
|
uri = path;
|
|
10851
10897
|
// If path is not an URI: prepend with peer URL
|
|
10852
10898
|
if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
|
|
@@ -10897,7 +10943,7 @@
|
|
|
10897
10943
|
}
|
|
10898
10944
|
};
|
|
10899
10945
|
NetworkService.prototype.resetData = function () {
|
|
10900
|
-
this.
|
|
10946
|
+
this._data = null;
|
|
10901
10947
|
};
|
|
10902
10948
|
/**
|
|
10903
10949
|
* Get default peers, from environment
|
|
@@ -10905,7 +10951,7 @@
|
|
|
10905
10951
|
NetworkService.prototype.getDefaultPeers = function () {
|
|
10906
10952
|
return __awaiter(this, void 0, void 0, function () {
|
|
10907
10953
|
var peers;
|
|
10908
|
-
return __generator(this, function (
|
|
10954
|
+
return __generator(this, function (_b) {
|
|
10909
10955
|
peers = (this.environment.defaultPeers || []).map(exports.Peer.fromObject);
|
|
10910
10956
|
return [2 /*return*/, Promise.resolve(peers)];
|
|
10911
10957
|
});
|
|
@@ -10918,7 +10964,7 @@
|
|
|
10918
10964
|
var _this = this;
|
|
10919
10965
|
this._listeners[name] = this._listeners[name] || [];
|
|
10920
10966
|
this._listeners[name].push(callback);
|
|
10921
|
-
// When
|
|
10967
|
+
// When unsubscribe, remove from the listener
|
|
10922
10968
|
return new rxjs.Subscription(function () {
|
|
10923
10969
|
var index = _this._listeners[name].indexOf(callback);
|
|
10924
10970
|
if (index !== -1) {
|
|
@@ -10929,7 +10975,7 @@
|
|
|
10929
10975
|
NetworkService.prototype.emit = function (name, data) {
|
|
10930
10976
|
return __awaiter(this, void 0, void 0, function () {
|
|
10931
10977
|
var hooks;
|
|
10932
|
-
return __generator(this, function (
|
|
10978
|
+
return __generator(this, function (_b) {
|
|
10933
10979
|
hooks = this._listeners[name];
|
|
10934
10980
|
if (isNotEmptyArray(hooks)) {
|
|
10935
10981
|
console.info("[network-service] Trigger " + name + " hook: Executing " + hooks.length + " callbacks...");
|
|
@@ -10945,7 +10991,7 @@
|
|
|
10945
10991
|
});
|
|
10946
10992
|
};
|
|
10947
10993
|
return NetworkService;
|
|
10948
|
-
}());
|
|
10994
|
+
}(StartableService));
|
|
10949
10995
|
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" });
|
|
10950
10996
|
NetworkService.decorators = [
|
|
10951
10997
|
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
|
|
@@ -11548,31 +11594,31 @@
|
|
|
11548
11594
|
}());
|
|
11549
11595
|
|
|
11550
11596
|
var APP_LOCAL_STORAGE_TYPE_POLICIES = new i0.InjectionToken('localStorageTypePolicies');
|
|
11551
|
-
|
|
11597
|
+
;
|
|
11598
|
+
var EntitiesStorage = /** @class */ (function (_super) {
|
|
11599
|
+
__extends(EntitiesStorage, _super);
|
|
11552
11600
|
function EntitiesStorage(platform, progressBarService, storage, environment, typePolicies) {
|
|
11553
|
-
this
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11601
|
+
var _this = _super.call(this, platform) || this;
|
|
11602
|
+
_this.platform = platform;
|
|
11603
|
+
_this.progressBarService = progressBarService;
|
|
11604
|
+
_this.storage = storage;
|
|
11605
|
+
_this.environment = environment;
|
|
11606
|
+
_this._subscription = new rxjs.Subscription();
|
|
11607
|
+
_this._$save = new i0.EventEmitter(true);
|
|
11608
|
+
_this._dirty = false;
|
|
11609
|
+
_this._saving = false;
|
|
11610
|
+
_this._typePolicies = typePolicies || {};
|
|
11611
|
+
_this._saveTimerPeriod = environment.storageSavePeriodMs || 10000 /* = 10s */;
|
|
11612
|
+
_this._data = {};
|
|
11565
11613
|
// For DEV only
|
|
11566
|
-
|
|
11567
|
-
if (
|
|
11614
|
+
_this._debug = !environment.production;
|
|
11615
|
+
if (_this._debug)
|
|
11568
11616
|
console.debug('[entities-storage] Creating service');
|
|
11617
|
+
return _this;
|
|
11569
11618
|
}
|
|
11570
11619
|
Object.defineProperty(EntitiesStorage.prototype, "dirty", {
|
|
11571
11620
|
get: function () {
|
|
11572
|
-
return this._dirty || Object.
|
|
11573
|
-
var _b = __read(_a, 2), _ = _b[0], store = _b[1];
|
|
11574
|
-
return store.dirty;
|
|
11575
|
-
}) !== undefined;
|
|
11621
|
+
return this._dirty || Object.values(this._data).some(function (store) { return store.dirty; });
|
|
11576
11622
|
},
|
|
11577
11623
|
enumerable: false,
|
|
11578
11624
|
configurable: true
|
|
@@ -11580,7 +11626,7 @@
|
|
|
11580
11626
|
EntitiesStorage.prototype.watchAll = function (entityName, variables, opts) {
|
|
11581
11627
|
var _this = this;
|
|
11582
11628
|
// Make sure store is ready
|
|
11583
|
-
if (!this.
|
|
11629
|
+
if (!this.started) {
|
|
11584
11630
|
return rxjs.defer(function () { return _this.ready(); })
|
|
11585
11631
|
.pipe(operators.switchMap(function () { return _this.watchAll(entityName, variables, opts); })); // Loop
|
|
11586
11632
|
}
|
|
@@ -11597,7 +11643,7 @@
|
|
|
11597
11643
|
return __generator(this, function (_a) {
|
|
11598
11644
|
switch (_a.label) {
|
|
11599
11645
|
case 0:
|
|
11600
|
-
if (!!this.
|
|
11646
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11601
11647
|
return [4 /*yield*/, this.ready()];
|
|
11602
11648
|
case 1:
|
|
11603
11649
|
_a.sent();
|
|
@@ -11700,9 +11746,12 @@
|
|
|
11700
11746
|
case 0:
|
|
11701
11747
|
if (!entity)
|
|
11702
11748
|
return [2 /*return*/]; // skip
|
|
11749
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11703
11750
|
return [4 /*yield*/, this.ready()];
|
|
11704
11751
|
case 1:
|
|
11705
11752
|
_a.sent();
|
|
11753
|
+
_a.label = 2;
|
|
11754
|
+
case 2:
|
|
11706
11755
|
try {
|
|
11707
11756
|
this.progressBarService.increase();
|
|
11708
11757
|
this._dirty = true;
|
|
@@ -11729,9 +11778,12 @@
|
|
|
11729
11778
|
case 0:
|
|
11730
11779
|
if (isEmptyArray(entities) && (!opts || opts.reset !== true))
|
|
11731
11780
|
return [2 /*return*/, entities]; // Skip (nothing to save)
|
|
11781
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11732
11782
|
return [4 /*yield*/, this.ready()];
|
|
11733
11783
|
case 1:
|
|
11734
11784
|
_a.sent();
|
|
11785
|
+
_a.label = 2;
|
|
11786
|
+
case 2:
|
|
11735
11787
|
try {
|
|
11736
11788
|
this.progressBarService.increase();
|
|
11737
11789
|
this._dirty = true;
|
|
@@ -11753,10 +11805,12 @@
|
|
|
11753
11805
|
case 0:
|
|
11754
11806
|
if (!entity)
|
|
11755
11807
|
return [2 /*return*/, undefined]; // skip
|
|
11808
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11756
11809
|
return [4 /*yield*/, this.ready()];
|
|
11757
11810
|
case 1:
|
|
11758
11811
|
_a.sent();
|
|
11759
|
-
|
|
11812
|
+
_a.label = 2;
|
|
11813
|
+
case 2: return [2 /*return*/, this.deleteById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
|
|
11760
11814
|
}
|
|
11761
11815
|
});
|
|
11762
11816
|
});
|
|
@@ -11766,9 +11820,13 @@
|
|
|
11766
11820
|
var entityStore, deletedEntity;
|
|
11767
11821
|
return __generator(this, function (_a) {
|
|
11768
11822
|
switch (_a.label) {
|
|
11769
|
-
case 0:
|
|
11823
|
+
case 0:
|
|
11824
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11825
|
+
return [4 /*yield*/, this.ready()];
|
|
11770
11826
|
case 1:
|
|
11771
11827
|
_a.sent();
|
|
11828
|
+
_a.label = 2;
|
|
11829
|
+
case 2:
|
|
11772
11830
|
if (!opts || isNilOrBlank(opts.entityName))
|
|
11773
11831
|
throw new Error('Missing argument \'opts\' or \'entityName\'');
|
|
11774
11832
|
//if (id >= 0) throw new Error('Invalid id a local entity (not a negative number): ' + id);
|
|
@@ -11800,9 +11858,13 @@
|
|
|
11800
11858
|
var entityStore, deletedEntities;
|
|
11801
11859
|
return __generator(this, function (_a) {
|
|
11802
11860
|
switch (_a.label) {
|
|
11803
|
-
case 0:
|
|
11861
|
+
case 0:
|
|
11862
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11863
|
+
return [4 /*yield*/, this.ready()];
|
|
11804
11864
|
case 1:
|
|
11805
11865
|
_a.sent();
|
|
11866
|
+
_a.label = 2;
|
|
11867
|
+
case 2:
|
|
11806
11868
|
if (!opts || isNilOrBlank(opts.entityName))
|
|
11807
11869
|
throw new Error('Missing argument \'opts\' or \'opts.entityName\'');
|
|
11808
11870
|
try {
|
|
@@ -11835,10 +11897,12 @@
|
|
|
11835
11897
|
case 0:
|
|
11836
11898
|
if (!entity)
|
|
11837
11899
|
return [2 /*return*/, undefined]; // skip
|
|
11900
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11838
11901
|
return [4 /*yield*/, this.ready()];
|
|
11839
11902
|
case 1:
|
|
11840
11903
|
_a.sent();
|
|
11841
|
-
|
|
11904
|
+
_a.label = 2;
|
|
11905
|
+
case 2: return [2 /*return*/, this.deleteFromTrashById(entity.id, Object.assign(Object.assign({}, opts), { entityName: opts && opts.entityName || this.detectEntityName(entity) }))];
|
|
11842
11906
|
}
|
|
11843
11907
|
});
|
|
11844
11908
|
});
|
|
@@ -11865,9 +11929,12 @@
|
|
|
11865
11929
|
case 0:
|
|
11866
11930
|
if (!entity)
|
|
11867
11931
|
return [2 /*return*/, undefined]; // skip
|
|
11932
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11868
11933
|
return [4 /*yield*/, this.ready()];
|
|
11869
11934
|
case 1:
|
|
11870
11935
|
_a.sent();
|
|
11936
|
+
_a.label = 2;
|
|
11937
|
+
case 2:
|
|
11871
11938
|
entityName = opts && opts.entityName || this.detectEntityName(entity);
|
|
11872
11939
|
entityStore = this.getEntityStore(entityName);
|
|
11873
11940
|
if (entityStore)
|
|
@@ -11887,9 +11954,13 @@
|
|
|
11887
11954
|
var entityStore, deletedEntities, trashName;
|
|
11888
11955
|
return __generator(this, function (_a) {
|
|
11889
11956
|
switch (_a.label) {
|
|
11890
|
-
case 0:
|
|
11957
|
+
case 0:
|
|
11958
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11959
|
+
return [4 /*yield*/, this.ready()];
|
|
11891
11960
|
case 1:
|
|
11892
11961
|
_a.sent();
|
|
11962
|
+
_a.label = 2;
|
|
11963
|
+
case 2:
|
|
11893
11964
|
if (!opts || isNilOrBlank(opts.entityName))
|
|
11894
11965
|
throw new Error('Missing argument \'opts.entityName\'');
|
|
11895
11966
|
entityStore = this.getEntityStore(opts.entityName, { create: false });
|
|
@@ -11921,9 +11992,12 @@
|
|
|
11921
11992
|
case 0:
|
|
11922
11993
|
if (!entity)
|
|
11923
11994
|
return [2 /*return*/, undefined]; // skip
|
|
11995
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
11924
11996
|
return [4 /*yield*/, this.ready()];
|
|
11925
11997
|
case 1:
|
|
11926
11998
|
_a.sent();
|
|
11999
|
+
_a.label = 2;
|
|
12000
|
+
case 2:
|
|
11927
12001
|
entityName = opts && opts.entityName || this.detectEntityName(entity);
|
|
11928
12002
|
trashName = EntitiesStorage.TRASH_PREFIX + entityName;
|
|
11929
12003
|
this.getEntityStore(trashName).save(entity, opts);
|
|
@@ -11938,9 +12012,13 @@
|
|
|
11938
12012
|
var trashName, entityStore;
|
|
11939
12013
|
return __generator(this, function (_a) {
|
|
11940
12014
|
switch (_a.label) {
|
|
11941
|
-
case 0:
|
|
12015
|
+
case 0:
|
|
12016
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
12017
|
+
return [4 /*yield*/, this.ready()];
|
|
11942
12018
|
case 1:
|
|
11943
12019
|
_a.sent();
|
|
12020
|
+
_a.label = 2;
|
|
12021
|
+
case 2:
|
|
11944
12022
|
trashName = EntitiesStorage.TRASH_PREFIX + entityName;
|
|
11945
12023
|
entityStore = this.getEntityStore(trashName, { create: false });
|
|
11946
12024
|
if (!entityStore)
|
|
@@ -11959,79 +12037,58 @@
|
|
|
11959
12037
|
}
|
|
11960
12038
|
return Promise.resolve();
|
|
11961
12039
|
};
|
|
11962
|
-
EntitiesStorage.prototype.
|
|
11963
|
-
if (this._started)
|
|
11964
|
-
return Promise.resolve();
|
|
11965
|
-
return this.start();
|
|
11966
|
-
};
|
|
11967
|
-
EntitiesStorage.prototype.start = function () {
|
|
11968
|
-
var _this = this;
|
|
11969
|
-
if (this._startPromise)
|
|
11970
|
-
return this._startPromise;
|
|
11971
|
-
if (this._started)
|
|
11972
|
-
return Promise.resolve();
|
|
11973
|
-
var now = Date.now();
|
|
11974
|
-
console.info("[entities-storage] Starting entity storage...");
|
|
11975
|
-
// Restore sequences
|
|
11976
|
-
this._startPromise = this.restoreLocally()
|
|
11977
|
-
.then(function () {
|
|
11978
|
-
// Start a save timer
|
|
11979
|
-
_this._subscription.add(rxjs.merge(_this._$save, rxjs.timer(2000, 10000))
|
|
11980
|
-
.pipe(operators.throttleTime(10000))
|
|
11981
|
-
.subscribe(function () { return _this.storeLocally(); }));
|
|
11982
|
-
_this._started = true;
|
|
11983
|
-
_this._startPromise = undefined;
|
|
11984
|
-
console.info("[entities-storage] Starting [OK] in " + (Date.now() - now) + "ms");
|
|
11985
|
-
// Emit event
|
|
11986
|
-
_this.onStart.next();
|
|
11987
|
-
});
|
|
11988
|
-
return this._startPromise;
|
|
11989
|
-
};
|
|
11990
|
-
EntitiesStorage.prototype.stop = function () {
|
|
12040
|
+
EntitiesStorage.prototype.ngOnStart = function () {
|
|
11991
12041
|
return __awaiter(this, void 0, void 0, function () {
|
|
12042
|
+
var now;
|
|
12043
|
+
var _this = this;
|
|
11992
12044
|
return __generator(this, function (_a) {
|
|
11993
12045
|
switch (_a.label) {
|
|
11994
12046
|
case 0:
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
return [4 /*yield*/, this.storeLocally()];
|
|
12047
|
+
now = Date.now();
|
|
12048
|
+
console.info("[entities-storage] Starting entity storage...");
|
|
12049
|
+
// Restore sequences
|
|
12050
|
+
return [4 /*yield*/, this.restoreLocally()];
|
|
12000
12051
|
case 1:
|
|
12052
|
+
// Restore sequences
|
|
12001
12053
|
_a.sent();
|
|
12002
|
-
|
|
12003
|
-
|
|
12054
|
+
// Start a save timer
|
|
12055
|
+
this._subscription.add(rxjs.merge(this._$save, rxjs.timer(this._saveTimerPeriod, this._saveTimerPeriod))
|
|
12056
|
+
.pipe(
|
|
12057
|
+
// Avoid to many call (e.g. when $save AND timer are triggered
|
|
12058
|
+
operators.throttleTime(this._saveTimerPeriod))
|
|
12059
|
+
.subscribe(function () { return _this.storeLocally(); }));
|
|
12060
|
+
console.info("[entities-storage] Starting [OK] in " + (Date.now() - now) + "ms");
|
|
12061
|
+
return [2 /*return*/, this._data];
|
|
12004
12062
|
}
|
|
12005
12063
|
});
|
|
12006
12064
|
});
|
|
12007
12065
|
};
|
|
12008
|
-
EntitiesStorage.prototype.
|
|
12066
|
+
EntitiesStorage.prototype.ngOnStop = function () {
|
|
12009
12067
|
return __awaiter(this, void 0, void 0, function () {
|
|
12010
12068
|
return __generator(this, function (_a) {
|
|
12011
12069
|
switch (_a.label) {
|
|
12012
12070
|
case 0:
|
|
12013
|
-
|
|
12014
|
-
|
|
12071
|
+
this._subscription.unsubscribe();
|
|
12072
|
+
this._subscription = new rxjs.Subscription();
|
|
12073
|
+
if (!this.dirty) return [3 /*break*/, 2];
|
|
12074
|
+
return [4 /*yield*/, this.storeLocally()];
|
|
12015
12075
|
case 1:
|
|
12016
12076
|
_a.sent();
|
|
12017
12077
|
_a.label = 2;
|
|
12018
|
-
case 2: return [
|
|
12019
|
-
case 3:
|
|
12020
|
-
_a.sent();
|
|
12021
|
-
return [2 /*return*/];
|
|
12078
|
+
case 2: return [2 /*return*/];
|
|
12022
12079
|
}
|
|
12023
12080
|
});
|
|
12024
12081
|
});
|
|
12025
12082
|
};
|
|
12026
12083
|
/* -- protected methods -- */
|
|
12027
12084
|
EntitiesStorage.prototype.getEntityStore = function (name, opts) {
|
|
12028
|
-
var store = this.
|
|
12085
|
+
var store = this._data[name];
|
|
12029
12086
|
if (!store && (!opts || opts.create !== false)) {
|
|
12030
12087
|
if (this._debug)
|
|
12031
12088
|
console.debug("[entities-storage] Creating store " + name);
|
|
12032
12089
|
var typePolicy = this._typePolicies[name];
|
|
12033
12090
|
store = new EntityStore(name, this.storage, typePolicy);
|
|
12034
|
-
this.
|
|
12091
|
+
this._data[name] = store;
|
|
12035
12092
|
}
|
|
12036
12093
|
return store;
|
|
12037
12094
|
};
|
|
@@ -12088,11 +12145,11 @@
|
|
|
12088
12145
|
this._saving = true;
|
|
12089
12146
|
this._dirty = false;
|
|
12090
12147
|
this.progressBarService.increase();
|
|
12091
|
-
entityNames = this.
|
|
12148
|
+
entityNames = this._data && Object.keys(this._data) || [];
|
|
12092
12149
|
now = Date.now();
|
|
12093
12150
|
if (this._debug)
|
|
12094
12151
|
console.debug('[entities-storage] Persisting...');
|
|
12095
|
-
return [2 /*return*/,
|
|
12152
|
+
return [2 /*return*/, chainPromises(entityNames.map(function (entityName) { return function () {
|
|
12096
12153
|
currentEntityName = entityName;
|
|
12097
12154
|
var entityStore = _this.getEntityStore(entityName, { create: false });
|
|
12098
12155
|
if (!entityStore) {
|
|
@@ -12106,17 +12163,20 @@
|
|
|
12106
12163
|
entityNames.splice(entityNames.findIndex(function (e) { return e === entityName; }), 1);
|
|
12107
12164
|
}
|
|
12108
12165
|
});
|
|
12109
|
-
}
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12166
|
+
}; }))
|
|
12167
|
+
.then(function () {
|
|
12168
|
+
currentEntityName = undefined;
|
|
12169
|
+
return isEmptyArray(entityNames) ?
|
|
12170
|
+
_this.storage.remove(ENTITIES_STORAGE_KEY_PREFIX) :
|
|
12171
|
+
_this.storage.set(ENTITIES_STORAGE_KEY_PREFIX, entityNames);
|
|
12172
|
+
})
|
|
12173
|
+
.then(function () {
|
|
12174
|
+
if (_this._debug)
|
|
12175
|
+
console.debug("[entities-storage] Persisting [OK] " + entityNames.length + " stores saved in " + (Date.now() - now) + "ms...");
|
|
12176
|
+
_this._saving = false;
|
|
12177
|
+
_this.progressBarService.decrease();
|
|
12178
|
+
})
|
|
12179
|
+
.catch(function (err) {
|
|
12120
12180
|
_this._saving = false;
|
|
12121
12181
|
_this.progressBarService.decrease();
|
|
12122
12182
|
if (currentEntityName) {
|
|
@@ -12125,13 +12185,13 @@
|
|
|
12125
12185
|
else {
|
|
12126
12186
|
console.error("[entities-storage] Error while persisting: " + (err && err.message || err), err);
|
|
12127
12187
|
}
|
|
12128
|
-
|
|
12129
|
-
})
|
|
12188
|
+
throw err;
|
|
12189
|
+
})];
|
|
12130
12190
|
});
|
|
12131
12191
|
});
|
|
12132
12192
|
};
|
|
12133
12193
|
return EntitiesStorage;
|
|
12134
|
-
}());
|
|
12194
|
+
}(StartableService));
|
|
12135
12195
|
EntitiesStorage.TRASH_PREFIX = 'Trash#';
|
|
12136
12196
|
EntitiesStorage.REMOTE_PREFIX = 'Remote#';
|
|
12137
12197
|
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" });
|
|
@@ -12142,7 +12202,7 @@
|
|
|
12142
12202
|
{ type: i1$5.Platform },
|
|
12143
12203
|
{ type: ProgressBarService },
|
|
12144
12204
|
{ type: i3$2.Storage },
|
|
12145
|
-
{ type:
|
|
12205
|
+
{ type: Environment, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] },
|
|
12146
12206
|
{ type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [APP_LOCAL_STORAGE_TYPE_POLICIES,] }] }
|
|
12147
12207
|
]; };
|
|
12148
12208
|
|
|
@@ -12667,59 +12727,36 @@
|
|
|
12667
12727
|
}
|
|
12668
12728
|
|
|
12669
12729
|
var APP_GRAPHQL_TYPE_POLICIES = new i0.InjectionToken('graphqlTypePolicies');
|
|
12670
|
-
var GraphqlService = /** @class */ (function () {
|
|
12730
|
+
var GraphqlService = /** @class */ (function (_super) {
|
|
12731
|
+
__extends(GraphqlService, _super);
|
|
12671
12732
|
function GraphqlService(platform, apollo, httpLink, network, storage, cryptoService, environment, typePolicies) {
|
|
12672
|
-
var _this = this;
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
this._debug = !environment.production;
|
|
12688
|
-
this._defaultFetchPolicy = environment.apolloFetchPolicy;
|
|
12689
|
-
// Restart if network restart
|
|
12690
|
-
this.network.on('start', function () { return _this.restart(); });
|
|
12691
|
-
// Clear cache
|
|
12692
|
-
this.network.on('resetCache', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
12693
|
-
return __generator(this, function (_a) {
|
|
12694
|
-
switch (_a.label) {
|
|
12695
|
-
case 0: return [4 /*yield*/, this.ready()];
|
|
12696
|
-
case 1:
|
|
12697
|
-
_a.sent();
|
|
12698
|
-
return [4 /*yield*/, this.clearCache()];
|
|
12699
|
-
case 2:
|
|
12700
|
-
_a.sent();
|
|
12701
|
-
return [2 /*return*/];
|
|
12702
|
-
}
|
|
12703
|
-
});
|
|
12704
|
-
}); });
|
|
12733
|
+
var _this = _super.call(this, platform) || this;
|
|
12734
|
+
_this.platform = platform;
|
|
12735
|
+
_this.apollo = apollo;
|
|
12736
|
+
_this.httpLink = httpLink;
|
|
12737
|
+
_this.network = network;
|
|
12738
|
+
_this.storage = storage;
|
|
12739
|
+
_this.cryptoService = cryptoService;
|
|
12740
|
+
_this.environment = environment;
|
|
12741
|
+
_this.typePolicies = typePolicies;
|
|
12742
|
+
_this._subscription = new rxjs.Subscription();
|
|
12743
|
+
_this.connectionParams = {};
|
|
12744
|
+
_this.onNetworkError = new rxjs.Subject();
|
|
12745
|
+
_this.customErrors = {};
|
|
12746
|
+
_this._debug = !environment.production;
|
|
12747
|
+
_this._defaultFetchPolicy = environment.apolloFetchPolicy;
|
|
12705
12748
|
// Listen network status
|
|
12706
|
-
|
|
12749
|
+
_this._networkStatusChanged$ = network.onNetworkStatusChanges
|
|
12707
12750
|
.pipe(operators.filter(isNotNil), operators.distinctUntilChanged());
|
|
12708
12751
|
// When getting network error: try to ping peer, and toggle to offline
|
|
12709
|
-
|
|
12752
|
+
_this.onNetworkError
|
|
12710
12753
|
.pipe(operators.throttleTime(300), operators.filter(function () { return _this.network.online; }), operators.mergeMap(function () { return _this.network.checkPeerAlive(); }), operators.filter(function (alive) { return !alive; }))
|
|
12711
12754
|
.subscribe(function () { return _this.network.setForceOffline(true, { showToast: true }); });
|
|
12755
|
+
return _this;
|
|
12712
12756
|
}
|
|
12713
|
-
Object.defineProperty(GraphqlService.prototype, "started", {
|
|
12714
|
-
get: function () {
|
|
12715
|
-
return this._started;
|
|
12716
|
-
},
|
|
12717
|
-
enumerable: false,
|
|
12718
|
-
configurable: true
|
|
12719
|
-
});
|
|
12720
12757
|
Object.defineProperty(GraphqlService.prototype, "client", {
|
|
12721
12758
|
get: function () {
|
|
12722
|
-
return this.
|
|
12759
|
+
return this._data;
|
|
12723
12760
|
},
|
|
12724
12761
|
enumerable: false,
|
|
12725
12762
|
configurable: true
|
|
@@ -12738,34 +12775,6 @@
|
|
|
12738
12775
|
enumerable: false,
|
|
12739
12776
|
configurable: true
|
|
12740
12777
|
});
|
|
12741
|
-
GraphqlService.prototype.ready = function () {
|
|
12742
|
-
if (this._started)
|
|
12743
|
-
return Promise.resolve();
|
|
12744
|
-
return this.start();
|
|
12745
|
-
};
|
|
12746
|
-
GraphqlService.prototype.start = function () {
|
|
12747
|
-
var _this = this;
|
|
12748
|
-
if (this._startPromise)
|
|
12749
|
-
return this._startPromise;
|
|
12750
|
-
if (this._started)
|
|
12751
|
-
return Promise.resolve();
|
|
12752
|
-
console.info('[graphql] Starting graphql...');
|
|
12753
|
-
// Waiting for network service
|
|
12754
|
-
this._startPromise = this.network.ready()
|
|
12755
|
-
.then(function () { return _this.initApollo(); })
|
|
12756
|
-
.then(function () {
|
|
12757
|
-
_this._started = true;
|
|
12758
|
-
_this._startPromise = undefined;
|
|
12759
|
-
// Emit event
|
|
12760
|
-
_this.onStart.next();
|
|
12761
|
-
console.info('[graphql] Starting graphql [OK]');
|
|
12762
|
-
})
|
|
12763
|
-
.catch(function (err) {
|
|
12764
|
-
console.error(err && err.message || err, err);
|
|
12765
|
-
_this._startPromise = undefined;
|
|
12766
|
-
});
|
|
12767
|
-
return this._startPromise;
|
|
12768
|
-
};
|
|
12769
12778
|
GraphqlService.prototype.setAuthToken = function (token) {
|
|
12770
12779
|
if (token) {
|
|
12771
12780
|
console.debug('[graphql] Apply token authentication to headers');
|
|
@@ -12798,15 +12807,18 @@
|
|
|
12798
12807
|
*/
|
|
12799
12808
|
GraphqlService.prototype.addResolver = function (resolvers) {
|
|
12800
12809
|
return __awaiter(this, void 0, void 0, function () {
|
|
12801
|
-
var client;
|
|
12802
|
-
var _this = this;
|
|
12803
12810
|
return __generator(this, function (_a) {
|
|
12804
|
-
|
|
12805
|
-
|
|
12811
|
+
switch (_a.label) {
|
|
12812
|
+
case 0:
|
|
12813
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
12814
|
+
return [4 /*yield*/, this.ready()];
|
|
12815
|
+
case 1:
|
|
12816
|
+
_a.sent();
|
|
12817
|
+
_a.label = 2;
|
|
12818
|
+
case 2:
|
|
12819
|
+
this.apollo.client.addResolvers(resolvers);
|
|
12820
|
+
return [2 /*return*/];
|
|
12806
12821
|
}
|
|
12807
|
-
client = this.apollo.getClient();
|
|
12808
|
-
client.addResolvers(resolvers);
|
|
12809
|
-
return [2 /*return*/];
|
|
12810
12822
|
});
|
|
12811
12823
|
});
|
|
12812
12824
|
};
|
|
@@ -12816,21 +12828,26 @@
|
|
|
12816
12828
|
return __generator(this, function (_a) {
|
|
12817
12829
|
switch (_a.label) {
|
|
12818
12830
|
case 0:
|
|
12819
|
-
|
|
12820
|
-
return [4 /*yield*/, this.
|
|
12821
|
-
case 1:
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined
|
|
12825
|
-
}).toPromise()];
|
|
12831
|
+
if (!!this.started) return [3 /*break*/, 2];
|
|
12832
|
+
return [4 /*yield*/, this.ready()];
|
|
12833
|
+
case 1:
|
|
12834
|
+
_a.sent();
|
|
12835
|
+
_a.label = 2;
|
|
12826
12836
|
case 2:
|
|
12827
|
-
|
|
12828
|
-
return [
|
|
12837
|
+
_a.trys.push([2, 4, , 5]);
|
|
12838
|
+
return [4 /*yield*/, this.client.query({
|
|
12839
|
+
query: opts.query,
|
|
12840
|
+
variables: opts.variables,
|
|
12841
|
+
fetchPolicy: opts.fetchPolicy || this._defaultFetchPolicy || undefined
|
|
12842
|
+
})];
|
|
12829
12843
|
case 3:
|
|
12844
|
+
res = _a.sent();
|
|
12845
|
+
return [3 /*break*/, 5];
|
|
12846
|
+
case 4:
|
|
12830
12847
|
err_1 = _a.sent();
|
|
12831
12848
|
res = this.toApolloError(err_1, opts.error);
|
|
12832
|
-
return [3 /*break*/,
|
|
12833
|
-
case
|
|
12849
|
+
return [3 /*break*/, 5];
|
|
12850
|
+
case 5:
|
|
12834
12851
|
if (res.errors) {
|
|
12835
12852
|
throw res.errors[0];
|
|
12836
12853
|
}
|
|
@@ -13188,12 +13205,14 @@
|
|
|
13188
13205
|
return __generator(this, function (_a) {
|
|
13189
13206
|
switch (_a.label) {
|
|
13190
13207
|
case 0:
|
|
13191
|
-
client = (client || this.
|
|
13208
|
+
client = (client || this.client);
|
|
13192
13209
|
if (!client) return [3 /*break*/, 2];
|
|
13193
|
-
now = this._debug && Date.now();
|
|
13194
13210
|
console.info('[graphql] Clearing Apollo client\'s cache... ');
|
|
13211
|
+
now = this._debug && Date.now();
|
|
13212
|
+
// Clearing the cache
|
|
13195
13213
|
return [4 /*yield*/, client.cache.reset()];
|
|
13196
13214
|
case 1:
|
|
13215
|
+
// Clearing the cache
|
|
13197
13216
|
_a.sent();
|
|
13198
13217
|
if (this._debug)
|
|
13199
13218
|
console.debug("[graphql] Apollo client's cache cleared, in " + (Date.now() - now) + "ms");
|
|
@@ -13207,13 +13226,16 @@
|
|
|
13207
13226
|
this.customErrors = Object.assign(Object.assign({}, this.customErrors), error);
|
|
13208
13227
|
};
|
|
13209
13228
|
/* -- protected methods -- */
|
|
13210
|
-
GraphqlService.prototype.
|
|
13229
|
+
GraphqlService.prototype.ngOnStart = function () {
|
|
13211
13230
|
return __awaiter(this, void 0, void 0, function () {
|
|
13212
13231
|
var mobile, enableTrackMutationQueries, peer, uri, wsUri, storage, client, wsLink, retryLink, authLink, httpLink, cache, mutationLinks, serializingLink, trackerLink, queueLink_1, err_2;
|
|
13213
13232
|
var _this = this;
|
|
13214
13233
|
return __generator(this, function (_a) {
|
|
13215
13234
|
switch (_a.label) {
|
|
13216
|
-
case 0:
|
|
13235
|
+
case 0: return [4 /*yield*/, this.network.ready()];
|
|
13236
|
+
case 1:
|
|
13237
|
+
_a.sent();
|
|
13238
|
+
console.info('[graphql] Starting graphql...');
|
|
13217
13239
|
mobile = this.platform.is('mobile') || this.platform.is('mobileweb');
|
|
13218
13240
|
enableTrackMutationQueries = !mobile;
|
|
13219
13241
|
peer = this.network.peer;
|
|
@@ -13232,7 +13254,7 @@
|
|
|
13232
13254
|
}, webSocketImpl: AppWebSocket, uri: wsUri });
|
|
13233
13255
|
storage = new apollo3CachePersist.IonicStorageWrapper(this.storage);
|
|
13234
13256
|
client = this.apollo.client;
|
|
13235
|
-
if (!!client) return [3 /*break*/,
|
|
13257
|
+
if (!!client) return [3 /*break*/, 4];
|
|
13236
13258
|
console.debug('[apollo] Creating GraphQL client...');
|
|
13237
13259
|
wsLink = new ws.WebSocketLink(this.wsParams);
|
|
13238
13260
|
retryLink = new retry.RetryLink();
|
|
@@ -13258,7 +13280,7 @@
|
|
|
13258
13280
|
cache = new core.InMemoryCache({
|
|
13259
13281
|
typePolicies: this.typePolicies
|
|
13260
13282
|
});
|
|
13261
|
-
if (!this.environment.persistCache) return [3 /*break*/,
|
|
13283
|
+
if (!this.environment.persistCache) return [3 /*break*/, 3];
|
|
13262
13284
|
console.debug('[graphql] Starting persistence cache...');
|
|
13263
13285
|
return [4 /*yield*/, apollo3CachePersist.persistCache({
|
|
13264
13286
|
cache: cache,
|
|
@@ -13267,10 +13289,10 @@
|
|
|
13267
13289
|
debounce: 1000,
|
|
13268
13290
|
debug: true
|
|
13269
13291
|
})];
|
|
13270
|
-
case 1:
|
|
13271
|
-
_a.sent();
|
|
13272
|
-
_a.label = 2;
|
|
13273
13292
|
case 2:
|
|
13293
|
+
_a.sent();
|
|
13294
|
+
_a.label = 3;
|
|
13295
|
+
case 3:
|
|
13274
13296
|
mutationLinks = void 0;
|
|
13275
13297
|
// Add queue to store tracked queries, when offline
|
|
13276
13298
|
if (enableTrackMutationQueries) {
|
|
@@ -13284,9 +13306,8 @@
|
|
|
13284
13306
|
queueLink_1 = new QueueLink__default["default"]();
|
|
13285
13307
|
this._subscription.add(this._networkStatusChanged$
|
|
13286
13308
|
.subscribe(function (type) {
|
|
13287
|
-
var offline = type === 'none';
|
|
13288
13309
|
// Network is offline: start buffering into queue
|
|
13289
|
-
if (
|
|
13310
|
+
if (type === 'none') {
|
|
13290
13311
|
console.info('[graphql] offline mode: enable mutations buffer');
|
|
13291
13312
|
queueLink_1.close();
|
|
13292
13313
|
}
|
|
@@ -13331,30 +13352,36 @@
|
|
|
13331
13352
|
connectToDevTools: !this.environment.production
|
|
13332
13353
|
});
|
|
13333
13354
|
this.apollo.client = client;
|
|
13334
|
-
_a.label = 3;
|
|
13335
|
-
case 3:
|
|
13336
|
-
if (!(enableTrackMutationQueries && this.environment.persistCache)) return [3 /*break*/, 7];
|
|
13337
13355
|
_a.label = 4;
|
|
13338
13356
|
case 4:
|
|
13339
|
-
|
|
13357
|
+
if (!(enableTrackMutationQueries && this.environment.persistCache)) return [3 /*break*/, 8];
|
|
13358
|
+
_a.label = 5;
|
|
13359
|
+
case 5:
|
|
13360
|
+
_a.trys.push([5, 7, , 8]);
|
|
13340
13361
|
return [4 /*yield*/, restoreTrackedQueries({
|
|
13341
13362
|
apolloClient: client,
|
|
13342
13363
|
storage: storage,
|
|
13343
13364
|
debug: true
|
|
13344
13365
|
})];
|
|
13345
|
-
case 5:
|
|
13346
|
-
_a.sent();
|
|
13347
|
-
return [3 /*break*/, 7];
|
|
13348
13366
|
case 6:
|
|
13367
|
+
_a.sent();
|
|
13368
|
+
return [3 /*break*/, 8];
|
|
13369
|
+
case 7:
|
|
13349
13370
|
err_2 = _a.sent();
|
|
13350
13371
|
console.error('[graphql] Failed to restore tracked queries from storage: ' + (err_2 && err_2.message || err_2), err_2);
|
|
13351
|
-
return [3 /*break*/,
|
|
13352
|
-
case
|
|
13372
|
+
return [3 /*break*/, 8];
|
|
13373
|
+
case 8:
|
|
13374
|
+
// Listen for network restart
|
|
13375
|
+
this._subscription.add(this.network.on('start', function () { return _this.restart(); }));
|
|
13376
|
+
// Listen for clear cache request, from network
|
|
13377
|
+
this._subscription.add(this.network.on('resetCache', function () { return _this.clearCache(); }));
|
|
13378
|
+
console.info('[graphql] Starting graphql [OK]');
|
|
13379
|
+
return [2 /*return*/, client];
|
|
13353
13380
|
}
|
|
13354
13381
|
});
|
|
13355
13382
|
});
|
|
13356
13383
|
};
|
|
13357
|
-
GraphqlService.prototype.
|
|
13384
|
+
GraphqlService.prototype.ngOnStop = function () {
|
|
13358
13385
|
return __awaiter(this, void 0, void 0, function () {
|
|
13359
13386
|
return __generator(this, function (_a) {
|
|
13360
13387
|
switch (_a.label) {
|
|
@@ -13365,24 +13392,11 @@
|
|
|
13365
13392
|
return [4 /*yield*/, this.resetClient()];
|
|
13366
13393
|
case 1:
|
|
13367
13394
|
_a.sent();
|
|
13368
|
-
this._started = false;
|
|
13369
|
-
this._startPromise = undefined;
|
|
13370
13395
|
return [2 /*return*/];
|
|
13371
13396
|
}
|
|
13372
13397
|
});
|
|
13373
13398
|
});
|
|
13374
13399
|
};
|
|
13375
|
-
GraphqlService.prototype.restart = function () {
|
|
13376
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
13377
|
-
var _this = this;
|
|
13378
|
-
return __generator(this, function (_a) {
|
|
13379
|
-
if (this.started) {
|
|
13380
|
-
return [2 /*return*/, this.stop().then(function () { return _this.start(); })];
|
|
13381
|
-
}
|
|
13382
|
-
return [2 /*return*/, this.start()];
|
|
13383
|
-
});
|
|
13384
|
-
});
|
|
13385
|
-
};
|
|
13386
13400
|
GraphqlService.prototype.resetClient = function (client) {
|
|
13387
13401
|
return __awaiter(this, void 0, void 0, function () {
|
|
13388
13402
|
return __generator(this, function (_a) {
|
|
@@ -13484,24 +13498,8 @@
|
|
|
13484
13498
|
}
|
|
13485
13499
|
return undefined;
|
|
13486
13500
|
};
|
|
13487
|
-
GraphqlService.prototype.getApollo = function () {
|
|
13488
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
13489
|
-
return __generator(this, function (_a) {
|
|
13490
|
-
switch (_a.label) {
|
|
13491
|
-
case 0:
|
|
13492
|
-
if (!!this._started) return [3 /*break*/, 2];
|
|
13493
|
-
console.debug('[graphql] Waiting apollo client... ');
|
|
13494
|
-
return [4 /*yield*/, this.onStart.toPromise()];
|
|
13495
|
-
case 1:
|
|
13496
|
-
_a.sent();
|
|
13497
|
-
_a.label = 2;
|
|
13498
|
-
case 2: return [2 /*return*/, this.apollo];
|
|
13499
|
-
}
|
|
13500
|
-
});
|
|
13501
|
-
});
|
|
13502
|
-
};
|
|
13503
13501
|
return GraphqlService;
|
|
13504
|
-
}());
|
|
13502
|
+
}(StartableService));
|
|
13505
13503
|
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" });
|
|
13506
13504
|
GraphqlService.decorators = [
|
|
13507
13505
|
{ type: i0.Injectable, args: [{
|
|
@@ -13784,7 +13782,12 @@
|
|
|
13784
13782
|
_this.storage = storage;
|
|
13785
13783
|
_this.file = file;
|
|
13786
13784
|
_this.environment = environment;
|
|
13787
|
-
_this.
|
|
13785
|
+
_this.onLogin = new rxjs.Subject();
|
|
13786
|
+
_this.onLogout = new rxjs.Subject();
|
|
13787
|
+
_this.onChange = new rxjs.Subject();
|
|
13788
|
+
_this.onAuthTokenChange = new rxjs.Subject();
|
|
13789
|
+
_this.onAuthBasicChange = new rxjs.Subject();
|
|
13790
|
+
_this._data = {
|
|
13788
13791
|
loaded: false,
|
|
13789
13792
|
keypair: null,
|
|
13790
13793
|
authToken: null,
|
|
@@ -13798,11 +13801,6 @@
|
|
|
13798
13801
|
_this._started = false;
|
|
13799
13802
|
_this._$additionalFields = new rxjs.BehaviorSubject([]);
|
|
13800
13803
|
_this._tokenType$ = new rxjs.BehaviorSubject(undefined);
|
|
13801
|
-
_this.onLogin = new rxjs.Subject();
|
|
13802
|
-
_this.onLogout = new rxjs.Subject();
|
|
13803
|
-
_this.onChange = new rxjs.Subject();
|
|
13804
|
-
_this.onAuthTokenChange = new rxjs.Subject();
|
|
13805
|
-
_this.onAuthBasicChange = new rxjs.Subject();
|
|
13806
13804
|
_this._debug = !environment.production;
|
|
13807
13805
|
if (_this._debug)
|
|
13808
13806
|
console.debug('[account-service] Creating service');
|
|
@@ -13810,7 +13808,7 @@
|
|
|
13810
13808
|
// Send auth token to the graphql layer, when changed
|
|
13811
13809
|
_this.onAuthTokenChange.subscribe(function (token) { return _this.graphql.setAuthToken(token); });
|
|
13812
13810
|
_this.onAuthBasicChange.subscribe(function (basic) { return _this.graphql.setAuthBasic(basic); });
|
|
13813
|
-
// Listen
|
|
13811
|
+
// Listen graphql start (or restart)
|
|
13814
13812
|
_this.graphql.onStart.subscribe(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
13815
13813
|
return __generator(this, function (_b) {
|
|
13816
13814
|
if (!this._started) {
|
|
@@ -13844,27 +13842,27 @@
|
|
|
13844
13842
|
}
|
|
13845
13843
|
Object.defineProperty(AccountService.prototype, "account", {
|
|
13846
13844
|
get: function () {
|
|
13847
|
-
return this.
|
|
13845
|
+
return this._data.loaded ? this._data.account : undefined;
|
|
13848
13846
|
},
|
|
13849
13847
|
enumerable: false,
|
|
13850
13848
|
configurable: true
|
|
13851
13849
|
});
|
|
13852
13850
|
Object.defineProperty(AccountService.prototype, "person", {
|
|
13853
13851
|
get: function () {
|
|
13854
|
-
if (this.
|
|
13855
|
-
this.
|
|
13852
|
+
if (this._data.loaded && !this._data.person) {
|
|
13853
|
+
this._data.person = this._data.loaded ? this._data.account.asPerson() : undefined;
|
|
13856
13854
|
}
|
|
13857
|
-
return this.
|
|
13855
|
+
return this._data.person;
|
|
13858
13856
|
},
|
|
13859
13857
|
enumerable: false,
|
|
13860
13858
|
configurable: true
|
|
13861
13859
|
});
|
|
13862
13860
|
Object.defineProperty(AccountService.prototype, "department", {
|
|
13863
13861
|
get: function () {
|
|
13864
|
-
if (this.
|
|
13865
|
-
this.
|
|
13862
|
+
if (this._data.loaded && !this._data.department) {
|
|
13863
|
+
this._data.department = this._data.loaded ? this._data.account.asPerson().department : undefined;
|
|
13866
13864
|
}
|
|
13867
|
-
return this.
|
|
13865
|
+
return this._data.department;
|
|
13868
13866
|
},
|
|
13869
13867
|
enumerable: false,
|
|
13870
13868
|
configurable: true
|
|
@@ -13878,32 +13876,21 @@
|
|
|
13878
13876
|
console.info('[account] Using authentication token type: ' + value);
|
|
13879
13877
|
this._tokenType$.next(value);
|
|
13880
13878
|
// Reset values
|
|
13881
|
-
this.
|
|
13879
|
+
this._data.authToken = undefined;
|
|
13882
13880
|
this.onAuthTokenChange.next(undefined);
|
|
13883
|
-
this.
|
|
13881
|
+
this._data.authBasic = undefined;
|
|
13884
13882
|
this.onAuthBasicChange.next(undefined);
|
|
13885
13883
|
}
|
|
13886
13884
|
},
|
|
13887
13885
|
enumerable: false,
|
|
13888
13886
|
configurable: true
|
|
13889
13887
|
});
|
|
13890
|
-
AccountService.prototype.resetData = function () {
|
|
13891
|
-
this.data.loaded = false;
|
|
13892
|
-
this.data.keypair = null;
|
|
13893
|
-
this.data.authToken = null;
|
|
13894
|
-
this.data.authBasic = null;
|
|
13895
|
-
this.data.pubkey = null;
|
|
13896
|
-
this.data.mainProfile = null;
|
|
13897
|
-
this.data.account = new exports.Account();
|
|
13898
|
-
this.data.person = null;
|
|
13899
|
-
this.data.department = null;
|
|
13900
|
-
};
|
|
13901
13888
|
AccountService.prototype.start = function () {
|
|
13902
13889
|
var _this = this;
|
|
13903
13890
|
if (this._startPromise)
|
|
13904
13891
|
return this._startPromise;
|
|
13905
13892
|
if (this._started)
|
|
13906
|
-
return Promise.resolve();
|
|
13893
|
+
return Promise.resolve(this.account);
|
|
13907
13894
|
// Restoring local settings
|
|
13908
13895
|
this._startPromise = Promise.all([
|
|
13909
13896
|
this.settings.ready(),
|
|
@@ -13914,6 +13901,7 @@
|
|
|
13914
13901
|
.then(function () {
|
|
13915
13902
|
_this._started = true;
|
|
13916
13903
|
_this._startPromise = undefined;
|
|
13904
|
+
return _this.account;
|
|
13917
13905
|
});
|
|
13918
13906
|
return this._startPromise;
|
|
13919
13907
|
};
|
|
@@ -13931,8 +13919,8 @@
|
|
|
13931
13919
|
if (this._started || this._startPromise) {
|
|
13932
13920
|
this._started = false;
|
|
13933
13921
|
this._startPromise = undefined;
|
|
13934
|
-
hadAuthToken = this.
|
|
13935
|
-
hadAuthBasic = this.
|
|
13922
|
+
hadAuthToken = this._data.authToken && true;
|
|
13923
|
+
hadAuthBasic = this._data.authBasic && true;
|
|
13936
13924
|
hadAuth = hadAuthToken || hadAuthBasic;
|
|
13937
13925
|
this.resetData();
|
|
13938
13926
|
if (hadAuth) {
|
|
@@ -13962,35 +13950,35 @@
|
|
|
13962
13950
|
};
|
|
13963
13951
|
AccountService.prototype.ready = function () {
|
|
13964
13952
|
if (this._started)
|
|
13965
|
-
return Promise.resolve();
|
|
13953
|
+
return Promise.resolve(this.account);
|
|
13966
13954
|
return this.start();
|
|
13967
13955
|
};
|
|
13968
13956
|
AccountService.prototype.isLogin = function () {
|
|
13969
|
-
return !!(this.
|
|
13957
|
+
return !!(this._data.pubkey && this._data.loaded);
|
|
13970
13958
|
};
|
|
13971
13959
|
AccountService.prototype.isAuth = function () {
|
|
13972
|
-
return !!(this.
|
|
13960
|
+
return !!(this._data.pubkey && this._data.keypair && this._data.keypair.secretKey);
|
|
13973
13961
|
};
|
|
13974
13962
|
AccountService.prototype.hasMinProfile = function (userProfile) {
|
|
13975
13963
|
// should be login, and status ENABLE or TEMPORARY
|
|
13976
|
-
if (!this.
|
|
13977
|
-
(this.
|
|
13964
|
+
if (!this._data.account || !this._data.account.pubkey ||
|
|
13965
|
+
(this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY)) {
|
|
13978
13966
|
return false;
|
|
13979
13967
|
}
|
|
13980
|
-
return PersonUtils.hasUpperOrEqualsProfile(this.
|
|
13968
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, userProfile);
|
|
13981
13969
|
};
|
|
13982
13970
|
AccountService.prototype.hasExactProfile = function (label) {
|
|
13983
13971
|
// should be login, and status ENABLE or TEMPORARY
|
|
13984
|
-
if (!this.
|
|
13985
|
-
(this.
|
|
13972
|
+
if (!this._data.account || !this._data.account.pubkey ||
|
|
13973
|
+
(this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY))
|
|
13986
13974
|
return false;
|
|
13987
|
-
return this.
|
|
13975
|
+
return this._data.account.profiles.some(function (profile) { return profile === label; });
|
|
13988
13976
|
};
|
|
13989
13977
|
AccountService.prototype.hasProfileAndIsEnable = function (userProfile) {
|
|
13990
13978
|
// should be login, and status ENABLE
|
|
13991
|
-
if (!this.
|
|
13979
|
+
if (!this._data.account || !this._data.account.pubkey || this._data.account.statusId !== StatusIds.ENABLE)
|
|
13992
13980
|
return false;
|
|
13993
|
-
return PersonUtils.hasUpperOrEqualsProfile(this.
|
|
13981
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, userProfile);
|
|
13994
13982
|
};
|
|
13995
13983
|
AccountService.prototype.isAdmin = function () {
|
|
13996
13984
|
return this.hasProfileAndIsEnable('ADMIN');
|
|
@@ -14010,11 +13998,11 @@
|
|
|
14010
13998
|
};
|
|
14011
13999
|
AccountService.prototype.isOnlyGuest = function () {
|
|
14012
14000
|
// Should be login, and status ENABLE or TEMPORARY
|
|
14013
|
-
if (!this.
|
|
14014
|
-
(this.
|
|
14001
|
+
if (!this._data.account || !this._data.account.pubkey ||
|
|
14002
|
+
(this._data.account.statusId !== StatusIds.ENABLE && this._data.account.statusId !== StatusIds.TEMPORARY))
|
|
14015
14003
|
return false;
|
|
14016
14004
|
// Profile less then user
|
|
14017
|
-
return !PersonUtils.hasUpperOrEqualsProfile(this.
|
|
14005
|
+
return !PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, 'USER');
|
|
14018
14006
|
};
|
|
14019
14007
|
AccountService.prototype.canUserWriteDataForDepartment = function (recorderDepartment) {
|
|
14020
14008
|
if (ReferentialUtils.isEmpty(recorderDepartment)) {
|
|
@@ -14023,17 +14011,17 @@
|
|
|
14023
14011
|
return this.isAdmin();
|
|
14024
14012
|
}
|
|
14025
14013
|
// Should be login, and status ENABLE
|
|
14026
|
-
if (!this.
|
|
14014
|
+
if (!this._data.account || !this._data.account.pubkey || this._data.account.statusId !== StatusIds.ENABLE)
|
|
14027
14015
|
return false;
|
|
14028
|
-
if (!this.
|
|
14016
|
+
if (!this._data.account.department || !this._data.account.department.id) {
|
|
14029
14017
|
console.warn('User account has no department ! Unable to check write right against recorderDepartment');
|
|
14030
14018
|
return false;
|
|
14031
14019
|
}
|
|
14032
14020
|
// Same recorder department: OK, user can write
|
|
14033
|
-
if (this.
|
|
14021
|
+
if (this._data.account.department.id === recorderDepartment.id)
|
|
14034
14022
|
return true;
|
|
14035
14023
|
// Else, check if supervisor (or more)
|
|
14036
|
-
return PersonUtils.hasUpperOrEqualsProfile(this.
|
|
14024
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.account.profiles, 'SUPERVISOR');
|
|
14037
14025
|
};
|
|
14038
14026
|
AccountService.prototype.register = function (data) {
|
|
14039
14027
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -14048,7 +14036,7 @@
|
|
|
14048
14036
|
throw new Error('Missing required username or password');
|
|
14049
14037
|
if (this._debug)
|
|
14050
14038
|
console.debug('[account] Register new user account...', data.account);
|
|
14051
|
-
this.
|
|
14039
|
+
this._data.loaded = false;
|
|
14052
14040
|
now = Date.now();
|
|
14053
14041
|
_b.label = 1;
|
|
14054
14042
|
case 1:
|
|
@@ -14062,29 +14050,29 @@
|
|
|
14062
14050
|
data.account.settings.locale = this.settings.locale;
|
|
14063
14051
|
data.account.settings.latLongFormat = this.settings.latLongFormat;
|
|
14064
14052
|
data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;
|
|
14065
|
-
this.
|
|
14053
|
+
this._data.keypair = keypair;
|
|
14066
14054
|
return [4 /*yield*/, this.saveRemotely(data.account, keypair)];
|
|
14067
14055
|
case 3:
|
|
14068
14056
|
account = _b.sent();
|
|
14069
14057
|
// Default values
|
|
14070
14058
|
account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
|
|
14071
|
-
this.
|
|
14072
|
-
this.
|
|
14073
|
-
this.
|
|
14059
|
+
this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
14060
|
+
this._data.account = account;
|
|
14061
|
+
this._data.pubkey = account.pubkey;
|
|
14074
14062
|
// Try to auth on pod
|
|
14075
14063
|
return [4 /*yield*/, this.authenticate(data)];
|
|
14076
14064
|
case 4:
|
|
14077
14065
|
// Try to auth on pod
|
|
14078
14066
|
_b.sent();
|
|
14079
|
-
this.
|
|
14067
|
+
this._data.loaded = true;
|
|
14080
14068
|
return [4 /*yield*/, this.saveLocally()];
|
|
14081
14069
|
case 5:
|
|
14082
14070
|
_b.sent();
|
|
14083
14071
|
console.debug("[account] Account successfully registered in " + (Date.now() - now) + "ms");
|
|
14084
14072
|
// Emit events
|
|
14085
|
-
this.onLogin.next(this.
|
|
14086
|
-
this.onChange.next(this.
|
|
14087
|
-
return [2 /*return*/, this.
|
|
14073
|
+
this.onLogin.next(this._data.account);
|
|
14074
|
+
this.onChange.next(this._data.account);
|
|
14075
|
+
return [2 /*return*/, this._data.account];
|
|
14088
14076
|
case 6:
|
|
14089
14077
|
error_1 = _b.sent();
|
|
14090
14078
|
console.error(error_1 && error_1.message || error_1);
|
|
@@ -14106,22 +14094,22 @@
|
|
|
14106
14094
|
// Basic auth
|
|
14107
14095
|
if (tokenType === 'basic' || tokenType === 'basic-and-token') {
|
|
14108
14096
|
// Generate the authBasic, if used
|
|
14109
|
-
if (!this.
|
|
14097
|
+
if (!this._data.authBasic) {
|
|
14110
14098
|
// Skip if token already provided
|
|
14111
|
-
if (!(this.
|
|
14099
|
+
if (!(this._data.authToken && tokenType === 'basic-and-token')) {
|
|
14112
14100
|
if (!data || !data.username || !data.password)
|
|
14113
14101
|
throw new Error('Missing username and password');
|
|
14114
|
-
this.
|
|
14102
|
+
this._data.authBasic = this.cryptoService.encodeBase64(data.username + ":" + data.password);
|
|
14115
14103
|
}
|
|
14116
14104
|
}
|
|
14117
|
-
this.onAuthBasicChange.next(this.
|
|
14105
|
+
this.onAuthBasicChange.next(this._data.authBasic);
|
|
14118
14106
|
}
|
|
14119
14107
|
if (!(tokenType === 'token' || tokenType === 'basic-and-token')) return [3 /*break*/, 5];
|
|
14120
14108
|
_c.label = 2;
|
|
14121
14109
|
case 2:
|
|
14122
14110
|
_c.trys.push([2, 4, , 5]);
|
|
14123
|
-
_b = this.
|
|
14124
|
-
return [4 /*yield*/, this.authenticateAndGetToken(this.
|
|
14111
|
+
_b = this._data;
|
|
14112
|
+
return [4 /*yield*/, this.authenticateAndGetToken(this._data.authToken)];
|
|
14125
14113
|
case 3:
|
|
14126
14114
|
_b.authToken = _c.sent();
|
|
14127
14115
|
return [3 /*break*/, 5];
|
|
@@ -14134,7 +14122,7 @@
|
|
|
14134
14122
|
case 5:
|
|
14135
14123
|
// Forget authBasic, to switch to authToken
|
|
14136
14124
|
if (tokenType === 'basic-and-token') {
|
|
14137
|
-
this.
|
|
14125
|
+
this._data.authBasic = undefined;
|
|
14138
14126
|
this.onAuthBasicChange.next(undefined);
|
|
14139
14127
|
}
|
|
14140
14128
|
return [2 /*return*/];
|
|
@@ -14165,18 +14153,18 @@
|
|
|
14165
14153
|
throw { code: ErrorCodes$2.UNKNOWN_ERROR, message: 'ERROR.SCRYPT_ERROR' };
|
|
14166
14154
|
case 4:
|
|
14167
14155
|
// Store pubkey+keypair
|
|
14168
|
-
this.
|
|
14169
|
-
this.
|
|
14156
|
+
this._data.pubkey = Base58.encode(keypair.publicKey);
|
|
14157
|
+
this._data.keypair = keypair;
|
|
14170
14158
|
return [4 /*yield*/, this.storage.get(TOKEN_STORAGE_KEY)];
|
|
14171
14159
|
case 5:
|
|
14172
14160
|
previousToken = _b.sent();
|
|
14173
|
-
previousToken = previousToken && previousToken.startsWith(this.
|
|
14161
|
+
previousToken = previousToken && previousToken.startsWith(this._data.pubkey) && previousToken || null;
|
|
14174
14162
|
offline = this.settings.hasOfflineFeature() && (this.network.offline || data.offline === true);
|
|
14175
14163
|
if (!offline) return [3 /*break*/, 6];
|
|
14176
|
-
this.
|
|
14164
|
+
this._data.authToken = previousToken;
|
|
14177
14165
|
// Make sure network if set as offline
|
|
14178
14166
|
this.network.setForceOffline(true, { showToast: false });
|
|
14179
|
-
console.info("[account] Login [OK] {pubkey: " + this.
|
|
14167
|
+
console.info("[account] Login [OK] {pubkey: " + this._data.pubkey.substr(0, 8) + "}, {offline: true}");
|
|
14180
14168
|
return [3 /*break*/, 9];
|
|
14181
14169
|
case 6:
|
|
14182
14170
|
_b.trys.push([6, 8, , 9]);
|
|
@@ -14236,9 +14224,9 @@
|
|
|
14236
14224
|
throw error_5;
|
|
14237
14225
|
case 21:
|
|
14238
14226
|
// Emit event to observers
|
|
14239
|
-
this.onLogin.next(this.
|
|
14240
|
-
this.onChange.next(this.
|
|
14241
|
-
return [2 /*return*/, this.
|
|
14227
|
+
this.onLogin.next(this._data.account);
|
|
14228
|
+
this.onChange.next(this._data.account);
|
|
14229
|
+
return [2 /*return*/, this._data.account];
|
|
14242
14230
|
}
|
|
14243
14231
|
});
|
|
14244
14232
|
});
|
|
@@ -14248,7 +14236,7 @@
|
|
|
14248
14236
|
return __generator(this, function (_b) {
|
|
14249
14237
|
switch (_b.label) {
|
|
14250
14238
|
case 0:
|
|
14251
|
-
if (!this.
|
|
14239
|
+
if (!this._data.pubkey)
|
|
14252
14240
|
throw new Error('User not logged');
|
|
14253
14241
|
if (this.network.offline)
|
|
14254
14242
|
throw new Error('Cannot check account in offline mode');
|
|
@@ -14260,9 +14248,9 @@
|
|
|
14260
14248
|
_b.sent();
|
|
14261
14249
|
console.debug('[account] Successfully reload account');
|
|
14262
14250
|
// Emit login event to subscribers
|
|
14263
|
-
this.onLogin.next(this.
|
|
14264
|
-
this.onChange.next(this.
|
|
14265
|
-
return [2 /*return*/, this.
|
|
14251
|
+
this.onLogin.next(this._data.account);
|
|
14252
|
+
this.onChange.next(this._data.account);
|
|
14253
|
+
return [2 /*return*/, this._data.account];
|
|
14266
14254
|
}
|
|
14267
14255
|
});
|
|
14268
14256
|
});
|
|
@@ -14277,27 +14265,27 @@
|
|
|
14277
14265
|
return __generator(this, function (_b) {
|
|
14278
14266
|
switch (_b.label) {
|
|
14279
14267
|
case 0:
|
|
14280
|
-
if (!this.
|
|
14268
|
+
if (!this._data.pubkey)
|
|
14281
14269
|
return [2 /*return*/, Promise.reject('User not logged')];
|
|
14282
|
-
if (this.
|
|
14270
|
+
if (this._data.pubkey !== account.pubkey)
|
|
14283
14271
|
return [2 /*return*/, Promise.reject('Not user account')];
|
|
14284
|
-
return [4 /*yield*/, this.saveRemotely(account, this.
|
|
14272
|
+
return [4 /*yield*/, this.saveRemotely(account, this._data.keypair)];
|
|
14285
14273
|
case 1:
|
|
14286
14274
|
account = _b.sent();
|
|
14287
14275
|
// Set defaults
|
|
14288
14276
|
account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
|
|
14289
|
-
this.
|
|
14290
|
-
this.
|
|
14291
|
-
this.
|
|
14277
|
+
this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
14278
|
+
this._data.account = account;
|
|
14279
|
+
this._data.loaded = true;
|
|
14292
14280
|
// Save locally (in storage)
|
|
14293
14281
|
return [4 /*yield*/, this.saveLocally()];
|
|
14294
14282
|
case 2:
|
|
14295
14283
|
// Save locally (in storage)
|
|
14296
14284
|
_b.sent();
|
|
14297
14285
|
// Send event
|
|
14298
|
-
this.onLogin.next(this.
|
|
14299
|
-
this.onChange.next(this.
|
|
14300
|
-
return [2 /*return*/, this.
|
|
14286
|
+
this.onLogin.next(this._data.account);
|
|
14287
|
+
this.onChange.next(this._data.account);
|
|
14288
|
+
return [2 /*return*/, this._data.account];
|
|
14301
14289
|
}
|
|
14302
14290
|
});
|
|
14303
14291
|
});
|
|
@@ -14308,9 +14296,9 @@
|
|
|
14308
14296
|
return __generator(this, function (_b) {
|
|
14309
14297
|
switch (_b.label) {
|
|
14310
14298
|
case 0:
|
|
14311
|
-
hadAuthToken = this.
|
|
14312
|
-
hadAuthBasic = this.
|
|
14313
|
-
pubkey = this.
|
|
14299
|
+
hadAuthToken = this._data.authToken && true;
|
|
14300
|
+
hadAuthBasic = this._data.authBasic && true;
|
|
14301
|
+
pubkey = this._data && this._data.pubkey;
|
|
14314
14302
|
this.resetData();
|
|
14315
14303
|
if (!!this.settings.hasOfflineFeature()) return [3 /*break*/, 2];
|
|
14316
14304
|
// Remove all data from the local storage
|
|
@@ -14382,9 +14370,9 @@
|
|
|
14382
14370
|
case 1:
|
|
14383
14371
|
json = _b.sent();
|
|
14384
14372
|
json = json && (typeof json === 'string') && JSON.parse(json) || json;
|
|
14385
|
-
json = json && this.
|
|
14386
|
-
if (!(!json && this.
|
|
14387
|
-
return [4 /*yield*/, this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this.
|
|
14373
|
+
json = json && this._data.pubkey && (json.pubkey === this._data.pubkey) && json || null;
|
|
14374
|
+
if (!(!json && this._data.pubkey)) return [3 /*break*/, 3];
|
|
14375
|
+
return [4 /*yield*/, this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this._data.pubkey)];
|
|
14388
14376
|
case 2:
|
|
14389
14377
|
json = _b.sent();
|
|
14390
14378
|
json = json && (typeof json === 'string') && JSON.parse(json) || json;
|
|
@@ -14515,7 +14503,8 @@
|
|
|
14515
14503
|
});
|
|
14516
14504
|
};
|
|
14517
14505
|
AccountService.prototype.listenChanges = function () {
|
|
14518
|
-
|
|
14506
|
+
var _this = this;
|
|
14507
|
+
if (!this._data.pubkey)
|
|
14519
14508
|
return rxjs.Subscription.EMPTY;
|
|
14520
14509
|
var self = this;
|
|
14521
14510
|
console.debug('[account] [WS] Listening account changes');
|
|
@@ -14531,15 +14520,14 @@
|
|
|
14531
14520
|
}).subscribe({
|
|
14532
14521
|
next: function (_b) {
|
|
14533
14522
|
var data = _b.data;
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
var existingUpdateDate;
|
|
14523
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
14524
|
+
var _a, existingUpdateDate;
|
|
14537
14525
|
return __generator(this, function (_b) {
|
|
14538
14526
|
switch (_b.label) {
|
|
14539
14527
|
case 0:
|
|
14540
14528
|
if (!data)
|
|
14541
14529
|
return [2 /*return*/];
|
|
14542
|
-
existingUpdateDate = toDateISOString((_a = self.
|
|
14530
|
+
existingUpdateDate = toDateISOString((_a = self._data.account) === null || _a === void 0 ? void 0 : _a.updateDate);
|
|
14543
14531
|
if (!(existingUpdateDate !== data.updateDate)) return [3 /*break*/, 2];
|
|
14544
14532
|
console.debug("[account] [WS] Detected update on {" + data.updateDate + "}");
|
|
14545
14533
|
return [4 /*yield*/, self.refresh()];
|
|
@@ -14551,32 +14539,30 @@
|
|
|
14551
14539
|
});
|
|
14552
14540
|
});
|
|
14553
14541
|
},
|
|
14554
|
-
error: function (err) {
|
|
14555
|
-
return
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
}
|
|
14577
|
-
});
|
|
14542
|
+
error: function (err) { return __awaiter(_this, void 0, void 0, function () {
|
|
14543
|
+
return __generator(this, function (_b) {
|
|
14544
|
+
switch (_b.label) {
|
|
14545
|
+
case 0:
|
|
14546
|
+
if (!(err && +err.code === ServerErrorCodes.NOT_FOUND)) return [3 /*break*/, 2];
|
|
14547
|
+
console.info('[account] Account not exists anymore: force user to logout...', err);
|
|
14548
|
+
return [4 /*yield*/, self.logout()];
|
|
14549
|
+
case 1:
|
|
14550
|
+
_b.sent();
|
|
14551
|
+
return [3 /*break*/, 5];
|
|
14552
|
+
case 2:
|
|
14553
|
+
if (!(err && +err.code === ServerErrorCodes.UNAUTHORIZED)) return [3 /*break*/, 4];
|
|
14554
|
+
console.info('[account] Account not authorized: force user to logout...', err);
|
|
14555
|
+
return [4 /*yield*/, self.logout()];
|
|
14556
|
+
case 3:
|
|
14557
|
+
_b.sent();
|
|
14558
|
+
return [3 /*break*/, 5];
|
|
14559
|
+
case 4:
|
|
14560
|
+
console.warn('[account] [WS] Received error:', err);
|
|
14561
|
+
_b.label = 5;
|
|
14562
|
+
case 5: return [2 /*return*/];
|
|
14563
|
+
}
|
|
14578
14564
|
});
|
|
14579
|
-
},
|
|
14565
|
+
}); },
|
|
14580
14566
|
complete: function () {
|
|
14581
14567
|
console.debug('[account] [WS] Completed');
|
|
14582
14568
|
}
|
|
@@ -14633,15 +14619,26 @@
|
|
|
14633
14619
|
this._$additionalFields.next(values.concat(field));
|
|
14634
14620
|
};
|
|
14635
14621
|
/* -- protected method -- */
|
|
14622
|
+
AccountService.prototype.resetData = function () {
|
|
14623
|
+
this._data.loaded = false;
|
|
14624
|
+
this._data.keypair = null;
|
|
14625
|
+
this._data.authToken = null;
|
|
14626
|
+
this._data.authBasic = null;
|
|
14627
|
+
this._data.pubkey = null;
|
|
14628
|
+
this._data.mainProfile = null;
|
|
14629
|
+
this._data.account = new exports.Account();
|
|
14630
|
+
this._data.person = null;
|
|
14631
|
+
this._data.department = null;
|
|
14632
|
+
};
|
|
14636
14633
|
AccountService.prototype.loadData = function (opts) {
|
|
14637
14634
|
return __awaiter(this, void 0, void 0, function () {
|
|
14638
14635
|
var account, error_6;
|
|
14639
14636
|
return __generator(this, function (_b) {
|
|
14640
14637
|
switch (_b.label) {
|
|
14641
14638
|
case 0:
|
|
14642
|
-
if (!this.
|
|
14639
|
+
if (!this._data.pubkey)
|
|
14643
14640
|
throw new Error('User not logged');
|
|
14644
|
-
this.
|
|
14641
|
+
this._data.loaded = false;
|
|
14645
14642
|
_b.label = 1;
|
|
14646
14643
|
case 1:
|
|
14647
14644
|
_b.trys.push([1, 3, , 4]);
|
|
@@ -14654,16 +14651,16 @@
|
|
|
14654
14651
|
account.settings.locale = account.settings.locale || this.settings.locale;
|
|
14655
14652
|
account.settings.latLongFormat = account.settings.latLongFormat || this.settings.latLongFormat || 'DDMM';
|
|
14656
14653
|
// Read main profile
|
|
14657
|
-
this.
|
|
14654
|
+
this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
14658
14655
|
// Update, instead of replace it
|
|
14659
|
-
if (this.
|
|
14660
|
-
this.
|
|
14656
|
+
if (this._data.account) {
|
|
14657
|
+
this._data.account.fromObject(account);
|
|
14661
14658
|
}
|
|
14662
14659
|
else {
|
|
14663
|
-
this.
|
|
14660
|
+
this._data.account = account;
|
|
14664
14661
|
}
|
|
14665
|
-
this.
|
|
14666
|
-
return [2 /*return*/, this.
|
|
14662
|
+
this._data.loaded = true;
|
|
14663
|
+
return [2 /*return*/, this._data.account];
|
|
14667
14664
|
case 3:
|
|
14668
14665
|
error_6 = _b.sent();
|
|
14669
14666
|
this.resetData();
|
|
@@ -14702,9 +14699,9 @@
|
|
|
14702
14699
|
return [2 /*return*/];
|
|
14703
14700
|
if (this._debug)
|
|
14704
14701
|
console.debug("[account] Account restoration...");
|
|
14705
|
-
this.
|
|
14706
|
-
this.
|
|
14707
|
-
this.
|
|
14702
|
+
this._data.authToken = token;
|
|
14703
|
+
this._data.pubkey = pubkey;
|
|
14704
|
+
this._data.keypair = seckey && {
|
|
14708
14705
|
publicKey: Base58.decode(pubkey),
|
|
14709
14706
|
secretKey: Base58.decode(seckey)
|
|
14710
14707
|
} || null;
|
|
@@ -14715,7 +14712,7 @@
|
|
|
14715
14712
|
return [4 /*yield*/, this.authenticate()];
|
|
14716
14713
|
case 3:
|
|
14717
14714
|
_b.sent();
|
|
14718
|
-
if (!this.
|
|
14715
|
+
if (!this._data.authToken && !this._data.authBasic)
|
|
14719
14716
|
throw new Error('Authentication failed');
|
|
14720
14717
|
return [3 /*break*/, 5];
|
|
14721
14718
|
case 4:
|
|
@@ -14748,14 +14745,14 @@
|
|
|
14748
14745
|
return [2 /*return*/];
|
|
14749
14746
|
account = exports.Account.fromObject(jsonAccount);
|
|
14750
14747
|
// Update data
|
|
14751
|
-
this.
|
|
14752
|
-
this.
|
|
14753
|
-
this.
|
|
14748
|
+
this._data.account = account;
|
|
14749
|
+
this._data.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
14750
|
+
this._data.loaded = true;
|
|
14754
14751
|
// Emit event
|
|
14755
|
-
this.onLogin.next(this.
|
|
14756
|
-
this.onChange.next(this.
|
|
14752
|
+
this.onLogin.next(this._data.account);
|
|
14753
|
+
this.onChange.next(this._data.account);
|
|
14757
14754
|
if (this._debug)
|
|
14758
|
-
console.debug("[account] Account restoration [OK] {pubkey: " + pubkey.substr(0, 8) + "}, {profile: " + this.
|
|
14755
|
+
console.debug("[account] Account restoration [OK] {pubkey: " + pubkey.substr(0, 8) + "}, {profile: " + this._data.mainProfile + "}");
|
|
14759
14756
|
return [2 /*return*/, account];
|
|
14760
14757
|
}
|
|
14761
14758
|
});
|
|
@@ -14771,12 +14768,12 @@
|
|
|
14771
14768
|
return __generator(this, function (_b) {
|
|
14772
14769
|
switch (_b.label) {
|
|
14773
14770
|
case 0:
|
|
14774
|
-
if (!this.
|
|
14771
|
+
if (!this._data.pubkey)
|
|
14775
14772
|
throw new Error('User not logged');
|
|
14776
14773
|
if (this._debug)
|
|
14777
|
-
console.debug("[account] Saving account {" + this.
|
|
14778
|
-
json = this.
|
|
14779
|
-
seckey = this.
|
|
14774
|
+
console.debug("[account] Saving account {" + this._data.pubkey.substring(0, 6) + "} in local storage...");
|
|
14775
|
+
json = this._data.account.asObject({ keepTypename: true });
|
|
14776
|
+
seckey = this._data.keypair && this._data.keypair.secretKey && Base58.encode(this._data.keypair.secretKey) || null;
|
|
14780
14777
|
hasAvatarUrl = json.avatar && !json.avatar.endsWith(DEFAULT_AVATAR_IMAGE) &&
|
|
14781
14778
|
(json.avatar.startsWith('http://') || (json.avatar.startsWith('https://')));
|
|
14782
14779
|
if (!(hasAvatarUrl && this.network.online)) return [3 /*break*/, 2];
|
|
@@ -14799,9 +14796,9 @@
|
|
|
14799
14796
|
case 2:
|
|
14800
14797
|
_b.trys.push([2, 4, , 5]);
|
|
14801
14798
|
return [4 /*yield*/, Promise.all([
|
|
14802
|
-
this.storage.set(PUBKEY_STORAGE_KEY, this.
|
|
14803
|
-
this.storage.set(TOKEN_STORAGE_KEY, this.
|
|
14804
|
-
this.storage.set(ACCOUNT_STORAGE_KEY + "#" + this.
|
|
14799
|
+
this.storage.set(PUBKEY_STORAGE_KEY, this._data.pubkey),
|
|
14800
|
+
this.storage.set(TOKEN_STORAGE_KEY, this._data.authToken),
|
|
14801
|
+
this.storage.set(ACCOUNT_STORAGE_KEY + "#" + this._data.pubkey, json),
|
|
14805
14802
|
// Secret key (optional)
|
|
14806
14803
|
seckey && this.storage.set(SECKEY_STORAGE_KEY, seckey) || this.storage.remove(SECKEY_STORAGE_KEY),
|
|
14807
14804
|
// Remove old storage key
|
|
@@ -14878,7 +14875,7 @@
|
|
|
14878
14875
|
return __generator(this, function (_b) {
|
|
14879
14876
|
switch (_b.label) {
|
|
14880
14877
|
case 0:
|
|
14881
|
-
if (!this.
|
|
14878
|
+
if (!this._data.pubkey)
|
|
14882
14879
|
throw new Error('User not logged');
|
|
14883
14880
|
if (!counter)
|
|
14884
14881
|
console.info('[account] Authentication on pod...');
|
|
@@ -14905,7 +14902,7 @@
|
|
|
14905
14902
|
if (data_1 && data_1.authenticate) {
|
|
14906
14903
|
// Store the token
|
|
14907
14904
|
this.onAuthTokenChange.next(token);
|
|
14908
|
-
console.info("[account] Authentication on pod [OK] {pubkey: '" + this.
|
|
14905
|
+
console.info("[account] Authentication on pod [OK] {pubkey: '" + this._data.pubkey.substr(0, 8) + "'}");
|
|
14909
14906
|
return [2 /*return*/, token]; // return the token
|
|
14910
14907
|
}
|
|
14911
14908
|
_b.label = 2;
|
|
@@ -14931,10 +14928,10 @@
|
|
|
14931
14928
|
if (!signatureOK) {
|
|
14932
14929
|
console.warn('FIXME: Bad peer signature on auth challenge !', data.authChallenge);
|
|
14933
14930
|
}
|
|
14934
|
-
return [4 /*yield*/, this.cryptoService.sign(data.authChallenge.challenge, this.
|
|
14931
|
+
return [4 /*yield*/, this.cryptoService.sign(data.authChallenge.challenge, this._data.keypair)];
|
|
14935
14932
|
case 5:
|
|
14936
14933
|
signature = _b.sent();
|
|
14937
|
-
newToken = this.
|
|
14934
|
+
newToken = this._data.pubkey + ":" + data.authChallenge.challenge + "|" + signature;
|
|
14938
14935
|
return [4 /*yield*/, this.authenticateAndGetToken(newToken, (counter || 1) + 1 /* increment */)];
|
|
14939
14936
|
case 6:
|
|
14940
14937
|
// iterate with the new token
|
|
@@ -15264,9 +15261,8 @@
|
|
|
15264
15261
|
Object.defineProperty(ConfigService.prototype, "config", {
|
|
15265
15262
|
get: function () {
|
|
15266
15263
|
// If first call: start loading
|
|
15267
|
-
if (!this._started)
|
|
15264
|
+
if (!this._started)
|
|
15268
15265
|
this.start();
|
|
15269
|
-
}
|
|
15270
15266
|
return this.$data.pipe(operators.filter(isNotNil));
|
|
15271
15267
|
},
|
|
15272
15268
|
enumerable: false,
|
|
@@ -15281,30 +15277,49 @@
|
|
|
15281
15277
|
console.info('[config] Starting configuration...');
|
|
15282
15278
|
this._startPromise = this.graphql.ready()
|
|
15283
15279
|
.then(function () { return _this.loadOrRestoreLocally(); })
|
|
15284
|
-
.then(function () {
|
|
15280
|
+
.then(function (data) {
|
|
15285
15281
|
_this._started = true;
|
|
15286
15282
|
_this._startPromise = undefined;
|
|
15283
|
+
_this.$data.next(data);
|
|
15284
|
+
return data;
|
|
15287
15285
|
})
|
|
15288
15286
|
.catch(function (err) {
|
|
15289
15287
|
console.error(err && err.message || err, err);
|
|
15288
|
+
_this._started = false;
|
|
15290
15289
|
_this._startPromise = undefined;
|
|
15290
|
+
return null;
|
|
15291
15291
|
});
|
|
15292
15292
|
return this._startPromise;
|
|
15293
15293
|
};
|
|
15294
15294
|
ConfigService.prototype.stop = function () {
|
|
15295
|
-
this
|
|
15296
|
-
|
|
15297
|
-
|
|
15298
|
-
|
|
15295
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
15296
|
+
return __generator(this, function (_a) {
|
|
15297
|
+
this._subscription.unsubscribe();
|
|
15298
|
+
this._subscription = new rxjs.Subscription();
|
|
15299
|
+
this._started = false;
|
|
15300
|
+
this._startPromise = undefined;
|
|
15301
|
+
return [2 /*return*/];
|
|
15302
|
+
});
|
|
15303
|
+
});
|
|
15299
15304
|
};
|
|
15300
15305
|
ConfigService.prototype.restart = function () {
|
|
15301
|
-
|
|
15302
|
-
this
|
|
15303
|
-
|
|
15306
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
15307
|
+
return __generator(this, function (_a) {
|
|
15308
|
+
switch (_a.label) {
|
|
15309
|
+
case 0:
|
|
15310
|
+
if (!this.started) return [3 /*break*/, 2];
|
|
15311
|
+
return [4 /*yield*/, this.stop()];
|
|
15312
|
+
case 1:
|
|
15313
|
+
_a.sent();
|
|
15314
|
+
_a.label = 2;
|
|
15315
|
+
case 2: return [2 /*return*/, this.start()];
|
|
15316
|
+
}
|
|
15317
|
+
});
|
|
15318
|
+
});
|
|
15304
15319
|
};
|
|
15305
15320
|
ConfigService.prototype.ready = function () {
|
|
15306
15321
|
if (this._started)
|
|
15307
|
-
return Promise.resolve();
|
|
15322
|
+
return Promise.resolve(this.$data.value);
|
|
15308
15323
|
if (this._startPromise)
|
|
15309
15324
|
return this._startPromise;
|
|
15310
15325
|
return this.start();
|
|
@@ -15375,7 +15390,7 @@
|
|
|
15375
15390
|
return [4 /*yield*/, this.loadDefault({ fetchPolicy: 'network-only' })];
|
|
15376
15391
|
case 2:
|
|
15377
15392
|
reloadedConfig = _a.sent();
|
|
15378
|
-
defaultConfig = this.$data.
|
|
15393
|
+
defaultConfig = this.$data.value;
|
|
15379
15394
|
if (isNotNil(defaultConfig) && reloadedConfig.label === defaultConfig.label) {
|
|
15380
15395
|
// Emit update event when is default config
|
|
15381
15396
|
this.$data.next(reloadedConfig);
|
|
@@ -15484,8 +15499,7 @@
|
|
|
15484
15499
|
if (wasJustLoaded) {
|
|
15485
15500
|
// TODO
|
|
15486
15501
|
}
|
|
15487
|
-
|
|
15488
|
-
return [2 /*return*/];
|
|
15502
|
+
return [2 /*return*/, data];
|
|
15489
15503
|
}
|
|
15490
15504
|
});
|
|
15491
15505
|
});
|
|
@@ -15664,6 +15678,7 @@
|
|
|
15664
15678
|
this.browser = browser;
|
|
15665
15679
|
this.downloader = downloader;
|
|
15666
15680
|
this._started = false;
|
|
15681
|
+
this._downloadingPromise = new Map();
|
|
15667
15682
|
this._debug = !environment.production;
|
|
15668
15683
|
if (this._debug)
|
|
15669
15684
|
console.debug('[platform] Creating service');
|
|
@@ -15696,6 +15711,13 @@
|
|
|
15696
15711
|
PlatformService.prototype.isAndroidCordova = function () {
|
|
15697
15712
|
return this._android && this._cordova;
|
|
15698
15713
|
};
|
|
15714
|
+
Object.defineProperty(PlatformService.prototype, "canDownload", {
|
|
15715
|
+
get: function () {
|
|
15716
|
+
return this._android && !!this.downloader;
|
|
15717
|
+
},
|
|
15718
|
+
enumerable: false,
|
|
15719
|
+
configurable: true
|
|
15720
|
+
});
|
|
15699
15721
|
PlatformService.prototype.width = function () {
|
|
15700
15722
|
return this.platform.width();
|
|
15701
15723
|
};
|
|
@@ -15738,7 +15760,7 @@
|
|
|
15738
15760
|
.then(function () {
|
|
15739
15761
|
_this._started = true;
|
|
15740
15762
|
_this._startPromise = undefined;
|
|
15741
|
-
console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + "} in " + (Date.now() - now) + "ms");
|
|
15763
|
+
console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + ", canDownload: " + _this.canDownload + "} in " + (Date.now() - now) + "ms");
|
|
15742
15764
|
// Update cache configuration when network changed
|
|
15743
15765
|
_this.networkService.onNetworkStatusChanges.subscribe(function (type) { return _this.configureCache(type !== 'none'); });
|
|
15744
15766
|
// Update authentication type
|
|
@@ -15787,18 +15809,48 @@
|
|
|
15787
15809
|
}
|
|
15788
15810
|
};
|
|
15789
15811
|
PlatformService.prototype.download = function (request) {
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
|
|
15812
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
15813
|
+
var promise, location, err_1;
|
|
15814
|
+
return __generator(this, function (_a) {
|
|
15815
|
+
switch (_a.label) {
|
|
15816
|
+
case 0:
|
|
15817
|
+
if (!request || !request.uri)
|
|
15818
|
+
throw new Error('Missing argument \'request\' or \'request.uri\'');
|
|
15819
|
+
if (!(this._android && this.downloader)) return [3 /*break*/, 6];
|
|
15820
|
+
promise = this._downloadingPromise.get(request.uri);
|
|
15821
|
+
if (promise)
|
|
15822
|
+
return [2 /*return*/, promise];
|
|
15823
|
+
request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted, title: request.title || request.filename }, request);
|
|
15824
|
+
_a.label = 1;
|
|
15825
|
+
case 1:
|
|
15826
|
+
_a.trys.push([1, 3, 4, 5]);
|
|
15827
|
+
console.debug('[platform] Downloading, using request: ' + JSON.stringify(request));
|
|
15828
|
+
// Start download
|
|
15829
|
+
promise = this.downloader.download(request);
|
|
15830
|
+
// Remember this request uri
|
|
15831
|
+
this._downloadingPromise.set(request.uri, promise);
|
|
15832
|
+
return [4 /*yield*/, promise];
|
|
15833
|
+
case 2:
|
|
15834
|
+
location = _a.sent();
|
|
15835
|
+
console.info('[platform] File successfully downloaded at:' + location);
|
|
15836
|
+
return [2 /*return*/, location];
|
|
15837
|
+
case 3:
|
|
15838
|
+
err_1 = _a.sent();
|
|
15839
|
+
console.error('[platform] Unable to download: ' + (err_1 && err_1.message || err_1));
|
|
15840
|
+
throw err_1;
|
|
15841
|
+
case 4:
|
|
15842
|
+
// Forget the request
|
|
15843
|
+
this._downloadingPromise.delete(request.uri);
|
|
15844
|
+
return [7 /*endfinally*/];
|
|
15845
|
+
case 5: return [3 /*break*/, 7];
|
|
15846
|
+
case 6:
|
|
15847
|
+
console.warn('[platform] Cannot use Android downloader: using browser open()');
|
|
15848
|
+
this.open(request.uri, '_system', 'location=no', true);
|
|
15849
|
+
return [2 /*return*/, undefined];
|
|
15850
|
+
case 7: return [2 /*return*/];
|
|
15851
|
+
}
|
|
15852
|
+
});
|
|
15853
|
+
});
|
|
15802
15854
|
};
|
|
15803
15855
|
/* -- protected methods -- */
|
|
15804
15856
|
PlatformService.prototype.configureCordovaPlugins = function (mobile) {
|
|
@@ -15894,7 +15946,7 @@
|
|
|
15894
15946
|
};
|
|
15895
15947
|
PlatformService.prototype.migrateStorage = function (forage) {
|
|
15896
15948
|
return __awaiter(this, void 0, void 0, function () {
|
|
15897
|
-
var canMigrate, oldForage, keys, now, toast_1, duration,
|
|
15949
|
+
var canMigrate, oldForage, keys, now, toast_1, duration, err_2;
|
|
15898
15950
|
return __generator(this, function (_a) {
|
|
15899
15951
|
switch (_a.label) {
|
|
15900
15952
|
case 0:
|
|
@@ -15912,8 +15964,8 @@
|
|
|
15912
15964
|
case 1:
|
|
15913
15965
|
keys = _a.sent();
|
|
15914
15966
|
if (!isEmptyArray(keys)) return [3 /*break*/, 3];
|
|
15915
|
-
// Drop the old instance
|
|
15916
|
-
console.
|
|
15967
|
+
// Drop the old instance (not need anymore)
|
|
15968
|
+
console.debug("[platform] Old storage is empty: dropping unused instance {name: '" + forage.config().name + "', driver: '" + oldForage.driver() + "'}");
|
|
15917
15969
|
return [4 /*yield*/, oldForage.dropInstance()];
|
|
15918
15970
|
case 2:
|
|
15919
15971
|
_a.sent();
|
|
@@ -15947,8 +15999,8 @@
|
|
|
15947
15999
|
_a.sent();
|
|
15948
16000
|
return [3 /*break*/, 12];
|
|
15949
16001
|
case 9:
|
|
15950
|
-
|
|
15951
|
-
console.error(
|
|
16002
|
+
err_2 = _a.sent();
|
|
16003
|
+
console.error(err_2 && err_2.message || err_2, err_2);
|
|
15952
16004
|
return [4 /*yield*/, toast_1.dismiss()];
|
|
15953
16005
|
case 10:
|
|
15954
16006
|
_a.sent();
|
|
@@ -17594,7 +17646,7 @@
|
|
|
17594
17646
|
AutocompleteTestPage.decorators = [
|
|
17595
17647
|
{ type: i0.Component, args: [{
|
|
17596
17648
|
selector: 'app-autocomplete-test',
|
|
17597
|
-
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\" >\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class=\"min-width-large\"</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col><ion-text><h4>Desktop mode</h4></ion-text></ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class: 'mat-autocomplete-panel-full-size'</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [compareWith]=\"compareWithFn\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\" >\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class=\"mat-autocomplete-panel-full-size\"</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\" >\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>panelWidth: string</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n </mat-checkbox>\n\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
17649
|
+
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row><ion-col><ion-text><h4>Debug memory leak</h4></ion-text></ion-col></ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\" >\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>mobile: true, items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class=\"min-width-large\"</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col><ion-text><h4>Desktop mode</h4></ion-text></ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class: 'mat-autocomplete-panel-full-size'</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [compareWith]=\"compareWithFn\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\" >\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>class=\"mat-autocomplete-panel-full-size\"</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\" >\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>panelWidth: string</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [compareWith]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
17598
17650
|
},] }
|
|
17599
17651
|
];
|
|
17600
17652
|
AutocompleteTestPage.ctorParameters = function () { return [
|
|
@@ -21257,22 +21309,25 @@
|
|
|
21257
21309
|
ANDROID_APK: 'application/vnd.android.package-archive'
|
|
21258
21310
|
});
|
|
21259
21311
|
var AppInstallUpgradeCard = /** @class */ (function () {
|
|
21260
|
-
function AppInstallUpgradeCard(modalCtrl, configService,
|
|
21312
|
+
function AppInstallUpgradeCard(modalCtrl, configService, toastController, alertController, translate, cd, platform, network, environment) {
|
|
21261
21313
|
this.modalCtrl = modalCtrl;
|
|
21262
21314
|
this.configService = configService;
|
|
21263
|
-
this.
|
|
21315
|
+
this.toastController = toastController;
|
|
21316
|
+
this.alertController = alertController;
|
|
21317
|
+
this.translate = translate;
|
|
21264
21318
|
this.cd = cd;
|
|
21319
|
+
this.platform = platform;
|
|
21265
21320
|
this.network = network;
|
|
21266
21321
|
this.environment = environment;
|
|
21267
21322
|
this._subscription = new rxjs.Subscription();
|
|
21268
21323
|
this._showUpdateOfflineFeature = false;
|
|
21269
21324
|
this.loading = true;
|
|
21325
|
+
this.downloading = false;
|
|
21270
21326
|
this.waitingNetwork = false;
|
|
21271
21327
|
this.showUpgradeWarning = true;
|
|
21272
21328
|
this.showOfflineWarning = true;
|
|
21273
21329
|
this.showInstallButton = false;
|
|
21274
21330
|
this.onUpdateOfflineModeClick = new i0.EventEmitter();
|
|
21275
|
-
this.isAndroidCordova = platform.isAndroidCordova();
|
|
21276
21331
|
}
|
|
21277
21332
|
Object.defineProperty(AppInstallUpgradeCard.prototype, "showUpdateOfflineFeature", {
|
|
21278
21333
|
get: function () {
|
|
@@ -21298,18 +21353,8 @@
|
|
|
21298
21353
|
this.offline = this.network.offline;
|
|
21299
21354
|
// Listen pod config
|
|
21300
21355
|
this._subscription.add(this.configService.config
|
|
21301
|
-
.
|
|
21302
|
-
|
|
21303
|
-
var installLinks = _this.getAllInstallLinks(config);
|
|
21304
|
-
// Check for upgrade
|
|
21305
|
-
_this.updateLinks = _this.getCompatibleUpgradeLinks(installLinks, config);
|
|
21306
|
-
// Check for install links (if no upgrade need)
|
|
21307
|
-
_this.installLinks = !_this.updateLinks && _this.getCompatibleInstallLinks(installLinks);
|
|
21308
|
-
setTimeout(function () {
|
|
21309
|
-
_this.loading = false;
|
|
21310
|
-
_this.markForCheck();
|
|
21311
|
-
}, 2000); // Add a delay, for animation
|
|
21312
|
-
}));
|
|
21356
|
+
.pipe(operators.debounceTime(1000))
|
|
21357
|
+
.subscribe(function (config) { return _this.checkNeedInstallOrUpdate(config); }));
|
|
21313
21358
|
// Listen network changes
|
|
21314
21359
|
this._subscription.add(this.network.onNetworkStatusChanges
|
|
21315
21360
|
.pipe(
|
|
@@ -21317,8 +21362,10 @@
|
|
|
21317
21362
|
//tap(() => this.waitingNetwork = false),
|
|
21318
21363
|
operators.map(function (connectionType) { return connectionType === 'none'; }), operators.distinctUntilChanged())
|
|
21319
21364
|
.subscribe(function (offline) {
|
|
21320
|
-
_this.offline
|
|
21321
|
-
|
|
21365
|
+
if (_this.offline !== offline) {
|
|
21366
|
+
_this.offline = offline;
|
|
21367
|
+
_this.markForCheck();
|
|
21368
|
+
}
|
|
21322
21369
|
}));
|
|
21323
21370
|
return [2 /*return*/];
|
|
21324
21371
|
}
|
|
@@ -21327,28 +21374,83 @@
|
|
|
21327
21374
|
};
|
|
21328
21375
|
AppInstallUpgradeCard.prototype.ngOnDestroy = function () {
|
|
21329
21376
|
this._subscription.unsubscribe();
|
|
21377
|
+
this._subscription = null;
|
|
21330
21378
|
};
|
|
21331
|
-
AppInstallUpgradeCard.prototype.
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21337
|
-
|
|
21379
|
+
AppInstallUpgradeCard.prototype.download = function (event, link) {
|
|
21380
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
21381
|
+
var location, err_1;
|
|
21382
|
+
return __generator(this, function (_a) {
|
|
21383
|
+
switch (_a.label) {
|
|
21384
|
+
case 0:
|
|
21385
|
+
if (!link || !link.url) {
|
|
21386
|
+
console.error('[install-upgrade-card] Missing required argument \'link.url\'');
|
|
21387
|
+
return [2 /*return*/]; // Skip
|
|
21388
|
+
}
|
|
21389
|
+
this.downloading = true;
|
|
21390
|
+
_a.label = 1;
|
|
21391
|
+
case 1:
|
|
21392
|
+
_a.trys.push([1, 3, 4, 5]);
|
|
21393
|
+
console.info('[install-upgrade-card] User click to download file: ' + link.url);
|
|
21394
|
+
return [4 /*yield*/, this.platform.download({
|
|
21395
|
+
uri: link.url,
|
|
21396
|
+
title: link.name,
|
|
21397
|
+
filename: link.downloadFilename,
|
|
21398
|
+
mimeType: link.mimeType
|
|
21399
|
+
})];
|
|
21400
|
+
case 2:
|
|
21401
|
+
location = _a.sent();
|
|
21402
|
+
console.info('[install-upgrade-card] File downloaded at: ' + location);
|
|
21403
|
+
return [3 /*break*/, 5];
|
|
21404
|
+
case 3:
|
|
21405
|
+
err_1 = _a.sent();
|
|
21406
|
+
console.error('[install-upgrade] Download failed: ' + (err_1 && err_1.message || err_1));
|
|
21407
|
+
this.showToast({
|
|
21408
|
+
message: 'ERROR.DOWNLOAD_FAILED',
|
|
21409
|
+
messageParams: { error: err_1 },
|
|
21410
|
+
type: 'error',
|
|
21411
|
+
showCloseButton: true
|
|
21412
|
+
});
|
|
21413
|
+
return [2 /*return*/]; // Stop here
|
|
21414
|
+
case 4:
|
|
21415
|
+
this.downloading = false;
|
|
21416
|
+
this.markForCheck();
|
|
21417
|
+
return [7 /*endfinally*/];
|
|
21418
|
+
case 5:
|
|
21419
|
+
if (!this._subscription)
|
|
21420
|
+
return [2 /*return*/]; // Skip if component destroyed
|
|
21421
|
+
return [4 /*yield*/, this.showDownloadCompleteDialog()];
|
|
21422
|
+
case 6:
|
|
21423
|
+
_a.sent();
|
|
21424
|
+
return [2 /*return*/];
|
|
21425
|
+
}
|
|
21426
|
+
});
|
|
21338
21427
|
});
|
|
21339
21428
|
};
|
|
21340
21429
|
AppInstallUpgradeCard.prototype.tryOnline = function () {
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21430
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
21431
|
+
return __generator(this, function (_a) {
|
|
21432
|
+
switch (_a.label) {
|
|
21433
|
+
case 0:
|
|
21434
|
+
this.waitingNetwork = true;
|
|
21435
|
+
this.markForCheck();
|
|
21436
|
+
_a.label = 1;
|
|
21437
|
+
case 1:
|
|
21438
|
+
_a.trys.push([1, , 3, 4]);
|
|
21439
|
+
return [4 /*yield*/, this.network.tryOnline({
|
|
21440
|
+
showLoadingToast: false,
|
|
21441
|
+
showOnlineToast: true,
|
|
21442
|
+
showOfflineToast: false
|
|
21443
|
+
})];
|
|
21444
|
+
case 2:
|
|
21445
|
+
_a.sent();
|
|
21446
|
+
return [3 /*break*/, 4];
|
|
21447
|
+
case 3:
|
|
21448
|
+
this.waitingNetwork = false;
|
|
21449
|
+
this.markForCheck();
|
|
21450
|
+
return [7 /*endfinally*/];
|
|
21451
|
+
case 4: return [2 /*return*/];
|
|
21452
|
+
}
|
|
21453
|
+
});
|
|
21352
21454
|
});
|
|
21353
21455
|
};
|
|
21354
21456
|
AppInstallUpgradeCard.prototype.getPlatformName = function (platform) {
|
|
@@ -21365,6 +21467,34 @@
|
|
|
21365
21467
|
return value;
|
|
21366
21468
|
};
|
|
21367
21469
|
/* -- private method -- */
|
|
21470
|
+
AppInstallUpgradeCard.prototype.checkNeedInstallOrUpdate = function (config) {
|
|
21471
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
21472
|
+
var installLinks;
|
|
21473
|
+
return __generator(this, function (_a) {
|
|
21474
|
+
switch (_a.label) {
|
|
21475
|
+
case 0:
|
|
21476
|
+
console.info('[install] Check if need to install or upgrade...');
|
|
21477
|
+
_a.label = 1;
|
|
21478
|
+
case 1:
|
|
21479
|
+
_a.trys.push([1, , 3, 4]);
|
|
21480
|
+
installLinks = this.getAllInstallLinks(config);
|
|
21481
|
+
// Check for upgrade
|
|
21482
|
+
this.updateLinks = this.getCompatibleUpgradeLinks(installLinks, config);
|
|
21483
|
+
// Check for install links (if no upgrade need)
|
|
21484
|
+
this.installLinks = !this.updateLinks && this.getCompatibleInstallLinks(installLinks);
|
|
21485
|
+
return [4 /*yield*/, sleep(500)];
|
|
21486
|
+
case 2:
|
|
21487
|
+
_a.sent(); // Add a delay, for animation
|
|
21488
|
+
return [3 /*break*/, 4];
|
|
21489
|
+
case 3:
|
|
21490
|
+
this.loading = false;
|
|
21491
|
+
this.markForCheck();
|
|
21492
|
+
return [7 /*endfinally*/];
|
|
21493
|
+
case 4: return [2 /*return*/];
|
|
21494
|
+
}
|
|
21495
|
+
});
|
|
21496
|
+
});
|
|
21497
|
+
};
|
|
21368
21498
|
AppInstallUpgradeCard.prototype.getCompatibleInstallLinks = function (installLinks) {
|
|
21369
21499
|
// Cordova already running: not need to install
|
|
21370
21500
|
if (this.platform.is('cordova'))
|
|
@@ -21377,15 +21507,20 @@
|
|
|
21377
21507
|
};
|
|
21378
21508
|
AppInstallUpgradeCard.prototype.getCompatibleUpgradeLinks = function (installLinks, config) {
|
|
21379
21509
|
var _this = this;
|
|
21380
|
-
var
|
|
21381
|
-
var
|
|
21510
|
+
var appVersion = this.environment.version;
|
|
21511
|
+
var appMinVersionFromPod = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
|
|
21512
|
+
if (!appVersion) {
|
|
21513
|
+
console.error('Missing value for \'environment.version\': cannot check app compatibility!');
|
|
21514
|
+
return undefined;
|
|
21515
|
+
}
|
|
21516
|
+
var needUpgrade = appMinVersionFromPod && !VersionUtils.isCompatible(appMinVersionFromPod, appVersion);
|
|
21382
21517
|
if (!needUpgrade)
|
|
21383
21518
|
return undefined;
|
|
21384
21519
|
var upgradeLinks = installLinks
|
|
21385
21520
|
.filter(function (link) { return _this.platform.is('mobileweb') || (link.platform && _this.platform.is(link.platform)); });
|
|
21386
21521
|
// Use min version as default version
|
|
21387
21522
|
upgradeLinks.forEach(function (link) {
|
|
21388
|
-
link.version = link.version ||
|
|
21523
|
+
link.version = link.version || appMinVersionFromPod;
|
|
21389
21524
|
});
|
|
21390
21525
|
return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
|
|
21391
21526
|
};
|
|
@@ -21397,6 +21532,12 @@
|
|
|
21397
21532
|
var url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
|
|
21398
21533
|
if (isNilOrBlank(url))
|
|
21399
21534
|
url = this.environment.defaultAndroidInstallUrl || null;
|
|
21535
|
+
// Resolve relative URL
|
|
21536
|
+
var peer = this.network.peer;
|
|
21537
|
+
if (peer && (url.startsWith('./') || url.startsWith('/'))) {
|
|
21538
|
+
url = exports.Peer.path(peer, url);
|
|
21539
|
+
}
|
|
21540
|
+
var minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
|
|
21400
21541
|
// Compute App name
|
|
21401
21542
|
var name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
|
|
21402
21543
|
if (url) {
|
|
@@ -21405,7 +21546,7 @@
|
|
|
21405
21546
|
var mimeType = void 0;
|
|
21406
21547
|
// Get file name
|
|
21407
21548
|
var filename = this.getFilename(url);
|
|
21408
|
-
version =
|
|
21549
|
+
version = minVersion || 'latest';
|
|
21409
21550
|
// OK, this is a downloadable APK file (e.g. NOT a link to a playstore)
|
|
21410
21551
|
if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.apk')) {
|
|
21411
21552
|
// Define mime type
|
|
@@ -21415,13 +21556,12 @@
|
|
|
21415
21556
|
version = versionMatches && versionMatches[1] || version;
|
|
21416
21557
|
// Compute a new file name, with the version
|
|
21417
21558
|
if (isNotNilOrBlank(name)) {
|
|
21418
|
-
downloadFilename = name + "-" + version + ".apk";
|
|
21559
|
+
downloadFilename = (name + "-v" + version + ".apk").toLowerCase();
|
|
21419
21560
|
}
|
|
21420
21561
|
else {
|
|
21421
21562
|
downloadFilename = filename;
|
|
21422
|
-
// Replace 'latest' with the app
|
|
21563
|
+
// Replace 'latest' with the app version, if present
|
|
21423
21564
|
if (downloadFilename.indexOf('latest')) {
|
|
21424
|
-
version = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
|
|
21425
21565
|
downloadFilename = downloadFilename.replace('latest', version);
|
|
21426
21566
|
}
|
|
21427
21567
|
}
|
|
@@ -21450,12 +21590,60 @@
|
|
|
21450
21590
|
AppInstallUpgradeCard.prototype.markForCheck = function () {
|
|
21451
21591
|
this.cd.markForCheck();
|
|
21452
21592
|
};
|
|
21593
|
+
AppInstallUpgradeCard.prototype.showToast = function (opts) {
|
|
21594
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
21595
|
+
return __generator(this, function (_a) {
|
|
21596
|
+
switch (_a.label) {
|
|
21597
|
+
case 0: return [4 /*yield*/, Toasts.show(this.toastController, this.translate, opts)];
|
|
21598
|
+
case 1:
|
|
21599
|
+
_a.sent();
|
|
21600
|
+
return [2 /*return*/];
|
|
21601
|
+
}
|
|
21602
|
+
});
|
|
21603
|
+
});
|
|
21604
|
+
};
|
|
21605
|
+
AppInstallUpgradeCard.prototype.showDownloadCompleteDialog = function () {
|
|
21606
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
21607
|
+
var translations, alert;
|
|
21608
|
+
return __generator(this, function (_a) {
|
|
21609
|
+
switch (_a.label) {
|
|
21610
|
+
case 0: return [4 /*yield*/, this.translate.get([
|
|
21611
|
+
'INFO.ALERT_HEADER',
|
|
21612
|
+
'INFO.DOWNLOAD_UPDATE_SUCCEED',
|
|
21613
|
+
'COMMON.BTN_CLOSE'
|
|
21614
|
+
]).toPromise()];
|
|
21615
|
+
case 1:
|
|
21616
|
+
translations = _a.sent();
|
|
21617
|
+
return [4 /*yield*/, this.alertController.create({
|
|
21618
|
+
header: translations['INFO.ALERT_HEADER'],
|
|
21619
|
+
message: translations['INFO.DOWNLOAD_UPDATE_SUCCEED'],
|
|
21620
|
+
buttons: [
|
|
21621
|
+
{
|
|
21622
|
+
text: translations['COMMON.BTN_CLOSE'],
|
|
21623
|
+
role: 'cancel',
|
|
21624
|
+
cssClass: 'secondary'
|
|
21625
|
+
}
|
|
21626
|
+
]
|
|
21627
|
+
})];
|
|
21628
|
+
case 2:
|
|
21629
|
+
alert = _a.sent();
|
|
21630
|
+
return [4 /*yield*/, alert.present()];
|
|
21631
|
+
case 3:
|
|
21632
|
+
_a.sent();
|
|
21633
|
+
return [4 /*yield*/, alert.onDidDismiss()];
|
|
21634
|
+
case 4:
|
|
21635
|
+
_a.sent();
|
|
21636
|
+
return [2 /*return*/];
|
|
21637
|
+
}
|
|
21638
|
+
});
|
|
21639
|
+
});
|
|
21640
|
+
};
|
|
21453
21641
|
return AppInstallUpgradeCard;
|
|
21454
21642
|
}());
|
|
21455
21643
|
AppInstallUpgradeCard.decorators = [
|
|
21456
21644
|
{ type: i0.Component, args: [{
|
|
21457
21645
|
selector: 'app-install-upgrade-card',
|
|
21458
|
-
template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n
|
|
21646
|
+
template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Display a download button, depending on the link URL, and the device platform -->\n<ng-template #downloadButton let-link>\n\n <ng-container *ngIf=\"link.downloadFilename; else redirectButton\">\n\n <ng-container *ngIf=\"platform.canDownload; else webDownloadButton\">\n <!-- Download using platform -->\n <ion-button *ngIf=\"!downloading; else waitingSpinner\"\n (click)=\"download($event, asLink(link))\"\n [disabled]=\"downloading\"\n color=\"tertiary\" class=\"ion-float-end\">\n <ion-icon slot=\"start\" *ngIf=\"!downloading\" name=\"download\"></ion-icon>\n <ion-spinner slot=\"start\" class=\"ion-no-padding\" *ngIf=\"downloading\"></ion-spinner>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-container>\n\n <!-- Web download button -->\n <ng-template #webDownloadButton>\n <ion-button [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-template>\n </ng-container>\n\n <!-- Web redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n</ng-template>\n\n\n<!-- Waiting spinner -->\n<ng-template #waitingSpinner>\n <ion-spinner color=\"light\"></ion-spinner>\n</ng-template>\n",
|
|
21459
21647
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
21460
21648
|
animations: [slideUpDownAnimation],
|
|
21461
21649
|
styles: ["ion-text small{font-size:85%}"]
|
|
@@ -21464,8 +21652,11 @@
|
|
|
21464
21652
|
AppInstallUpgradeCard.ctorParameters = function () { return [
|
|
21465
21653
|
{ type: i1$5.ModalController },
|
|
21466
21654
|
{ type: ConfigService },
|
|
21467
|
-
{ type:
|
|
21655
|
+
{ type: i1$5.ToastController },
|
|
21656
|
+
{ type: i1$5.AlertController },
|
|
21657
|
+
{ type: i1$2.TranslateService },
|
|
21468
21658
|
{ type: i0.ChangeDetectorRef },
|
|
21659
|
+
{ type: PlatformService },
|
|
21469
21660
|
{ type: NetworkService },
|
|
21470
21661
|
{ type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] }
|
|
21471
21662
|
]; };
|
|
@@ -27155,6 +27346,7 @@
|
|
|
27155
27346
|
_this.filterCriteriaCount = 0;
|
|
27156
27347
|
_this.statusList = StatusList;
|
|
27157
27348
|
_this.statusById = StatusById;
|
|
27349
|
+
_this.useSticky = false;
|
|
27158
27350
|
_this.referentialToString = referentialToString;
|
|
27159
27351
|
_this.inlineEdition = accountService.isAdmin(); // Allow inline edition only if admin
|
|
27160
27352
|
_this.canEdit = accountService.isAdmin();
|
|
@@ -27273,13 +27465,13 @@
|
|
|
27273
27465
|
UsersPage.decorators = [
|
|
27274
27466
|
{ type: i0.Component, args: [{
|
|
27275
27467
|
selector: 'app-users-table',
|
|
27276
|
-
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 >=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 >=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",
|
|
27468
|
+
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 >=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 >=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",
|
|
27277
27469
|
providers: [
|
|
27278
27470
|
{ provide: ngxMaterialTable.ValidatorService, useExisting: PersonValidatorService }
|
|
27279
27471
|
],
|
|
27280
27472
|
animations: [slideUpDownAnimation],
|
|
27281
27473
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
27282
|
-
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-avatar{min-width:
|
|
27474
|
+
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}"]
|
|
27283
27475
|
},] }
|
|
27284
27476
|
];
|
|
27285
27477
|
UsersPage.ctorParameters = function () { return [
|
|
@@ -27299,6 +27491,7 @@
|
|
|
27299
27491
|
{ type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] }
|
|
27300
27492
|
]; };
|
|
27301
27493
|
UsersPage.propDecorators = {
|
|
27494
|
+
useSticky: [{ type: i0.Input }],
|
|
27302
27495
|
filterExpansionPanel: [{ type: i0.ViewChild, args: [expansion.MatExpansionPanel, { static: true },] }]
|
|
27303
27496
|
};
|
|
27304
27497
|
|
|
@@ -27572,6 +27765,7 @@
|
|
|
27572
27765
|
exports.SharedTestingModule = SharedTestingModule;
|
|
27573
27766
|
exports.SharedValidators = SharedValidators;
|
|
27574
27767
|
exports.SocialModule = SocialModule;
|
|
27768
|
+
exports.StartableService = StartableService;
|
|
27575
27769
|
exports.StatusById = StatusById;
|
|
27576
27770
|
exports.StatusIds = StatusIds;
|
|
27577
27771
|
exports.StatusList = StatusList;
|