@sumaris-net/ngx-components 1.21.0-beta9 → 1.21.2
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 +594 -1227
- 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 +12 -0
- package/esm2015/public_api.js +3 -8
- package/esm2015/src/app/core/account/account.js +2 -2
- package/esm2015/src/app/core/auth/form/form-auth.js +4 -2
- package/esm2015/src/app/core/form/editor.class.js +64 -20
- package/esm2015/src/app/core/form/entity-editor-modal.class.js +20 -15
- package/esm2015/src/app/core/form/entity-editor.class.js +21 -12
- package/esm2015/src/app/core/form/form.class.js +68 -35
- package/esm2015/src/app/core/graphql/graphql.service.js +5 -3
- package/esm2015/src/app/core/icon/icon.component.js +2 -5
- package/esm2015/src/app/core/menu/menu.component.js +2 -2
- package/esm2015/src/app/core/services/local-settings.service.js +2 -2
- package/esm2015/src/app/core/table/table.class.js +26 -27
- package/esm2015/src/app/shared/functions.js +1 -60
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +5 -4
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +10 -7
- package/esm2015/src/app/shared/material/chips/material.chips.js +3 -2
- package/esm2015/src/app/shared/material/chips/testing/chips.test.js +3 -2
- package/esm2015/src/app/shared/material/datetime/material.date.js +3 -2
- package/esm2015/src/app/shared/material/datetime/material.datetime.js +3 -2
- package/esm2015/src/app/shared/observables.js +13 -7
- package/esm2015/src/app/shared/pipes/arrays.pipe.js +1 -1
- package/esm2015/src/app/shared/pipes/form.pipes.js +4 -6
- package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
- package/esm2015/src/app/shared/pipes/string.pipes.js +7 -18
- package/esm2015/src/app/shared/services/memory-entity-service.class.js +13 -1
- package/esm2015/src/app/shared/services.js +61 -0
- package/esm2015/src/app/shared/types.js +1 -1
- package/esm2015/src/app/social/social.errors.js +2 -5
- package/esm2015/src/app/social/social.module.js +15 -10
- package/esm2015/src/app/social/user-event/user-event.model.js +2 -58
- package/esm2015/src/app/social/user-event/user-event.service.js +167 -295
- package/esm2015/src/app/social/user-event/user-events.table.js +12 -17
- package/esm2015/sumaris-net.ngx-components.js +6 -8
- package/fesm2015/sumaris-net.ngx-components.js +479 -1015
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +3 -2
- package/public_api.d.ts +2 -7
- package/src/app/core/auth/form/form-auth.d.ts +1 -1
- package/src/app/core/form/editor.class.d.ts +39 -12
- package/src/app/core/form/entity-editor-modal.class.d.ts +4 -3
- package/src/app/core/form/entity-editor.class.d.ts +10 -5
- package/src/app/core/form/form.class.d.ts +32 -19
- package/src/app/core/icon/icon.component.d.ts +4 -4
- package/src/app/core/table/table.class.d.ts +21 -14
- package/src/app/shared/functions.d.ts +0 -9
- package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +1 -2
- package/src/app/shared/material/badge/badge-icon.test.d.ts +1 -1
- package/src/app/shared/observables.d.ts +1 -0
- package/src/app/shared/pipes/form.pipes.d.ts +1 -2
- package/src/app/shared/services/memory-entity-service.class.d.ts +6 -0
- package/src/app/shared/services.d.ts +9 -0
- package/src/app/shared/types.d.ts +0 -4
- package/src/app/social/social.errors.d.ts +0 -3
- package/src/app/social/social.module.d.ts +0 -8
- package/src/app/social/user-event/user-event.model.d.ts +6 -51
- package/src/app/social/user-event/user-event.service.d.ts +51 -79
- package/src/app/social/user-event/user-events.table.d.ts +6 -6
- package/src/assets/i18n/en-US.json +2 -15
- package/src/assets/i18n/en.json +2 -15
- package/src/assets/i18n/fr.json +1 -14
- package/src/theme/_ngx-components.scss +0 -7
- package/sumaris-net.ngx-components.d.ts +5 -7
- package/sumaris-net.ngx-components.metadata.json +1 -1
- package/esm2015/src/app/social/job/job.model.js +0 -24
- package/esm2015/src/app/social/job/job.module.js +0 -25
- package/esm2015/src/app/social/job/job.service.js +0 -53
- package/esm2015/src/app/social/job/progression/job-progression.component.js +0 -192
- package/esm2015/src/app/social/job/progression/job-progression.list.js +0 -20
- package/esm2015/src/app/social/message/message.module.js +0 -25
- package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +0 -92
- package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +0 -39
- package/esm2015/src/app/social/user-event/user-event.module.js +0 -28
- package/src/app/social/job/job.model.d.ts +0 -32
- package/src/app/social/job/job.module.d.ts +0 -2
- package/src/app/social/job/job.service.d.ts +0 -23
- package/src/app/social/job/progression/job-progression.component.d.ts +0 -43
- package/src/app/social/job/progression/job-progression.list.d.ts +0 -12
- package/src/app/social/message/message.module.d.ts +0 -2
- package/src/app/social/user-event/notification/user-event-notification.component.d.ts +0 -25
- package/src/app/social/user-event/notification/user-event-notification.list.d.ts +0 -20
- package/src/app/social/user-event/user-event.module.d.ts +0 -2
|
@@ -241,64 +241,6 @@ function changeCaseToUnderscore(value) {
|
|
|
241
241
|
function removeDiacritics(text) {
|
|
242
242
|
return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
243
243
|
}
|
|
244
|
-
function suggestFromArray(items, value, opts) {
|
|
245
|
-
if (isNotNil(value) && typeof value === 'object')
|
|
246
|
-
return { data: [value] };
|
|
247
|
-
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
248
|
-
const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
|
|
249
|
-
if (!items) {
|
|
250
|
-
return { data: [], total: 0 };
|
|
251
|
-
}
|
|
252
|
-
// Filter items
|
|
253
|
-
let filteredItems = items;
|
|
254
|
-
if (isNotNilOrBlank(value)) {
|
|
255
|
-
// If wildcard, search using regexp
|
|
256
|
-
if (value.indexOf('*') !== -1) {
|
|
257
|
-
value = value.replace(/[*]+/g, '.*');
|
|
258
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
259
|
-
}
|
|
260
|
-
// Else (no wildcard), search using startsWith
|
|
261
|
-
else {
|
|
262
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
// Exclude ids
|
|
266
|
-
if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
|
|
267
|
-
filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
|
|
268
|
-
}
|
|
269
|
-
// Sort
|
|
270
|
-
if (!opts || opts.skipSort !== true) {
|
|
271
|
-
// Make to copy input items, before sorting (if not yet already done)
|
|
272
|
-
if (filteredItems === items)
|
|
273
|
-
filteredItems = filteredItems.slice();
|
|
274
|
-
// Sort by keys
|
|
275
|
-
filteredItems.sort(propertiesPathComparator(keys));
|
|
276
|
-
}
|
|
277
|
-
const total = filteredItems.length || 0;
|
|
278
|
-
// Pagination (truncate if need)
|
|
279
|
-
let pageData = filteredItems;
|
|
280
|
-
if (opts) {
|
|
281
|
-
if ((opts.offset || 0) > 0) {
|
|
282
|
-
pageData = pageData.slice(opts.offset);
|
|
283
|
-
}
|
|
284
|
-
if (isNotNil(opts.size) && pageData.length > opts.size) {
|
|
285
|
-
pageData = pageData.slice(0, opts.size);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
const result = {
|
|
289
|
-
data: pageData,
|
|
290
|
-
total
|
|
291
|
-
};
|
|
292
|
-
// Add fetch more capability, if total was fetched
|
|
293
|
-
const nextOffset = (opts && opts.offset || 0) + pageData.length;
|
|
294
|
-
if (nextOffset < total) {
|
|
295
|
-
result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
|
|
296
|
-
return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
|
|
297
|
-
}));
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
return result;
|
|
301
|
-
}
|
|
302
244
|
function suggestFromStringArray(values, value, options) {
|
|
303
245
|
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
304
246
|
if (isNilOrBlank(value))
|
|
@@ -843,11 +785,11 @@ function chainPromises(defers) {
|
|
|
843
785
|
}, null);
|
|
844
786
|
}
|
|
845
787
|
function firstTrue(obs) {
|
|
846
|
-
return obs.pipe(first(
|
|
788
|
+
return obs.pipe(first(value => value === true), map(_ => { }) // Convert to void
|
|
847
789
|
);
|
|
848
790
|
}
|
|
849
791
|
function firstFalse(obs) {
|
|
850
|
-
return obs.pipe(first(
|
|
792
|
+
return obs.pipe(first(value => value === false), map(_ => { }) // Convert to void
|
|
851
793
|
);
|
|
852
794
|
}
|
|
853
795
|
/**
|
|
@@ -879,12 +821,11 @@ function waitFor(predicate, opts) {
|
|
|
879
821
|
}
|
|
880
822
|
function waitForTrue(observable, opts) {
|
|
881
823
|
return __awaiter(this, void 0, void 0, function* () {
|
|
882
|
-
const firstTrueObservable = firstTrue(observable);
|
|
883
824
|
// Timeout (+ dueTime)
|
|
884
825
|
if (opts && opts.timeout > 0) {
|
|
885
826
|
const $timeout = timer(opts.timeout);
|
|
886
827
|
return merge(timer(opts.dueTime || 0)
|
|
887
|
-
.pipe(switchMap(() =>
|
|
828
|
+
.pipe(switchMap(() => firstTrue(observable)), takeUntil($timeout)), $timeout
|
|
888
829
|
.pipe(map(() => {
|
|
889
830
|
throw new Error(`Timeout ready() - after ${opts.timeout}ms`);
|
|
890
831
|
})))
|
|
@@ -893,10 +834,17 @@ function waitForTrue(observable, opts) {
|
|
|
893
834
|
// dueTime (without timeout)
|
|
894
835
|
if (opts && opts.dueTime > 0) {
|
|
895
836
|
return timer(opts.dueTime)
|
|
896
|
-
.pipe(switchMap(() =>
|
|
837
|
+
.pipe(switchMap(() => firstTrue(observable)))
|
|
897
838
|
.toPromise();
|
|
898
839
|
}
|
|
899
|
-
return
|
|
840
|
+
return firstTrue(observable).toPromise();
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
function waitForFalse(observable, opts) {
|
|
844
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
845
|
+
return waitForTrue(
|
|
846
|
+
// Inverse the logic
|
|
847
|
+
observable.pipe(map(v => v === false)), opts);
|
|
900
848
|
});
|
|
901
849
|
}
|
|
902
850
|
|
|
@@ -1100,6 +1048,65 @@ const isMobile = (win) => {
|
|
|
1100
1048
|
return _cache.mobile;
|
|
1101
1049
|
};
|
|
1102
1050
|
|
|
1051
|
+
function suggestFromArray(items, value, opts) {
|
|
1052
|
+
if (isNotNil(value) && typeof value === 'object')
|
|
1053
|
+
return { data: [value] };
|
|
1054
|
+
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
1055
|
+
const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
|
|
1056
|
+
if (!items) {
|
|
1057
|
+
return { data: [], total: 0 };
|
|
1058
|
+
}
|
|
1059
|
+
// Filter items
|
|
1060
|
+
let filteredItems = items;
|
|
1061
|
+
if (isNotNilOrBlank(value)) {
|
|
1062
|
+
// If wildcard, search using regexp
|
|
1063
|
+
if (value.indexOf('*') !== -1) {
|
|
1064
|
+
value = value.replace(/[*]+/g, '.*');
|
|
1065
|
+
filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1066
|
+
}
|
|
1067
|
+
// Else (no wildcard), search using startsWith
|
|
1068
|
+
else {
|
|
1069
|
+
filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
// Exclude ids
|
|
1073
|
+
if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
|
|
1074
|
+
filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
|
|
1075
|
+
}
|
|
1076
|
+
// Sort
|
|
1077
|
+
if (!opts || opts.skipSort !== true) {
|
|
1078
|
+
// Make to copy input items, before sorting (if not yet already done)
|
|
1079
|
+
if (filteredItems === items)
|
|
1080
|
+
filteredItems = filteredItems.slice();
|
|
1081
|
+
// Sort by keys
|
|
1082
|
+
filteredItems.sort(propertiesPathComparator(keys));
|
|
1083
|
+
}
|
|
1084
|
+
const total = filteredItems.length || 0;
|
|
1085
|
+
// Pagination (truncate if need)
|
|
1086
|
+
let pageData = filteredItems;
|
|
1087
|
+
if (opts) {
|
|
1088
|
+
if ((opts.offset || 0) > 0) {
|
|
1089
|
+
pageData = pageData.slice(opts.offset);
|
|
1090
|
+
}
|
|
1091
|
+
if (isNotNil(opts.size) && pageData.length > opts.size) {
|
|
1092
|
+
pageData = pageData.slice(0, opts.size);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
const result = {
|
|
1096
|
+
data: pageData,
|
|
1097
|
+
total
|
|
1098
|
+
};
|
|
1099
|
+
// Add fetch more capability, if total was fetched
|
|
1100
|
+
const nextOffset = (opts && opts.offset || 0) + pageData.length;
|
|
1101
|
+
if (nextOffset < total) {
|
|
1102
|
+
result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
|
|
1103
|
+
return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
|
|
1104
|
+
}));
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
return result;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1103
1110
|
class MatAutocompleteConfigHolder {
|
|
1104
1111
|
constructor(options) {
|
|
1105
1112
|
this.options = options;
|
|
@@ -1360,11 +1367,11 @@ class MatAutocompleteField {
|
|
|
1360
1367
|
// Search text (no distinctUntilChanged() because of the debounceTime() pipe)
|
|
1361
1368
|
this.formControl.valueChanges
|
|
1362
1369
|
.pipe(filter(value => this.enabled && isNotNilString(value)),
|
|
1363
|
-
// Mark as loading (to show loading spinner) -
|
|
1370
|
+
// Mark as loading (to show loading spinner) - as soon as possible, and before debounceTime
|
|
1364
1371
|
tap(_ => this.showLoadingSpinner && this.markAsLoading()),
|
|
1365
1372
|
// Filter if not enough character
|
|
1366
1373
|
filter(value => {
|
|
1367
|
-
if (value.length
|
|
1374
|
+
if (((value === null || value === void 0 ? void 0 : value.length) || 0) < this.suggestLengthThreshold) {
|
|
1368
1375
|
// Update display value, to enable the message "not enough characters"
|
|
1369
1376
|
this.displayValue = value;
|
|
1370
1377
|
return false;
|
|
@@ -2328,9 +2335,9 @@ class HighlightPipe {
|
|
|
2328
2335
|
const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
|
|
2329
2336
|
const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
|
|
2330
2337
|
if (index !== -1) {
|
|
2331
|
-
return value.
|
|
2332
|
-
'<b>' + value.
|
|
2333
|
-
value.
|
|
2338
|
+
return value.substring(0, index - 1) +
|
|
2339
|
+
'<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +
|
|
2340
|
+
value.substring(index + cleanedSearchText.length);
|
|
2334
2341
|
}
|
|
2335
2342
|
return value;
|
|
2336
2343
|
}
|
|
@@ -2728,60 +2735,50 @@ class IsNotNilOrBlankPipe {
|
|
|
2728
2735
|
return isNotNilOrBlank(value);
|
|
2729
2736
|
}
|
|
2730
2737
|
}
|
|
2731
|
-
IsNotNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
|
|
2732
2738
|
IsNotNilOrBlankPipe.decorators = [
|
|
2733
2739
|
{ type: Pipe, args: [{
|
|
2734
2740
|
name: 'isNotNilOrBlank'
|
|
2735
|
-
},] }
|
|
2736
|
-
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2741
|
+
},] }
|
|
2737
2742
|
];
|
|
2738
2743
|
class IsNilOrBlankPipe {
|
|
2739
2744
|
transform(value) {
|
|
2740
2745
|
return isNilOrBlank(value);
|
|
2741
2746
|
}
|
|
2742
2747
|
}
|
|
2743
|
-
IsNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
|
|
2744
2748
|
IsNilOrBlankPipe.decorators = [
|
|
2745
2749
|
{ type: Pipe, args: [{
|
|
2746
2750
|
name: 'isNilOrBlank'
|
|
2747
|
-
},] }
|
|
2748
|
-
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2751
|
+
},] }
|
|
2749
2752
|
];
|
|
2750
2753
|
class ToStringPipe {
|
|
2751
2754
|
transform(value) {
|
|
2752
2755
|
return (value !== null && value !== undefined) ? value.toString() : '';
|
|
2753
2756
|
}
|
|
2754
2757
|
}
|
|
2755
|
-
ToStringPipe.ɵprov = ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
|
|
2756
2758
|
ToStringPipe.decorators = [
|
|
2757
2759
|
{ type: Pipe, args: [{
|
|
2758
2760
|
name: 'toString'
|
|
2759
|
-
},] }
|
|
2760
|
-
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2761
|
+
},] }
|
|
2761
2762
|
];
|
|
2762
2763
|
class StrLengthPipe {
|
|
2763
2764
|
transform(value) {
|
|
2764
2765
|
return value && value.length || 0;
|
|
2765
2766
|
}
|
|
2766
2767
|
}
|
|
2767
|
-
StrLengthPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
|
|
2768
2768
|
StrLengthPipe.decorators = [
|
|
2769
2769
|
{ type: Pipe, args: [{
|
|
2770
2770
|
name: 'strLength'
|
|
2771
|
-
},] }
|
|
2772
|
-
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2771
|
+
},] }
|
|
2773
2772
|
];
|
|
2774
2773
|
class StrIncludesPipe {
|
|
2775
2774
|
transform(value, searchString, position) {
|
|
2776
2775
|
return (value === null || value === void 0 ? void 0 : value.includes(searchString, position)) || false;
|
|
2777
2776
|
}
|
|
2778
2777
|
}
|
|
2779
|
-
StrIncludesPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
|
|
2780
2778
|
StrIncludesPipe.decorators = [
|
|
2781
2779
|
{ type: Pipe, args: [{
|
|
2782
2780
|
name: 'strIncludes'
|
|
2783
|
-
},] }
|
|
2784
|
-
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2781
|
+
},] }
|
|
2785
2782
|
];
|
|
2786
2783
|
|
|
2787
2784
|
class TranslateContextService {
|
|
@@ -4203,7 +4200,7 @@ FormGetPipe.decorators = [
|
|
|
4203
4200
|
];
|
|
4204
4201
|
class FormGetControlPipe {
|
|
4205
4202
|
transform(form, path) {
|
|
4206
|
-
return (form && path && form.get(path) || form);
|
|
4203
|
+
return (form && isNotNil(path) && form.get(path) || form);
|
|
4207
4204
|
}
|
|
4208
4205
|
}
|
|
4209
4206
|
FormGetControlPipe.decorators = [
|
|
@@ -4232,8 +4229,7 @@ FormGetGroupPipe.decorators = [
|
|
|
4232
4229
|
},] }
|
|
4233
4230
|
];
|
|
4234
4231
|
class FormGetValuePipe {
|
|
4235
|
-
constructor(
|
|
4236
|
-
this.adapter = adapter;
|
|
4232
|
+
constructor(_ref) {
|
|
4237
4233
|
this._ref = _ref;
|
|
4238
4234
|
this.value = undefined;
|
|
4239
4235
|
this._lastControl = null;
|
|
@@ -4298,7 +4294,6 @@ FormGetValuePipe.decorators = [
|
|
|
4298
4294
|
},] }
|
|
4299
4295
|
];
|
|
4300
4296
|
FormGetValuePipe.ctorParameters = () => [
|
|
4301
|
-
{ type: FormErrorTranslator },
|
|
4302
4297
|
{ type: ChangeDetectorRef }
|
|
4303
4298
|
];
|
|
4304
4299
|
|
|
@@ -5169,7 +5164,8 @@ class MatDate {
|
|
|
5169
5164
|
set tabindex(value) {
|
|
5170
5165
|
if (this._tabindex !== value) {
|
|
5171
5166
|
this._tabindex = value;
|
|
5172
|
-
|
|
5167
|
+
if (!this._writing)
|
|
5168
|
+
this.updateTabIndex();
|
|
5173
5169
|
}
|
|
5174
5170
|
}
|
|
5175
5171
|
get tabindex() {
|
|
@@ -5528,7 +5524,8 @@ class MatDateTime {
|
|
|
5528
5524
|
set tabindex(value) {
|
|
5529
5525
|
if (this._tabindex !== value) {
|
|
5530
5526
|
this._tabindex = value;
|
|
5531
|
-
|
|
5527
|
+
if (!this._writing)
|
|
5528
|
+
this.updateTabIndex();
|
|
5532
5529
|
}
|
|
5533
5530
|
}
|
|
5534
5531
|
get tabindex() {
|
|
@@ -10707,7 +10704,7 @@ class LocalSettingsService extends StartableService {
|
|
|
10707
10704
|
}
|
|
10708
10705
|
get usageMode() {
|
|
10709
10706
|
var _a;
|
|
10710
|
-
if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.
|
|
10707
|
+
if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.usageMode)) {
|
|
10711
10708
|
console.warn("[settings] Accessing to property 'usageMode' BEFORE service started! Please use ready()");
|
|
10712
10709
|
return isCordova(window) ? 'FIELD' : 'DESK';
|
|
10713
10710
|
}
|
|
@@ -13307,7 +13304,8 @@ class GraphqlService extends StartableService {
|
|
|
13307
13304
|
console.debug('[graphql] Apply token authentication to headers');
|
|
13308
13305
|
this.connectionParams.authToken = token;
|
|
13309
13306
|
}
|
|
13310
|
-
|
|
13307
|
+
// Clean auth token
|
|
13308
|
+
else if (this.connectionParams.authToken) {
|
|
13311
13309
|
console.debug('[graphql] Remove token authentication from headers');
|
|
13312
13310
|
delete this.connectionParams.authToken;
|
|
13313
13311
|
// Clear cache
|
|
@@ -13319,7 +13317,8 @@ class GraphqlService extends StartableService {
|
|
|
13319
13317
|
console.debug('[graphql] Apply basic authentication to headers');
|
|
13320
13318
|
this.connectionParams.authBasic = basic;
|
|
13321
13319
|
}
|
|
13322
|
-
|
|
13320
|
+
// Clean auth basic
|
|
13321
|
+
else if (this.connectionParams.authBasic) {
|
|
13323
13322
|
console.debug('[graphql] Remove basic authentication from headers');
|
|
13324
13323
|
delete this.connectionParams.authBasic;
|
|
13325
13324
|
// Clear cache
|
|
@@ -17425,12 +17424,12 @@ class FormFieldValuesHolder {
|
|
|
17425
17424
|
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
|
17426
17425
|
class AppForm {
|
|
17427
17426
|
constructor(injector, form) {
|
|
17428
|
-
this.
|
|
17427
|
+
this._subscription = new Subscription();
|
|
17429
17428
|
this._enable = false;
|
|
17430
|
-
this._$ready = new BehaviorSubject(false);
|
|
17431
|
-
this._$loading = new BehaviorSubject(true);
|
|
17432
17429
|
this.i18nFieldPrefix = null;
|
|
17433
|
-
this.
|
|
17430
|
+
this.readySubject = new BehaviorSubject(false);
|
|
17431
|
+
this.loadingSubject = new BehaviorSubject(true);
|
|
17432
|
+
this.errorSubject = new BehaviorSubject(undefined);
|
|
17434
17433
|
this.debug = false;
|
|
17435
17434
|
this.onCancel = new EventEmitter();
|
|
17436
17435
|
this.onSubmit = new EventEmitter();
|
|
@@ -17448,16 +17447,37 @@ class AppForm {
|
|
|
17448
17447
|
* @deprecated
|
|
17449
17448
|
*/
|
|
17450
17449
|
set _loading(value) {
|
|
17451
|
-
this.
|
|
17450
|
+
this.loadingSubject.next(value);
|
|
17452
17451
|
}
|
|
17453
17452
|
/**
|
|
17454
17453
|
* @deprecated
|
|
17455
17454
|
*/
|
|
17456
17455
|
get _loading() {
|
|
17457
|
-
return this.
|
|
17456
|
+
return this.loadingSubject.value;
|
|
17457
|
+
}
|
|
17458
|
+
/**
|
|
17459
|
+
* @deprecated
|
|
17460
|
+
*/
|
|
17461
|
+
get _$ready() {
|
|
17462
|
+
return this.readySubject;
|
|
17463
|
+
}
|
|
17464
|
+
/**
|
|
17465
|
+
* @deprecated
|
|
17466
|
+
*/
|
|
17467
|
+
get _$loading() {
|
|
17468
|
+
return this.loadingSubject;
|
|
17469
|
+
}
|
|
17470
|
+
get error() {
|
|
17471
|
+
return this.errorSubject.value;
|
|
17472
|
+
}
|
|
17473
|
+
set error(error) {
|
|
17474
|
+
this.setError(error);
|
|
17458
17475
|
}
|
|
17459
17476
|
get loading() {
|
|
17460
|
-
return this.
|
|
17477
|
+
return this.loadingSubject.value;
|
|
17478
|
+
}
|
|
17479
|
+
get loaded() {
|
|
17480
|
+
return !this.loadingSubject.value;
|
|
17461
17481
|
}
|
|
17462
17482
|
get value() {
|
|
17463
17483
|
return this.form.value;
|
|
@@ -17466,7 +17486,8 @@ class AppForm {
|
|
|
17466
17486
|
this.setValue(data);
|
|
17467
17487
|
}
|
|
17468
17488
|
get dirty() {
|
|
17469
|
-
|
|
17489
|
+
var _a;
|
|
17490
|
+
return ((_a = this.form) === null || _a === void 0 ? void 0 : _a.dirty) || false;
|
|
17470
17491
|
}
|
|
17471
17492
|
get invalid() {
|
|
17472
17493
|
return !this.form || this.form.invalid;
|
|
@@ -17475,7 +17496,8 @@ class AppForm {
|
|
|
17475
17496
|
return !this.form || (this.form.dirty && this.form.pending);
|
|
17476
17497
|
}
|
|
17477
17498
|
get valid() {
|
|
17478
|
-
|
|
17499
|
+
var _a;
|
|
17500
|
+
return ((_a = this.form) === null || _a === void 0 ? void 0 : _a.valid) || false;
|
|
17479
17501
|
}
|
|
17480
17502
|
get empty() {
|
|
17481
17503
|
return !this.form || (!this.form.dirty && !this.form.touched);
|
|
@@ -17521,17 +17543,16 @@ class AppForm {
|
|
|
17521
17543
|
}
|
|
17522
17544
|
ngOnDestroy() {
|
|
17523
17545
|
this._subscription.unsubscribe();
|
|
17524
|
-
this.
|
|
17546
|
+
this.readySubject.unsubscribe();
|
|
17547
|
+
this.loadingSubject.unsubscribe();
|
|
17548
|
+
this.errorSubject.unsubscribe();
|
|
17525
17549
|
this.onCancel.unsubscribe();
|
|
17526
|
-
this.onSubmit.complete();
|
|
17527
17550
|
this.onSubmit.unsubscribe();
|
|
17528
|
-
this._$ready.complete();
|
|
17529
|
-
this._$ready.unsubscribe();
|
|
17530
|
-
this._$loading.complete();
|
|
17531
|
-
this._$loading.unsubscribe();
|
|
17532
17551
|
}
|
|
17533
17552
|
cancel() {
|
|
17534
|
-
this
|
|
17553
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17554
|
+
this.onCancel.emit();
|
|
17555
|
+
});
|
|
17535
17556
|
}
|
|
17536
17557
|
/**
|
|
17537
17558
|
*
|
|
@@ -17626,22 +17647,14 @@ class AppForm {
|
|
|
17626
17647
|
this.markForCheck();
|
|
17627
17648
|
}
|
|
17628
17649
|
markAsLoading(opts) {
|
|
17629
|
-
|
|
17630
|
-
this._$loading.next(true);
|
|
17631
|
-
if (!opts || opts.emitEvent !== false)
|
|
17632
|
-
this.markForCheck();
|
|
17633
|
-
}
|
|
17650
|
+
this.setLoading(true, opts);
|
|
17634
17651
|
}
|
|
17635
17652
|
markAsLoaded(opts) {
|
|
17636
|
-
|
|
17637
|
-
this._$loading.next(false);
|
|
17638
|
-
if (!opts || opts.emitEvent !== false)
|
|
17639
|
-
this.markForCheck();
|
|
17640
|
-
}
|
|
17653
|
+
this.setLoading(false, opts);
|
|
17641
17654
|
}
|
|
17642
17655
|
markAsReady(opts) {
|
|
17643
|
-
if (this.
|
|
17644
|
-
this.
|
|
17656
|
+
if (this.readySubject.value !== true) {
|
|
17657
|
+
this.readySubject.next(true);
|
|
17645
17658
|
// If subclasses implements OnReady
|
|
17646
17659
|
if (typeof this['ngOnReady'] === 'function') {
|
|
17647
17660
|
this.ngOnReady();
|
|
@@ -17653,16 +17666,18 @@ class AppForm {
|
|
|
17653
17666
|
* @param opts
|
|
17654
17667
|
*/
|
|
17655
17668
|
ready(opts) {
|
|
17656
|
-
|
|
17669
|
+
if (this.readySubject.value)
|
|
17670
|
+
return Promise.resolve();
|
|
17671
|
+
return waitForTrue(this.readySubject, opts);
|
|
17657
17672
|
}
|
|
17658
17673
|
/**
|
|
17659
|
-
* Wait form is
|
|
17674
|
+
* Wait form is not busy (=loaded)
|
|
17660
17675
|
* @param opts
|
|
17661
17676
|
*/
|
|
17662
17677
|
waitIdle(opts) {
|
|
17663
|
-
|
|
17664
|
-
return
|
|
17665
|
-
|
|
17678
|
+
if (!this.loadingSubject.value)
|
|
17679
|
+
return Promise.resolve();
|
|
17680
|
+
return waitForFalse(this.loadingSubject, opts);
|
|
17666
17681
|
}
|
|
17667
17682
|
updateValueAndValidity(opts) {
|
|
17668
17683
|
AppFormUtils.updateValueAndValidity(this.form, opts);
|
|
@@ -17692,10 +17707,27 @@ class AppForm {
|
|
|
17692
17707
|
registerAutocompleteField(fieldName, opts) {
|
|
17693
17708
|
return this.autocompleteHelper.add(fieldName, opts);
|
|
17694
17709
|
}
|
|
17710
|
+
setError(value, opts) {
|
|
17711
|
+
if (this.errorSubject.value !== value) {
|
|
17712
|
+
this.errorSubject.next(value);
|
|
17713
|
+
if (!opts || opts.emitEvent !== false) {
|
|
17714
|
+
this.markForCheck();
|
|
17715
|
+
}
|
|
17716
|
+
}
|
|
17717
|
+
}
|
|
17695
17718
|
markForCheck() {
|
|
17696
17719
|
// Should be overwritten by subclasses
|
|
17697
17720
|
console.warn('markForCheck() has been called, but is not overwritten by component ' + this.constructor.name);
|
|
17698
17721
|
}
|
|
17722
|
+
/* -- private function -- */
|
|
17723
|
+
setLoading(value, opts) {
|
|
17724
|
+
if (this.loadingSubject.value !== value) {
|
|
17725
|
+
this.loadingSubject.next(value);
|
|
17726
|
+
if (!opts || opts.emitEvent !== false) {
|
|
17727
|
+
this.markForCheck();
|
|
17728
|
+
}
|
|
17729
|
+
}
|
|
17730
|
+
}
|
|
17699
17731
|
}
|
|
17700
17732
|
AppForm.decorators = [
|
|
17701
17733
|
{ type: Directive }
|
|
@@ -18213,6 +18245,18 @@ class InMemoryEntitiesService extends EntitiesService {
|
|
|
18213
18245
|
return this._equalsFn(d1, d2);
|
|
18214
18246
|
return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
|
|
18215
18247
|
}
|
|
18248
|
+
/**
|
|
18249
|
+
* Count data stored by the service (without hidden data).
|
|
18250
|
+
* @param opts
|
|
18251
|
+
*/
|
|
18252
|
+
get count() {
|
|
18253
|
+
var _a;
|
|
18254
|
+
return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
|
|
18255
|
+
}
|
|
18256
|
+
get hiddenCount() {
|
|
18257
|
+
var _a;
|
|
18258
|
+
return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
18259
|
+
}
|
|
18216
18260
|
/* -- protected methods -- */
|
|
18217
18261
|
filter(data, _filter, hiddenData) {
|
|
18218
18262
|
// if filter is DataFilter instance, use its test function
|
|
@@ -18766,7 +18810,9 @@ class AuthForm extends AppForm {
|
|
|
18766
18810
|
}
|
|
18767
18811
|
}
|
|
18768
18812
|
cancel() {
|
|
18769
|
-
this
|
|
18813
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18814
|
+
this.onCancel.emit();
|
|
18815
|
+
});
|
|
18770
18816
|
}
|
|
18771
18817
|
doSubmit(event) {
|
|
18772
18818
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -19623,7 +19669,7 @@ class AccountPage extends AppForm {
|
|
|
19623
19669
|
cancel: { get: () => super.cancel }
|
|
19624
19670
|
});
|
|
19625
19671
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19626
|
-
_super.cancel.call(this);
|
|
19672
|
+
yield _super.cancel.call(this);
|
|
19627
19673
|
});
|
|
19628
19674
|
}
|
|
19629
19675
|
markForCheck() {
|
|
@@ -21431,7 +21477,7 @@ class MenuComponent {
|
|
|
21431
21477
|
MenuComponent.decorators = [
|
|
21432
21478
|
{ type: Component, args: [{
|
|
21433
21479
|
selector: 'app-menu',
|
|
21434
|
-
template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n
|
|
21480
|
+
template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\" @fadeInAnimation\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n\n <ion-list lines=\"none\">\n <ion-menu-toggle auto-hide=\"false\"\n [class.flex-spacer]=\"item.cssClass == 'flex-spacer'\"\n *ngFor=\"let item of $items | async\">\n\n <!-- link -->\n <ion-item *ngIf=\"!loading && item.path\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/')}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"!loading && item.action\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!loading && !item.path && !item.action\">\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item-divider>\n\n </ion-menu-toggle>\n </ion-list>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n",
|
|
21435
21481
|
animations: [fadeInAnimation],
|
|
21436
21482
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21437
21483
|
styles: ["ion-menu{--ion-item-background:transparent;--ion-item-divider-background:transparent;--ion-item-icon-color:var(--ion-color-primary-tint);--ion-item-text-color:var(--ion-color-primary-tint);--ion-item-background-selected:var(--ion-color-secondary100);--ion-item-text-color-selected:var(--ion-color-primary);--ion-item-icon-color-selected:var(--ion-color-primary);--ion-item-text-color-disable:var(--ion-color-medium);--ion-item-icon-color-disable:var(--ion-color-medium)}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:50%;background-color:var(--ion-color-secondary);border:1px solid var(--ion-color-primary);overflow:hidden!important;font-size:var(--avatar-size,60px)!important;line-height:var(--avatar-size,60px);height:var(--avatar-size,60px)!important;width:var(--avatar-size,60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size,60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu .scroll-content{margin-top:79px!important}ion-menu .has-user-header .scroll-content{margin-top:188px!important}ion-menu ion-content.has-profile-header{--offset-top:188px}ion-menu ion-content.no-profile-header{--offset-top:79px}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color:var(--ion-color-primary-tint);--ion-item-text-color:var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color:var(--ion-color-secondary-tint);--ion-item-text-color:var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color:var(--ion-color-tertiary-tint);--ion-item-text-color:var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color:var(--ion-color-danger-tint);--ion-item-text-color:var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color:var(--ion-color-medium-shade);--ion-item-text-color:var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color:var(--ion-color-dark-tint);--ion-item-text-color:var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item ion-icon,ion-menu ion-content ion-list ion-item mat-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-label,ion-menu ion-content ion-list ion-item ion-text{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover:var(--ion-item-background-selected)!important}ion-menu ion-content ion-list ion-item.selected ion-icon,ion-menu ion-content ion-list ion-item.selected mat-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-label,ion-menu ion-content ion-list ion-item.selected ion-text{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover:var(--ion-item-background-selected)!important;--ion-item-icon-color-selected:var(--ion-item-icon-color)!important;--ion-item-text-color-selected:var(--ion-item-text-color)!important}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width:40px}@media screen and (max-width:767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width:768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size,80px)!important;line-height:var(--avatar-size,80px);height:var(--avatar-size,80px)!important;width:var(--avatar-size,80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size,80px)}}"]
|
|
@@ -21495,14 +21541,13 @@ class AppIconComponent {
|
|
|
21495
21541
|
this.icon = value.icon;
|
|
21496
21542
|
this.matIcon = value.matIcon;
|
|
21497
21543
|
this.matSvgIcon = value.matSvgIcon;
|
|
21498
|
-
this.color = value.color;
|
|
21499
21544
|
}
|
|
21500
21545
|
;
|
|
21501
21546
|
}
|
|
21502
21547
|
AppIconComponent.decorators = [
|
|
21503
21548
|
{ type: Component, args: [{
|
|
21504
21549
|
selector: 'app-icon',
|
|
21505
|
-
template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n
|
|
21550
|
+
template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\">{{matIcon}}</mat-icon>\n</ng-template>\n\n"
|
|
21506
21551
|
},] }
|
|
21507
21552
|
];
|
|
21508
21553
|
AppIconComponent.propDecorators = {
|
|
@@ -21510,8 +21555,6 @@ AppIconComponent.propDecorators = {
|
|
|
21510
21555
|
matIcon: [{ type: Input }],
|
|
21511
21556
|
matSvgIcon: [{ type: Input }],
|
|
21512
21557
|
color: [{ type: Input }],
|
|
21513
|
-
height: [{ type: Input }],
|
|
21514
|
-
width: [{ type: Input }],
|
|
21515
21558
|
ref: [{ type: Input }]
|
|
21516
21559
|
};
|
|
21517
21560
|
|
|
@@ -22583,19 +22626,24 @@ class AppTable {
|
|
|
22583
22626
|
get error() {
|
|
22584
22627
|
return this.errorSubject.value;
|
|
22585
22628
|
}
|
|
22586
|
-
get error$() {
|
|
22587
|
-
return this.errorSubject.asObservable();
|
|
22588
|
-
}
|
|
22589
22629
|
/**
|
|
22590
22630
|
* @deprecated
|
|
22591
|
-
* @param error
|
|
22592
22631
|
*/
|
|
22632
|
+
get error$() {
|
|
22633
|
+
return this.errorSubject.asObservable();
|
|
22634
|
+
}
|
|
22593
22635
|
set error(error) {
|
|
22594
22636
|
this.setError(error);
|
|
22595
22637
|
}
|
|
22638
|
+
/**
|
|
22639
|
+
* @deprecated
|
|
22640
|
+
*/
|
|
22596
22641
|
get loading$() {
|
|
22597
22642
|
return this.loadingSubject.asObservable();
|
|
22598
22643
|
}
|
|
22644
|
+
/**
|
|
22645
|
+
* @deprecated
|
|
22646
|
+
*/
|
|
22599
22647
|
get saving$() {
|
|
22600
22648
|
return this.savingSubject.asObservable();
|
|
22601
22649
|
}
|
|
@@ -22718,17 +22766,15 @@ class AppTable {
|
|
|
22718
22766
|
if (this.savingSubject.value !== true) {
|
|
22719
22767
|
this.focusColumn = undefined; // unselect focus column
|
|
22720
22768
|
this.savingSubject.next(true);
|
|
22721
|
-
if (!opts || opts.emitEvent !== false)
|
|
22769
|
+
if (!opts || opts.emitEvent !== false)
|
|
22722
22770
|
this.markForCheck();
|
|
22723
|
-
}
|
|
22724
22771
|
}
|
|
22725
22772
|
}
|
|
22726
22773
|
markAsSaved(opts) {
|
|
22727
22774
|
if (this.savingSubject.value !== false) {
|
|
22728
22775
|
this.savingSubject.next(false);
|
|
22729
|
-
if (!opts || opts.emitEvent !== false)
|
|
22776
|
+
if (!opts || opts.emitEvent !== false)
|
|
22730
22777
|
this.markForCheck();
|
|
22731
|
-
}
|
|
22732
22778
|
}
|
|
22733
22779
|
}
|
|
22734
22780
|
markAsLoading(opts) {
|
|
@@ -23013,7 +23059,7 @@ class AppTable {
|
|
|
23013
23059
|
.then(() => this.editRowById(event, row.id, { focusColumn: this.lastUserColumn }));
|
|
23014
23060
|
return true;
|
|
23015
23061
|
}
|
|
23016
|
-
// Edit
|
|
23062
|
+
// Edit previous row
|
|
23017
23063
|
this.editRow(event, row, { focusColumn: this.lastUserColumn });
|
|
23018
23064
|
return true;
|
|
23019
23065
|
}
|
|
@@ -23036,8 +23082,7 @@ class AppTable {
|
|
|
23036
23082
|
if (id < 0)
|
|
23037
23083
|
return;
|
|
23038
23084
|
if (id >= this.visibleRowCount) {
|
|
23039
|
-
this.
|
|
23040
|
-
this.addRow(event);
|
|
23085
|
+
this.addRow(event, undefined, opts);
|
|
23041
23086
|
}
|
|
23042
23087
|
else {
|
|
23043
23088
|
const row = yield this.dataSource.getRow(id);
|
|
@@ -23110,7 +23155,7 @@ class AppTable {
|
|
|
23110
23155
|
this.cancelExistingRow(event, row, opts);
|
|
23111
23156
|
}
|
|
23112
23157
|
}
|
|
23113
|
-
addRow(event, insertAt) {
|
|
23158
|
+
addRow(event, insertAt, opts) {
|
|
23114
23159
|
if (this.debug)
|
|
23115
23160
|
console.debug('[table] Asking for new row...');
|
|
23116
23161
|
if (!this._enabled)
|
|
@@ -23125,7 +23170,7 @@ class AppTable {
|
|
|
23125
23170
|
return false;
|
|
23126
23171
|
}
|
|
23127
23172
|
// Add new row
|
|
23128
|
-
this.addRowToTable(insertAt);
|
|
23173
|
+
this.addRowToTable(insertAt, opts);
|
|
23129
23174
|
return true;
|
|
23130
23175
|
}
|
|
23131
23176
|
save(opts) {
|
|
@@ -23240,7 +23285,7 @@ class AppTable {
|
|
|
23240
23285
|
* @param event
|
|
23241
23286
|
* @param row
|
|
23242
23287
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23243
|
-
*
|
|
23288
|
+
* And to force deletion even if table is busy
|
|
23244
23289
|
*/
|
|
23245
23290
|
deleteRow(event, row, opts) {
|
|
23246
23291
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -23253,7 +23298,7 @@ class AppTable {
|
|
|
23253
23298
|
* @param event
|
|
23254
23299
|
* @param rows
|
|
23255
23300
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23256
|
-
*
|
|
23301
|
+
* And to force deletion even if table is busy
|
|
23257
23302
|
*/
|
|
23258
23303
|
deleteRows(event, rows, opts) {
|
|
23259
23304
|
var _a;
|
|
@@ -23266,8 +23311,8 @@ class AppTable {
|
|
|
23266
23311
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
23267
23312
|
if (!this._enabled || isEmptyArray(rows))
|
|
23268
23313
|
return 0; // Skip is disabled, or no rows to delete
|
|
23269
|
-
if (this.loading && (!opts || opts.
|
|
23270
|
-
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.
|
|
23314
|
+
if (this.loading && (!opts || opts.interactive !== false)) {
|
|
23315
|
+
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.interactive = false to force deletion');
|
|
23271
23316
|
return 0; // Skip if loading
|
|
23272
23317
|
}
|
|
23273
23318
|
// Make sure to keep newly created row
|
|
@@ -23404,15 +23449,11 @@ class AppTable {
|
|
|
23404
23449
|
moveRow(id, direction) {
|
|
23405
23450
|
this.dataSource.move(id, direction);
|
|
23406
23451
|
}
|
|
23407
|
-
ready() {
|
|
23408
|
-
return
|
|
23409
|
-
yield firstTruePromise(this.readySubject);
|
|
23410
|
-
});
|
|
23452
|
+
ready(opts) {
|
|
23453
|
+
return waitForTrue(this.readySubject, opts);
|
|
23411
23454
|
}
|
|
23412
23455
|
waitIdle(opts) {
|
|
23413
|
-
return
|
|
23414
|
-
yield firstFalsePromise(this.loadingSubject);
|
|
23415
|
-
});
|
|
23456
|
+
return waitForFalse(this.loadingSubject, opts);
|
|
23416
23457
|
}
|
|
23417
23458
|
openSelectColumnsModal(event) {
|
|
23418
23459
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -23790,9 +23831,10 @@ class AppTable {
|
|
|
23790
23831
|
//if (this.debug) console.debug("[table] id = " + id);
|
|
23791
23832
|
return id;
|
|
23792
23833
|
}
|
|
23793
|
-
addRowToTable(insertAt) {
|
|
23834
|
+
addRowToTable(insertAt, opts) {
|
|
23794
23835
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23795
23836
|
this.focusFirstColumn = true;
|
|
23837
|
+
this.focusColumn = (opts === null || opts === void 0 ? void 0 : opts.focusColumn) || this.firstUserColumn;
|
|
23796
23838
|
yield this._dataSource.asyncCreateNew(insertAt);
|
|
23797
23839
|
this.editedRow = this._dataSource.getRow(-1);
|
|
23798
23840
|
// Emit start editing event
|
|
@@ -24139,8 +24181,9 @@ class AppEditor {
|
|
|
24139
24181
|
this._subscription = new Subscription();
|
|
24140
24182
|
this._enabled = false;
|
|
24141
24183
|
this._dirty = false;
|
|
24142
|
-
this.
|
|
24143
|
-
this.
|
|
24184
|
+
this.readySubject = new BehaviorSubject(false);
|
|
24185
|
+
this.loadingSubject = new BehaviorSubject(true);
|
|
24186
|
+
this.errorSubject = new BehaviorSubject(undefined);
|
|
24144
24187
|
this.debug = false;
|
|
24145
24188
|
this.submitted = false;
|
|
24146
24189
|
this.toolbar = null;
|
|
@@ -24150,18 +24193,36 @@ class AppEditor {
|
|
|
24150
24193
|
* @deprecated
|
|
24151
24194
|
*/
|
|
24152
24195
|
set _loading(value) {
|
|
24153
|
-
this.
|
|
24196
|
+
this.loadingSubject.next(value);
|
|
24154
24197
|
}
|
|
24155
24198
|
/**
|
|
24156
24199
|
* @deprecated
|
|
24157
24200
|
*/
|
|
24158
24201
|
get _loading() {
|
|
24159
|
-
return this.
|
|
24202
|
+
return this.loadingSubject.value;
|
|
24160
24203
|
}
|
|
24161
|
-
|
|
24162
|
-
|
|
24204
|
+
/**
|
|
24205
|
+
* @deprecated
|
|
24206
|
+
*/
|
|
24207
|
+
get _$ready() {
|
|
24208
|
+
return this.readySubject;
|
|
24163
24209
|
}
|
|
24164
|
-
|
|
24210
|
+
/**
|
|
24211
|
+
* @deprecated
|
|
24212
|
+
*/
|
|
24213
|
+
get _$loading() {
|
|
24214
|
+
return this.loadingSubject;
|
|
24215
|
+
}
|
|
24216
|
+
get error() {
|
|
24217
|
+
return this.errorSubject.value;
|
|
24218
|
+
}
|
|
24219
|
+
set error(error) {
|
|
24220
|
+
this.setError(error);
|
|
24221
|
+
}
|
|
24222
|
+
get tables() {
|
|
24223
|
+
return this._children && this._children.filter(c => c instanceof AppTable);
|
|
24224
|
+
}
|
|
24225
|
+
get forms() {
|
|
24165
24226
|
return this._children && this._children.filter(c => c instanceof AppForm);
|
|
24166
24227
|
}
|
|
24167
24228
|
get dirty() {
|
|
@@ -24185,7 +24246,7 @@ class AppEditor {
|
|
|
24185
24246
|
}
|
|
24186
24247
|
get loading() {
|
|
24187
24248
|
var _a;
|
|
24188
|
-
return this.
|
|
24249
|
+
return this.loadingSubject.value || (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(c => c.enabled && c.loading)) !== -1) || false;
|
|
24189
24250
|
}
|
|
24190
24251
|
get enabled() {
|
|
24191
24252
|
return this._enabled;
|
|
@@ -24209,10 +24270,9 @@ class AppEditor {
|
|
|
24209
24270
|
}
|
|
24210
24271
|
ngOnDestroy() {
|
|
24211
24272
|
this._subscription.unsubscribe();
|
|
24212
|
-
this.
|
|
24213
|
-
this.
|
|
24214
|
-
this.
|
|
24215
|
-
this._$loading.unsubscribe();
|
|
24273
|
+
this.readySubject.unsubscribe();
|
|
24274
|
+
this.loadingSubject.unsubscribe();
|
|
24275
|
+
this.errorSubject.unsubscribe();
|
|
24216
24276
|
}
|
|
24217
24277
|
addChildForm(form) {
|
|
24218
24278
|
if (!form)
|
|
@@ -24281,16 +24341,16 @@ class AppEditor {
|
|
|
24281
24341
|
this.markForCheck();
|
|
24282
24342
|
}
|
|
24283
24343
|
markAsLoading(opts) {
|
|
24284
|
-
if (!this.
|
|
24285
|
-
this.
|
|
24344
|
+
if (!this.loadingSubject.value) {
|
|
24345
|
+
this.loadingSubject.next(true);
|
|
24286
24346
|
if (!opts || opts.emitEvent !== false)
|
|
24287
24347
|
this.markForCheck();
|
|
24288
24348
|
}
|
|
24289
24349
|
}
|
|
24290
24350
|
markAsLoaded(opts) {
|
|
24291
24351
|
var _a;
|
|
24292
|
-
if (this.
|
|
24293
|
-
this.
|
|
24352
|
+
if (this.loadingSubject.value) {
|
|
24353
|
+
this.loadingSubject.next(false);
|
|
24294
24354
|
if (!opts || opts.onlySelf !== true) {
|
|
24295
24355
|
// Emit to children forms
|
|
24296
24356
|
// Tables should be changed by parent
|
|
@@ -24304,15 +24364,17 @@ class AppEditor {
|
|
|
24304
24364
|
markAsReady(opts) {
|
|
24305
24365
|
var _a;
|
|
24306
24366
|
(_a = this._children) === null || _a === void 0 ? void 0 : _a.forEach(c => c.markAsReady(opts));
|
|
24307
|
-
this.
|
|
24367
|
+
this.readySubject.next(true);
|
|
24308
24368
|
}
|
|
24309
24369
|
ready(opts) {
|
|
24310
|
-
|
|
24311
|
-
return
|
|
24312
|
-
|
|
24370
|
+
if (this.readySubject.value)
|
|
24371
|
+
return Promise.resolve();
|
|
24372
|
+
return waitForTrue(this.readySubject, opts);
|
|
24313
24373
|
}
|
|
24314
24374
|
waitIdle(opts) {
|
|
24315
|
-
|
|
24375
|
+
if (!this.loadingSubject.value)
|
|
24376
|
+
return Promise.resolve();
|
|
24377
|
+
return waitForFalse(this.loadingSubject, opts);
|
|
24316
24378
|
}
|
|
24317
24379
|
cancel(event) {
|
|
24318
24380
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -24515,6 +24577,14 @@ class AppEditor {
|
|
|
24515
24577
|
console.warn(`${prefix} Unknown children sub-form: `, c);
|
|
24516
24578
|
}
|
|
24517
24579
|
}
|
|
24580
|
+
setError(value, opts) {
|
|
24581
|
+
if (this.errorSubject.value !== value) {
|
|
24582
|
+
this.errorSubject.next(value);
|
|
24583
|
+
if (!opts || opts.emitEvent !== false) {
|
|
24584
|
+
this.markForCheck();
|
|
24585
|
+
}
|
|
24586
|
+
}
|
|
24587
|
+
}
|
|
24518
24588
|
markForCheck() {
|
|
24519
24589
|
// Should be override by subclasses, if change detection is Push
|
|
24520
24590
|
}
|
|
@@ -24579,6 +24649,8 @@ class AppTabEditor extends AppEditor {
|
|
|
24579
24649
|
ngOnDestroy() {
|
|
24580
24650
|
super.ngOnDestroy();
|
|
24581
24651
|
this.selectedTabIndexChange.complete();
|
|
24652
|
+
this.loadingSubject.unsubscribe();
|
|
24653
|
+
this.errorSubject.unsubscribe();
|
|
24582
24654
|
}
|
|
24583
24655
|
setSelectedTabIndex(value, opts) {
|
|
24584
24656
|
// Fix value
|
|
@@ -24601,6 +24673,10 @@ class AppTabEditor extends AppEditor {
|
|
|
24601
24673
|
this.markForCheck();
|
|
24602
24674
|
}
|
|
24603
24675
|
}
|
|
24676
|
+
realignInkBar() {
|
|
24677
|
+
var _a;
|
|
24678
|
+
(_a = this.tabGroup) === null || _a === void 0 ? void 0 : _a.realignInkBar();
|
|
24679
|
+
}
|
|
24604
24680
|
onTabChange(event, queryTabIndexParamName) {
|
|
24605
24681
|
queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;
|
|
24606
24682
|
if (!queryTabIndexParamName || !this.route)
|
|
@@ -24670,6 +24746,16 @@ class AppTabEditor extends AppEditor {
|
|
|
24670
24746
|
yield _super.unload.call(this, opts);
|
|
24671
24747
|
});
|
|
24672
24748
|
}
|
|
24749
|
+
saveDirtyTables() {
|
|
24750
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24751
|
+
// Save all dirty tables
|
|
24752
|
+
const results = yield Promise.all((this.tables || [])
|
|
24753
|
+
.filter(c => c.dirty)
|
|
24754
|
+
.map(c => c.save()));
|
|
24755
|
+
const saved = results.findIndex(result => result !== true) === -1;
|
|
24756
|
+
return saved;
|
|
24757
|
+
});
|
|
24758
|
+
}
|
|
24673
24759
|
}
|
|
24674
24760
|
AppTabEditor.decorators = [
|
|
24675
24761
|
{ type: Directive }
|
|
@@ -24698,7 +24784,7 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
24698
24784
|
super(injector.get(ActivatedRoute), injector.get(Router), injector.get(AlertController), injector.get(TranslateService), options);
|
|
24699
24785
|
this.dataType = dataType;
|
|
24700
24786
|
this.dataService = dataService;
|
|
24701
|
-
this.
|
|
24787
|
+
this.savingSubject = new BehaviorSubject(false);
|
|
24702
24788
|
this.$title = new Subject();
|
|
24703
24789
|
this.onUpdateView = new EventEmitter();
|
|
24704
24790
|
this.environement = injector.get(ENVIRONMENT);
|
|
@@ -24741,21 +24827,24 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
24741
24827
|
return isNil((_a = this.data) === null || _a === void 0 ? void 0 : _a.id);
|
|
24742
24828
|
}
|
|
24743
24829
|
get loading() {
|
|
24744
|
-
return this.
|
|
24830
|
+
return this.loadingSubject.value;
|
|
24831
|
+
}
|
|
24832
|
+
get saving() {
|
|
24833
|
+
return this.savingSubject.value;
|
|
24745
24834
|
}
|
|
24746
24835
|
get service() {
|
|
24747
24836
|
return this.dataService;
|
|
24748
24837
|
}
|
|
24749
24838
|
markAsSaving(opts) {
|
|
24750
|
-
if (
|
|
24751
|
-
this.
|
|
24839
|
+
if (this.savingSubject.value !== true) {
|
|
24840
|
+
this.savingSubject.next(true);
|
|
24752
24841
|
if (!opts || opts.emitEvent !== false)
|
|
24753
24842
|
this.markForCheck();
|
|
24754
24843
|
}
|
|
24755
24844
|
}
|
|
24756
24845
|
markAsSaved(opts) {
|
|
24757
|
-
if (this.
|
|
24758
|
-
this.
|
|
24846
|
+
if (this.savingSubject.value !== false) {
|
|
24847
|
+
this.savingSubject.next(false);
|
|
24759
24848
|
if (!opts || opts.emitEvent !== false)
|
|
24760
24849
|
this.markForCheck();
|
|
24761
24850
|
}
|
|
@@ -24784,11 +24873,12 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
24784
24873
|
this.$title.unsubscribe();
|
|
24785
24874
|
this.onUpdateView.complete();
|
|
24786
24875
|
this.onUpdateView.unsubscribe();
|
|
24876
|
+
this.savingSubject.unsubscribe();
|
|
24787
24877
|
}
|
|
24788
24878
|
waitIdle(opts) {
|
|
24789
24879
|
// Wait end of saving
|
|
24790
24880
|
if (this.saving)
|
|
24791
|
-
return
|
|
24881
|
+
return waitForFalse(this.savingSubject);
|
|
24792
24882
|
return super.waitIdle(opts);
|
|
24793
24883
|
}
|
|
24794
24884
|
/**
|
|
@@ -25033,9 +25123,10 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
25033
25123
|
yield this.waitWhilePending();
|
|
25034
25124
|
// If invalid
|
|
25035
25125
|
if (this.invalid) {
|
|
25036
|
-
this.markAllAsTouched();
|
|
25037
25126
|
this.logFormErrors();
|
|
25038
25127
|
this.openFirstInvalidTab();
|
|
25128
|
+
this.scrollToTop();
|
|
25129
|
+
this.markAllAsTouched();
|
|
25039
25130
|
this.submitted = true;
|
|
25040
25131
|
return false;
|
|
25041
25132
|
}
|
|
@@ -25046,6 +25137,10 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
25046
25137
|
try {
|
|
25047
25138
|
// Compute next tab index (if enable)
|
|
25048
25139
|
const nextTabIndex = this._autoOpenNextTab && isNil(this.previousDataId) && this.computeNextTabIndex();
|
|
25140
|
+
// Save all dirty tables
|
|
25141
|
+
const saved = yield this.saveDirtyTables();
|
|
25142
|
+
if (!saved)
|
|
25143
|
+
return false;
|
|
25049
25144
|
// Get data
|
|
25050
25145
|
const data = yield this.getValue();
|
|
25051
25146
|
this.disable();
|
|
@@ -25159,7 +25254,7 @@ class AppEntityEditor extends AppTabEditor {
|
|
|
25159
25254
|
this.registerForms();
|
|
25160
25255
|
this._dirty = false;
|
|
25161
25256
|
this.data = null;
|
|
25162
|
-
this.
|
|
25257
|
+
this.savingSubject.next(false);
|
|
25163
25258
|
});
|
|
25164
25259
|
}
|
|
25165
25260
|
goBack(event) {
|
|
@@ -25369,7 +25464,7 @@ class AppEntityEditorModal extends AppTabEditor {
|
|
|
25369
25464
|
constructor(injector, dataType, options) {
|
|
25370
25465
|
super(null, injector.get(Router), injector.get(AlertController), injector.get(TranslateService), options);
|
|
25371
25466
|
this.dataType = dataType;
|
|
25372
|
-
this.
|
|
25467
|
+
this.savingSubject = new BehaviorSubject(false);
|
|
25373
25468
|
this.$title = new Subject();
|
|
25374
25469
|
this.i18nSuffix = null;
|
|
25375
25470
|
this.environement = injector.get(ENVIRONMENT);
|
|
@@ -25405,16 +25500,19 @@ class AppEntityEditorModal extends AppTabEditor {
|
|
|
25405
25500
|
get isOnFieldMode() {
|
|
25406
25501
|
return this.settings.isOnFieldMode(this._usageMode);
|
|
25407
25502
|
}
|
|
25503
|
+
get saving() {
|
|
25504
|
+
return this.savingSubject.value;
|
|
25505
|
+
}
|
|
25408
25506
|
markAsSaving(opts) {
|
|
25409
|
-
if (
|
|
25410
|
-
this.
|
|
25507
|
+
if (this.savingSubject.value !== true) {
|
|
25508
|
+
this.savingSubject.next(true);
|
|
25411
25509
|
if (!opts || opts.emitEvent !== false)
|
|
25412
25510
|
this.markForCheck();
|
|
25413
25511
|
}
|
|
25414
25512
|
}
|
|
25415
25513
|
markAsSaved(opts) {
|
|
25416
|
-
if (this.
|
|
25417
|
-
this.
|
|
25514
|
+
if (this.savingSubject.value !== false) {
|
|
25515
|
+
this.savingSubject.next(false);
|
|
25418
25516
|
if (!opts || opts.emitEvent !== false)
|
|
25419
25517
|
this.markForCheck();
|
|
25420
25518
|
}
|
|
@@ -25458,11 +25556,12 @@ class AppEntityEditorModal extends AppTabEditor {
|
|
|
25458
25556
|
super.ngOnDestroy();
|
|
25459
25557
|
this.$title.complete();
|
|
25460
25558
|
this.$title.unsubscribe();
|
|
25559
|
+
this.savingSubject.unsubscribe();
|
|
25461
25560
|
}
|
|
25462
25561
|
waitIdle(opts) {
|
|
25463
25562
|
// Wait end of saving
|
|
25464
25563
|
if (this.saving)
|
|
25465
|
-
return
|
|
25564
|
+
return waitForFalse(this.savingSubject);
|
|
25466
25565
|
return super.waitIdle(opts);
|
|
25467
25566
|
}
|
|
25468
25567
|
load() {
|
|
@@ -25568,9 +25667,9 @@ class AppEntityEditorModal extends AppTabEditor {
|
|
|
25568
25667
|
if (this.invalid) {
|
|
25569
25668
|
this.logFormErrors();
|
|
25570
25669
|
this.setError('COMMON.FORM.HAS_ERROR');
|
|
25571
|
-
this.markAllAsTouched();
|
|
25572
25670
|
this.openFirstInvalidTab();
|
|
25573
25671
|
this.scrollToTop();
|
|
25672
|
+
this.markAllAsTouched();
|
|
25574
25673
|
this.submitted = true;
|
|
25575
25674
|
return false;
|
|
25576
25675
|
}
|
|
@@ -25580,13 +25679,14 @@ class AppEntityEditorModal extends AppTabEditor {
|
|
|
25580
25679
|
console.debug(this._logPrefix + 'Saving data...');
|
|
25581
25680
|
try {
|
|
25582
25681
|
// Save all dirty tables
|
|
25583
|
-
const saved =
|
|
25584
|
-
|
|
25585
|
-
|
|
25586
|
-
|
|
25682
|
+
const saved = yield this.saveDirtyTables();
|
|
25683
|
+
if (!saved)
|
|
25684
|
+
return false;
|
|
25685
|
+
// Fill data
|
|
25587
25686
|
this.data = yield this.getValue();
|
|
25687
|
+
// Mark as submitted
|
|
25588
25688
|
this.submitted = true;
|
|
25589
|
-
return
|
|
25689
|
+
return true;
|
|
25590
25690
|
}
|
|
25591
25691
|
catch (err) {
|
|
25592
25692
|
this.submitted = true;
|
|
@@ -25823,10 +25923,7 @@ AppInMemoryTable.propDecorators = {
|
|
|
25823
25923
|
const SocialErrorCodes = {
|
|
25824
25924
|
LOAD_USER_EVENTS_ERROR: 50000,
|
|
25825
25925
|
SAVE_USER_EVENT_ERROR: 50001,
|
|
25826
|
-
|
|
25827
|
-
SEND_MESSAGE_ERROR: 50003,
|
|
25828
|
-
SUBSCRIBE_USER_EVENTS_ERROR: 50005,
|
|
25829
|
-
SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
|
|
25926
|
+
SEND_MESSAGE_ERROR: 50003
|
|
25830
25927
|
};
|
|
25831
25928
|
|
|
25832
25929
|
var UserEvent_1;
|
|
@@ -25841,23 +25938,16 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25841
25938
|
}
|
|
25842
25939
|
asObject(opts) {
|
|
25843
25940
|
const target = super.asObject(opts);
|
|
25844
|
-
target.creationDate = toDateISOString(this.creationDate);
|
|
25845
|
-
target.readDate = toDateISOString(this.readDate);
|
|
25846
25941
|
// Serialize content
|
|
25847
25942
|
if (typeof target.content === 'object') {
|
|
25848
25943
|
target.content = JSON.stringify(target.content);
|
|
25849
25944
|
}
|
|
25850
|
-
delete target.avatar;
|
|
25851
|
-
delete target.avatarIcon;
|
|
25852
|
-
delete target.icon;
|
|
25853
|
-
delete target.actions;
|
|
25854
25945
|
return target;
|
|
25855
25946
|
}
|
|
25856
25947
|
fromObject(source) {
|
|
25857
25948
|
Object.assign(this, source); // Copy all properties
|
|
25858
25949
|
super.fromObject(source);
|
|
25859
25950
|
this.creationDate = fromDateISOString(source.creationDate);
|
|
25860
|
-
this.readDate = fromDateISOString(source.readDate);
|
|
25861
25951
|
try {
|
|
25862
25952
|
// Deserialize content
|
|
25863
25953
|
if (typeof source.content === 'string' && source.content.startsWith('{')) {
|
|
@@ -25876,52 +25966,6 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25876
25966
|
UserEvent = UserEvent_1 = __decorate([
|
|
25877
25967
|
EntityClass({ typename: 'UserEventVO' })
|
|
25878
25968
|
], UserEvent);
|
|
25879
|
-
// @dynamic
|
|
25880
|
-
let UserEventFilter = class UserEventFilter extends EntityFilter {
|
|
25881
|
-
constructor() {
|
|
25882
|
-
super(...arguments);
|
|
25883
|
-
this.types = [];
|
|
25884
|
-
this.levels = [];
|
|
25885
|
-
this.issuers = [];
|
|
25886
|
-
this.recipients = [];
|
|
25887
|
-
this.startDate = null;
|
|
25888
|
-
this.excludeRead = false;
|
|
25889
|
-
}
|
|
25890
|
-
fromObject(source, opts) {
|
|
25891
|
-
super.fromObject(source, opts);
|
|
25892
|
-
this.types = source.types || [];
|
|
25893
|
-
this.levels = source.levels || [];
|
|
25894
|
-
this.issuers = source.issuers || [];
|
|
25895
|
-
this.recipients = source.recipients || [];
|
|
25896
|
-
this.startDate = fromDateISOString(source.startDate);
|
|
25897
|
-
this.excludeRead = source.excludeRead || false;
|
|
25898
|
-
}
|
|
25899
|
-
buildFilter() {
|
|
25900
|
-
const filterFns = super.buildFilter();
|
|
25901
|
-
if (isNotEmptyArray(this.types)) {
|
|
25902
|
-
filterFns.push(t => this.types.includes(t.type));
|
|
25903
|
-
}
|
|
25904
|
-
if (isNotEmptyArray(this.levels)) {
|
|
25905
|
-
filterFns.push(t => this.levels.includes(t.level));
|
|
25906
|
-
}
|
|
25907
|
-
if (isNotEmptyArray(this.issuers)) {
|
|
25908
|
-
filterFns.push(t => this.issuers.includes(t.issuer));
|
|
25909
|
-
}
|
|
25910
|
-
if (isNotEmptyArray(this.recipients)) {
|
|
25911
|
-
filterFns.push(t => this.recipients.includes(t.recipient));
|
|
25912
|
-
}
|
|
25913
|
-
if (isNotNil(this.startDate)) {
|
|
25914
|
-
filterFns.push(t => this.startDate.isSameOrBefore(t.creationDate));
|
|
25915
|
-
}
|
|
25916
|
-
if (this.excludeRead === true) {
|
|
25917
|
-
filterFns.push(t => isNil(t.readSignature)); // todo or t.signature ?
|
|
25918
|
-
}
|
|
25919
|
-
return filterFns;
|
|
25920
|
-
}
|
|
25921
|
-
};
|
|
25922
|
-
UserEventFilter = __decorate([
|
|
25923
|
-
EntityClass({ typename: 'UserEventFilterVO' })
|
|
25924
|
-
], UserEventFilter);
|
|
25925
25969
|
|
|
25926
25970
|
const UserEventFragments = {
|
|
25927
25971
|
userEvent: gql `fragment UserEventFragment on UserEventVO {
|
|
@@ -25949,190 +25993,134 @@ const UserEventFragments = {
|
|
|
25949
25993
|
}`
|
|
25950
25994
|
};
|
|
25951
25995
|
|
|
25952
|
-
|
|
25953
|
-
|
|
25954
|
-
|
|
25955
|
-
|
|
25996
|
+
// @dynamic
|
|
25997
|
+
let UserEventFilter = class UserEventFilter extends EntityFilter {
|
|
25998
|
+
constructor() {
|
|
25999
|
+
super(...arguments);
|
|
26000
|
+
this.issuer = null;
|
|
26001
|
+
this.recipient = null;
|
|
26002
|
+
}
|
|
26003
|
+
fromObject(source, opts) {
|
|
26004
|
+
super.fromObject(source, opts);
|
|
26005
|
+
this.issuer = source.issuer;
|
|
26006
|
+
this.recipient = source.recipient;
|
|
26007
|
+
}
|
|
26008
|
+
buildFilter() {
|
|
26009
|
+
const filterFns = super.buildFilter();
|
|
26010
|
+
// issuer
|
|
26011
|
+
if (this.issuer) {
|
|
26012
|
+
filterFns.push(t => (t.issuer === this.issuer));
|
|
26013
|
+
}
|
|
26014
|
+
if (this.recipient) {
|
|
26015
|
+
filterFns.push(t => (t.recipient === this.recipient));
|
|
26016
|
+
}
|
|
26017
|
+
return filterFns;
|
|
26018
|
+
}
|
|
26019
|
+
};
|
|
26020
|
+
UserEventFilter = __decorate([
|
|
26021
|
+
EntityClass({ typename: 'UserEventFilterVO' })
|
|
26022
|
+
], UserEventFilter);
|
|
26023
|
+
const SaveQuery = gql `
|
|
26024
|
+
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26025
|
+
data: saveUserEvent(userEvent: $data){
|
|
26026
|
+
...UserEventFragment
|
|
26027
|
+
}
|
|
26028
|
+
}
|
|
26029
|
+
${UserEventFragments.userEvent}
|
|
26030
|
+
`;
|
|
26031
|
+
const LoadAllQuery = gql `
|
|
26032
|
+
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26033
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26034
|
+
...LightUserEventFragment
|
|
26035
|
+
}
|
|
26036
|
+
}
|
|
26037
|
+
${UserEventFragments.lightUserEvent}
|
|
26038
|
+
`;
|
|
26039
|
+
const DeleteByIdsMutation = gql `
|
|
26040
|
+
mutation DeleteUserEvents($ids:[Int]){
|
|
26041
|
+
deleteUserEvents(ids: $ids)
|
|
26042
|
+
}
|
|
26043
|
+
`;
|
|
26044
|
+
const LoadAllWithContentQuery = gql `
|
|
26045
|
+
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26046
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26047
|
+
...UserEventFragment
|
|
26048
|
+
}
|
|
26049
|
+
}
|
|
26050
|
+
${UserEventFragments.userEvent}
|
|
26051
|
+
`;
|
|
26052
|
+
class UserEventService extends BaseGraphqlService {
|
|
26053
|
+
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
25956
26054
|
super(graphql, environment);
|
|
25957
26055
|
this.graphql = graphql;
|
|
25958
26056
|
this.accountService = accountService;
|
|
25959
26057
|
this.network = network;
|
|
25960
26058
|
this.translate = translate;
|
|
25961
|
-
this.
|
|
25962
|
-
this.mutations = mutations;
|
|
25963
|
-
this.subscriptions = subscriptions;
|
|
26059
|
+
this.toastController = toastController;
|
|
25964
26060
|
this.environment = environment;
|
|
25965
|
-
this.
|
|
25966
|
-
this._subscriptions = new Subscription();
|
|
25967
|
-
this.listeners = [];
|
|
25968
|
-
this._logPrefix = '[user-event-service] ';
|
|
26061
|
+
this._userEventActions = [];
|
|
25969
26062
|
// For DEV only
|
|
25970
|
-
this._debug =
|
|
25971
|
-
// listen login/logout
|
|
25972
|
-
this._subscriptions.add(accountService.onLogin.subscribe(() => __awaiter(this, void 0, void 0, function* () {
|
|
25973
|
-
const count = yield this.count(this.defaultFilter());
|
|
25974
|
-
if (count && this._debug) {
|
|
25975
|
-
console.debug(`${this._logPrefix}Received ${count} unread notifications`);
|
|
25976
|
-
}
|
|
25977
|
-
this._count$.next(count);
|
|
25978
|
-
})));
|
|
25979
|
-
}
|
|
25980
|
-
get userEventCount() {
|
|
25981
|
-
return this._count$.asObservable();
|
|
25982
|
-
}
|
|
25983
|
-
ngOnDestroy() {
|
|
25984
|
-
this._subscriptions.unsubscribe();
|
|
26063
|
+
this._debug = environment && !environment.production;
|
|
25985
26064
|
}
|
|
26065
|
+
/**
|
|
26066
|
+
*
|
|
26067
|
+
* @param offset
|
|
26068
|
+
* @param size
|
|
26069
|
+
* @param sortBy
|
|
26070
|
+
* @param sortDirection
|
|
26071
|
+
* @param filter
|
|
26072
|
+
* @param options
|
|
26073
|
+
* @deprecated use watchPage() instead
|
|
26074
|
+
*/
|
|
25986
26075
|
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
25987
26076
|
return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
|
|
25988
26077
|
}
|
|
25989
26078
|
watchPage(page, filter, options) {
|
|
25990
|
-
var _a;
|
|
25991
26079
|
let now = this._debug && Date.now();
|
|
25992
26080
|
//if (this._debug)
|
|
25993
|
-
console.debug(
|
|
26081
|
+
console.debug('[user-event-service] Loading user events...', filter);
|
|
25994
26082
|
filter = this.asFilter(filter);
|
|
25995
26083
|
// Force recipient to current issuer, if not admin and not specified
|
|
25996
|
-
if (
|
|
25997
|
-
const recipient = this.
|
|
25998
|
-
if (
|
|
26084
|
+
if (isNilOrBlank(filter.recipient) || !this.accountService.isAdmin()) {
|
|
26085
|
+
const recipient = this.accountService.account.pubkey;
|
|
26086
|
+
if (recipient !== filter.recipient) {
|
|
25999
26087
|
console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
|
|
26000
|
-
filter.
|
|
26088
|
+
filter.recipient = recipient;
|
|
26001
26089
|
}
|
|
26002
26090
|
}
|
|
26003
|
-
const withContent =
|
|
26091
|
+
const withContent = options && options.withContent === true;
|
|
26004
26092
|
return this.mutableWatchQuery({
|
|
26005
26093
|
queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
|
|
26006
|
-
query: withContent ?
|
|
26094
|
+
query: withContent ? LoadAllWithContentQuery : LoadAllQuery,
|
|
26007
26095
|
variables: {
|
|
26008
|
-
page: Object.assign(Object.assign({ sortBy: '
|
|
26009
|
-
// @ts-ignore
|
|
26010
|
-
sortDirection: (page.sortDirection || 'desc').toUpperCase() }),
|
|
26096
|
+
page: Object.assign(Object.assign({ sortBy: 'updateDate' }, page), { sortDirection: (page.sortDirection || 'DESC').toUpperCase() }),
|
|
26011
26097
|
filter: filter && filter.asPodObject()
|
|
26012
26098
|
},
|
|
26013
26099
|
arrayFieldName: 'data',
|
|
26014
26100
|
error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
|
|
26015
|
-
fetchPolicy:
|
|
26101
|
+
fetchPolicy: options && options.fetchPolicy || undefined
|
|
26016
26102
|
})
|
|
26017
26103
|
.pipe(map(res => {
|
|
26018
|
-
const data =
|
|
26104
|
+
const data = res && (res.data || []).map(UserEvent.fromObject);
|
|
26019
26105
|
if (now) {
|
|
26020
|
-
console.debug(
|
|
26106
|
+
console.debug(`[user-event-service] ${data.length} user events loaded in ${Date.now() - now}ms`);
|
|
26021
26107
|
now = null;
|
|
26022
26108
|
}
|
|
26023
|
-
const unreadCount = this.unreadEvents(data);
|
|
26024
26109
|
return {
|
|
26025
26110
|
data,
|
|
26026
|
-
total:
|
|
26111
|
+
total: res && toNumber(res.total, data.length)
|
|
26027
26112
|
};
|
|
26028
26113
|
}));
|
|
26029
26114
|
}
|
|
26030
|
-
|
|
26031
|
-
|
|
26032
|
-
|
|
26033
|
-
const withContent = !!entity.content;
|
|
26034
|
-
// Add user event locally
|
|
26035
|
-
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26036
|
-
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26037
|
-
data: entity
|
|
26038
|
-
});
|
|
26039
|
-
// Update count
|
|
26040
|
-
this._count$.next(this._count$.value + 1);
|
|
26041
|
-
}
|
|
26042
|
-
count(filter, options) {
|
|
26043
|
-
var _a;
|
|
26044
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
26045
|
-
if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
|
|
26046
|
-
console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
|
|
26047
|
-
return undefined;
|
|
26048
|
-
}
|
|
26049
|
-
if (!filter)
|
|
26050
|
-
throw new Error(`Missing argument 'filter'`);
|
|
26051
|
-
filter = this.asFilter(filter);
|
|
26052
|
-
if (this._debug)
|
|
26053
|
-
console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
|
|
26054
|
-
const res = yield this.graphql.query({
|
|
26055
|
-
query: this.queries.count,
|
|
26056
|
-
variables: {
|
|
26057
|
-
filter: filter.asPodObject()
|
|
26058
|
-
},
|
|
26059
|
-
error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
|
|
26060
|
-
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
|
|
26061
|
-
});
|
|
26062
|
-
return res.total;
|
|
26063
|
-
});
|
|
26064
|
-
}
|
|
26065
|
-
listenChanges(filter, options) {
|
|
26066
|
-
var _a;
|
|
26067
|
-
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
|
|
26068
|
-
console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
|
|
26069
|
-
return of();
|
|
26070
|
-
}
|
|
26071
|
-
if (!filter)
|
|
26072
|
-
throw new Error(`Missing argument 'filter'`);
|
|
26073
|
-
filter = this.asFilter(filter);
|
|
26074
|
-
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26075
|
-
if (this._debug)
|
|
26076
|
-
console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
|
|
26077
|
-
return this.graphql.subscribe({
|
|
26078
|
-
query: this.subscriptions.listenChanges,
|
|
26079
|
-
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26080
|
-
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26081
|
-
error: {
|
|
26082
|
-
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26083
|
-
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26084
|
-
}
|
|
26085
|
-
}).pipe(map(({ data }) => {
|
|
26086
|
-
if (data && this._debug)
|
|
26087
|
-
console.debug(`${this._logPrefix}Received new user events:`, data);
|
|
26088
|
-
const updatedData = data === null || data === void 0 ? void 0 : data.map(this.processUserEvent);
|
|
26089
|
-
// Update cache
|
|
26090
|
-
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26091
|
-
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26092
|
-
data: updatedData
|
|
26093
|
-
});
|
|
26094
|
-
// update count
|
|
26095
|
-
this._count$.next(this.unreadEvents(updatedData));
|
|
26096
|
-
return updatedData;
|
|
26097
|
-
}));
|
|
26098
|
-
}
|
|
26099
|
-
delete(entity) {
|
|
26100
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
26101
|
-
if (!entity)
|
|
26102
|
-
return; // skip
|
|
26103
|
-
yield this.deleteAll([entity]);
|
|
26104
|
-
});
|
|
26105
|
-
}
|
|
26106
|
-
deleteAll(entities, opts) {
|
|
26107
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
26108
|
-
const ids = entities && entities
|
|
26109
|
-
.map(t => t.id);
|
|
26110
|
-
if (isEmptyArray(ids))
|
|
26111
|
-
return; // stop, if nothing else to do
|
|
26112
|
-
const now = Date.now();
|
|
26113
|
-
if (this._debug)
|
|
26114
|
-
console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
|
|
26115
|
-
yield this.graphql.mutate({
|
|
26116
|
-
mutation: this.mutations.deleteByIds,
|
|
26117
|
-
variables: {
|
|
26118
|
-
ids
|
|
26119
|
-
},
|
|
26120
|
-
update: (proxy) => {
|
|
26121
|
-
// Remove from caches
|
|
26122
|
-
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26123
|
-
query: this.queries.loadAll,
|
|
26124
|
-
ids
|
|
26125
|
-
});
|
|
26126
|
-
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26127
|
-
query: this.queries.loadAllWithContent,
|
|
26128
|
-
ids
|
|
26129
|
-
});
|
|
26130
|
-
if (this._debug)
|
|
26131
|
-
console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
|
|
26132
|
-
}
|
|
26133
|
-
});
|
|
26134
|
-
});
|
|
26115
|
+
saveAll(data, options) {
|
|
26116
|
+
return Promise.all(data
|
|
26117
|
+
.map(entity => this.save(entity, options)));
|
|
26135
26118
|
}
|
|
26119
|
+
/**
|
|
26120
|
+
* Save a userEvent entity
|
|
26121
|
+
*
|
|
26122
|
+
* @param entity
|
|
26123
|
+
*/
|
|
26136
26124
|
save(entity, options) {
|
|
26137
26125
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26138
26126
|
this.fillDefaultProperties(entity);
|
|
@@ -26141,9 +26129,9 @@ class AbstractUserEventService extends BaseGraphqlService {
|
|
|
26141
26129
|
const json = entity.asObject();
|
|
26142
26130
|
const now = Date.now();
|
|
26143
26131
|
if (this._debug)
|
|
26144
|
-
console.debug(
|
|
26132
|
+
console.debug(`[user-event-service] Saving user event...`, json);
|
|
26145
26133
|
yield this.graphql.mutate({
|
|
26146
|
-
mutation:
|
|
26134
|
+
mutation: SaveQuery,
|
|
26147
26135
|
variables: {
|
|
26148
26136
|
data: json
|
|
26149
26137
|
},
|
|
@@ -26153,16 +26141,16 @@ class AbstractUserEventService extends BaseGraphqlService {
|
|
|
26153
26141
|
const savedEntity = data && data.data;
|
|
26154
26142
|
if (savedEntity) {
|
|
26155
26143
|
if (this._debug)
|
|
26156
|
-
console.debug(
|
|
26144
|
+
console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
|
|
26157
26145
|
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26158
26146
|
// Add to cache
|
|
26159
26147
|
if (isNew) {
|
|
26160
26148
|
this.insertIntoMutableCachedQueries(proxy, {
|
|
26161
|
-
query:
|
|
26149
|
+
query: LoadAllQuery,
|
|
26162
26150
|
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26163
26151
|
});
|
|
26164
26152
|
this.insertIntoMutableCachedQueries(proxy, {
|
|
26165
|
-
query:
|
|
26153
|
+
query: LoadAllWithContentQuery,
|
|
26166
26154
|
data: savedEntity
|
|
26167
26155
|
});
|
|
26168
26156
|
}
|
|
@@ -26172,144 +26160,63 @@ class AbstractUserEventService extends BaseGraphqlService {
|
|
|
26172
26160
|
return entity;
|
|
26173
26161
|
});
|
|
26174
26162
|
}
|
|
26175
|
-
|
|
26176
|
-
|
|
26177
|
-
|
|
26178
|
-
|
|
26179
|
-
|
|
26163
|
+
/**
|
|
26164
|
+
* Save many trips
|
|
26165
|
+
*
|
|
26166
|
+
* @param entities
|
|
26167
|
+
* @param opts
|
|
26168
|
+
*/
|
|
26169
|
+
deleteAll(entities, opts) {
|
|
26180
26170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
if (
|
|
26184
|
-
|
|
26185
|
-
|
|
26171
|
+
const ids = entities && entities
|
|
26172
|
+
.map(t => t.id);
|
|
26173
|
+
if (isEmptyArray(ids))
|
|
26174
|
+
return; // stop, if nothing else to do
|
|
26175
|
+
const now = Date.now();
|
|
26176
|
+
if (this._debug)
|
|
26177
|
+
console.debug('[user-event-service] Deleting events... ids:', ids);
|
|
26178
|
+
yield this.graphql.mutate({
|
|
26179
|
+
mutation: DeleteByIdsMutation,
|
|
26180
|
+
variables: {
|
|
26181
|
+
ids
|
|
26182
|
+
},
|
|
26183
|
+
update: (proxy) => {
|
|
26184
|
+
// Remove from caches
|
|
26185
|
+
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26186
|
+
query: LoadAllQuery,
|
|
26187
|
+
ids
|
|
26188
|
+
});
|
|
26189
|
+
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26190
|
+
query: LoadAllWithContentQuery,
|
|
26191
|
+
ids
|
|
26192
|
+
});
|
|
26193
|
+
if (this._debug)
|
|
26194
|
+
console.debug(`[user-event-service] Events deleted in ${Date.now() - now}ms`);
|
|
26186
26195
|
}
|
|
26187
|
-
}
|
|
26188
|
-
else {
|
|
26189
|
-
// Use default
|
|
26190
|
-
yield this.defaultMarkAsRead(entity);
|
|
26191
|
-
}
|
|
26196
|
+
});
|
|
26192
26197
|
});
|
|
26193
26198
|
}
|
|
26194
|
-
|
|
26195
|
-
|
|
26196
|
-
|
|
26197
|
-
|
|
26198
|
-
}
|
|
26199
|
-
/* -- protected methods -- */
|
|
26200
|
-
processUserEvent(source) {
|
|
26201
|
-
// Convert json source to IUserEvent
|
|
26202
|
-
let target = this.fromObject(source);
|
|
26203
|
-
// Get listeners
|
|
26204
|
-
const listeners = (this.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
|
|
26205
|
-
for (const listener of listeners) {
|
|
26206
|
-
if (target) {
|
|
26207
|
-
target = listener.onReceived(target);
|
|
26208
|
-
}
|
|
26209
|
-
else {
|
|
26210
|
-
if (this._debug)
|
|
26211
|
-
console.debug(`${this._logPrefix}Event has been rejected by a listener`, source);
|
|
26212
|
-
break;
|
|
26213
|
-
}
|
|
26214
|
-
}
|
|
26215
|
-
return target;
|
|
26216
|
-
}
|
|
26217
|
-
defaultMarkAsRead(userEvent) {
|
|
26199
|
+
/**
|
|
26200
|
+
* Delete userEvent entities
|
|
26201
|
+
*/
|
|
26202
|
+
delete(data) {
|
|
26218
26203
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26219
|
-
if (!
|
|
26220
|
-
|
|
26221
|
-
|
|
26222
|
-
userEvent.readDate = moment$6();
|
|
26223
|
-
if (!userEvent.id || userEvent.id < 0) {
|
|
26224
|
-
if (this._debug)
|
|
26225
|
-
console.debug(`${this._logPrefix}Save local user event`);
|
|
26226
|
-
// TODO !!!!!!!!!!!!!
|
|
26227
|
-
}
|
|
26228
|
-
else {
|
|
26229
|
-
yield this.save(userEvent);
|
|
26230
|
-
}
|
|
26204
|
+
if (!data)
|
|
26205
|
+
return; // skip
|
|
26206
|
+
yield this.deleteAll([data]);
|
|
26231
26207
|
});
|
|
26232
26208
|
}
|
|
26233
|
-
|
|
26234
|
-
//
|
|
26235
|
-
|
|
26236
|
-
|
|
26237
|
-
};
|
|
26238
|
-
}
|
|
26239
|
-
defaultRecipient() {
|
|
26240
|
-
return this.accountService.person.pubkey;
|
|
26241
|
-
}
|
|
26242
|
-
fillDefaultProperties(entity) {
|
|
26209
|
+
listenChanges(id, options) {
|
|
26210
|
+
// TODO
|
|
26211
|
+
console.warn('TODO: implement listen changes on user events');
|
|
26212
|
+
return of();
|
|
26243
26213
|
}
|
|
26244
|
-
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
return undefined;
|
|
26248
|
-
const lastReadDate = events
|
|
26249
|
-
.filter(event => isNotNil(event.readDate))
|
|
26250
|
-
.reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
|
|
26251
|
-
return events
|
|
26252
|
-
.filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
|
|
26214
|
+
registerAction(definition) {
|
|
26215
|
+
console.info(`[user-event-service] Registering action ${definition.name} for ${definition.__typename}`);
|
|
26216
|
+
this._userEventActions.push(definition);
|
|
26253
26217
|
}
|
|
26254
|
-
|
|
26255
|
-
|
|
26256
|
-
}
|
|
26257
|
-
}
|
|
26258
|
-
AbstractUserEventService.decorators = [
|
|
26259
|
-
{ type: Directive }
|
|
26260
|
-
];
|
|
26261
|
-
AbstractUserEventService.ctorParameters = () => [
|
|
26262
|
-
{ type: GraphqlService },
|
|
26263
|
-
{ type: AccountService },
|
|
26264
|
-
{ type: NetworkService },
|
|
26265
|
-
{ type: TranslateService },
|
|
26266
|
-
{ type: undefined },
|
|
26267
|
-
{ type: undefined },
|
|
26268
|
-
{ type: undefined },
|
|
26269
|
-
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
26270
|
-
];
|
|
26271
|
-
const userEventQueries = {
|
|
26272
|
-
loadAll: gql `
|
|
26273
|
-
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26274
|
-
data: userEvents(filter: $filter, page: $page){
|
|
26275
|
-
...LightUserEventFragment
|
|
26276
|
-
}
|
|
26277
|
-
}
|
|
26278
|
-
${UserEventFragments.lightUserEvent}
|
|
26279
|
-
`,
|
|
26280
|
-
loadAllWithContent: gql `
|
|
26281
|
-
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26282
|
-
data: userEvents(filter: $filter, page: $page){
|
|
26283
|
-
...UserEventFragment
|
|
26284
|
-
}
|
|
26285
|
-
}
|
|
26286
|
-
${UserEventFragments.userEvent}
|
|
26287
|
-
`
|
|
26288
|
-
};
|
|
26289
|
-
const userEventMutations = {
|
|
26290
|
-
deleteByIds: gql `
|
|
26291
|
-
mutation DeleteUserEvents($ids:[Int]){
|
|
26292
|
-
deleteUserEvents(ids: $ids)
|
|
26293
|
-
}
|
|
26294
|
-
`,
|
|
26295
|
-
save: gql `
|
|
26296
|
-
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26297
|
-
data: saveUserEvent(userEvent: $data){
|
|
26298
|
-
...UserEventFragment
|
|
26299
|
-
}
|
|
26300
|
-
}
|
|
26301
|
-
${UserEventFragments.userEvent}
|
|
26302
|
-
`
|
|
26303
|
-
};
|
|
26304
|
-
class UserEventService extends AbstractUserEventService {
|
|
26305
|
-
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26306
|
-
super(graphql, accountService, network, translate, userEventQueries, userEventMutations, undefined, environment);
|
|
26307
|
-
this.graphql = graphql;
|
|
26308
|
-
this.accountService = accountService;
|
|
26309
|
-
this.network = network;
|
|
26310
|
-
this.translate = translate;
|
|
26311
|
-
this.toastController = toastController;
|
|
26312
|
-
this.environment = environment;
|
|
26218
|
+
getActionsByTypename(typename) {
|
|
26219
|
+
return this._userEventActions.filter(def => def.__typename === typename);
|
|
26313
26220
|
}
|
|
26314
26221
|
showToastErrorWithContext(opts) {
|
|
26315
26222
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -26373,16 +26280,13 @@ class UserEventService extends AbstractUserEventService {
|
|
|
26373
26280
|
}
|
|
26374
26281
|
sendDataForDebug(data) {
|
|
26375
26282
|
const userEvent = new UserEvent();
|
|
26376
|
-
userEvent.
|
|
26283
|
+
userEvent.eventType = UserEventTypes.DEBUG_DATA;
|
|
26377
26284
|
userEvent.content = this.convertObjectToString(data);
|
|
26378
26285
|
return this.save(userEvent);
|
|
26379
26286
|
}
|
|
26380
26287
|
asFilter(filter) {
|
|
26381
26288
|
return UserEventFilter.fromObject(filter);
|
|
26382
26289
|
}
|
|
26383
|
-
fromObject(source) {
|
|
26384
|
-
return UserEvent.fromObject(source);
|
|
26385
|
-
}
|
|
26386
26290
|
/* -- protected methods -- */
|
|
26387
26291
|
convertObjectToString(data) {
|
|
26388
26292
|
if (typeof data === 'string') {
|
|
@@ -26411,9 +26315,13 @@ class UserEventService extends AbstractUserEventService {
|
|
|
26411
26315
|
// TODO: compute sign
|
|
26412
26316
|
console.warn('TODO: sign user event before sending');
|
|
26413
26317
|
}
|
|
26318
|
+
copyIdAndUpdateDate(source, target) {
|
|
26319
|
+
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26320
|
+
}
|
|
26414
26321
|
}
|
|
26322
|
+
UserEventService.ɵprov = ɵɵdefineInjectable({ factory: function UserEventService_Factory() { return new UserEventService(ɵɵinject(GraphqlService), ɵɵinject(AccountService), ɵɵinject(NetworkService), ɵɵinject(TranslateService), ɵɵinject(ToastController), ɵɵinject(ENVIRONMENT, 8)); }, token: UserEventService, providedIn: "root" });
|
|
26415
26323
|
UserEventService.decorators = [
|
|
26416
|
-
{ type: Injectable }
|
|
26324
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
26417
26325
|
];
|
|
26418
26326
|
UserEventService.ctorParameters = () => [
|
|
26419
26327
|
{ type: GraphqlService },
|
|
@@ -26426,7 +26334,7 @@ UserEventService.ctorParameters = () => [
|
|
|
26426
26334
|
|
|
26427
26335
|
const ICONS_MAP = {
|
|
26428
26336
|
DEBUG_DATA: { matIcon: 'bug_report' },
|
|
26429
|
-
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26337
|
+
INBOX_MESSAGE: { matIcon: 'mail' },
|
|
26430
26338
|
};
|
|
26431
26339
|
// TODO: refactor with a registration done by data service:
|
|
26432
26340
|
// - userEventService.registerEventAction({__typename: 'TripVO', ...})
|
|
@@ -26492,7 +26400,7 @@ class UserEventsTable extends AppTable {
|
|
|
26492
26400
|
}
|
|
26493
26401
|
}));
|
|
26494
26402
|
const filter = this.filter || new UserEventFilter();
|
|
26495
|
-
filter.
|
|
26403
|
+
filter.recipient = this.recipient;
|
|
26496
26404
|
this.setFilter(filter, { emitEvent: true });
|
|
26497
26405
|
}
|
|
26498
26406
|
start() {
|
|
@@ -26505,17 +26413,17 @@ class UserEventsTable extends AppTable {
|
|
|
26505
26413
|
});
|
|
26506
26414
|
}
|
|
26507
26415
|
getIcon(source) {
|
|
26508
|
-
return ICONS_MAP[source.
|
|
26416
|
+
return ICONS_MAP[source.eventType];
|
|
26509
26417
|
}
|
|
26510
26418
|
getDetail(source) {
|
|
26511
26419
|
if (!source)
|
|
26512
26420
|
return undefined;
|
|
26513
|
-
if (source.content && source.
|
|
26421
|
+
if (source.content && source.eventType === UserEventTypes.DEBUG_DATA) {
|
|
26514
26422
|
const context = source.content.context;
|
|
26515
26423
|
if (context && context.__typename) {
|
|
26516
|
-
|
|
26424
|
+
const actions = this.service.getActionsByTypename(context.__typename);
|
|
26517
26425
|
return {
|
|
26518
|
-
|
|
26426
|
+
actions,
|
|
26519
26427
|
title: source.content.error && source.content.error.message || source.content.message,
|
|
26520
26428
|
description: source.content.error && source.content.error.details || undefined
|
|
26521
26429
|
};
|
|
@@ -26527,11 +26435,11 @@ class UserEventsTable extends AppTable {
|
|
|
26527
26435
|
doAction(action, row) {
|
|
26528
26436
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26529
26437
|
const event = row.currentData;
|
|
26530
|
-
|
|
26438
|
+
const context = event.content && event.content.context;
|
|
26531
26439
|
this.markAsLoading();
|
|
26532
26440
|
if (action && typeof action.executeAction === 'function') {
|
|
26533
26441
|
try {
|
|
26534
|
-
let res = action.executeAction(event
|
|
26442
|
+
let res = action.executeAction(event, context);
|
|
26535
26443
|
res = (res instanceof Promise) ? yield res : res;
|
|
26536
26444
|
}
|
|
26537
26445
|
catch (err) {
|
|
@@ -26550,18 +26458,13 @@ UserEventsTable.decorators = [
|
|
|
26550
26458
|
selector: 'app-user-events-table',
|
|
26551
26459
|
template: "\n<!-- Type = options menu -->\n<mat-menu #optionsMenu=\"matMenu\" xPosition=\"after\">\n\n <!-- display columns -->\n <button mat-menu-item\n (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n</mat-menu>\n\n<!-- top header -->\n<mat-toolbar>\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <button mat-icon-button [title]=\"'COMMON.BTN_REFRESH'|translate\" (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button class=\"hidden-xs hidden-sm\" *ngIf=\"canDelete\"\n [title]=\"'COMMON.BTN_DELETE'|translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" hidden-xs hidden-sm hidden-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=\"toolbar-spacer\"></div>\n\n <button mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS'|translate\"\n [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n</mat-toolbar>\n\n\n<mat-table [dataSource]=\"dataSource\" matSort\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <!-- select -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <!-- id -->\n <ng-container matColumnDef=\"id\">\n <mat-header-cell *matHeaderCellDef mat-sort-header [class.cdk-visually-hidden]=\"!isAdmin\">\n <app-loading-spinner [loading]=\"loadingSubject|async\"><ion-label>#</ion-label></app-loading-spinner>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!isAdmin\">{{ row.currentData.id | mathAbs }}</mat-cell>\n </ng-container>\n\n <!-- creationDate -->\n <ng-container matColumnDef=\"creationDate\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.CREATION_DATE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ion-text>\n {{row.currentData.creationDate | dateFromNow }}<br/>\n <ion-text color=\"medium\"><small>{{row.currentData.creationDate | dateFormat: {time: true} }}</small></ion-text>\n </ion-text>\n </mat-cell>\n </ng-container>\n\n <!-- icon -->\n <ng-container matColumnDef=\"icon\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getIcon(row.currentData); let details\">\n <ion-icon slot=\"start\" *ngIf=\"details.icon\" [name]=\"details.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"details.matIcon\">{{details.matIcon}}</mat-icon>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- event type -->\n <ng-container matColumnDef=\"eventType\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.EVENT_TYPE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <span>{{'SOCIAL.USER_EVENT.TYPE_ENUM.' + row.currentData.eventType | translate}}</span>\n </mat-cell>\n </ng-container>\n\n <!-- message -->\n <ng-container matColumnDef=\"message\">\n <mat-header-cell *matHeaderCellDef>\n <ion-label translate>SOCIAL.USER_EVENT.MESSAGE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <ion-text [innerHTML]=\"details.title|translate\">\n </ion-text>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- Actions buttons column -->\n <ng-container matColumnDef=\"actions\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <button mat-icon-button color=\"light\"\n *ngFor=\"let action of details.actions\"\n [title]=\"action.title |translate\"\n [color]=\"action.color\"\n (click)=\"doAction(action, row)\">\n <ion-icon slot=\"start\" *ngIf=\"action.icon\" [name]=\"action.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"action.matIcon\">{{action.matIcon}}</mat-icon>\n </button>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n class=\"mat-row-disabled\"\n (click)=\"clickRow($event, row)\"></mat-row>\n\n</mat-table>\n\n<ion-row class=\"ion-no-padding\">\n <ion-col></ion-col>\n <ion-col class=\"ion-no-padding\" size=\"auto\">\n <mat-paginator [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n </ion-col>\n</ion-row>\n",
|
|
26552
26460
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26553
|
-
providers: [
|
|
26554
|
-
{
|
|
26555
|
-
provide: UserEventServiceToken, useClass: UserEventService
|
|
26556
|
-
}
|
|
26557
|
-
],
|
|
26558
26461
|
styles: [".mat-header-row .mat-column-icon,.mat-row .mat-column-icon{max-width:40px;padding-left:0}.mat-header-row .mat-column-icon ion-icon,.mat-header-row .mat-column-icon mat-icon,.mat-row .mat-column-icon ion-icon,.mat-row .mat-column-icon mat-icon{font-size:1.2em;height:1.2em;width:1.2em}.mat-header-row .mat-column-creationDate,.mat-row .mat-column-creationDate{min-width:100px;max-width:120px}"]
|
|
26559
26462
|
},] }
|
|
26560
26463
|
];
|
|
26561
26464
|
UserEventsTable.ctorParameters = () => [
|
|
26562
26465
|
{ type: Injector },
|
|
26563
26466
|
{ type: AccountService },
|
|
26564
|
-
{ type:
|
|
26467
|
+
{ type: UserEventService },
|
|
26565
26468
|
{ type: EntitiesStorage },
|
|
26566
26469
|
{ type: ChangeDetectorRef },
|
|
26567
26470
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
@@ -26573,147 +26476,6 @@ UserEventsTable.propDecorators = {
|
|
|
26573
26476
|
defaultSortDirection: [{ type: Input }]
|
|
26574
26477
|
};
|
|
26575
26478
|
|
|
26576
|
-
class UserEventNotificationList {
|
|
26577
|
-
constructor(popoverController) {
|
|
26578
|
-
this.popoverController = popoverController;
|
|
26579
|
-
}
|
|
26580
|
-
ngOnInit() {
|
|
26581
|
-
}
|
|
26582
|
-
read($event, userEvent) {
|
|
26583
|
-
var _a;
|
|
26584
|
-
if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
|
|
26585
|
-
return;
|
|
26586
|
-
(_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
|
|
26587
|
-
}
|
|
26588
|
-
executeAction(action, userEvent) {
|
|
26589
|
-
// Execute then close popover
|
|
26590
|
-
action.executeAction(userEvent);
|
|
26591
|
-
this.dismiss();
|
|
26592
|
-
}
|
|
26593
|
-
dismiss() {
|
|
26594
|
-
this.popoverController.dismiss();
|
|
26595
|
-
}
|
|
26596
|
-
}
|
|
26597
|
-
UserEventNotificationList.decorators = [
|
|
26598
|
-
{ type: Component, args: [{
|
|
26599
|
-
selector: 'app-user-event-notification-list',
|
|
26600
|
-
template: "\n<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!(userEvents | async)?.length\">\n {{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}\n </ion-item>\n <ion-item\n *ngFor=\"let userEvent of userEvents | async\"\n (click)=\"read($event, userEvent)\"\n >\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"userEvent.avatar; else avatarIcon\" src=\"{{ userEvent.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"userEvent.avatarIcon\"\n [ref]=\"userEvent.avatarIcon\"\n height=\"40\"\n width=\"40\"\n ></app-icon>\n </ng-template>\n\n </ion-avatar>\n\n <ion-grid class=\"ion-no-margin ion-no-padding\">\n <ion-row>\n <ion-col>\n <p [class.unread]=\"!userEvent.readDate\">\n {{userEvent.message}}\n </p>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"userEvent.actions?.length\">\n <ion-col>\n <p>\n <span *ngFor=\"let action of userEvent.actions\">\n <a\n [style.margin-right.px]=\"8\"\n [style.cursor]=\"'pointer'\"\n (click)=\"executeAction(action, userEvent)\"\n >\n {{ '➞ ' + action.name}}\n </a>\n </span>\n </p>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <app-icon\n *ngIf=\"userEvent.icon\"\n [ref]=\"userEvent.icon\"\n height=\"16\"\n width=\"16\"\n [style.vertical-align]=\"'sub'\"\n ></app-icon>\n <small>\n <span>{{userEvent.creationDate|dateFromNow}}</span>\n <span [style.color]=\"'gray'\">{{ ' | ' + (userEvent.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
|
|
26601
|
-
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
|
|
26602
|
-
},] }
|
|
26603
|
-
];
|
|
26604
|
-
UserEventNotificationList.ctorParameters = () => [
|
|
26605
|
-
{ type: PopoverController }
|
|
26606
|
-
];
|
|
26607
|
-
UserEventNotificationList.propDecorators = {
|
|
26608
|
-
titleI18n: [{ type: Input }],
|
|
26609
|
-
userEvents: [{ type: Input }],
|
|
26610
|
-
readEvent: [{ type: Output }]
|
|
26611
|
-
};
|
|
26612
|
-
|
|
26613
|
-
class UserEventNotificationComponent {
|
|
26614
|
-
constructor(userEventService, accountService, popoverController, cd) {
|
|
26615
|
-
this.userEventService = userEventService;
|
|
26616
|
-
this.accountService = accountService;
|
|
26617
|
-
this.popoverController = popoverController;
|
|
26618
|
-
this.cd = cd;
|
|
26619
|
-
this.debug = false;
|
|
26620
|
-
this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
|
|
26621
|
-
this.disabled = false;
|
|
26622
|
-
this.userEventsSubject = new BehaviorSubject(undefined);
|
|
26623
|
-
this._subscriptions = new Subscription();
|
|
26624
|
-
this._logPrefix = '[user-event-notification] ';
|
|
26625
|
-
this._readEvent = new EventEmitter();
|
|
26626
|
-
}
|
|
26627
|
-
get count() {
|
|
26628
|
-
var _a;
|
|
26629
|
-
return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(map(value => value === 0 ? undefined : value));
|
|
26630
|
-
}
|
|
26631
|
-
ngOnInit() {
|
|
26632
|
-
if (isNil(this.userEventService)) {
|
|
26633
|
-
console.warn(`${this._logPrefix}No service injected`);
|
|
26634
|
-
this.disabled = true;
|
|
26635
|
-
return;
|
|
26636
|
-
}
|
|
26637
|
-
this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc").subscribe(value => {
|
|
26638
|
-
const data = value.data;
|
|
26639
|
-
if (this.debug) {
|
|
26640
|
-
console.debug(`${this._logPrefix}Receiving user events`, data);
|
|
26641
|
-
}
|
|
26642
|
-
this.userEventsSubject.next(data);
|
|
26643
|
-
}));
|
|
26644
|
-
this._readEvent.subscribe(value => {
|
|
26645
|
-
this.userEventService.markAsRead(value);
|
|
26646
|
-
});
|
|
26647
|
-
}
|
|
26648
|
-
showList(event) {
|
|
26649
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
26650
|
-
const popover = yield this.popoverController.create({
|
|
26651
|
-
component: UserEventNotificationList,
|
|
26652
|
-
componentProps: {
|
|
26653
|
-
titleI18n: this.titleI18n,
|
|
26654
|
-
userEvents: this.userEventsSubject,
|
|
26655
|
-
readEvent: this._readEvent
|
|
26656
|
-
},
|
|
26657
|
-
backdropDismiss: true,
|
|
26658
|
-
keyboardClose: true,
|
|
26659
|
-
event,
|
|
26660
|
-
translucent: true,
|
|
26661
|
-
cssClass: 'popover-large'
|
|
26662
|
-
});
|
|
26663
|
-
yield popover.present();
|
|
26664
|
-
});
|
|
26665
|
-
}
|
|
26666
|
-
markForCheck() {
|
|
26667
|
-
this.cd.markForCheck();
|
|
26668
|
-
}
|
|
26669
|
-
ngOnDestroy() {
|
|
26670
|
-
if (this.debug) {
|
|
26671
|
-
console.debug(`${this._logPrefix}Destroying`);
|
|
26672
|
-
}
|
|
26673
|
-
this._subscriptions.unsubscribe();
|
|
26674
|
-
}
|
|
26675
|
-
}
|
|
26676
|
-
UserEventNotificationComponent.decorators = [
|
|
26677
|
-
{ type: Component, args: [{
|
|
26678
|
-
selector: 'app-user-event-notification-component',
|
|
26679
|
-
template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n (click)=\"showList($event)\"\n>\n <mat-icon\n [matBadge]=\"count | async\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n >notifications\n </mat-icon>\n</button>\n\n",
|
|
26680
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26681
|
-
styles: [""]
|
|
26682
|
-
},] }
|
|
26683
|
-
];
|
|
26684
|
-
UserEventNotificationComponent.ctorParameters = () => [
|
|
26685
|
-
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] },
|
|
26686
|
-
{ type: AccountService },
|
|
26687
|
-
{ type: PopoverController },
|
|
26688
|
-
{ type: ChangeDetectorRef }
|
|
26689
|
-
];
|
|
26690
|
-
UserEventNotificationComponent.propDecorators = {
|
|
26691
|
-
debug: [{ type: Input }],
|
|
26692
|
-
titleI18n: [{ type: Input }],
|
|
26693
|
-
disabled: [{ type: Input }]
|
|
26694
|
-
};
|
|
26695
|
-
|
|
26696
|
-
class UserEventModule {
|
|
26697
|
-
}
|
|
26698
|
-
UserEventModule.decorators = [
|
|
26699
|
-
{ type: NgModule, args: [{
|
|
26700
|
-
imports: [
|
|
26701
|
-
CommonModule,
|
|
26702
|
-
CoreModule,
|
|
26703
|
-
SharedModule
|
|
26704
|
-
],
|
|
26705
|
-
declarations: [
|
|
26706
|
-
UserEventsTable,
|
|
26707
|
-
UserEventNotificationComponent,
|
|
26708
|
-
UserEventNotificationList,
|
|
26709
|
-
],
|
|
26710
|
-
exports: [
|
|
26711
|
-
UserEventsTable,
|
|
26712
|
-
UserEventNotificationComponent
|
|
26713
|
-
]
|
|
26714
|
-
},] }
|
|
26715
|
-
];
|
|
26716
|
-
|
|
26717
26479
|
const MessageTypes = {
|
|
26718
26480
|
INBOX_MESSAGE: 'INBOX_MESSAGE',
|
|
26719
26481
|
EMAIL: 'EMAIL',
|
|
@@ -26925,9 +26687,9 @@ MessageForm.propDecorators = {
|
|
|
26925
26687
|
canSelectType: [{ type: Input }]
|
|
26926
26688
|
};
|
|
26927
26689
|
|
|
26928
|
-
class
|
|
26690
|
+
class SocialModule {
|
|
26929
26691
|
}
|
|
26930
|
-
|
|
26692
|
+
SocialModule.decorators = [
|
|
26931
26693
|
{ type: NgModule, args: [{
|
|
26932
26694
|
imports: [
|
|
26933
26695
|
CommonModule,
|
|
@@ -26935,317 +26697,17 @@ MessageModule.decorators = [
|
|
|
26935
26697
|
SharedModule
|
|
26936
26698
|
],
|
|
26937
26699
|
declarations: [
|
|
26700
|
+
UserEventsTable,
|
|
26938
26701
|
MessageModal,
|
|
26939
26702
|
MessageForm
|
|
26940
26703
|
],
|
|
26941
26704
|
exports: [
|
|
26705
|
+
UserEventsTable,
|
|
26942
26706
|
MessageModal
|
|
26943
26707
|
]
|
|
26944
26708
|
},] }
|
|
26945
26709
|
];
|
|
26946
26710
|
|
|
26947
|
-
var JobProgression_1;
|
|
26948
|
-
// todo use entity
|
|
26949
|
-
class Job {
|
|
26950
|
-
}
|
|
26951
|
-
// @dynamic
|
|
26952
|
-
let JobProgression = JobProgression_1 = class JobProgression extends Entity {
|
|
26953
|
-
constructor() {
|
|
26954
|
-
super(JobProgression_1.TYPENAME);
|
|
26955
|
-
}
|
|
26956
|
-
fromObject(source) {
|
|
26957
|
-
super.fromObject(source);
|
|
26958
|
-
this.message = source.message;
|
|
26959
|
-
this.current = source.current;
|
|
26960
|
-
this.total = source.total;
|
|
26961
|
-
}
|
|
26962
|
-
};
|
|
26963
|
-
JobProgression = JobProgression_1 = __decorate([
|
|
26964
|
-
EntityClass({ typename: 'JobProgressionVO' })
|
|
26965
|
-
], JobProgression);
|
|
26966
|
-
|
|
26967
|
-
const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
|
|
26968
|
-
const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
|
|
26969
|
-
data: updateJobProgression(id: $id, interval: $interval) {
|
|
26970
|
-
id
|
|
26971
|
-
message
|
|
26972
|
-
current
|
|
26973
|
-
total
|
|
26974
|
-
}
|
|
26975
|
-
}`;
|
|
26976
|
-
class JobProgressionService extends BaseGraphqlService {
|
|
26977
|
-
constructor(graphql, environment) {
|
|
26978
|
-
super(graphql, environment);
|
|
26979
|
-
this.graphql = graphql;
|
|
26980
|
-
this.environment = environment;
|
|
26981
|
-
this._logPrefix = '[job-progression-service] ';
|
|
26982
|
-
// For DEV only
|
|
26983
|
-
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
26984
|
-
}
|
|
26985
|
-
listenChanges(id, options) {
|
|
26986
|
-
if (isNil(id))
|
|
26987
|
-
throw new Error(`${this._logPrefix}Missing argument 'id'`);
|
|
26988
|
-
if (this._debug)
|
|
26989
|
-
console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
|
|
26990
|
-
return this.graphql.subscribe({
|
|
26991
|
-
query: jobProgressionSubscription,
|
|
26992
|
-
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26993
|
-
variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26994
|
-
error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
|
|
26995
|
-
}).pipe(map(({ data }) => {
|
|
26996
|
-
const progression = data && JobProgression.fromObject(data);
|
|
26997
|
-
if (progression && this._debug)
|
|
26998
|
-
console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
|
|
26999
|
-
return progression;
|
|
27000
|
-
}));
|
|
27001
|
-
}
|
|
27002
|
-
}
|
|
27003
|
-
JobProgressionService.decorators = [
|
|
27004
|
-
{ type: Injectable }
|
|
27005
|
-
];
|
|
27006
|
-
JobProgressionService.ctorParameters = () => [
|
|
27007
|
-
{ type: GraphqlService },
|
|
27008
|
-
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27009
|
-
];
|
|
27010
|
-
|
|
27011
|
-
class JobProgressionList {
|
|
27012
|
-
constructor() {
|
|
27013
|
-
}
|
|
27014
|
-
ngOnInit() {
|
|
27015
|
-
}
|
|
27016
|
-
}
|
|
27017
|
-
JobProgressionList.decorators = [
|
|
27018
|
-
{ type: Component, args: [{
|
|
27019
|
-
selector: 'app-job-progression-list',
|
|
27020
|
-
template: "<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!jobProgressions?.length\">\n {{'SOCIAL.JOB.PROGRESSION.EMPTY' | translate}}\n </ion-item>\n <ion-item *ngFor=\"let jobProgression of jobProgressions\">\n <ion-grid class=\"ion-no-margin\">\n <ion-row>\n <ion-col>\n {{jobProgression.message}}\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-progress-bar\n [value]=\"jobProgression.total > 0 ? jobProgression.current / jobProgression.total : undefined\"\n [type]=\"jobProgression.total > 0 ? 'determinate' : 'indeterminate'\">\n </ion-progress-bar>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
|
|
27021
|
-
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
|
|
27022
|
-
},] }
|
|
27023
|
-
];
|
|
27024
|
-
JobProgressionList.ctorParameters = () => [];
|
|
27025
|
-
JobProgressionList.propDecorators = {
|
|
27026
|
-
titleI18n: [{ type: Input }],
|
|
27027
|
-
jobProgressions: [{ type: Input }]
|
|
27028
|
-
};
|
|
27029
|
-
|
|
27030
|
-
class JobProgressionComponent {
|
|
27031
|
-
constructor(jobProgressionService, popoverController, cd) {
|
|
27032
|
-
this.jobProgressionService = jobProgressionService;
|
|
27033
|
-
this.popoverController = popoverController;
|
|
27034
|
-
this.cd = cd;
|
|
27035
|
-
this.debug = false;
|
|
27036
|
-
this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
|
|
27037
|
-
this.jobFinished = new EventEmitter();
|
|
27038
|
-
this.disabled = true;
|
|
27039
|
-
this.color = 'accent';
|
|
27040
|
-
this.mode = 'determinate';
|
|
27041
|
-
this.value = 0;
|
|
27042
|
-
this.jobProgressions = [];
|
|
27043
|
-
this._subscriptions = new Subscription();
|
|
27044
|
-
this._subscriptionsById = {};
|
|
27045
|
-
this._logPrefix = '[job-progression] ';
|
|
27046
|
-
}
|
|
27047
|
-
ngOnInit() {
|
|
27048
|
-
var _a, _b, _c, _d;
|
|
27049
|
-
if (isNil(this.jobProgressionService)) {
|
|
27050
|
-
console.warn(`${this._logPrefix}No service injected`);
|
|
27051
|
-
}
|
|
27052
|
-
// parse options
|
|
27053
|
-
this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
|
|
27054
|
-
this.visible = !this.autoHide;
|
|
27055
|
-
this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
|
|
27056
|
-
this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
|
|
27057
|
-
this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
|
|
27058
|
-
}
|
|
27059
|
-
addJob(id) {
|
|
27060
|
-
if (isNil(this.jobProgressionService)) {
|
|
27061
|
-
console.warn(`${this._logPrefix}No service injected. Can't add a job`);
|
|
27062
|
-
return;
|
|
27063
|
-
}
|
|
27064
|
-
if (this.debug) {
|
|
27065
|
-
console.debug(`${this._logPrefix}Add job id=${id}`);
|
|
27066
|
-
}
|
|
27067
|
-
if (!!this.getProgression(id)) {
|
|
27068
|
-
console.warn(`${this._logPrefix}Job (id=${id}) already present`);
|
|
27069
|
-
return;
|
|
27070
|
-
}
|
|
27071
|
-
this.disabled = false;
|
|
27072
|
-
const sub = this.jobProgressionService.listenChanges(id)
|
|
27073
|
-
.pipe(filter(progression => {
|
|
27074
|
-
if (id !== progression.id) {
|
|
27075
|
-
console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
|
|
27076
|
-
return false;
|
|
27077
|
-
}
|
|
27078
|
-
return true;
|
|
27079
|
-
}), map(progression => {
|
|
27080
|
-
// Ensure visible
|
|
27081
|
-
this.visible = true;
|
|
27082
|
-
// Get current progression object
|
|
27083
|
-
const currentProgression = this.getProgression(id);
|
|
27084
|
-
if (!currentProgression) {
|
|
27085
|
-
// add it
|
|
27086
|
-
this.jobProgressions.push(progression);
|
|
27087
|
-
if (this.debug) {
|
|
27088
|
-
console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
|
|
27089
|
-
}
|
|
27090
|
-
}
|
|
27091
|
-
else {
|
|
27092
|
-
// update current
|
|
27093
|
-
Object.assign(currentProgression, progression);
|
|
27094
|
-
if (this.debug) {
|
|
27095
|
-
console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
|
|
27096
|
-
}
|
|
27097
|
-
}
|
|
27098
|
-
return progression;
|
|
27099
|
-
}))
|
|
27100
|
-
.subscribe(progression => {
|
|
27101
|
-
// update value
|
|
27102
|
-
this.updateValue();
|
|
27103
|
-
// job finished
|
|
27104
|
-
if (progression.total > 0 && progression.current == progression.total) {
|
|
27105
|
-
if (this.debug) {
|
|
27106
|
-
console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
|
|
27107
|
-
}
|
|
27108
|
-
// emit event
|
|
27109
|
-
this.jobFinished.emit(progression.id);
|
|
27110
|
-
if (this.autoRemove) {
|
|
27111
|
-
setTimeout(() => {
|
|
27112
|
-
var _a;
|
|
27113
|
-
this.removeJob(progression.id);
|
|
27114
|
-
// If last job
|
|
27115
|
-
if (this.autoHide && !((_a = this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
27116
|
-
setTimeout(() => {
|
|
27117
|
-
this.visible = false;
|
|
27118
|
-
this.markForCheck();
|
|
27119
|
-
}, this.autoHideDelay);
|
|
27120
|
-
}
|
|
27121
|
-
}, this.autoRemoveDelay);
|
|
27122
|
-
}
|
|
27123
|
-
}
|
|
27124
|
-
});
|
|
27125
|
-
this._subscriptionsById[id] = sub;
|
|
27126
|
-
this._subscriptions.add(sub);
|
|
27127
|
-
}
|
|
27128
|
-
removeJob(id) {
|
|
27129
|
-
if (this.debug) {
|
|
27130
|
-
console.debug(`${this._logPrefix}Remove job id=${id}`);
|
|
27131
|
-
}
|
|
27132
|
-
const sub = this._subscriptionsById[id];
|
|
27133
|
-
if (sub) {
|
|
27134
|
-
this._subscriptions.remove(sub);
|
|
27135
|
-
sub.unsubscribe();
|
|
27136
|
-
}
|
|
27137
|
-
const progression = this.getProgression(id);
|
|
27138
|
-
if (progression) {
|
|
27139
|
-
this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
|
|
27140
|
-
}
|
|
27141
|
-
this.updateValue();
|
|
27142
|
-
}
|
|
27143
|
-
getProgression(id) {
|
|
27144
|
-
return this.jobProgressions.find(progression => progression.id === id);
|
|
27145
|
-
}
|
|
27146
|
-
updateValue() {
|
|
27147
|
-
if (this.debug) {
|
|
27148
|
-
console.debug(`${this._logPrefix}Updating value`);
|
|
27149
|
-
}
|
|
27150
|
-
let value = 0;
|
|
27151
|
-
const nbProgression = arraySize(this.jobProgressions);
|
|
27152
|
-
let allIndeterminate = nbProgression > 0;
|
|
27153
|
-
this.jobProgressions.forEach(progression => {
|
|
27154
|
-
const indeterminate = progression.total === 0;
|
|
27155
|
-
allIndeterminate = allIndeterminate && indeterminate;
|
|
27156
|
-
if (!indeterminate) {
|
|
27157
|
-
value = value + progression.current * 100 / progression.total;
|
|
27158
|
-
}
|
|
27159
|
-
});
|
|
27160
|
-
this.value = nbProgression > 0 ? value / nbProgression : 0;
|
|
27161
|
-
this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
|
|
27162
|
-
if (this.debug) {
|
|
27163
|
-
console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
|
|
27164
|
-
}
|
|
27165
|
-
this.markForCheck();
|
|
27166
|
-
}
|
|
27167
|
-
showList(event) {
|
|
27168
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
27169
|
-
const popover = yield this.popoverController.create({
|
|
27170
|
-
component: JobProgressionList,
|
|
27171
|
-
componentProps: {
|
|
27172
|
-
titleI18n: this.titleI18n,
|
|
27173
|
-
jobProgressions: this.jobProgressions
|
|
27174
|
-
},
|
|
27175
|
-
backdropDismiss: true,
|
|
27176
|
-
keyboardClose: true,
|
|
27177
|
-
event,
|
|
27178
|
-
translucent: true,
|
|
27179
|
-
cssClass: 'popover-large'
|
|
27180
|
-
});
|
|
27181
|
-
yield popover.present();
|
|
27182
|
-
});
|
|
27183
|
-
}
|
|
27184
|
-
markForCheck() {
|
|
27185
|
-
this.cd.markForCheck();
|
|
27186
|
-
}
|
|
27187
|
-
ngOnDestroy() {
|
|
27188
|
-
if (this.debug) {
|
|
27189
|
-
console.debug(`${this._logPrefix}Destroying`);
|
|
27190
|
-
}
|
|
27191
|
-
this._subscriptions.unsubscribe();
|
|
27192
|
-
}
|
|
27193
|
-
}
|
|
27194
|
-
JobProgressionComponent.decorators = [
|
|
27195
|
-
{ type: Component, args: [{
|
|
27196
|
-
selector: 'app-job-progression',
|
|
27197
|
-
template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n *ngIf=\"visible\"\n (click)=\"showList($event)\"\n>\n <mat-icon\n [matBadge]=\"jobProgressions?.length\"\n [matBadgeHidden]=\"!jobProgressions?.length\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n >{{ disabled || jobProgressions?.length ? 'schedule' : 'task_alt' }}\n </mat-icon>\n <mat-spinner\n #spinner\n *ngIf=\"jobProgressions?.length\"\n class=\"floating-spinner\"\n [color]=\"color\"\n [mode]=\"mode\"\n [value]=\"value\"\n diameter=\"30\"\n strokeWidth=\"3\"\n ></mat-spinner>\n</button>\n\n",
|
|
27198
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27199
|
-
styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
|
|
27200
|
-
},] }
|
|
27201
|
-
];
|
|
27202
|
-
JobProgressionComponent.ctorParameters = () => [
|
|
27203
|
-
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [JobProgressionServiceToken,] }] },
|
|
27204
|
-
{ type: PopoverController },
|
|
27205
|
-
{ type: ChangeDetectorRef }
|
|
27206
|
-
];
|
|
27207
|
-
JobProgressionComponent.propDecorators = {
|
|
27208
|
-
debug: [{ type: Input }],
|
|
27209
|
-
titleI18n: [{ type: Input }],
|
|
27210
|
-
options: [{ type: Input }],
|
|
27211
|
-
jobFinished: [{ type: Output }]
|
|
27212
|
-
};
|
|
27213
|
-
|
|
27214
|
-
class JobModule {
|
|
27215
|
-
}
|
|
27216
|
-
JobModule.decorators = [
|
|
27217
|
-
{ type: NgModule, args: [{
|
|
27218
|
-
imports: [
|
|
27219
|
-
CommonModule,
|
|
27220
|
-
SharedModule,
|
|
27221
|
-
TranslateModule.forChild(),
|
|
27222
|
-
],
|
|
27223
|
-
declarations: [
|
|
27224
|
-
JobProgressionComponent,
|
|
27225
|
-
JobProgressionList
|
|
27226
|
-
],
|
|
27227
|
-
exports: [
|
|
27228
|
-
JobProgressionComponent
|
|
27229
|
-
]
|
|
27230
|
-
},] }
|
|
27231
|
-
];
|
|
27232
|
-
|
|
27233
|
-
const SocialModuleOptionsToken = new InjectionToken("SocialModuleOptions");
|
|
27234
|
-
class SocialModule {
|
|
27235
|
-
}
|
|
27236
|
-
SocialModule.decorators = [
|
|
27237
|
-
{ type: NgModule, args: [{
|
|
27238
|
-
imports: [
|
|
27239
|
-
CommonModule,
|
|
27240
|
-
CoreModule,
|
|
27241
|
-
SharedModule,
|
|
27242
|
-
UserEventModule,
|
|
27243
|
-
JobModule,
|
|
27244
|
-
MessageModule,
|
|
27245
|
-
],
|
|
27246
|
-
},] }
|
|
27247
|
-
];
|
|
27248
|
-
|
|
27249
26711
|
const Mutations = {
|
|
27250
26712
|
send: gql `mutation SendMessage($data: MessageVOInput){
|
|
27251
26713
|
done: sendMessage(message: $data)
|
|
@@ -27891,10 +27353,12 @@ class AutocompleteTestPage {
|
|
|
27891
27353
|
});
|
|
27892
27354
|
}
|
|
27893
27355
|
ngAfterViewInit() {
|
|
27894
|
-
|
|
27895
|
-
|
|
27896
|
-
|
|
27897
|
-
|
|
27356
|
+
if (this.farEntityField) {
|
|
27357
|
+
setTimeout(() => {
|
|
27358
|
+
this.farEntityField.suggestLengthThreshold = 2;
|
|
27359
|
+
this.farEntityField.reloadItems();
|
|
27360
|
+
}, 2000);
|
|
27361
|
+
}
|
|
27898
27362
|
setTimeout(() => this.loadData(), 1000);
|
|
27899
27363
|
}
|
|
27900
27364
|
// Load the form with data
|
|
@@ -27982,7 +27446,7 @@ class AutocompleteTestPage {
|
|
|
27982
27446
|
AutocompleteTestPage.decorators = [
|
|
27983
27447
|
{ type: Component, args: [{
|
|
27984
27448
|
selector: 'app-autocomplete-test',
|
|
27985
|
-
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>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </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 [equals]=\"equals\"\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 Entity far in the list (not in first page)\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre style=\"white-space: normal !important;\">value: {{stringify(form.controls.farEntity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"farEntity\" #farEntityField\n [config]=\"autocompleteFields.get('entity-far')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-far]'\"\n [debug]=\"true\"\n [required]=\"true\"\n [clearable]=\"true\"\n placeholder=\"Far entity (in the list)\"\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 Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre>\n </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 [equals]=\"equals\"\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>\n <pre>mobile: true, items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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>\n <pre>mobile: true, items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\n [clearable]=\"true\"\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-text color=\"primary\">\n search with a suggestLengthThreshold\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>\n </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]=\"true\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-mobile-suggestLengthThreshold]'\"\n required\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 Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"true\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-multiple]'\"\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 [equals]=\"equals\"\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>\n <pre></pre>\n </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(filterChangeField, '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\" #filterChangeField\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\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>\n <pre>class=\"min-width-large\"</pre>\n </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 [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\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 <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\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 Fullscreen\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </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 [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-mobile-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\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>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </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></pre>\n </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 [equals]=\"equals\"\n [clearable]=\"true\"\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 search with a suggestLengthThreshold\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>\n </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 [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggestLengthThreshold]'\"\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>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </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 [equals]=\"equals\"\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>\n <pre>items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"false\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-multiple]'\"\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>\n <pre>items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </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 [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\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 [equals]=\"equals\"\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 [equals]=\"equals\"\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>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </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 [equals]=\"equals\"\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>\n <pre>panelWidth: string</pre>\n </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 [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\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 Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\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"
|
|
27449
|
+
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>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </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 [equals]=\"equals\"\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 Entity far in the list (not in first page)\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre style=\"white-space: normal !important;\">value: {{stringify(form.controls.farEntity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"farEntity\" #farEntityField\n [config]=\"autocompleteFields.get('entity-far')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-far]'\"\n [debug]=\"true\"\n [required]=\"true\"\n [clearable]=\"true\"\n placeholder=\"Far entity (in the list)\"\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 Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre>\n </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 [equals]=\"equals\"\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>\n <pre>mobile: true, items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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>\n <pre>mobile: true, items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\n [clearable]=\"true\"\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-text color=\"primary\">\n search with a suggestLengthThreshold\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>\n </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]=\"true\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-mobile-suggestLengthThreshold]'\"\n required\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 Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"true\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-multiple]'\"\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 [equals]=\"equals\"\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>\n <pre></pre>\n </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(filterChangeField, '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\" #filterChangeField\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\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>\n <pre>class=\"min-width-large\"</pre>\n </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 [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\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 <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\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 Fullscreen\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </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 [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-mobile-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\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>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </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></pre>\n </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 [equals]=\"equals\"\n [clearable]=\"true\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n [debug]=\"true\">\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 search with a suggestLengthThreshold\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>\n </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 [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggestLengthThreshold]'\"\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>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </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 [equals]=\"equals\"\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>\n <pre>items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"false\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-multiple]'\"\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>\n <pre>items: Observable<any[]></pre>\n </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 [equals]=\"equals\"\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>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </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 [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\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 [equals]=\"equals\"\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 [equals]=\"equals\"\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>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </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 [equals]=\"equals\"\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>\n <pre>panelWidth: string</pre>\n </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 [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\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 Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\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"
|
|
27986
27450
|
},] }
|
|
27987
27451
|
];
|
|
27988
27452
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -28058,13 +27522,13 @@ LatLongTestPage.ctorParameters = () => [
|
|
|
28058
27522
|
{ type: FormBuilder }
|
|
28059
27523
|
];
|
|
28060
27524
|
|
|
28061
|
-
const moment$
|
|
27525
|
+
const moment$6 = momentImported;
|
|
28062
27526
|
class SwipeTestPage {
|
|
28063
27527
|
constructor(formBuilder, dateFormatPipe) {
|
|
28064
27528
|
this.formBuilder = formBuilder;
|
|
28065
27529
|
this.dateFormatPipe = dateFormatPipe;
|
|
28066
27530
|
this.$dates = new BehaviorSubject(undefined);
|
|
28067
|
-
this._today = moment$
|
|
27531
|
+
this._today = moment$6().startOf('day');
|
|
28068
27532
|
this.form = formBuilder.group({
|
|
28069
27533
|
empty: [null, Validators.required],
|
|
28070
27534
|
date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
|
|
@@ -28077,7 +27541,7 @@ class SwipeTestPage {
|
|
|
28077
27541
|
ngOnInit() {
|
|
28078
27542
|
const dates = [];
|
|
28079
27543
|
for (let d = 0; d < 7; d++) {
|
|
28080
|
-
dates[d] = moment$
|
|
27544
|
+
dates[d] = moment$6(this._today).add(d - 3, 'day');
|
|
28081
27545
|
}
|
|
28082
27546
|
this.$dates.next(dates);
|
|
28083
27547
|
this.loadData();
|
|
@@ -28118,7 +27582,7 @@ SwipeTestPage.ctorParameters = () => [
|
|
|
28118
27582
|
{ type: DateFormatPipe }
|
|
28119
27583
|
];
|
|
28120
27584
|
|
|
28121
|
-
const moment$
|
|
27585
|
+
const moment$7 = momentImported;
|
|
28122
27586
|
class DateTimeTestPage {
|
|
28123
27587
|
constructor(platform, formBuilder, cd) {
|
|
28124
27588
|
this.platform = platform;
|
|
@@ -28150,7 +27614,7 @@ class DateTimeTestPage {
|
|
|
28150
27614
|
// Load the form with data
|
|
28151
27615
|
loadData() {
|
|
28152
27616
|
return __awaiter(this, void 0, void 0, function* () {
|
|
28153
|
-
const now = moment$
|
|
27617
|
+
const now = moment$7();
|
|
28154
27618
|
const data = {
|
|
28155
27619
|
empty: null,
|
|
28156
27620
|
emptyRequired: null,
|
|
@@ -28396,7 +27860,7 @@ NumpadTestPage.ctorParameters = () => [
|
|
|
28396
27860
|
{ type: FormBuilder }
|
|
28397
27861
|
];
|
|
28398
27862
|
|
|
28399
|
-
const moment$
|
|
27863
|
+
const moment$8 = momentImported;
|
|
28400
27864
|
class DateTestPage {
|
|
28401
27865
|
constructor(formBuilder, cd) {
|
|
28402
27866
|
this.formBuilder = formBuilder;
|
|
@@ -28429,7 +27893,7 @@ class DateTestPage {
|
|
|
28429
27893
|
// Load the form with data
|
|
28430
27894
|
loadData() {
|
|
28431
27895
|
return __awaiter(this, void 0, void 0, function* () {
|
|
28432
|
-
const now = moment$
|
|
27896
|
+
const now = moment$8();
|
|
28433
27897
|
const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
|
|
28434
27898
|
const data = {
|
|
28435
27899
|
empty: null,
|
|
@@ -29175,5 +28639,5 @@ CoreTestingModule.decorators = [
|
|
|
29175
28639
|
* Generated bundle index. Do not edit.
|
|
29176
28640
|
*/
|
|
29177
28641
|
|
|
29178
|
-
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal,
|
|
28642
|
+
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj, DateTestPage as ɵk, NumpadTestPage as ɵl, MatBadgeIconTestPage as ɵm, ToastTestingModule as ɵn, ToastTestingPage as ɵo };
|
|
29179
28643
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|