@sumaris-net/ngx-components 1.20.36 → 1.21.0-beta11
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 +1110 -328
- 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 +0 -9
- package/esm2015/public_api.js +8 -3
- package/esm2015/src/app/core/form/editor.class.js +1 -3
- package/esm2015/src/app/core/icon/icon.component.js +5 -2
- 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 +11 -11
- package/esm2015/src/app/shared/functions.js +60 -1
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +4 -5
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +7 -10
- package/esm2015/src/app/shared/material/chips/material.chips.js +2 -3
- package/esm2015/src/app/shared/material/chips/testing/chips.test.js +2 -3
- package/esm2015/src/app/shared/material/datetime/material.date.js +2 -3
- package/esm2015/src/app/shared/material/datetime/material.datetime.js +2 -3
- package/esm2015/src/app/shared/observables.js +5 -4
- package/esm2015/src/app/shared/pipes/arrays.pipe.js +1 -1
- package/esm2015/src/app/shared/pipes/form.pipes.js +4 -2
- package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
- package/esm2015/src/app/shared/pipes/string.pipes.js +18 -7
- package/esm2015/src/app/shared/services/memory-entity-service.class.js +1 -13
- package/esm2015/src/app/shared/types.js +1 -1
- package/esm2015/src/app/social/job/job.model.js +24 -0
- package/esm2015/src/app/social/job/job.module.js +25 -0
- package/esm2015/src/app/social/job/job.service.js +53 -0
- package/esm2015/src/app/social/job/progression/job-progression.component.js +192 -0
- package/esm2015/src/app/social/job/progression/job-progression.list.js +20 -0
- package/esm2015/src/app/social/message/message.module.js +25 -0
- package/esm2015/src/app/social/social.errors.js +5 -2
- package/esm2015/src/app/social/social.module.js +10 -15
- package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +100 -0
- package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +39 -0
- package/esm2015/src/app/social/user-event/user-event.model.js +58 -2
- package/esm2015/src/app/social/user-event/user-event.module.js +28 -0
- package/esm2015/src/app/social/user-event/user-event.service.js +299 -168
- package/esm2015/src/app/social/user-event/user-events.table.js +17 -12
- package/esm2015/sumaris-net.ngx-components.js +8 -6
- package/fesm2015/sumaris-net.ngx-components.js +936 -290
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +2 -3
- package/public_api.d.ts +7 -2
- package/src/app/core/icon/icon.component.d.ts +4 -4
- package/src/app/core/table/table.class.d.ts +6 -8
- package/src/app/shared/functions.d.ts +9 -0
- package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +2 -1
- package/src/app/shared/material/badge/badge-icon.test.d.ts +1 -1
- package/src/app/shared/pipes/form.pipes.d.ts +2 -1
- package/src/app/shared/services/memory-entity-service.class.d.ts +0 -6
- package/src/app/shared/types.d.ts +4 -0
- package/src/app/social/job/job.model.d.ts +32 -0
- package/src/app/social/job/job.module.d.ts +2 -0
- package/src/app/social/job/job.service.d.ts +23 -0
- package/src/app/social/job/progression/job-progression.component.d.ts +43 -0
- package/src/app/social/job/progression/job-progression.list.d.ts +12 -0
- package/src/app/social/message/message.module.d.ts +2 -0
- package/src/app/social/social.errors.d.ts +3 -0
- package/src/app/social/social.module.d.ts +8 -0
- package/src/app/social/user-event/notification/user-event-notification.component.d.ts +25 -0
- package/src/app/social/user-event/notification/user-event-notification.list.d.ts +20 -0
- package/src/app/social/user-event/user-event.model.d.ts +51 -6
- package/src/app/social/user-event/user-event.module.d.ts +2 -0
- package/src/app/social/user-event/user-event.service.d.ts +79 -51
- package/src/app/social/user-event/user-events.table.d.ts +6 -6
- package/src/assets/i18n/en-US.json +15 -2
- package/src/assets/i18n/en.json +15 -2
- package/src/assets/i18n/fr.json +14 -1
- package/src/theme/_ngx-components.scss +7 -0
- package/sumaris-net.ngx-components.d.ts +7 -5
- package/sumaris-net.ngx-components.metadata.json +1 -1
- package/esm2015/src/app/shared/services.js +0 -61
- package/src/app/shared/services.d.ts +0 -9
|
@@ -241,6 +241,64 @@ 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
|
+
}
|
|
244
302
|
function suggestFromStringArray(values, value, options) {
|
|
245
303
|
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
246
304
|
if (isNilOrBlank(value))
|
|
@@ -821,11 +879,12 @@ function waitFor(predicate, opts) {
|
|
|
821
879
|
}
|
|
822
880
|
function waitForTrue(observable, opts) {
|
|
823
881
|
return __awaiter(this, void 0, void 0, function* () {
|
|
882
|
+
const firstTrueObservable = firstTrue(observable);
|
|
824
883
|
// Timeout (+ dueTime)
|
|
825
884
|
if (opts && opts.timeout > 0) {
|
|
826
885
|
const $timeout = timer(opts.timeout);
|
|
827
886
|
return merge(timer(opts.dueTime || 0)
|
|
828
|
-
.pipe(switchMap(() =>
|
|
887
|
+
.pipe(switchMap(() => firstTrueObservable), takeUntil($timeout)), $timeout
|
|
829
888
|
.pipe(map(() => {
|
|
830
889
|
throw new Error(`Timeout ready() - after ${opts.timeout}ms`);
|
|
831
890
|
})))
|
|
@@ -834,10 +893,10 @@ function waitForTrue(observable, opts) {
|
|
|
834
893
|
// dueTime (without timeout)
|
|
835
894
|
if (opts && opts.dueTime > 0) {
|
|
836
895
|
return timer(opts.dueTime)
|
|
837
|
-
.pipe(switchMap(() =>
|
|
896
|
+
.pipe(switchMap(() => firstTrueObservable))
|
|
838
897
|
.toPromise();
|
|
839
898
|
}
|
|
840
|
-
return
|
|
899
|
+
return firstTrueObservable.toPromise();
|
|
841
900
|
});
|
|
842
901
|
}
|
|
843
902
|
|
|
@@ -1041,65 +1100,6 @@ const isMobile = (win) => {
|
|
|
1041
1100
|
return _cache.mobile;
|
|
1042
1101
|
};
|
|
1043
1102
|
|
|
1044
|
-
function suggestFromArray(items, value, opts) {
|
|
1045
|
-
if (isNotNil(value) && typeof value === 'object')
|
|
1046
|
-
return { data: [value] };
|
|
1047
|
-
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
1048
|
-
const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
|
|
1049
|
-
if (!items) {
|
|
1050
|
-
return { data: [], total: 0 };
|
|
1051
|
-
}
|
|
1052
|
-
// Filter items
|
|
1053
|
-
let filteredItems = items;
|
|
1054
|
-
if (isNotNilOrBlank(value)) {
|
|
1055
|
-
// If wildcard, search using regexp
|
|
1056
|
-
if (value.indexOf('*') !== -1) {
|
|
1057
|
-
value = value.replace(/[*]+/g, '.*');
|
|
1058
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1059
|
-
}
|
|
1060
|
-
// Else (no wildcard), search using startsWith
|
|
1061
|
-
else {
|
|
1062
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
// Exclude ids
|
|
1066
|
-
if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
|
|
1067
|
-
filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
|
|
1068
|
-
}
|
|
1069
|
-
// Sort
|
|
1070
|
-
if (!opts || opts.skipSort !== true) {
|
|
1071
|
-
// Make to copy input items, before sorting (if not yet already done)
|
|
1072
|
-
if (filteredItems === items)
|
|
1073
|
-
filteredItems = filteredItems.slice();
|
|
1074
|
-
// Sort by keys
|
|
1075
|
-
filteredItems.sort(propertiesPathComparator(keys));
|
|
1076
|
-
}
|
|
1077
|
-
const total = filteredItems.length || 0;
|
|
1078
|
-
// Pagination (truncate if need)
|
|
1079
|
-
let pageData = filteredItems;
|
|
1080
|
-
if (opts) {
|
|
1081
|
-
if ((opts.offset || 0) > 0) {
|
|
1082
|
-
pageData = pageData.slice(opts.offset);
|
|
1083
|
-
}
|
|
1084
|
-
if (isNotNil(opts.size) && pageData.length > opts.size) {
|
|
1085
|
-
pageData = pageData.slice(0, opts.size);
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
const result = {
|
|
1089
|
-
data: pageData,
|
|
1090
|
-
total
|
|
1091
|
-
};
|
|
1092
|
-
// Add fetch more capability, if total was fetched
|
|
1093
|
-
const nextOffset = (opts && opts.offset || 0) + pageData.length;
|
|
1094
|
-
if (nextOffset < total) {
|
|
1095
|
-
result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
|
|
1096
|
-
return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
|
|
1097
|
-
}));
|
|
1098
|
-
});
|
|
1099
|
-
}
|
|
1100
|
-
return result;
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
1103
|
class MatAutocompleteConfigHolder {
|
|
1104
1104
|
constructor(options) {
|
|
1105
1105
|
this.options = options;
|
|
@@ -1360,11 +1360,11 @@ class MatAutocompleteField {
|
|
|
1360
1360
|
// Search text (no distinctUntilChanged() because of the debounceTime() pipe)
|
|
1361
1361
|
this.formControl.valueChanges
|
|
1362
1362
|
.pipe(filter(value => this.enabled && isNotNilString(value)),
|
|
1363
|
-
// Mark as loading (to show loading spinner) -
|
|
1363
|
+
// Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
|
|
1364
1364
|
tap(_ => this.showLoadingSpinner && this.markAsLoading()),
|
|
1365
1365
|
// Filter if not enough character
|
|
1366
1366
|
filter(value => {
|
|
1367
|
-
if (
|
|
1367
|
+
if (value.length <= this.suggestLengthThreshold) {
|
|
1368
1368
|
// Update display value, to enable the message "not enough characters"
|
|
1369
1369
|
this.displayValue = value;
|
|
1370
1370
|
return false;
|
|
@@ -2328,9 +2328,9 @@ class HighlightPipe {
|
|
|
2328
2328
|
const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
|
|
2329
2329
|
const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
|
|
2330
2330
|
if (index !== -1) {
|
|
2331
|
-
return value.
|
|
2332
|
-
'<b>' + value.
|
|
2333
|
-
value.
|
|
2331
|
+
return value.substr(0, index - 1) +
|
|
2332
|
+
'<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
|
|
2333
|
+
value.substr(index + cleanedSearchText.length);
|
|
2334
2334
|
}
|
|
2335
2335
|
return value;
|
|
2336
2336
|
}
|
|
@@ -2728,50 +2728,60 @@ class IsNotNilOrBlankPipe {
|
|
|
2728
2728
|
return isNotNilOrBlank(value);
|
|
2729
2729
|
}
|
|
2730
2730
|
}
|
|
2731
|
+
IsNotNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
|
|
2731
2732
|
IsNotNilOrBlankPipe.decorators = [
|
|
2732
2733
|
{ type: Pipe, args: [{
|
|
2733
2734
|
name: 'isNotNilOrBlank'
|
|
2734
|
-
},] }
|
|
2735
|
+
},] },
|
|
2736
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2735
2737
|
];
|
|
2736
2738
|
class IsNilOrBlankPipe {
|
|
2737
2739
|
transform(value) {
|
|
2738
2740
|
return isNilOrBlank(value);
|
|
2739
2741
|
}
|
|
2740
2742
|
}
|
|
2743
|
+
IsNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
|
|
2741
2744
|
IsNilOrBlankPipe.decorators = [
|
|
2742
2745
|
{ type: Pipe, args: [{
|
|
2743
2746
|
name: 'isNilOrBlank'
|
|
2744
|
-
},] }
|
|
2747
|
+
},] },
|
|
2748
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2745
2749
|
];
|
|
2746
2750
|
class ToStringPipe {
|
|
2747
2751
|
transform(value) {
|
|
2748
2752
|
return (value !== null && value !== undefined) ? value.toString() : '';
|
|
2749
2753
|
}
|
|
2750
2754
|
}
|
|
2755
|
+
ToStringPipe.ɵprov = ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
|
|
2751
2756
|
ToStringPipe.decorators = [
|
|
2752
2757
|
{ type: Pipe, args: [{
|
|
2753
2758
|
name: 'toString'
|
|
2754
|
-
},] }
|
|
2759
|
+
},] },
|
|
2760
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2755
2761
|
];
|
|
2756
2762
|
class StrLengthPipe {
|
|
2757
2763
|
transform(value) {
|
|
2758
2764
|
return value && value.length || 0;
|
|
2759
2765
|
}
|
|
2760
2766
|
}
|
|
2767
|
+
StrLengthPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
|
|
2761
2768
|
StrLengthPipe.decorators = [
|
|
2762
2769
|
{ type: Pipe, args: [{
|
|
2763
2770
|
name: 'strLength'
|
|
2764
|
-
},] }
|
|
2771
|
+
},] },
|
|
2772
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2765
2773
|
];
|
|
2766
2774
|
class StrIncludesPipe {
|
|
2767
2775
|
transform(value, searchString, position) {
|
|
2768
2776
|
return (value === null || value === void 0 ? void 0 : value.includes(searchString, position)) || false;
|
|
2769
2777
|
}
|
|
2770
2778
|
}
|
|
2779
|
+
StrIncludesPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
|
|
2771
2780
|
StrIncludesPipe.decorators = [
|
|
2772
2781
|
{ type: Pipe, args: [{
|
|
2773
2782
|
name: 'strIncludes'
|
|
2774
|
-
},] }
|
|
2783
|
+
},] },
|
|
2784
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2775
2785
|
];
|
|
2776
2786
|
|
|
2777
2787
|
class TranslateContextService {
|
|
@@ -4222,7 +4232,8 @@ FormGetGroupPipe.decorators = [
|
|
|
4222
4232
|
},] }
|
|
4223
4233
|
];
|
|
4224
4234
|
class FormGetValuePipe {
|
|
4225
|
-
constructor(_ref) {
|
|
4235
|
+
constructor(adapter, _ref) {
|
|
4236
|
+
this.adapter = adapter;
|
|
4226
4237
|
this._ref = _ref;
|
|
4227
4238
|
this.value = undefined;
|
|
4228
4239
|
this._lastControl = null;
|
|
@@ -4287,6 +4298,7 @@ FormGetValuePipe.decorators = [
|
|
|
4287
4298
|
},] }
|
|
4288
4299
|
];
|
|
4289
4300
|
FormGetValuePipe.ctorParameters = () => [
|
|
4301
|
+
{ type: FormErrorTranslator },
|
|
4290
4302
|
{ type: ChangeDetectorRef }
|
|
4291
4303
|
];
|
|
4292
4304
|
|
|
@@ -5157,8 +5169,7 @@ class MatDate {
|
|
|
5157
5169
|
set tabindex(value) {
|
|
5158
5170
|
if (this._tabindex !== value) {
|
|
5159
5171
|
this._tabindex = value;
|
|
5160
|
-
|
|
5161
|
-
this.updateTabIndex();
|
|
5172
|
+
setTimeout(() => this.updateTabIndex());
|
|
5162
5173
|
}
|
|
5163
5174
|
}
|
|
5164
5175
|
get tabindex() {
|
|
@@ -5517,8 +5528,7 @@ class MatDateTime {
|
|
|
5517
5528
|
set tabindex(value) {
|
|
5518
5529
|
if (this._tabindex !== value) {
|
|
5519
5530
|
this._tabindex = value;
|
|
5520
|
-
|
|
5521
|
-
this.updateTabIndex();
|
|
5531
|
+
setTimeout(() => this.updateTabIndex());
|
|
5522
5532
|
}
|
|
5523
5533
|
}
|
|
5524
5534
|
get tabindex() {
|
|
@@ -10697,7 +10707,7 @@ class LocalSettingsService extends StartableService {
|
|
|
10697
10707
|
}
|
|
10698
10708
|
get usageMode() {
|
|
10699
10709
|
var _a;
|
|
10700
|
-
if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.
|
|
10710
|
+
if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.mobile)) {
|
|
10701
10711
|
console.warn("[settings] Accessing to property 'usageMode' BEFORE service started! Please use ready()");
|
|
10702
10712
|
return isCordova(window) ? 'FIELD' : 'DESK';
|
|
10703
10713
|
}
|
|
@@ -18203,18 +18213,6 @@ class InMemoryEntitiesService extends EntitiesService {
|
|
|
18203
18213
|
return this._equalsFn(d1, d2);
|
|
18204
18214
|
return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
|
|
18205
18215
|
}
|
|
18206
|
-
/**
|
|
18207
|
-
* Count data stored by the service (without hidden data).
|
|
18208
|
-
* @param opts
|
|
18209
|
-
*/
|
|
18210
|
-
get count() {
|
|
18211
|
-
var _a;
|
|
18212
|
-
return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
|
|
18213
|
-
}
|
|
18214
|
-
get hiddenCount() {
|
|
18215
|
-
var _a;
|
|
18216
|
-
return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
18217
|
-
}
|
|
18218
18216
|
/* -- protected methods -- */
|
|
18219
18217
|
filter(data, _filter, hiddenData) {
|
|
18220
18218
|
// if filter is DataFilter instance, use its test function
|
|
@@ -21433,7 +21431,7 @@ class MenuComponent {
|
|
|
21433
21431
|
MenuComponent.decorators = [
|
|
21434
21432
|
{ type: Component, args: [{
|
|
21435
21433
|
selector: 'app-menu',
|
|
21436
|
-
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",
|
|
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<!-- todo ajouter ici les 2 composants du module social -->\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",
|
|
21437
21435
|
animations: [fadeInAnimation],
|
|
21438
21436
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21439
21437
|
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)}}"]
|
|
@@ -21497,13 +21495,14 @@ class AppIconComponent {
|
|
|
21497
21495
|
this.icon = value.icon;
|
|
21498
21496
|
this.matIcon = value.matIcon;
|
|
21499
21497
|
this.matSvgIcon = value.matSvgIcon;
|
|
21498
|
+
this.color = value.color;
|
|
21500
21499
|
}
|
|
21501
21500
|
;
|
|
21502
21501
|
}
|
|
21503
21502
|
AppIconComponent.decorators = [
|
|
21504
21503
|
{ type: Component, args: [{
|
|
21505
21504
|
selector: 'app-icon',
|
|
21506
|
-
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"
|
|
21505
|
+
template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n [style.font-size.px]=\"height || width\"\n >{{matIcon}}</mat-icon>\n</ng-template>\n\n"
|
|
21507
21506
|
},] }
|
|
21508
21507
|
];
|
|
21509
21508
|
AppIconComponent.propDecorators = {
|
|
@@ -21511,6 +21510,8 @@ AppIconComponent.propDecorators = {
|
|
|
21511
21510
|
matIcon: [{ type: Input }],
|
|
21512
21511
|
matSvgIcon: [{ type: Input }],
|
|
21513
21512
|
color: [{ type: Input }],
|
|
21513
|
+
height: [{ type: Input }],
|
|
21514
|
+
width: [{ type: Input }],
|
|
21514
21515
|
ref: [{ type: Input }]
|
|
21515
21516
|
};
|
|
21516
21517
|
|
|
@@ -23012,7 +23013,7 @@ class AppTable {
|
|
|
23012
23013
|
.then(() => this.editRowById(event, row.id, { focusColumn: this.lastUserColumn }));
|
|
23013
23014
|
return true;
|
|
23014
23015
|
}
|
|
23015
|
-
// Edit
|
|
23016
|
+
// Edit next row
|
|
23016
23017
|
this.editRow(event, row, { focusColumn: this.lastUserColumn });
|
|
23017
23018
|
return true;
|
|
23018
23019
|
}
|
|
@@ -23035,7 +23036,8 @@ class AppTable {
|
|
|
23035
23036
|
if (id < 0)
|
|
23036
23037
|
return;
|
|
23037
23038
|
if (id >= this.visibleRowCount) {
|
|
23038
|
-
this.
|
|
23039
|
+
this.focusColumn = opts && opts.focusColumn || this.firstUserColumn;
|
|
23040
|
+
this.addRow(event);
|
|
23039
23041
|
}
|
|
23040
23042
|
else {
|
|
23041
23043
|
const row = yield this.dataSource.getRow(id);
|
|
@@ -23108,7 +23110,7 @@ class AppTable {
|
|
|
23108
23110
|
this.cancelExistingRow(event, row, opts);
|
|
23109
23111
|
}
|
|
23110
23112
|
}
|
|
23111
|
-
addRow(event, insertAt
|
|
23113
|
+
addRow(event, insertAt) {
|
|
23112
23114
|
if (this.debug)
|
|
23113
23115
|
console.debug('[table] Asking for new row...');
|
|
23114
23116
|
if (!this._enabled)
|
|
@@ -23123,7 +23125,7 @@ class AppTable {
|
|
|
23123
23125
|
return false;
|
|
23124
23126
|
}
|
|
23125
23127
|
// Add new row
|
|
23126
|
-
this.addRowToTable(insertAt
|
|
23128
|
+
this.addRowToTable(insertAt);
|
|
23127
23129
|
return true;
|
|
23128
23130
|
}
|
|
23129
23131
|
save(opts) {
|
|
@@ -23238,7 +23240,7 @@ class AppTable {
|
|
|
23238
23240
|
* @param event
|
|
23239
23241
|
* @param row
|
|
23240
23242
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23241
|
-
*
|
|
23243
|
+
* Use skipIfLoading=false to force deletion even if table is busy
|
|
23242
23244
|
*/
|
|
23243
23245
|
deleteRow(event, row, opts) {
|
|
23244
23246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -23251,7 +23253,7 @@ class AppTable {
|
|
|
23251
23253
|
* @param event
|
|
23252
23254
|
* @param rows
|
|
23253
23255
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23254
|
-
*
|
|
23256
|
+
* Use skipIfLoading=false to force deletion even if table is busy
|
|
23255
23257
|
*/
|
|
23256
23258
|
deleteRows(event, rows, opts) {
|
|
23257
23259
|
var _a;
|
|
@@ -23264,8 +23266,8 @@ class AppTable {
|
|
|
23264
23266
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
23265
23267
|
if (!this._enabled || isEmptyArray(rows))
|
|
23266
23268
|
return 0; // Skip is disabled, or no rows to delete
|
|
23267
|
-
if (this.loading && (!opts || opts.
|
|
23268
|
-
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.
|
|
23269
|
+
if (this.loading && (!opts || opts.skipIfLoading !== false)) {
|
|
23270
|
+
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.skipLoading = false to force deletion');
|
|
23269
23271
|
return 0; // Skip if loading
|
|
23270
23272
|
}
|
|
23271
23273
|
// Make sure to keep newly created row
|
|
@@ -23788,10 +23790,9 @@ class AppTable {
|
|
|
23788
23790
|
//if (this.debug) console.debug("[table] id = " + id);
|
|
23789
23791
|
return id;
|
|
23790
23792
|
}
|
|
23791
|
-
addRowToTable(insertAt
|
|
23793
|
+
addRowToTable(insertAt) {
|
|
23792
23794
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23793
23795
|
this.focusFirstColumn = true;
|
|
23794
|
-
this.focusColumn = (opts === null || opts === void 0 ? void 0 : opts.focusColumn) || this.firstUserColumn;
|
|
23795
23796
|
yield this._dataSource.asyncCreateNew(insertAt);
|
|
23796
23797
|
this.editedRow = this._dataSource.getRow(-1);
|
|
23797
23798
|
// Emit start editing event
|
|
@@ -24307,8 +24308,6 @@ class AppEditor {
|
|
|
24307
24308
|
}
|
|
24308
24309
|
ready(opts) {
|
|
24309
24310
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24310
|
-
if (this._$ready.value)
|
|
24311
|
-
return;
|
|
24312
24311
|
return waitForTrue(this._$ready, opts);
|
|
24313
24312
|
});
|
|
24314
24313
|
}
|
|
@@ -25824,7 +25823,10 @@ AppInMemoryTable.propDecorators = {
|
|
|
25824
25823
|
const SocialErrorCodes = {
|
|
25825
25824
|
LOAD_USER_EVENTS_ERROR: 50000,
|
|
25826
25825
|
SAVE_USER_EVENT_ERROR: 50001,
|
|
25827
|
-
|
|
25826
|
+
COUNT_USER_EVENT_ERROR: 50002,
|
|
25827
|
+
SEND_MESSAGE_ERROR: 50003,
|
|
25828
|
+
SUBSCRIBE_USER_EVENTS_ERROR: 50005,
|
|
25829
|
+
SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
|
|
25828
25830
|
};
|
|
25829
25831
|
|
|
25830
25832
|
var UserEvent_1;
|
|
@@ -25839,16 +25841,23 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25839
25841
|
}
|
|
25840
25842
|
asObject(opts) {
|
|
25841
25843
|
const target = super.asObject(opts);
|
|
25844
|
+
target.creationDate = toDateISOString(this.creationDate);
|
|
25845
|
+
target.readDate = toDateISOString(this.readDate);
|
|
25842
25846
|
// Serialize content
|
|
25843
25847
|
if (typeof target.content === 'object') {
|
|
25844
25848
|
target.content = JSON.stringify(target.content);
|
|
25845
25849
|
}
|
|
25850
|
+
delete target.avatar;
|
|
25851
|
+
delete target.avatarIcon;
|
|
25852
|
+
delete target.icon;
|
|
25853
|
+
delete target.actions;
|
|
25846
25854
|
return target;
|
|
25847
25855
|
}
|
|
25848
25856
|
fromObject(source) {
|
|
25849
25857
|
Object.assign(this, source); // Copy all properties
|
|
25850
25858
|
super.fromObject(source);
|
|
25851
25859
|
this.creationDate = fromDateISOString(source.creationDate);
|
|
25860
|
+
this.readDate = fromDateISOString(source.readDate);
|
|
25852
25861
|
try {
|
|
25853
25862
|
// Deserialize content
|
|
25854
25863
|
if (typeof source.content === 'string' && source.content.startsWith('{')) {
|
|
@@ -25867,6 +25876,52 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25867
25876
|
UserEvent = UserEvent_1 = __decorate([
|
|
25868
25877
|
EntityClass({ typename: 'UserEventVO' })
|
|
25869
25878
|
], 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);
|
|
25870
25925
|
|
|
25871
25926
|
const UserEventFragments = {
|
|
25872
25927
|
userEvent: gql `fragment UserEventFragment on UserEventVO {
|
|
@@ -25894,179 +25949,162 @@ const UserEventFragments = {
|
|
|
25894
25949
|
}`
|
|
25895
25950
|
};
|
|
25896
25951
|
|
|
25897
|
-
|
|
25898
|
-
|
|
25899
|
-
|
|
25900
|
-
|
|
25901
|
-
this.issuer = null;
|
|
25902
|
-
this.recipient = null;
|
|
25903
|
-
}
|
|
25904
|
-
fromObject(source, opts) {
|
|
25905
|
-
super.fromObject(source, opts);
|
|
25906
|
-
this.issuer = source.issuer;
|
|
25907
|
-
this.recipient = source.recipient;
|
|
25908
|
-
}
|
|
25909
|
-
buildFilter() {
|
|
25910
|
-
const filterFns = super.buildFilter();
|
|
25911
|
-
// issuer
|
|
25912
|
-
if (this.issuer) {
|
|
25913
|
-
filterFns.push(t => (t.issuer === this.issuer));
|
|
25914
|
-
}
|
|
25915
|
-
if (this.recipient) {
|
|
25916
|
-
filterFns.push(t => (t.recipient === this.recipient));
|
|
25917
|
-
}
|
|
25918
|
-
return filterFns;
|
|
25919
|
-
}
|
|
25920
|
-
};
|
|
25921
|
-
UserEventFilter = __decorate([
|
|
25922
|
-
EntityClass({ typename: 'UserEventFilterVO' })
|
|
25923
|
-
], UserEventFilter);
|
|
25924
|
-
const SaveQuery = gql `
|
|
25925
|
-
mutation SaveUserEvent($data: UserEventVOInput){
|
|
25926
|
-
data: saveUserEvent(userEvent: $data){
|
|
25927
|
-
...UserEventFragment
|
|
25928
|
-
}
|
|
25929
|
-
}
|
|
25930
|
-
${UserEventFragments.userEvent}
|
|
25931
|
-
`;
|
|
25932
|
-
const LoadAllQuery = gql `
|
|
25933
|
-
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
25934
|
-
data: userEvents(filter: $filter, page: $page){
|
|
25935
|
-
...LightUserEventFragment
|
|
25936
|
-
}
|
|
25937
|
-
}
|
|
25938
|
-
${UserEventFragments.lightUserEvent}
|
|
25939
|
-
`;
|
|
25940
|
-
const DeleteByIdsMutation = gql `
|
|
25941
|
-
mutation DeleteUserEvents($ids:[Int]){
|
|
25942
|
-
deleteUserEvents(ids: $ids)
|
|
25943
|
-
}
|
|
25944
|
-
`;
|
|
25945
|
-
const LoadAllWithContentQuery = gql `
|
|
25946
|
-
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
25947
|
-
data: userEvents(filter: $filter, page: $page){
|
|
25948
|
-
...UserEventFragment
|
|
25949
|
-
}
|
|
25950
|
-
}
|
|
25951
|
-
${UserEventFragments.userEvent}
|
|
25952
|
-
`;
|
|
25953
|
-
class UserEventService extends BaseGraphqlService {
|
|
25954
|
-
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
25952
|
+
const moment$6 = momentImported;
|
|
25953
|
+
const UserEventServiceToken = new InjectionToken('UserEventService');
|
|
25954
|
+
class AbstractUserEventService extends BaseGraphqlService {
|
|
25955
|
+
constructor(graphql, accountService, network, translate, queries, mutations, subscriptions, environment) {
|
|
25955
25956
|
super(graphql, environment);
|
|
25956
25957
|
this.graphql = graphql;
|
|
25957
25958
|
this.accountService = accountService;
|
|
25958
25959
|
this.network = network;
|
|
25959
25960
|
this.translate = translate;
|
|
25960
|
-
this.
|
|
25961
|
+
this.queries = queries;
|
|
25962
|
+
this.mutations = mutations;
|
|
25963
|
+
this.subscriptions = subscriptions;
|
|
25961
25964
|
this.environment = environment;
|
|
25962
|
-
this.
|
|
25965
|
+
this._count$ = new BehaviorSubject(0);
|
|
25966
|
+
this._subscriptions = new Subscription();
|
|
25967
|
+
this.listeners = [];
|
|
25968
|
+
this._logPrefix = '[user-event-service] ';
|
|
25963
25969
|
// For DEV only
|
|
25964
|
-
this._debug = environment
|
|
25970
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
25971
|
+
// listen login/logout
|
|
25972
|
+
this._subscriptions.add(accountService.onLogin.subscribe(() => __awaiter(this, void 0, void 0, function* () {
|
|
25973
|
+
const count = yield this.count(undefined);
|
|
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();
|
|
25965
25985
|
}
|
|
25966
|
-
/**
|
|
25967
|
-
*
|
|
25968
|
-
* @param offset
|
|
25969
|
-
* @param size
|
|
25970
|
-
* @param sortBy
|
|
25971
|
-
* @param sortDirection
|
|
25972
|
-
* @param filter
|
|
25973
|
-
* @param options
|
|
25974
|
-
* @deprecated use watchPage() instead
|
|
25975
|
-
*/
|
|
25976
25986
|
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
25977
25987
|
return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
|
|
25978
25988
|
}
|
|
25979
25989
|
watchPage(page, filter, options) {
|
|
25990
|
+
var _a;
|
|
25980
25991
|
let now = this._debug && Date.now();
|
|
25981
|
-
|
|
25982
|
-
|
|
25992
|
+
if (!filter) {
|
|
25993
|
+
filter = this.defaultFilter();
|
|
25994
|
+
}
|
|
25995
|
+
console.debug(`${this._logPrefix}Loading user events...`, filter);
|
|
25983
25996
|
filter = this.asFilter(filter);
|
|
25984
25997
|
// Force recipient to current issuer, if not admin and not specified
|
|
25985
|
-
if (
|
|
25986
|
-
const recipient = this.
|
|
25987
|
-
if (
|
|
25998
|
+
if (isEmptyArray(filter === null || filter === void 0 ? void 0 : filter.recipients) || !this.accountService.isAdmin()) {
|
|
25999
|
+
const recipient = this.defaultRecipient();
|
|
26000
|
+
if (!((_a = filter === null || filter === void 0 ? void 0 : filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
|
|
25988
26001
|
console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
|
|
25989
|
-
filter.
|
|
26002
|
+
filter.recipients = [recipient];
|
|
25990
26003
|
}
|
|
25991
26004
|
}
|
|
25992
|
-
const withContent = options
|
|
26005
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
25993
26006
|
return this.mutableWatchQuery({
|
|
25994
26007
|
queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
|
|
25995
|
-
query: withContent ?
|
|
26008
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
25996
26009
|
variables: {
|
|
25997
|
-
page: Object.assign(Object.assign({ sortBy: '
|
|
26010
|
+
page: Object.assign(Object.assign({ sortBy: 'creationDate' }, page), {
|
|
26011
|
+
// @ts-ignore
|
|
26012
|
+
sortDirection: (page.sortDirection || 'desc').toUpperCase() }),
|
|
25998
26013
|
filter: filter && filter.asPodObject()
|
|
25999
26014
|
},
|
|
26000
26015
|
arrayFieldName: 'data',
|
|
26001
26016
|
error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
|
|
26002
|
-
fetchPolicy: options
|
|
26017
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
|
|
26003
26018
|
})
|
|
26004
26019
|
.pipe(map(res => {
|
|
26005
|
-
const data = res
|
|
26020
|
+
const data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(value => this.processUserEvent(value, this));
|
|
26006
26021
|
if (now) {
|
|
26007
|
-
console.debug(
|
|
26022
|
+
console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);
|
|
26008
26023
|
now = null;
|
|
26009
26024
|
}
|
|
26025
|
+
const unreadCount = this.unreadEvents(data);
|
|
26010
26026
|
return {
|
|
26011
26027
|
data,
|
|
26012
|
-
total: res
|
|
26028
|
+
total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
|
|
26013
26029
|
};
|
|
26014
26030
|
}));
|
|
26015
26031
|
}
|
|
26016
|
-
|
|
26017
|
-
|
|
26018
|
-
|
|
26032
|
+
add(entity) {
|
|
26033
|
+
// TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
26034
|
+
entity = this.processUserEvent(entity);
|
|
26035
|
+
const withContent = !!entity.content;
|
|
26036
|
+
// Add user event locally
|
|
26037
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26038
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26039
|
+
data: entity
|
|
26040
|
+
});
|
|
26041
|
+
// Update count
|
|
26042
|
+
this._count$.next(this._count$.value + 1);
|
|
26019
26043
|
}
|
|
26020
|
-
|
|
26021
|
-
|
|
26022
|
-
*
|
|
26023
|
-
* @param entity
|
|
26024
|
-
*/
|
|
26025
|
-
save(entity, options) {
|
|
26044
|
+
count(filter, options) {
|
|
26045
|
+
var _a;
|
|
26026
26046
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26027
|
-
this.
|
|
26028
|
-
|
|
26029
|
-
|
|
26030
|
-
|
|
26031
|
-
|
|
26047
|
+
if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
|
|
26048
|
+
console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
|
|
26049
|
+
return undefined;
|
|
26050
|
+
}
|
|
26051
|
+
if (!filter)
|
|
26052
|
+
filter = this.defaultFilter();
|
|
26053
|
+
filter = this.asFilter(filter);
|
|
26032
26054
|
if (this._debug)
|
|
26033
|
-
console.debug(
|
|
26034
|
-
yield this.graphql.
|
|
26035
|
-
|
|
26055
|
+
console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
|
|
26056
|
+
const res = yield this.graphql.query({
|
|
26057
|
+
query: this.queries.count,
|
|
26036
26058
|
variables: {
|
|
26037
|
-
|
|
26059
|
+
filter: filter.asPodObject()
|
|
26038
26060
|
},
|
|
26039
|
-
error: { code: SocialErrorCodes.
|
|
26040
|
-
|
|
26041
|
-
// Update entity
|
|
26042
|
-
const savedEntity = data && data.data;
|
|
26043
|
-
if (savedEntity) {
|
|
26044
|
-
if (this._debug)
|
|
26045
|
-
console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
|
|
26046
|
-
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26047
|
-
// Add to cache
|
|
26048
|
-
if (isNew) {
|
|
26049
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26050
|
-
query: LoadAllQuery,
|
|
26051
|
-
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26052
|
-
});
|
|
26053
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26054
|
-
query: LoadAllWithContentQuery,
|
|
26055
|
-
data: savedEntity
|
|
26056
|
-
});
|
|
26057
|
-
}
|
|
26058
|
-
}
|
|
26059
|
-
}
|
|
26061
|
+
error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
|
|
26062
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
|
|
26060
26063
|
});
|
|
26061
|
-
return
|
|
26064
|
+
return res.total;
|
|
26065
|
+
});
|
|
26066
|
+
}
|
|
26067
|
+
listenChanges(filter, options) {
|
|
26068
|
+
var _a;
|
|
26069
|
+
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
|
|
26070
|
+
console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
|
|
26071
|
+
return of();
|
|
26072
|
+
}
|
|
26073
|
+
if (!filter)
|
|
26074
|
+
filter = this.defaultFilter();
|
|
26075
|
+
filter = this.asFilter(filter);
|
|
26076
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26077
|
+
if (this._debug)
|
|
26078
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
|
|
26079
|
+
return this.graphql.subscribe({
|
|
26080
|
+
query: this.subscriptions.listenChanges,
|
|
26081
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26082
|
+
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26083
|
+
error: {
|
|
26084
|
+
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26085
|
+
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26086
|
+
}
|
|
26087
|
+
}).pipe(map(({ data }) => {
|
|
26088
|
+
if (data && this._debug)
|
|
26089
|
+
console.debug(`${this._logPrefix}Received new user events:`, data);
|
|
26090
|
+
const updatedData = data === null || data === void 0 ? void 0 : data.map(value => this.processUserEvent(value, this));
|
|
26091
|
+
// Update cache
|
|
26092
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26093
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26094
|
+
data: updatedData
|
|
26095
|
+
});
|
|
26096
|
+
// update count
|
|
26097
|
+
this._count$.next(this.unreadEvents(updatedData));
|
|
26098
|
+
return updatedData;
|
|
26099
|
+
}));
|
|
26100
|
+
}
|
|
26101
|
+
delete(entity) {
|
|
26102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26103
|
+
if (!entity)
|
|
26104
|
+
return; // skip
|
|
26105
|
+
yield this.deleteAll([entity]);
|
|
26062
26106
|
});
|
|
26063
26107
|
}
|
|
26064
|
-
/**
|
|
26065
|
-
* Save many trips
|
|
26066
|
-
*
|
|
26067
|
-
* @param entities
|
|
26068
|
-
* @param opts
|
|
26069
|
-
*/
|
|
26070
26108
|
deleteAll(entities, opts) {
|
|
26071
26109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26072
26110
|
const ids = entities && entities
|
|
@@ -26075,49 +26113,206 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26075
26113
|
return; // stop, if nothing else to do
|
|
26076
26114
|
const now = Date.now();
|
|
26077
26115
|
if (this._debug)
|
|
26078
|
-
console.debug(
|
|
26116
|
+
console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
|
|
26079
26117
|
yield this.graphql.mutate({
|
|
26080
|
-
mutation:
|
|
26118
|
+
mutation: this.mutations.deleteByIds,
|
|
26081
26119
|
variables: {
|
|
26082
26120
|
ids
|
|
26083
26121
|
},
|
|
26084
26122
|
update: (proxy) => {
|
|
26085
26123
|
// Remove from caches
|
|
26086
26124
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26087
|
-
query:
|
|
26125
|
+
query: this.queries.loadAll,
|
|
26088
26126
|
ids
|
|
26089
26127
|
});
|
|
26090
26128
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26091
|
-
query:
|
|
26129
|
+
query: this.queries.loadAllWithContent,
|
|
26092
26130
|
ids
|
|
26093
26131
|
});
|
|
26094
26132
|
if (this._debug)
|
|
26095
|
-
console.debug(
|
|
26133
|
+
console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
|
|
26096
26134
|
}
|
|
26097
26135
|
});
|
|
26098
26136
|
});
|
|
26099
26137
|
}
|
|
26100
|
-
|
|
26101
|
-
* Delete userEvent entities
|
|
26102
|
-
*/
|
|
26103
|
-
delete(data) {
|
|
26138
|
+
save(entity, options) {
|
|
26104
26139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26105
|
-
|
|
26106
|
-
|
|
26107
|
-
|
|
26140
|
+
this.fillDefaultProperties(entity);
|
|
26141
|
+
// Transform into json
|
|
26142
|
+
const isNew = isNil(entity.id);
|
|
26143
|
+
const json = entity.asObject();
|
|
26144
|
+
const now = Date.now();
|
|
26145
|
+
if (this._debug)
|
|
26146
|
+
console.debug(`${this._logPrefix}Saving user event...`, json);
|
|
26147
|
+
yield this.graphql.mutate({
|
|
26148
|
+
mutation: this.mutations.save,
|
|
26149
|
+
variables: {
|
|
26150
|
+
data: json
|
|
26151
|
+
},
|
|
26152
|
+
error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
|
|
26153
|
+
update: (proxy, { data }) => {
|
|
26154
|
+
// Update entity
|
|
26155
|
+
const savedEntity = data && data.data;
|
|
26156
|
+
if (savedEntity) {
|
|
26157
|
+
if (this._debug)
|
|
26158
|
+
console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
|
|
26159
|
+
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26160
|
+
// Add to cache
|
|
26161
|
+
if (isNew) {
|
|
26162
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26163
|
+
query: this.queries.loadAll,
|
|
26164
|
+
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26165
|
+
});
|
|
26166
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26167
|
+
query: this.queries.loadAllWithContent,
|
|
26168
|
+
data: savedEntity
|
|
26169
|
+
});
|
|
26170
|
+
}
|
|
26171
|
+
}
|
|
26172
|
+
}
|
|
26173
|
+
});
|
|
26174
|
+
return entity;
|
|
26108
26175
|
});
|
|
26109
26176
|
}
|
|
26110
|
-
|
|
26111
|
-
|
|
26112
|
-
|
|
26113
|
-
|
|
26177
|
+
saveAll(data, opts) {
|
|
26178
|
+
return Promise.all(data
|
|
26179
|
+
.map(entity => this.save(entity, opts)));
|
|
26180
|
+
}
|
|
26181
|
+
markAsRead(entity) {
|
|
26182
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26183
|
+
// Get onRead listeners
|
|
26184
|
+
const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));
|
|
26185
|
+
if (onReadListeners.length) {
|
|
26186
|
+
for (const listener of onReadListeners) {
|
|
26187
|
+
yield listener.onRead(entity);
|
|
26188
|
+
}
|
|
26189
|
+
}
|
|
26190
|
+
else {
|
|
26191
|
+
// Use default
|
|
26192
|
+
yield this.defaultMarkAsRead(entity);
|
|
26193
|
+
}
|
|
26194
|
+
});
|
|
26195
|
+
}
|
|
26196
|
+
registerListener(listener) {
|
|
26197
|
+
if (!this.listeners)
|
|
26198
|
+
this.listeners = [];
|
|
26199
|
+
this.listeners.push(listener);
|
|
26200
|
+
}
|
|
26201
|
+
/* -- protected methods -- */
|
|
26202
|
+
processUserEvent(source, that) {
|
|
26203
|
+
that = that || this;
|
|
26204
|
+
// Convert json source to IUserEvent
|
|
26205
|
+
let target = that.fromObject(source);
|
|
26206
|
+
// Get listeners
|
|
26207
|
+
const listeners = (that.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
|
|
26208
|
+
for (const listener of listeners) {
|
|
26209
|
+
if (target) {
|
|
26210
|
+
target = listener.onReceived(target);
|
|
26211
|
+
}
|
|
26212
|
+
else {
|
|
26213
|
+
if (that._debug)
|
|
26214
|
+
console.debug(`${that._logPrefix}Event has been rejected by a listener`, source);
|
|
26215
|
+
break;
|
|
26216
|
+
}
|
|
26217
|
+
}
|
|
26218
|
+
return target;
|
|
26219
|
+
}
|
|
26220
|
+
defaultMarkAsRead(userEvent) {
|
|
26221
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26222
|
+
if (!userEvent)
|
|
26223
|
+
throw new Error(`${this._logPrefix}Invalid event to save`);
|
|
26224
|
+
// set read date
|
|
26225
|
+
userEvent.readDate = moment$6();
|
|
26226
|
+
if (!userEvent.id || userEvent.id < 0) {
|
|
26227
|
+
if (this._debug)
|
|
26228
|
+
console.debug(`${this._logPrefix}Save local user event`);
|
|
26229
|
+
// TODO !!!!!!!!!!!!!
|
|
26230
|
+
}
|
|
26231
|
+
else {
|
|
26232
|
+
yield this.save(userEvent);
|
|
26233
|
+
}
|
|
26234
|
+
});
|
|
26235
|
+
}
|
|
26236
|
+
defaultFilter() {
|
|
26237
|
+
// By default
|
|
26238
|
+
return {
|
|
26239
|
+
recipients: [this.defaultRecipient()]
|
|
26240
|
+
};
|
|
26241
|
+
}
|
|
26242
|
+
defaultRecipient() {
|
|
26243
|
+
return this.accountService.person.pubkey;
|
|
26244
|
+
}
|
|
26245
|
+
fillDefaultProperties(entity) {
|
|
26246
|
+
}
|
|
26247
|
+
unreadEvents(events) {
|
|
26248
|
+
// default calculation on unread events from a list
|
|
26249
|
+
if (isEmptyArray(events))
|
|
26250
|
+
return undefined;
|
|
26251
|
+
const lastReadDate = events
|
|
26252
|
+
.filter(event => isNotNil(event.readDate))
|
|
26253
|
+
.reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
|
|
26254
|
+
return events
|
|
26255
|
+
.filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
|
|
26256
|
+
}
|
|
26257
|
+
copyIdAndUpdateDate(source, target) {
|
|
26258
|
+
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26259
|
+
}
|
|
26260
|
+
}
|
|
26261
|
+
AbstractUserEventService.decorators = [
|
|
26262
|
+
{ type: Directive }
|
|
26263
|
+
];
|
|
26264
|
+
AbstractUserEventService.ctorParameters = () => [
|
|
26265
|
+
{ type: GraphqlService },
|
|
26266
|
+
{ type: AccountService },
|
|
26267
|
+
{ type: NetworkService },
|
|
26268
|
+
{ type: TranslateService },
|
|
26269
|
+
{ type: undefined },
|
|
26270
|
+
{ type: undefined },
|
|
26271
|
+
{ type: undefined },
|
|
26272
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
26273
|
+
];
|
|
26274
|
+
const userEventQueries = {
|
|
26275
|
+
loadAll: gql `
|
|
26276
|
+
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26277
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26278
|
+
...LightUserEventFragment
|
|
26279
|
+
}
|
|
26280
|
+
}
|
|
26281
|
+
${UserEventFragments.lightUserEvent}
|
|
26282
|
+
`,
|
|
26283
|
+
loadAllWithContent: gql `
|
|
26284
|
+
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26285
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26286
|
+
...UserEventFragment
|
|
26287
|
+
}
|
|
26114
26288
|
}
|
|
26115
|
-
|
|
26116
|
-
|
|
26117
|
-
|
|
26289
|
+
${UserEventFragments.userEvent}
|
|
26290
|
+
`
|
|
26291
|
+
};
|
|
26292
|
+
const userEventMutations = {
|
|
26293
|
+
deleteByIds: gql `
|
|
26294
|
+
mutation DeleteUserEvents($ids:[Int]){
|
|
26295
|
+
deleteUserEvents(ids: $ids)
|
|
26296
|
+
}
|
|
26297
|
+
`,
|
|
26298
|
+
save: gql `
|
|
26299
|
+
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26300
|
+
data: saveUserEvent(userEvent: $data){
|
|
26301
|
+
...UserEventFragment
|
|
26302
|
+
}
|
|
26118
26303
|
}
|
|
26119
|
-
|
|
26120
|
-
|
|
26304
|
+
${UserEventFragments.userEvent}
|
|
26305
|
+
`
|
|
26306
|
+
};
|
|
26307
|
+
class UserEventService extends AbstractUserEventService {
|
|
26308
|
+
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26309
|
+
super(graphql, accountService, network, translate, userEventQueries, userEventMutations, undefined, environment);
|
|
26310
|
+
this.graphql = graphql;
|
|
26311
|
+
this.accountService = accountService;
|
|
26312
|
+
this.network = network;
|
|
26313
|
+
this.translate = translate;
|
|
26314
|
+
this.toastController = toastController;
|
|
26315
|
+
this.environment = environment;
|
|
26121
26316
|
}
|
|
26122
26317
|
showToastErrorWithContext(opts) {
|
|
26123
26318
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -26181,13 +26376,16 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26181
26376
|
}
|
|
26182
26377
|
sendDataForDebug(data) {
|
|
26183
26378
|
const userEvent = new UserEvent();
|
|
26184
|
-
userEvent.
|
|
26379
|
+
userEvent.type = UserEventTypes.DEBUG_DATA;
|
|
26185
26380
|
userEvent.content = this.convertObjectToString(data);
|
|
26186
26381
|
return this.save(userEvent);
|
|
26187
26382
|
}
|
|
26188
26383
|
asFilter(filter) {
|
|
26189
26384
|
return UserEventFilter.fromObject(filter);
|
|
26190
26385
|
}
|
|
26386
|
+
fromObject(source) {
|
|
26387
|
+
return UserEvent.fromObject(source);
|
|
26388
|
+
}
|
|
26191
26389
|
/* -- protected methods -- */
|
|
26192
26390
|
convertObjectToString(data) {
|
|
26193
26391
|
if (typeof data === 'string') {
|
|
@@ -26216,13 +26414,9 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26216
26414
|
// TODO: compute sign
|
|
26217
26415
|
console.warn('TODO: sign user event before sending');
|
|
26218
26416
|
}
|
|
26219
|
-
copyIdAndUpdateDate(source, target) {
|
|
26220
|
-
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26221
|
-
}
|
|
26222
26417
|
}
|
|
26223
|
-
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" });
|
|
26224
26418
|
UserEventService.decorators = [
|
|
26225
|
-
{ type: Injectable
|
|
26419
|
+
{ type: Injectable }
|
|
26226
26420
|
];
|
|
26227
26421
|
UserEventService.ctorParameters = () => [
|
|
26228
26422
|
{ type: GraphqlService },
|
|
@@ -26235,7 +26429,7 @@ UserEventService.ctorParameters = () => [
|
|
|
26235
26429
|
|
|
26236
26430
|
const ICONS_MAP = {
|
|
26237
26431
|
DEBUG_DATA: { matIcon: 'bug_report' },
|
|
26238
|
-
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26432
|
+
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26239
26433
|
};
|
|
26240
26434
|
// TODO: refactor with a registration done by data service:
|
|
26241
26435
|
// - userEventService.registerEventAction({__typename: 'TripVO', ...})
|
|
@@ -26301,7 +26495,7 @@ class UserEventsTable extends AppTable {
|
|
|
26301
26495
|
}
|
|
26302
26496
|
}));
|
|
26303
26497
|
const filter = this.filter || new UserEventFilter();
|
|
26304
|
-
filter.
|
|
26498
|
+
filter.recipients = [this.recipient];
|
|
26305
26499
|
this.setFilter(filter, { emitEvent: true });
|
|
26306
26500
|
}
|
|
26307
26501
|
start() {
|
|
@@ -26314,17 +26508,17 @@ class UserEventsTable extends AppTable {
|
|
|
26314
26508
|
});
|
|
26315
26509
|
}
|
|
26316
26510
|
getIcon(source) {
|
|
26317
|
-
return ICONS_MAP[source.
|
|
26511
|
+
return ICONS_MAP[source.type];
|
|
26318
26512
|
}
|
|
26319
26513
|
getDetail(source) {
|
|
26320
26514
|
if (!source)
|
|
26321
26515
|
return undefined;
|
|
26322
|
-
if (source.content && source.
|
|
26516
|
+
if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
|
|
26323
26517
|
const context = source.content.context;
|
|
26324
26518
|
if (context && context.__typename) {
|
|
26325
|
-
const actions = this.service.getActionsByTypename(context.__typename);
|
|
26519
|
+
// const actions = this.service.getActionsByTypename(context.__typename);
|
|
26326
26520
|
return {
|
|
26327
|
-
actions,
|
|
26521
|
+
// actions,
|
|
26328
26522
|
title: source.content.error && source.content.error.message || source.content.message,
|
|
26329
26523
|
description: source.content.error && source.content.error.details || undefined
|
|
26330
26524
|
};
|
|
@@ -26336,11 +26530,11 @@ class UserEventsTable extends AppTable {
|
|
|
26336
26530
|
doAction(action, row) {
|
|
26337
26531
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26338
26532
|
const event = row.currentData;
|
|
26339
|
-
const context = event.content && event.content.context;
|
|
26533
|
+
// const context = event.content && event.content.context;
|
|
26340
26534
|
this.markAsLoading();
|
|
26341
26535
|
if (action && typeof action.executeAction === 'function') {
|
|
26342
26536
|
try {
|
|
26343
|
-
let res = action.executeAction(event
|
|
26537
|
+
let res = action.executeAction(event /*, context*/);
|
|
26344
26538
|
res = (res instanceof Promise) ? yield res : res;
|
|
26345
26539
|
}
|
|
26346
26540
|
catch (err) {
|
|
@@ -26359,13 +26553,18 @@ UserEventsTable.decorators = [
|
|
|
26359
26553
|
selector: 'app-user-events-table',
|
|
26360
26554
|
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",
|
|
26361
26555
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26556
|
+
providers: [
|
|
26557
|
+
{
|
|
26558
|
+
provide: UserEventServiceToken, useClass: UserEventService
|
|
26559
|
+
}
|
|
26560
|
+
],
|
|
26362
26561
|
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}"]
|
|
26363
26562
|
},] }
|
|
26364
26563
|
];
|
|
26365
26564
|
UserEventsTable.ctorParameters = () => [
|
|
26366
26565
|
{ type: Injector },
|
|
26367
26566
|
{ type: AccountService },
|
|
26368
|
-
{ type:
|
|
26567
|
+
{ type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
|
|
26369
26568
|
{ type: EntitiesStorage },
|
|
26370
26569
|
{ type: ChangeDetectorRef },
|
|
26371
26570
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
@@ -26377,6 +26576,155 @@ UserEventsTable.propDecorators = {
|
|
|
26377
26576
|
defaultSortDirection: [{ type: Input }]
|
|
26378
26577
|
};
|
|
26379
26578
|
|
|
26579
|
+
class UserEventNotificationList {
|
|
26580
|
+
constructor(popoverController) {
|
|
26581
|
+
this.popoverController = popoverController;
|
|
26582
|
+
}
|
|
26583
|
+
ngOnInit() {
|
|
26584
|
+
}
|
|
26585
|
+
read($event, userEvent) {
|
|
26586
|
+
var _a;
|
|
26587
|
+
if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
|
|
26588
|
+
return;
|
|
26589
|
+
(_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
|
|
26590
|
+
}
|
|
26591
|
+
executeAction(action, userEvent) {
|
|
26592
|
+
// Execute then close popover
|
|
26593
|
+
action.executeAction(userEvent);
|
|
26594
|
+
this.dismiss();
|
|
26595
|
+
}
|
|
26596
|
+
dismiss() {
|
|
26597
|
+
this.popoverController.dismiss();
|
|
26598
|
+
}
|
|
26599
|
+
}
|
|
26600
|
+
UserEventNotificationList.decorators = [
|
|
26601
|
+
{ type: Component, args: [{
|
|
26602
|
+
selector: 'app-user-event-notification-list',
|
|
26603
|
+
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",
|
|
26604
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
|
|
26605
|
+
},] }
|
|
26606
|
+
];
|
|
26607
|
+
UserEventNotificationList.ctorParameters = () => [
|
|
26608
|
+
{ type: PopoverController }
|
|
26609
|
+
];
|
|
26610
|
+
UserEventNotificationList.propDecorators = {
|
|
26611
|
+
titleI18n: [{ type: Input }],
|
|
26612
|
+
userEvents: [{ type: Input }],
|
|
26613
|
+
readEvent: [{ type: Output }]
|
|
26614
|
+
};
|
|
26615
|
+
|
|
26616
|
+
class UserEventNotificationComponent {
|
|
26617
|
+
constructor(userEventService, accountService, popoverController, cd) {
|
|
26618
|
+
this.userEventService = userEventService;
|
|
26619
|
+
this.accountService = accountService;
|
|
26620
|
+
this.popoverController = popoverController;
|
|
26621
|
+
this.cd = cd;
|
|
26622
|
+
this.debug = false;
|
|
26623
|
+
this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
|
|
26624
|
+
this.disabled = false;
|
|
26625
|
+
this.userEventsSubject = new BehaviorSubject(undefined);
|
|
26626
|
+
this._subscriptions = new Subscription();
|
|
26627
|
+
this._logPrefix = '[user-event-notification] ';
|
|
26628
|
+
this._readEvent = new EventEmitter();
|
|
26629
|
+
}
|
|
26630
|
+
get count() {
|
|
26631
|
+
var _a;
|
|
26632
|
+
return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(map(value => value === 0 ? undefined : value));
|
|
26633
|
+
}
|
|
26634
|
+
ngOnInit() {
|
|
26635
|
+
if (isNil(this.userEventService)) {
|
|
26636
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
26637
|
+
this.disabled = true;
|
|
26638
|
+
return;
|
|
26639
|
+
}
|
|
26640
|
+
// Watch first
|
|
26641
|
+
this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', 'desc').subscribe(value => {
|
|
26642
|
+
const data = value.data;
|
|
26643
|
+
if (this.debug) {
|
|
26644
|
+
console.debug(`${this._logPrefix}Receiving user events`, data);
|
|
26645
|
+
}
|
|
26646
|
+
this.userEventsSubject.next(data);
|
|
26647
|
+
}));
|
|
26648
|
+
// Then listen changes
|
|
26649
|
+
this._subscriptions.add(this.userEventService.listenChanges(undefined).subscribe(data => {
|
|
26650
|
+
if (this.debug) {
|
|
26651
|
+
console.debug(`${this._logPrefix}Receiving new user events`, data);
|
|
26652
|
+
}
|
|
26653
|
+
this.userEventsSubject.next(data);
|
|
26654
|
+
}));
|
|
26655
|
+
this._readEvent.subscribe(value => {
|
|
26656
|
+
this.userEventService.markAsRead(value);
|
|
26657
|
+
});
|
|
26658
|
+
}
|
|
26659
|
+
showList(event) {
|
|
26660
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26661
|
+
const popover = yield this.popoverController.create({
|
|
26662
|
+
component: UserEventNotificationList,
|
|
26663
|
+
componentProps: {
|
|
26664
|
+
titleI18n: this.titleI18n,
|
|
26665
|
+
userEvents: this.userEventsSubject,
|
|
26666
|
+
readEvent: this._readEvent
|
|
26667
|
+
},
|
|
26668
|
+
backdropDismiss: true,
|
|
26669
|
+
keyboardClose: true,
|
|
26670
|
+
event,
|
|
26671
|
+
translucent: true,
|
|
26672
|
+
cssClass: 'popover-large'
|
|
26673
|
+
});
|
|
26674
|
+
yield popover.present();
|
|
26675
|
+
});
|
|
26676
|
+
}
|
|
26677
|
+
markForCheck() {
|
|
26678
|
+
this.cd.markForCheck();
|
|
26679
|
+
}
|
|
26680
|
+
ngOnDestroy() {
|
|
26681
|
+
if (this.debug) {
|
|
26682
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
26683
|
+
}
|
|
26684
|
+
this._subscriptions.unsubscribe();
|
|
26685
|
+
}
|
|
26686
|
+
}
|
|
26687
|
+
UserEventNotificationComponent.decorators = [
|
|
26688
|
+
{ type: Component, args: [{
|
|
26689
|
+
selector: 'app-user-event-notification-component',
|
|
26690
|
+
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",
|
|
26691
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26692
|
+
styles: [""]
|
|
26693
|
+
},] }
|
|
26694
|
+
];
|
|
26695
|
+
UserEventNotificationComponent.ctorParameters = () => [
|
|
26696
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] },
|
|
26697
|
+
{ type: AccountService },
|
|
26698
|
+
{ type: PopoverController },
|
|
26699
|
+
{ type: ChangeDetectorRef }
|
|
26700
|
+
];
|
|
26701
|
+
UserEventNotificationComponent.propDecorators = {
|
|
26702
|
+
debug: [{ type: Input }],
|
|
26703
|
+
titleI18n: [{ type: Input }],
|
|
26704
|
+
disabled: [{ type: Input }]
|
|
26705
|
+
};
|
|
26706
|
+
|
|
26707
|
+
class UserEventModule {
|
|
26708
|
+
}
|
|
26709
|
+
UserEventModule.decorators = [
|
|
26710
|
+
{ type: NgModule, args: [{
|
|
26711
|
+
imports: [
|
|
26712
|
+
CommonModule,
|
|
26713
|
+
CoreModule,
|
|
26714
|
+
SharedModule
|
|
26715
|
+
],
|
|
26716
|
+
declarations: [
|
|
26717
|
+
UserEventsTable,
|
|
26718
|
+
UserEventNotificationComponent,
|
|
26719
|
+
UserEventNotificationList,
|
|
26720
|
+
],
|
|
26721
|
+
exports: [
|
|
26722
|
+
UserEventsTable,
|
|
26723
|
+
UserEventNotificationComponent
|
|
26724
|
+
]
|
|
26725
|
+
},] }
|
|
26726
|
+
];
|
|
26727
|
+
|
|
26380
26728
|
const MessageTypes = {
|
|
26381
26729
|
INBOX_MESSAGE: 'INBOX_MESSAGE',
|
|
26382
26730
|
EMAIL: 'EMAIL',
|
|
@@ -26588,9 +26936,9 @@ MessageForm.propDecorators = {
|
|
|
26588
26936
|
canSelectType: [{ type: Input }]
|
|
26589
26937
|
};
|
|
26590
26938
|
|
|
26591
|
-
class
|
|
26939
|
+
class MessageModule {
|
|
26592
26940
|
}
|
|
26593
|
-
|
|
26941
|
+
MessageModule.decorators = [
|
|
26594
26942
|
{ type: NgModule, args: [{
|
|
26595
26943
|
imports: [
|
|
26596
26944
|
CommonModule,
|
|
@@ -26598,17 +26946,317 @@ SocialModule.decorators = [
|
|
|
26598
26946
|
SharedModule
|
|
26599
26947
|
],
|
|
26600
26948
|
declarations: [
|
|
26601
|
-
UserEventsTable,
|
|
26602
26949
|
MessageModal,
|
|
26603
26950
|
MessageForm
|
|
26604
26951
|
],
|
|
26605
26952
|
exports: [
|
|
26606
|
-
UserEventsTable,
|
|
26607
26953
|
MessageModal
|
|
26608
26954
|
]
|
|
26609
26955
|
},] }
|
|
26610
26956
|
];
|
|
26611
26957
|
|
|
26958
|
+
var JobProgression_1;
|
|
26959
|
+
// todo use entity
|
|
26960
|
+
class Job {
|
|
26961
|
+
}
|
|
26962
|
+
// @dynamic
|
|
26963
|
+
let JobProgression = JobProgression_1 = class JobProgression extends Entity {
|
|
26964
|
+
constructor() {
|
|
26965
|
+
super(JobProgression_1.TYPENAME);
|
|
26966
|
+
}
|
|
26967
|
+
fromObject(source) {
|
|
26968
|
+
super.fromObject(source);
|
|
26969
|
+
this.message = source.message;
|
|
26970
|
+
this.current = source.current;
|
|
26971
|
+
this.total = source.total;
|
|
26972
|
+
}
|
|
26973
|
+
};
|
|
26974
|
+
JobProgression = JobProgression_1 = __decorate([
|
|
26975
|
+
EntityClass({ typename: 'JobProgressionVO' })
|
|
26976
|
+
], JobProgression);
|
|
26977
|
+
|
|
26978
|
+
const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
|
|
26979
|
+
const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
|
|
26980
|
+
data: updateJobProgression(id: $id, interval: $interval) {
|
|
26981
|
+
id
|
|
26982
|
+
message
|
|
26983
|
+
current
|
|
26984
|
+
total
|
|
26985
|
+
}
|
|
26986
|
+
}`;
|
|
26987
|
+
class JobProgressionService extends BaseGraphqlService {
|
|
26988
|
+
constructor(graphql, environment) {
|
|
26989
|
+
super(graphql, environment);
|
|
26990
|
+
this.graphql = graphql;
|
|
26991
|
+
this.environment = environment;
|
|
26992
|
+
this._logPrefix = '[job-progression-service] ';
|
|
26993
|
+
// For DEV only
|
|
26994
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
26995
|
+
}
|
|
26996
|
+
listenChanges(id, options) {
|
|
26997
|
+
if (isNil(id))
|
|
26998
|
+
throw new Error(`${this._logPrefix}Missing argument 'id'`);
|
|
26999
|
+
if (this._debug)
|
|
27000
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
|
|
27001
|
+
return this.graphql.subscribe({
|
|
27002
|
+
query: jobProgressionSubscription,
|
|
27003
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
27004
|
+
variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
27005
|
+
error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
|
|
27006
|
+
}).pipe(map(({ data }) => {
|
|
27007
|
+
const progression = data && JobProgression.fromObject(data);
|
|
27008
|
+
if (progression && this._debug)
|
|
27009
|
+
console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
|
|
27010
|
+
return progression;
|
|
27011
|
+
}));
|
|
27012
|
+
}
|
|
27013
|
+
}
|
|
27014
|
+
JobProgressionService.decorators = [
|
|
27015
|
+
{ type: Injectable }
|
|
27016
|
+
];
|
|
27017
|
+
JobProgressionService.ctorParameters = () => [
|
|
27018
|
+
{ type: GraphqlService },
|
|
27019
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27020
|
+
];
|
|
27021
|
+
|
|
27022
|
+
class JobProgressionList {
|
|
27023
|
+
constructor() {
|
|
27024
|
+
}
|
|
27025
|
+
ngOnInit() {
|
|
27026
|
+
}
|
|
27027
|
+
}
|
|
27028
|
+
JobProgressionList.decorators = [
|
|
27029
|
+
{ type: Component, args: [{
|
|
27030
|
+
selector: 'app-job-progression-list',
|
|
27031
|
+
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",
|
|
27032
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
|
|
27033
|
+
},] }
|
|
27034
|
+
];
|
|
27035
|
+
JobProgressionList.ctorParameters = () => [];
|
|
27036
|
+
JobProgressionList.propDecorators = {
|
|
27037
|
+
titleI18n: [{ type: Input }],
|
|
27038
|
+
jobProgressions: [{ type: Input }]
|
|
27039
|
+
};
|
|
27040
|
+
|
|
27041
|
+
class JobProgressionComponent {
|
|
27042
|
+
constructor(jobProgressionService, popoverController, cd) {
|
|
27043
|
+
this.jobProgressionService = jobProgressionService;
|
|
27044
|
+
this.popoverController = popoverController;
|
|
27045
|
+
this.cd = cd;
|
|
27046
|
+
this.debug = false;
|
|
27047
|
+
this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
|
|
27048
|
+
this.jobFinished = new EventEmitter();
|
|
27049
|
+
this.disabled = true;
|
|
27050
|
+
this.color = 'accent';
|
|
27051
|
+
this.mode = 'determinate';
|
|
27052
|
+
this.value = 0;
|
|
27053
|
+
this.jobProgressions = [];
|
|
27054
|
+
this._subscriptions = new Subscription();
|
|
27055
|
+
this._subscriptionsById = {};
|
|
27056
|
+
this._logPrefix = '[job-progression] ';
|
|
27057
|
+
}
|
|
27058
|
+
ngOnInit() {
|
|
27059
|
+
var _a, _b, _c, _d;
|
|
27060
|
+
if (isNil(this.jobProgressionService)) {
|
|
27061
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
27062
|
+
}
|
|
27063
|
+
// parse options
|
|
27064
|
+
this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
|
|
27065
|
+
this.visible = !this.autoHide;
|
|
27066
|
+
this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
|
|
27067
|
+
this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
|
|
27068
|
+
this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
|
|
27069
|
+
}
|
|
27070
|
+
addJob(id) {
|
|
27071
|
+
if (isNil(this.jobProgressionService)) {
|
|
27072
|
+
console.warn(`${this._logPrefix}No service injected. Can't add a job`);
|
|
27073
|
+
return;
|
|
27074
|
+
}
|
|
27075
|
+
if (this.debug) {
|
|
27076
|
+
console.debug(`${this._logPrefix}Add job id=${id}`);
|
|
27077
|
+
}
|
|
27078
|
+
if (!!this.getProgression(id)) {
|
|
27079
|
+
console.warn(`${this._logPrefix}Job (id=${id}) already present`);
|
|
27080
|
+
return;
|
|
27081
|
+
}
|
|
27082
|
+
this.disabled = false;
|
|
27083
|
+
const sub = this.jobProgressionService.listenChanges(id)
|
|
27084
|
+
.pipe(filter(progression => {
|
|
27085
|
+
if (id !== progression.id) {
|
|
27086
|
+
console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
|
|
27087
|
+
return false;
|
|
27088
|
+
}
|
|
27089
|
+
return true;
|
|
27090
|
+
}), map(progression => {
|
|
27091
|
+
// Ensure visible
|
|
27092
|
+
this.visible = true;
|
|
27093
|
+
// Get current progression object
|
|
27094
|
+
const currentProgression = this.getProgression(id);
|
|
27095
|
+
if (!currentProgression) {
|
|
27096
|
+
// add it
|
|
27097
|
+
this.jobProgressions.push(progression);
|
|
27098
|
+
if (this.debug) {
|
|
27099
|
+
console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
|
|
27100
|
+
}
|
|
27101
|
+
}
|
|
27102
|
+
else {
|
|
27103
|
+
// update current
|
|
27104
|
+
Object.assign(currentProgression, progression);
|
|
27105
|
+
if (this.debug) {
|
|
27106
|
+
console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
|
|
27107
|
+
}
|
|
27108
|
+
}
|
|
27109
|
+
return progression;
|
|
27110
|
+
}))
|
|
27111
|
+
.subscribe(progression => {
|
|
27112
|
+
// update value
|
|
27113
|
+
this.updateValue();
|
|
27114
|
+
// job finished
|
|
27115
|
+
if (progression.total > 0 && progression.current == progression.total) {
|
|
27116
|
+
if (this.debug) {
|
|
27117
|
+
console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
|
|
27118
|
+
}
|
|
27119
|
+
// emit event
|
|
27120
|
+
this.jobFinished.emit(progression.id);
|
|
27121
|
+
if (this.autoRemove) {
|
|
27122
|
+
setTimeout(() => {
|
|
27123
|
+
var _a;
|
|
27124
|
+
this.removeJob(progression.id);
|
|
27125
|
+
// If last job
|
|
27126
|
+
if (this.autoHide && !((_a = this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
27127
|
+
setTimeout(() => {
|
|
27128
|
+
this.visible = false;
|
|
27129
|
+
this.markForCheck();
|
|
27130
|
+
}, this.autoHideDelay);
|
|
27131
|
+
}
|
|
27132
|
+
}, this.autoRemoveDelay);
|
|
27133
|
+
}
|
|
27134
|
+
}
|
|
27135
|
+
});
|
|
27136
|
+
this._subscriptionsById[id] = sub;
|
|
27137
|
+
this._subscriptions.add(sub);
|
|
27138
|
+
}
|
|
27139
|
+
removeJob(id) {
|
|
27140
|
+
if (this.debug) {
|
|
27141
|
+
console.debug(`${this._logPrefix}Remove job id=${id}`);
|
|
27142
|
+
}
|
|
27143
|
+
const sub = this._subscriptionsById[id];
|
|
27144
|
+
if (sub) {
|
|
27145
|
+
this._subscriptions.remove(sub);
|
|
27146
|
+
sub.unsubscribe();
|
|
27147
|
+
}
|
|
27148
|
+
const progression = this.getProgression(id);
|
|
27149
|
+
if (progression) {
|
|
27150
|
+
this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
|
|
27151
|
+
}
|
|
27152
|
+
this.updateValue();
|
|
27153
|
+
}
|
|
27154
|
+
getProgression(id) {
|
|
27155
|
+
return this.jobProgressions.find(progression => progression.id === id);
|
|
27156
|
+
}
|
|
27157
|
+
updateValue() {
|
|
27158
|
+
if (this.debug) {
|
|
27159
|
+
console.debug(`${this._logPrefix}Updating value`);
|
|
27160
|
+
}
|
|
27161
|
+
let value = 0;
|
|
27162
|
+
const nbProgression = arraySize(this.jobProgressions);
|
|
27163
|
+
let allIndeterminate = nbProgression > 0;
|
|
27164
|
+
this.jobProgressions.forEach(progression => {
|
|
27165
|
+
const indeterminate = progression.total === 0;
|
|
27166
|
+
allIndeterminate = allIndeterminate && indeterminate;
|
|
27167
|
+
if (!indeterminate) {
|
|
27168
|
+
value = value + progression.current * 100 / progression.total;
|
|
27169
|
+
}
|
|
27170
|
+
});
|
|
27171
|
+
this.value = nbProgression > 0 ? value / nbProgression : 0;
|
|
27172
|
+
this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
|
|
27173
|
+
if (this.debug) {
|
|
27174
|
+
console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
|
|
27175
|
+
}
|
|
27176
|
+
this.markForCheck();
|
|
27177
|
+
}
|
|
27178
|
+
showList(event) {
|
|
27179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27180
|
+
const popover = yield this.popoverController.create({
|
|
27181
|
+
component: JobProgressionList,
|
|
27182
|
+
componentProps: {
|
|
27183
|
+
titleI18n: this.titleI18n,
|
|
27184
|
+
jobProgressions: this.jobProgressions
|
|
27185
|
+
},
|
|
27186
|
+
backdropDismiss: true,
|
|
27187
|
+
keyboardClose: true,
|
|
27188
|
+
event,
|
|
27189
|
+
translucent: true,
|
|
27190
|
+
cssClass: 'popover-large'
|
|
27191
|
+
});
|
|
27192
|
+
yield popover.present();
|
|
27193
|
+
});
|
|
27194
|
+
}
|
|
27195
|
+
markForCheck() {
|
|
27196
|
+
this.cd.markForCheck();
|
|
27197
|
+
}
|
|
27198
|
+
ngOnDestroy() {
|
|
27199
|
+
if (this.debug) {
|
|
27200
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
27201
|
+
}
|
|
27202
|
+
this._subscriptions.unsubscribe();
|
|
27203
|
+
}
|
|
27204
|
+
}
|
|
27205
|
+
JobProgressionComponent.decorators = [
|
|
27206
|
+
{ type: Component, args: [{
|
|
27207
|
+
selector: 'app-job-progression',
|
|
27208
|
+
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",
|
|
27209
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27210
|
+
styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
|
|
27211
|
+
},] }
|
|
27212
|
+
];
|
|
27213
|
+
JobProgressionComponent.ctorParameters = () => [
|
|
27214
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [JobProgressionServiceToken,] }] },
|
|
27215
|
+
{ type: PopoverController },
|
|
27216
|
+
{ type: ChangeDetectorRef }
|
|
27217
|
+
];
|
|
27218
|
+
JobProgressionComponent.propDecorators = {
|
|
27219
|
+
debug: [{ type: Input }],
|
|
27220
|
+
titleI18n: [{ type: Input }],
|
|
27221
|
+
options: [{ type: Input }],
|
|
27222
|
+
jobFinished: [{ type: Output }]
|
|
27223
|
+
};
|
|
27224
|
+
|
|
27225
|
+
class JobModule {
|
|
27226
|
+
}
|
|
27227
|
+
JobModule.decorators = [
|
|
27228
|
+
{ type: NgModule, args: [{
|
|
27229
|
+
imports: [
|
|
27230
|
+
CommonModule,
|
|
27231
|
+
SharedModule,
|
|
27232
|
+
TranslateModule.forChild(),
|
|
27233
|
+
],
|
|
27234
|
+
declarations: [
|
|
27235
|
+
JobProgressionComponent,
|
|
27236
|
+
JobProgressionList
|
|
27237
|
+
],
|
|
27238
|
+
exports: [
|
|
27239
|
+
JobProgressionComponent
|
|
27240
|
+
]
|
|
27241
|
+
},] }
|
|
27242
|
+
];
|
|
27243
|
+
|
|
27244
|
+
const SocialModuleOptionsToken = new InjectionToken("SocialModuleOptions");
|
|
27245
|
+
class SocialModule {
|
|
27246
|
+
}
|
|
27247
|
+
SocialModule.decorators = [
|
|
27248
|
+
{ type: NgModule, args: [{
|
|
27249
|
+
imports: [
|
|
27250
|
+
CommonModule,
|
|
27251
|
+
CoreModule,
|
|
27252
|
+
SharedModule,
|
|
27253
|
+
UserEventModule,
|
|
27254
|
+
JobModule,
|
|
27255
|
+
MessageModule,
|
|
27256
|
+
],
|
|
27257
|
+
},] }
|
|
27258
|
+
];
|
|
27259
|
+
|
|
26612
27260
|
const Mutations = {
|
|
26613
27261
|
send: gql `mutation SendMessage($data: MessageVOInput){
|
|
26614
27262
|
done: sendMessage(message: $data)
|
|
@@ -27254,12 +27902,10 @@ class AutocompleteTestPage {
|
|
|
27254
27902
|
});
|
|
27255
27903
|
}
|
|
27256
27904
|
ngAfterViewInit() {
|
|
27257
|
-
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
}, 2000);
|
|
27262
|
-
}
|
|
27905
|
+
setTimeout(() => {
|
|
27906
|
+
this.farEntityField.suggestLengthThreshold = 2;
|
|
27907
|
+
this.farEntityField.reloadItems();
|
|
27908
|
+
}, 2000);
|
|
27263
27909
|
setTimeout(() => this.loadData(), 1000);
|
|
27264
27910
|
}
|
|
27265
27911
|
// Load the form with data
|
|
@@ -27347,7 +27993,7 @@ class AutocompleteTestPage {
|
|
|
27347
27993
|
AutocompleteTestPage.decorators = [
|
|
27348
27994
|
{ type: Component, args: [{
|
|
27349
27995
|
selector: 'app-autocomplete-test',
|
|
27350
|
-
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"
|
|
27996
|
+
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"
|
|
27351
27997
|
},] }
|
|
27352
27998
|
];
|
|
27353
27999
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -27423,13 +28069,13 @@ LatLongTestPage.ctorParameters = () => [
|
|
|
27423
28069
|
{ type: FormBuilder }
|
|
27424
28070
|
];
|
|
27425
28071
|
|
|
27426
|
-
const moment$
|
|
28072
|
+
const moment$7 = momentImported;
|
|
27427
28073
|
class SwipeTestPage {
|
|
27428
28074
|
constructor(formBuilder, dateFormatPipe) {
|
|
27429
28075
|
this.formBuilder = formBuilder;
|
|
27430
28076
|
this.dateFormatPipe = dateFormatPipe;
|
|
27431
28077
|
this.$dates = new BehaviorSubject(undefined);
|
|
27432
|
-
this._today = moment$
|
|
28078
|
+
this._today = moment$7().startOf('day');
|
|
27433
28079
|
this.form = formBuilder.group({
|
|
27434
28080
|
empty: [null, Validators.required],
|
|
27435
28081
|
date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
|
|
@@ -27442,7 +28088,7 @@ class SwipeTestPage {
|
|
|
27442
28088
|
ngOnInit() {
|
|
27443
28089
|
const dates = [];
|
|
27444
28090
|
for (let d = 0; d < 7; d++) {
|
|
27445
|
-
dates[d] = moment$
|
|
28091
|
+
dates[d] = moment$7(this._today).add(d - 3, 'day');
|
|
27446
28092
|
}
|
|
27447
28093
|
this.$dates.next(dates);
|
|
27448
28094
|
this.loadData();
|
|
@@ -27483,7 +28129,7 @@ SwipeTestPage.ctorParameters = () => [
|
|
|
27483
28129
|
{ type: DateFormatPipe }
|
|
27484
28130
|
];
|
|
27485
28131
|
|
|
27486
|
-
const moment$
|
|
28132
|
+
const moment$8 = momentImported;
|
|
27487
28133
|
class DateTimeTestPage {
|
|
27488
28134
|
constructor(platform, formBuilder, cd) {
|
|
27489
28135
|
this.platform = platform;
|
|
@@ -27515,7 +28161,7 @@ class DateTimeTestPage {
|
|
|
27515
28161
|
// Load the form with data
|
|
27516
28162
|
loadData() {
|
|
27517
28163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27518
|
-
const now = moment$
|
|
28164
|
+
const now = moment$8();
|
|
27519
28165
|
const data = {
|
|
27520
28166
|
empty: null,
|
|
27521
28167
|
emptyRequired: null,
|
|
@@ -27761,7 +28407,7 @@ NumpadTestPage.ctorParameters = () => [
|
|
|
27761
28407
|
{ type: FormBuilder }
|
|
27762
28408
|
];
|
|
27763
28409
|
|
|
27764
|
-
const moment$
|
|
28410
|
+
const moment$9 = momentImported;
|
|
27765
28411
|
class DateTestPage {
|
|
27766
28412
|
constructor(formBuilder, cd) {
|
|
27767
28413
|
this.formBuilder = formBuilder;
|
|
@@ -27794,7 +28440,7 @@ class DateTestPage {
|
|
|
27794
28440
|
// Load the form with data
|
|
27795
28441
|
loadData() {
|
|
27796
28442
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27797
|
-
const now = moment$
|
|
28443
|
+
const now = moment$9();
|
|
27798
28444
|
const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
|
|
27799
28445
|
const data = {
|
|
27800
28446
|
empty: null,
|
|
@@ -28540,5 +29186,5 @@ CoreTestingModule.decorators = [
|
|
|
28540
29186
|
* Generated bundle index. Do not edit.
|
|
28541
29187
|
*/
|
|
28542
29188
|
|
|
28543
|
-
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, 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,
|
|
29189
|
+
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, AbstractUserEventService, 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, Job, JobModule, JobProgression, JobProgressionComponent, JobProgressionService, JobProgressionServiceToken, 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, MessageModule, 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, SocialModuleOptionsToken, 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, UserEventModule, UserEventNotificationComponent, UserEventService, UserEventServiceToken, 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, 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, UserEventNotificationList as ɵk, JobProgressionList as ɵl, DateTestPage as ɵm, NumpadTestPage as ɵn, MatBadgeIconTestPage as ɵo, ToastTestingModule as ɵp, ToastTestingPage as ɵq };
|
|
28544
29190
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|