@sumaris-net/ngx-components 1.20.36 → 1.21.0-beta3
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 +1099 -326
- 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 +54 -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 +95 -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 +294 -166
- 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 +927 -288
- 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 +80 -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,159 @@ 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, toastController, 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
25961
|
this.toastController = toastController;
|
|
25962
|
+
this.queries = queries;
|
|
25963
|
+
this.mutations = mutations;
|
|
25964
|
+
this.subscriptions = subscriptions;
|
|
25961
25965
|
this.environment = environment;
|
|
25962
|
-
this.
|
|
25966
|
+
this._count$ = new BehaviorSubject(0);
|
|
25967
|
+
this._subscriptions = new Subscription();
|
|
25968
|
+
this.listeners = [];
|
|
25969
|
+
this._logPrefix = '[user-event-service] ';
|
|
25963
25970
|
// For DEV only
|
|
25964
|
-
this._debug = environment
|
|
25971
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
25972
|
+
// listen login/logout
|
|
25973
|
+
this._subscriptions.add(accountService.onLogin.subscribe(() => __awaiter(this, void 0, void 0, function* () {
|
|
25974
|
+
const count = yield this.count(this.defaultFilter());
|
|
25975
|
+
if (count && this._debug) {
|
|
25976
|
+
console.debug(`${this._logPrefix}Received ${count} unread notifications`);
|
|
25977
|
+
}
|
|
25978
|
+
this._count$.next(count);
|
|
25979
|
+
})));
|
|
25980
|
+
}
|
|
25981
|
+
get userEventCount() {
|
|
25982
|
+
return this._count$.asObservable();
|
|
25983
|
+
}
|
|
25984
|
+
ngOnDestroy() {
|
|
25985
|
+
this._subscriptions.unsubscribe();
|
|
25965
25986
|
}
|
|
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
25987
|
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
25977
25988
|
return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
|
|
25978
25989
|
}
|
|
25979
25990
|
watchPage(page, filter, options) {
|
|
25991
|
+
var _a;
|
|
25980
25992
|
let now = this._debug && Date.now();
|
|
25981
25993
|
//if (this._debug)
|
|
25982
|
-
console.debug(
|
|
25994
|
+
console.debug(`${this._logPrefix}Loading user events...`, filter);
|
|
25983
25995
|
filter = this.asFilter(filter);
|
|
25984
25996
|
// Force recipient to current issuer, if not admin and not specified
|
|
25985
|
-
if (
|
|
25986
|
-
const recipient = this.
|
|
25987
|
-
if (
|
|
25997
|
+
if (isEmptyArray(filter.recipients) || !this.accountService.isAdmin()) {
|
|
25998
|
+
const recipient = this.defaultRecipient();
|
|
25999
|
+
if (!((_a = filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
|
|
25988
26000
|
console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
|
|
25989
|
-
filter.
|
|
26001
|
+
filter.recipients = [recipient];
|
|
25990
26002
|
}
|
|
25991
26003
|
}
|
|
25992
|
-
const withContent = options
|
|
26004
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
25993
26005
|
return this.mutableWatchQuery({
|
|
25994
26006
|
queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
|
|
25995
|
-
query: withContent ?
|
|
26007
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
25996
26008
|
variables: {
|
|
25997
|
-
page: Object.assign(
|
|
26009
|
+
page: Object.assign({ sortBy: 'updateDate', sortDirection: 'desc' }, page),
|
|
25998
26010
|
filter: filter && filter.asPodObject()
|
|
25999
26011
|
},
|
|
26000
26012
|
arrayFieldName: 'data',
|
|
26001
26013
|
error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
|
|
26002
|
-
fetchPolicy: options
|
|
26014
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
|
|
26003
26015
|
})
|
|
26004
26016
|
.pipe(map(res => {
|
|
26005
|
-
const data = res
|
|
26017
|
+
const data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(this.processUserEvent);
|
|
26006
26018
|
if (now) {
|
|
26007
|
-
console.debug(
|
|
26019
|
+
console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);
|
|
26008
26020
|
now = null;
|
|
26009
26021
|
}
|
|
26022
|
+
const unreadCount = this.unreadEvents(data);
|
|
26010
26023
|
return {
|
|
26011
26024
|
data,
|
|
26012
|
-
total: res
|
|
26025
|
+
total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
|
|
26013
26026
|
};
|
|
26014
26027
|
}));
|
|
26015
26028
|
}
|
|
26016
|
-
|
|
26017
|
-
|
|
26018
|
-
|
|
26029
|
+
add(entity) {
|
|
26030
|
+
// TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
26031
|
+
entity = this.processUserEvent(entity);
|
|
26032
|
+
const withContent = !!entity.content;
|
|
26033
|
+
// Add user event locally
|
|
26034
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26035
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26036
|
+
data: entity
|
|
26037
|
+
});
|
|
26038
|
+
// Update count
|
|
26039
|
+
this._count$.next(this._count$.value + 1);
|
|
26019
26040
|
}
|
|
26020
|
-
|
|
26021
|
-
|
|
26022
|
-
*
|
|
26023
|
-
* @param entity
|
|
26024
|
-
*/
|
|
26025
|
-
save(entity, options) {
|
|
26041
|
+
count(filter, options) {
|
|
26042
|
+
var _a;
|
|
26026
26043
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26027
|
-
this.
|
|
26028
|
-
|
|
26029
|
-
|
|
26030
|
-
|
|
26031
|
-
|
|
26044
|
+
if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
|
|
26045
|
+
console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
|
|
26046
|
+
return undefined;
|
|
26047
|
+
}
|
|
26048
|
+
if (!filter)
|
|
26049
|
+
throw new Error(`Missing argument 'filter'`);
|
|
26050
|
+
filter = this.asFilter(filter);
|
|
26032
26051
|
if (this._debug)
|
|
26033
|
-
console.debug(
|
|
26034
|
-
yield this.graphql.
|
|
26035
|
-
|
|
26052
|
+
console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
|
|
26053
|
+
const res = yield this.graphql.query({
|
|
26054
|
+
query: this.queries.count,
|
|
26036
26055
|
variables: {
|
|
26037
|
-
|
|
26056
|
+
filter: filter.asPodObject()
|
|
26038
26057
|
},
|
|
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
|
-
}
|
|
26058
|
+
error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
|
|
26059
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
|
|
26060
26060
|
});
|
|
26061
|
-
return
|
|
26061
|
+
return res.total;
|
|
26062
|
+
});
|
|
26063
|
+
}
|
|
26064
|
+
listenChanges(filter, options) {
|
|
26065
|
+
var _a;
|
|
26066
|
+
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
|
|
26067
|
+
console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
|
|
26068
|
+
return of();
|
|
26069
|
+
}
|
|
26070
|
+
if (!filter)
|
|
26071
|
+
throw new Error(`Missing argument 'filter'`);
|
|
26072
|
+
filter = this.asFilter(filter);
|
|
26073
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26074
|
+
if (this._debug)
|
|
26075
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
|
|
26076
|
+
return this.graphql.subscribe({
|
|
26077
|
+
query: this.subscriptions.listenChanges,
|
|
26078
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26079
|
+
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26080
|
+
error: {
|
|
26081
|
+
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26082
|
+
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26083
|
+
}
|
|
26084
|
+
}).pipe(map(({ data }) => {
|
|
26085
|
+
if (data && this._debug)
|
|
26086
|
+
console.debug(`${this._logPrefix}Received new user events:`, data);
|
|
26087
|
+
const updatedData = data === null || data === void 0 ? void 0 : data.map(this.processUserEvent);
|
|
26088
|
+
// Update cache
|
|
26089
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26090
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26091
|
+
data: updatedData
|
|
26092
|
+
});
|
|
26093
|
+
// update count
|
|
26094
|
+
this._count$.next(this.unreadEvents(updatedData));
|
|
26095
|
+
return updatedData;
|
|
26096
|
+
}));
|
|
26097
|
+
}
|
|
26098
|
+
delete(entity) {
|
|
26099
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26100
|
+
if (!entity)
|
|
26101
|
+
return; // skip
|
|
26102
|
+
yield this.deleteAll([entity]);
|
|
26062
26103
|
});
|
|
26063
26104
|
}
|
|
26064
|
-
/**
|
|
26065
|
-
* Save many trips
|
|
26066
|
-
*
|
|
26067
|
-
* @param entities
|
|
26068
|
-
* @param opts
|
|
26069
|
-
*/
|
|
26070
26105
|
deleteAll(entities, opts) {
|
|
26071
26106
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26072
26107
|
const ids = entities && entities
|
|
@@ -26075,49 +26110,206 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26075
26110
|
return; // stop, if nothing else to do
|
|
26076
26111
|
const now = Date.now();
|
|
26077
26112
|
if (this._debug)
|
|
26078
|
-
console.debug(
|
|
26113
|
+
console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
|
|
26079
26114
|
yield this.graphql.mutate({
|
|
26080
|
-
mutation:
|
|
26115
|
+
mutation: this.mutations.deleteByIds,
|
|
26081
26116
|
variables: {
|
|
26082
26117
|
ids
|
|
26083
26118
|
},
|
|
26084
26119
|
update: (proxy) => {
|
|
26085
26120
|
// Remove from caches
|
|
26086
26121
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26087
|
-
query:
|
|
26122
|
+
query: this.queries.loadAll,
|
|
26088
26123
|
ids
|
|
26089
26124
|
});
|
|
26090
26125
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26091
|
-
query:
|
|
26126
|
+
query: this.queries.loadAllWithContent,
|
|
26092
26127
|
ids
|
|
26093
26128
|
});
|
|
26094
26129
|
if (this._debug)
|
|
26095
|
-
console.debug(
|
|
26130
|
+
console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
|
|
26096
26131
|
}
|
|
26097
26132
|
});
|
|
26098
26133
|
});
|
|
26099
26134
|
}
|
|
26100
|
-
|
|
26101
|
-
* Delete userEvent entities
|
|
26102
|
-
*/
|
|
26103
|
-
delete(data) {
|
|
26135
|
+
save(entity, options) {
|
|
26104
26136
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26105
|
-
|
|
26106
|
-
|
|
26107
|
-
|
|
26137
|
+
this.fillDefaultProperties(entity);
|
|
26138
|
+
// Transform into json
|
|
26139
|
+
const isNew = isNil(entity.id);
|
|
26140
|
+
const json = entity.asObject();
|
|
26141
|
+
const now = Date.now();
|
|
26142
|
+
if (this._debug)
|
|
26143
|
+
console.debug(`${this._logPrefix}Saving user event...`, json);
|
|
26144
|
+
yield this.graphql.mutate({
|
|
26145
|
+
mutation: this.mutations.save,
|
|
26146
|
+
variables: {
|
|
26147
|
+
data: json
|
|
26148
|
+
},
|
|
26149
|
+
error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
|
|
26150
|
+
update: (proxy, { data }) => {
|
|
26151
|
+
// Update entity
|
|
26152
|
+
const savedEntity = data && data.data;
|
|
26153
|
+
if (savedEntity) {
|
|
26154
|
+
if (this._debug)
|
|
26155
|
+
console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
|
|
26156
|
+
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26157
|
+
// Add to cache
|
|
26158
|
+
if (isNew) {
|
|
26159
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26160
|
+
query: this.queries.loadAll,
|
|
26161
|
+
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26162
|
+
});
|
|
26163
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26164
|
+
query: this.queries.loadAllWithContent,
|
|
26165
|
+
data: savedEntity
|
|
26166
|
+
});
|
|
26167
|
+
}
|
|
26168
|
+
}
|
|
26169
|
+
}
|
|
26170
|
+
});
|
|
26171
|
+
return entity;
|
|
26108
26172
|
});
|
|
26109
26173
|
}
|
|
26110
|
-
|
|
26111
|
-
|
|
26112
|
-
|
|
26113
|
-
|
|
26174
|
+
saveAll(data, opts) {
|
|
26175
|
+
return Promise.all(data
|
|
26176
|
+
.map(entity => this.save(entity, opts)));
|
|
26177
|
+
}
|
|
26178
|
+
markAsRead(entity) {
|
|
26179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26180
|
+
// Get onRead listeners
|
|
26181
|
+
const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));
|
|
26182
|
+
if (onReadListeners.length) {
|
|
26183
|
+
for (const listener of onReadListeners) {
|
|
26184
|
+
yield listener.onRead(entity);
|
|
26185
|
+
}
|
|
26186
|
+
}
|
|
26187
|
+
else {
|
|
26188
|
+
// Use default
|
|
26189
|
+
yield this.defaultMarkAsRead(entity);
|
|
26190
|
+
}
|
|
26191
|
+
});
|
|
26192
|
+
}
|
|
26193
|
+
registerListener(listener) {
|
|
26194
|
+
if (!this.listeners)
|
|
26195
|
+
this.listeners = [];
|
|
26196
|
+
this.listeners.push(listener);
|
|
26197
|
+
}
|
|
26198
|
+
/* -- protected methods -- */
|
|
26199
|
+
processUserEvent(source) {
|
|
26200
|
+
// Convert json source to IUserEvent
|
|
26201
|
+
let target = this.fromObject(source);
|
|
26202
|
+
// Get listeners
|
|
26203
|
+
const listeners = (this.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
|
|
26204
|
+
for (const listener of listeners) {
|
|
26205
|
+
if (target) {
|
|
26206
|
+
target = listener.onReceived(target);
|
|
26207
|
+
}
|
|
26208
|
+
else {
|
|
26209
|
+
if (this._debug)
|
|
26210
|
+
console.debug(`${this._logPrefix}Event has been rejected by a listener`, source);
|
|
26211
|
+
break;
|
|
26212
|
+
}
|
|
26213
|
+
}
|
|
26214
|
+
return target;
|
|
26215
|
+
}
|
|
26216
|
+
defaultMarkAsRead(userEvent) {
|
|
26217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26218
|
+
if (!userEvent)
|
|
26219
|
+
throw new Error(`${this._logPrefix}Invalid event to save`);
|
|
26220
|
+
// set read date
|
|
26221
|
+
userEvent.readDate = moment$6();
|
|
26222
|
+
if (!userEvent.id || userEvent.id < 0) {
|
|
26223
|
+
if (this._debug)
|
|
26224
|
+
console.debug(`${this._logPrefix}Save local user event`);
|
|
26225
|
+
// TODO !!!!!!!!!!!!!
|
|
26226
|
+
}
|
|
26227
|
+
else {
|
|
26228
|
+
yield this.save(userEvent);
|
|
26229
|
+
}
|
|
26230
|
+
});
|
|
26231
|
+
}
|
|
26232
|
+
defaultFilter() {
|
|
26233
|
+
// By default
|
|
26234
|
+
return {
|
|
26235
|
+
recipients: [this.defaultRecipient()]
|
|
26236
|
+
};
|
|
26237
|
+
}
|
|
26238
|
+
defaultRecipient() {
|
|
26239
|
+
return this.accountService.person.pubkey;
|
|
26240
|
+
}
|
|
26241
|
+
fillDefaultProperties(entity) {
|
|
26242
|
+
}
|
|
26243
|
+
unreadEvents(events) {
|
|
26244
|
+
// default calculation on unread events from a list
|
|
26245
|
+
if (isEmptyArray(events))
|
|
26246
|
+
return undefined;
|
|
26247
|
+
const lastReadDate = events
|
|
26248
|
+
.filter(event => isNotNil(event.readDate))
|
|
26249
|
+
.reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
|
|
26250
|
+
return events
|
|
26251
|
+
.filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
|
|
26252
|
+
}
|
|
26253
|
+
copyIdAndUpdateDate(source, target) {
|
|
26254
|
+
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26255
|
+
}
|
|
26256
|
+
}
|
|
26257
|
+
AbstractUserEventService.decorators = [
|
|
26258
|
+
{ type: Directive }
|
|
26259
|
+
];
|
|
26260
|
+
AbstractUserEventService.ctorParameters = () => [
|
|
26261
|
+
{ type: GraphqlService },
|
|
26262
|
+
{ type: AccountService },
|
|
26263
|
+
{ type: NetworkService },
|
|
26264
|
+
{ type: TranslateService },
|
|
26265
|
+
{ type: ToastController },
|
|
26266
|
+
{ type: undefined },
|
|
26267
|
+
{ type: undefined },
|
|
26268
|
+
{ type: undefined },
|
|
26269
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
26270
|
+
];
|
|
26271
|
+
const userEventQueries = {
|
|
26272
|
+
loadAll: gql `
|
|
26273
|
+
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26274
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26275
|
+
...LightUserEventFragment
|
|
26276
|
+
}
|
|
26277
|
+
}
|
|
26278
|
+
${UserEventFragments.lightUserEvent}
|
|
26279
|
+
`,
|
|
26280
|
+
loadAllWithContent: gql `
|
|
26281
|
+
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26282
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26283
|
+
...UserEventFragment
|
|
26284
|
+
}
|
|
26114
26285
|
}
|
|
26115
|
-
|
|
26116
|
-
|
|
26117
|
-
|
|
26286
|
+
${UserEventFragments.userEvent}
|
|
26287
|
+
`
|
|
26288
|
+
};
|
|
26289
|
+
const userEventMutations = {
|
|
26290
|
+
deleteByIds: gql `
|
|
26291
|
+
mutation DeleteUserEvents($ids:[Int]){
|
|
26292
|
+
deleteUserEvents(ids: $ids)
|
|
26293
|
+
}
|
|
26294
|
+
`,
|
|
26295
|
+
save: gql `
|
|
26296
|
+
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26297
|
+
data: saveUserEvent(userEvent: $data){
|
|
26298
|
+
...UserEventFragment
|
|
26299
|
+
}
|
|
26118
26300
|
}
|
|
26119
|
-
|
|
26120
|
-
|
|
26301
|
+
${UserEventFragments.userEvent}
|
|
26302
|
+
`
|
|
26303
|
+
};
|
|
26304
|
+
class UserEventService extends AbstractUserEventService {
|
|
26305
|
+
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26306
|
+
super(graphql, accountService, network, translate, toastController, userEventQueries, userEventMutations, undefined, environment);
|
|
26307
|
+
this.graphql = graphql;
|
|
26308
|
+
this.accountService = accountService;
|
|
26309
|
+
this.network = network;
|
|
26310
|
+
this.translate = translate;
|
|
26311
|
+
this.toastController = toastController;
|
|
26312
|
+
this.environment = environment;
|
|
26121
26313
|
}
|
|
26122
26314
|
showToastErrorWithContext(opts) {
|
|
26123
26315
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -26181,13 +26373,16 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26181
26373
|
}
|
|
26182
26374
|
sendDataForDebug(data) {
|
|
26183
26375
|
const userEvent = new UserEvent();
|
|
26184
|
-
userEvent.
|
|
26376
|
+
userEvent.type = UserEventTypes.DEBUG_DATA;
|
|
26185
26377
|
userEvent.content = this.convertObjectToString(data);
|
|
26186
26378
|
return this.save(userEvent);
|
|
26187
26379
|
}
|
|
26188
26380
|
asFilter(filter) {
|
|
26189
26381
|
return UserEventFilter.fromObject(filter);
|
|
26190
26382
|
}
|
|
26383
|
+
fromObject(source) {
|
|
26384
|
+
return UserEvent.fromObject(source);
|
|
26385
|
+
}
|
|
26191
26386
|
/* -- protected methods -- */
|
|
26192
26387
|
convertObjectToString(data) {
|
|
26193
26388
|
if (typeof data === 'string') {
|
|
@@ -26216,13 +26411,9 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26216
26411
|
// TODO: compute sign
|
|
26217
26412
|
console.warn('TODO: sign user event before sending');
|
|
26218
26413
|
}
|
|
26219
|
-
copyIdAndUpdateDate(source, target) {
|
|
26220
|
-
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26221
|
-
}
|
|
26222
26414
|
}
|
|
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
26415
|
UserEventService.decorators = [
|
|
26225
|
-
{ type: Injectable
|
|
26416
|
+
{ type: Injectable }
|
|
26226
26417
|
];
|
|
26227
26418
|
UserEventService.ctorParameters = () => [
|
|
26228
26419
|
{ type: GraphqlService },
|
|
@@ -26235,7 +26426,7 @@ UserEventService.ctorParameters = () => [
|
|
|
26235
26426
|
|
|
26236
26427
|
const ICONS_MAP = {
|
|
26237
26428
|
DEBUG_DATA: { matIcon: 'bug_report' },
|
|
26238
|
-
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26429
|
+
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26239
26430
|
};
|
|
26240
26431
|
// TODO: refactor with a registration done by data service:
|
|
26241
26432
|
// - userEventService.registerEventAction({__typename: 'TripVO', ...})
|
|
@@ -26301,7 +26492,7 @@ class UserEventsTable extends AppTable {
|
|
|
26301
26492
|
}
|
|
26302
26493
|
}));
|
|
26303
26494
|
const filter = this.filter || new UserEventFilter();
|
|
26304
|
-
filter.
|
|
26495
|
+
filter.recipients = [this.recipient];
|
|
26305
26496
|
this.setFilter(filter, { emitEvent: true });
|
|
26306
26497
|
}
|
|
26307
26498
|
start() {
|
|
@@ -26314,17 +26505,17 @@ class UserEventsTable extends AppTable {
|
|
|
26314
26505
|
});
|
|
26315
26506
|
}
|
|
26316
26507
|
getIcon(source) {
|
|
26317
|
-
return ICONS_MAP[source.
|
|
26508
|
+
return ICONS_MAP[source.type];
|
|
26318
26509
|
}
|
|
26319
26510
|
getDetail(source) {
|
|
26320
26511
|
if (!source)
|
|
26321
26512
|
return undefined;
|
|
26322
|
-
if (source.content && source.
|
|
26513
|
+
if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
|
|
26323
26514
|
const context = source.content.context;
|
|
26324
26515
|
if (context && context.__typename) {
|
|
26325
|
-
const actions = this.service.getActionsByTypename(context.__typename);
|
|
26516
|
+
// const actions = this.service.getActionsByTypename(context.__typename);
|
|
26326
26517
|
return {
|
|
26327
|
-
actions,
|
|
26518
|
+
// actions,
|
|
26328
26519
|
title: source.content.error && source.content.error.message || source.content.message,
|
|
26329
26520
|
description: source.content.error && source.content.error.details || undefined
|
|
26330
26521
|
};
|
|
@@ -26336,11 +26527,11 @@ class UserEventsTable extends AppTable {
|
|
|
26336
26527
|
doAction(action, row) {
|
|
26337
26528
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26338
26529
|
const event = row.currentData;
|
|
26339
|
-
const context = event.content && event.content.context;
|
|
26530
|
+
// const context = event.content && event.content.context;
|
|
26340
26531
|
this.markAsLoading();
|
|
26341
26532
|
if (action && typeof action.executeAction === 'function') {
|
|
26342
26533
|
try {
|
|
26343
|
-
let res = action.executeAction(event
|
|
26534
|
+
let res = action.executeAction(event /*, context*/);
|
|
26344
26535
|
res = (res instanceof Promise) ? yield res : res;
|
|
26345
26536
|
}
|
|
26346
26537
|
catch (err) {
|
|
@@ -26359,13 +26550,18 @@ UserEventsTable.decorators = [
|
|
|
26359
26550
|
selector: 'app-user-events-table',
|
|
26360
26551
|
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
26552
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26553
|
+
providers: [
|
|
26554
|
+
{
|
|
26555
|
+
provide: UserEventServiceToken, useClass: UserEventService
|
|
26556
|
+
}
|
|
26557
|
+
],
|
|
26362
26558
|
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
26559
|
},] }
|
|
26364
26560
|
];
|
|
26365
26561
|
UserEventsTable.ctorParameters = () => [
|
|
26366
26562
|
{ type: Injector },
|
|
26367
26563
|
{ type: AccountService },
|
|
26368
|
-
{ type:
|
|
26564
|
+
{ type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
|
|
26369
26565
|
{ type: EntitiesStorage },
|
|
26370
26566
|
{ type: ChangeDetectorRef },
|
|
26371
26567
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
@@ -26377,6 +26573,150 @@ UserEventsTable.propDecorators = {
|
|
|
26377
26573
|
defaultSortDirection: [{ type: Input }]
|
|
26378
26574
|
};
|
|
26379
26575
|
|
|
26576
|
+
class UserEventNotificationList {
|
|
26577
|
+
constructor(popoverController) {
|
|
26578
|
+
this.popoverController = popoverController;
|
|
26579
|
+
}
|
|
26580
|
+
ngOnInit() {
|
|
26581
|
+
}
|
|
26582
|
+
read($event, userEvent) {
|
|
26583
|
+
var _a;
|
|
26584
|
+
if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
|
|
26585
|
+
return;
|
|
26586
|
+
(_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
|
|
26587
|
+
}
|
|
26588
|
+
executeAction(action, userEvent) {
|
|
26589
|
+
// Execute then close popover
|
|
26590
|
+
action.executeAction(userEvent);
|
|
26591
|
+
this.dismiss();
|
|
26592
|
+
}
|
|
26593
|
+
dismiss() {
|
|
26594
|
+
this.popoverController.dismiss();
|
|
26595
|
+
}
|
|
26596
|
+
}
|
|
26597
|
+
UserEventNotificationList.decorators = [
|
|
26598
|
+
{ type: Component, args: [{
|
|
26599
|
+
selector: 'app-user-event-notification-list',
|
|
26600
|
+
template: "\n<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!(userEvents | async)?.length\">\n {{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}\n </ion-item>\n <ion-item\n *ngFor=\"let userEvent of userEvents | async\"\n (click)=\"read($event, userEvent)\"\n >\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"userEvent.avatar; else avatarIcon\" src=\"{{ userEvent.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"userEvent.avatarIcon\"\n [ref]=\"userEvent.avatarIcon\"\n height=\"40\"\n width=\"40\"\n ></app-icon>\n </ng-template>\n\n </ion-avatar>\n\n <ion-grid class=\"ion-no-margin ion-no-padding\">\n <ion-row>\n <ion-col>\n <p [class.unread]=\"!userEvent.readDate\">\n {{userEvent.message}}\n </p>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"userEvent.actions?.length\">\n <ion-col>\n <p>\n <span *ngFor=\"let action of userEvent.actions\">\n <a\n [style.margin-right.px]=\"8\"\n [style.cursor]=\"'pointer'\"\n (click)=\"executeAction(action, userEvent)\"\n >\n {{ '➞ ' + action.name}}\n </a>\n </span>\n </p>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <app-icon\n *ngIf=\"userEvent.icon\"\n [ref]=\"userEvent.icon\"\n height=\"16\"\n width=\"16\"\n [style.vertical-align]=\"'sub'\"\n ></app-icon>\n <small>\n <span>{{userEvent.creationDate|dateFromNow}}</span>\n <span [style.color]=\"'gray'\">{{ ' | ' + (userEvent.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
|
|
26601
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
|
|
26602
|
+
},] }
|
|
26603
|
+
];
|
|
26604
|
+
UserEventNotificationList.ctorParameters = () => [
|
|
26605
|
+
{ type: PopoverController }
|
|
26606
|
+
];
|
|
26607
|
+
UserEventNotificationList.propDecorators = {
|
|
26608
|
+
titleI18n: [{ type: Input }],
|
|
26609
|
+
userEvents: [{ type: Input }],
|
|
26610
|
+
readEvent: [{ type: Output }]
|
|
26611
|
+
};
|
|
26612
|
+
|
|
26613
|
+
class UserEventNotificationComponent {
|
|
26614
|
+
constructor(userEventService, accountService, popoverController, cd) {
|
|
26615
|
+
this.userEventService = userEventService;
|
|
26616
|
+
this.accountService = accountService;
|
|
26617
|
+
this.popoverController = popoverController;
|
|
26618
|
+
this.cd = cd;
|
|
26619
|
+
this.debug = false;
|
|
26620
|
+
this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
|
|
26621
|
+
this.disabled = false;
|
|
26622
|
+
this.userEventsSubject = new BehaviorSubject(undefined);
|
|
26623
|
+
this._subscriptions = new Subscription();
|
|
26624
|
+
this._logPrefix = '[user-event-notification] ';
|
|
26625
|
+
this._readEvent = new EventEmitter();
|
|
26626
|
+
}
|
|
26627
|
+
get count() {
|
|
26628
|
+
var _a;
|
|
26629
|
+
return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(map(value => value === 0 ? undefined : value));
|
|
26630
|
+
}
|
|
26631
|
+
ngOnInit() {
|
|
26632
|
+
var _a;
|
|
26633
|
+
if (isNil(this.userEventService)) {
|
|
26634
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
26635
|
+
this.disabled = true;
|
|
26636
|
+
return;
|
|
26637
|
+
}
|
|
26638
|
+
this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc", {
|
|
26639
|
+
recipients: [(_a = this.accountService.person) === null || _a === void 0 ? void 0 : _a.pubkey]
|
|
26640
|
+
}).subscribe(value => {
|
|
26641
|
+
const data = value.data;
|
|
26642
|
+
if (this.debug) {
|
|
26643
|
+
console.debug(`${this._logPrefix}Receiving user events`, data);
|
|
26644
|
+
}
|
|
26645
|
+
this.userEventsSubject.next(data);
|
|
26646
|
+
}));
|
|
26647
|
+
this._readEvent.subscribe(value => {
|
|
26648
|
+
this.userEventService.markAsRead(value);
|
|
26649
|
+
});
|
|
26650
|
+
}
|
|
26651
|
+
showList(event) {
|
|
26652
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26653
|
+
const popover = yield this.popoverController.create({
|
|
26654
|
+
component: UserEventNotificationList,
|
|
26655
|
+
componentProps: {
|
|
26656
|
+
titleI18n: this.titleI18n,
|
|
26657
|
+
userEvents: this.userEventsSubject,
|
|
26658
|
+
readEvent: this._readEvent
|
|
26659
|
+
},
|
|
26660
|
+
backdropDismiss: true,
|
|
26661
|
+
keyboardClose: true,
|
|
26662
|
+
event,
|
|
26663
|
+
translucent: true,
|
|
26664
|
+
cssClass: 'popover-large'
|
|
26665
|
+
});
|
|
26666
|
+
yield popover.present();
|
|
26667
|
+
});
|
|
26668
|
+
}
|
|
26669
|
+
markForCheck() {
|
|
26670
|
+
this.cd.markForCheck();
|
|
26671
|
+
}
|
|
26672
|
+
ngOnDestroy() {
|
|
26673
|
+
if (this.debug) {
|
|
26674
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
26675
|
+
}
|
|
26676
|
+
this._subscriptions.unsubscribe();
|
|
26677
|
+
}
|
|
26678
|
+
}
|
|
26679
|
+
UserEventNotificationComponent.decorators = [
|
|
26680
|
+
{ type: Component, args: [{
|
|
26681
|
+
selector: 'app-user-event-notification-component',
|
|
26682
|
+
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",
|
|
26683
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26684
|
+
styles: [""]
|
|
26685
|
+
},] }
|
|
26686
|
+
];
|
|
26687
|
+
UserEventNotificationComponent.ctorParameters = () => [
|
|
26688
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] },
|
|
26689
|
+
{ type: AccountService },
|
|
26690
|
+
{ type: PopoverController },
|
|
26691
|
+
{ type: ChangeDetectorRef }
|
|
26692
|
+
];
|
|
26693
|
+
UserEventNotificationComponent.propDecorators = {
|
|
26694
|
+
debug: [{ type: Input }],
|
|
26695
|
+
titleI18n: [{ type: Input }],
|
|
26696
|
+
disabled: [{ type: Input }]
|
|
26697
|
+
};
|
|
26698
|
+
|
|
26699
|
+
class UserEventModule {
|
|
26700
|
+
}
|
|
26701
|
+
UserEventModule.decorators = [
|
|
26702
|
+
{ type: NgModule, args: [{
|
|
26703
|
+
imports: [
|
|
26704
|
+
CommonModule,
|
|
26705
|
+
CoreModule,
|
|
26706
|
+
SharedModule
|
|
26707
|
+
],
|
|
26708
|
+
declarations: [
|
|
26709
|
+
UserEventsTable,
|
|
26710
|
+
UserEventNotificationComponent,
|
|
26711
|
+
UserEventNotificationList,
|
|
26712
|
+
],
|
|
26713
|
+
exports: [
|
|
26714
|
+
UserEventsTable,
|
|
26715
|
+
UserEventNotificationComponent
|
|
26716
|
+
]
|
|
26717
|
+
},] }
|
|
26718
|
+
];
|
|
26719
|
+
|
|
26380
26720
|
const MessageTypes = {
|
|
26381
26721
|
INBOX_MESSAGE: 'INBOX_MESSAGE',
|
|
26382
26722
|
EMAIL: 'EMAIL',
|
|
@@ -26588,9 +26928,9 @@ MessageForm.propDecorators = {
|
|
|
26588
26928
|
canSelectType: [{ type: Input }]
|
|
26589
26929
|
};
|
|
26590
26930
|
|
|
26591
|
-
class
|
|
26931
|
+
class MessageModule {
|
|
26592
26932
|
}
|
|
26593
|
-
|
|
26933
|
+
MessageModule.decorators = [
|
|
26594
26934
|
{ type: NgModule, args: [{
|
|
26595
26935
|
imports: [
|
|
26596
26936
|
CommonModule,
|
|
@@ -26598,17 +26938,318 @@ SocialModule.decorators = [
|
|
|
26598
26938
|
SharedModule
|
|
26599
26939
|
],
|
|
26600
26940
|
declarations: [
|
|
26601
|
-
UserEventsTable,
|
|
26602
26941
|
MessageModal,
|
|
26603
26942
|
MessageForm
|
|
26604
26943
|
],
|
|
26605
26944
|
exports: [
|
|
26606
|
-
UserEventsTable,
|
|
26607
26945
|
MessageModal
|
|
26608
26946
|
]
|
|
26609
26947
|
},] }
|
|
26610
26948
|
];
|
|
26611
26949
|
|
|
26950
|
+
var JobProgression_1;
|
|
26951
|
+
// todo use entity
|
|
26952
|
+
class Job {
|
|
26953
|
+
}
|
|
26954
|
+
// @dynamic
|
|
26955
|
+
let JobProgression = JobProgression_1 = class JobProgression extends Entity {
|
|
26956
|
+
constructor() {
|
|
26957
|
+
super(JobProgression_1.TYPENAME);
|
|
26958
|
+
}
|
|
26959
|
+
fromObject(source) {
|
|
26960
|
+
super.fromObject(source);
|
|
26961
|
+
this.message = source.message;
|
|
26962
|
+
this.current = source.current;
|
|
26963
|
+
this.total = source.total;
|
|
26964
|
+
}
|
|
26965
|
+
};
|
|
26966
|
+
JobProgression = JobProgression_1 = __decorate([
|
|
26967
|
+
EntityClass({ typename: 'JobProgressionVO' })
|
|
26968
|
+
], JobProgression);
|
|
26969
|
+
|
|
26970
|
+
const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
|
|
26971
|
+
const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
|
|
26972
|
+
data: updateJobProgression(id: $id, interval: $interval) {
|
|
26973
|
+
id
|
|
26974
|
+
message
|
|
26975
|
+
current
|
|
26976
|
+
total
|
|
26977
|
+
updateDate
|
|
26978
|
+
}
|
|
26979
|
+
}`;
|
|
26980
|
+
class JobProgressionService extends BaseGraphqlService {
|
|
26981
|
+
constructor(graphql, environment) {
|
|
26982
|
+
super(graphql, environment);
|
|
26983
|
+
this.graphql = graphql;
|
|
26984
|
+
this.environment = environment;
|
|
26985
|
+
this._logPrefix = '[job-progression-service] ';
|
|
26986
|
+
// For DEV only
|
|
26987
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
26988
|
+
}
|
|
26989
|
+
listenChanges(id, options) {
|
|
26990
|
+
if (isNil(id))
|
|
26991
|
+
throw new Error(`${this._logPrefix}Missing argument 'id'`);
|
|
26992
|
+
if (this._debug)
|
|
26993
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
|
|
26994
|
+
return this.graphql.subscribe({
|
|
26995
|
+
query: jobProgressionSubscription,
|
|
26996
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26997
|
+
variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26998
|
+
error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
|
|
26999
|
+
}).pipe(map(({ data }) => {
|
|
27000
|
+
const progression = data && JobProgression.fromObject(data);
|
|
27001
|
+
if (progression && this._debug)
|
|
27002
|
+
console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
|
|
27003
|
+
return progression;
|
|
27004
|
+
}));
|
|
27005
|
+
}
|
|
27006
|
+
}
|
|
27007
|
+
JobProgressionService.decorators = [
|
|
27008
|
+
{ type: Injectable }
|
|
27009
|
+
];
|
|
27010
|
+
JobProgressionService.ctorParameters = () => [
|
|
27011
|
+
{ type: GraphqlService },
|
|
27012
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27013
|
+
];
|
|
27014
|
+
|
|
27015
|
+
class JobProgressionList {
|
|
27016
|
+
constructor() {
|
|
27017
|
+
}
|
|
27018
|
+
ngOnInit() {
|
|
27019
|
+
}
|
|
27020
|
+
}
|
|
27021
|
+
JobProgressionList.decorators = [
|
|
27022
|
+
{ type: Component, args: [{
|
|
27023
|
+
selector: 'app-job-progression-list',
|
|
27024
|
+
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",
|
|
27025
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
|
|
27026
|
+
},] }
|
|
27027
|
+
];
|
|
27028
|
+
JobProgressionList.ctorParameters = () => [];
|
|
27029
|
+
JobProgressionList.propDecorators = {
|
|
27030
|
+
titleI18n: [{ type: Input }],
|
|
27031
|
+
jobProgressions: [{ type: Input }]
|
|
27032
|
+
};
|
|
27033
|
+
|
|
27034
|
+
class JobProgressionComponent {
|
|
27035
|
+
constructor(jobProgressionService, popoverController, cd) {
|
|
27036
|
+
this.jobProgressionService = jobProgressionService;
|
|
27037
|
+
this.popoverController = popoverController;
|
|
27038
|
+
this.cd = cd;
|
|
27039
|
+
this.debug = false;
|
|
27040
|
+
this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
|
|
27041
|
+
this.jobFinished = new EventEmitter();
|
|
27042
|
+
this.disabled = true;
|
|
27043
|
+
this.color = 'accent';
|
|
27044
|
+
this.mode = 'determinate';
|
|
27045
|
+
this.value = 0;
|
|
27046
|
+
this.jobProgressions = [];
|
|
27047
|
+
this._subscriptions = new Subscription();
|
|
27048
|
+
this._subscriptionsById = {};
|
|
27049
|
+
this._logPrefix = '[job-progression] ';
|
|
27050
|
+
}
|
|
27051
|
+
ngOnInit() {
|
|
27052
|
+
var _a, _b, _c, _d;
|
|
27053
|
+
if (isNil(this.jobProgressionService)) {
|
|
27054
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
27055
|
+
}
|
|
27056
|
+
// parse options
|
|
27057
|
+
this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
|
|
27058
|
+
this.visible = !this.autoHide;
|
|
27059
|
+
this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
|
|
27060
|
+
this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
|
|
27061
|
+
this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
|
|
27062
|
+
}
|
|
27063
|
+
addJob(id) {
|
|
27064
|
+
if (isNil(this.jobProgressionService)) {
|
|
27065
|
+
console.warn(`${this._logPrefix}No service injected. Can't add a job`);
|
|
27066
|
+
return;
|
|
27067
|
+
}
|
|
27068
|
+
if (this.debug) {
|
|
27069
|
+
console.debug(`${this._logPrefix}Add job id=${id}`);
|
|
27070
|
+
}
|
|
27071
|
+
if (!!this.getProgression(id)) {
|
|
27072
|
+
console.warn(`${this._logPrefix}Job (id=${id}) already present`);
|
|
27073
|
+
return;
|
|
27074
|
+
}
|
|
27075
|
+
this.disabled = false;
|
|
27076
|
+
const sub = this.jobProgressionService.listenChanges(id)
|
|
27077
|
+
.pipe(filter(progression => {
|
|
27078
|
+
if (id !== progression.id) {
|
|
27079
|
+
console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
|
|
27080
|
+
return false;
|
|
27081
|
+
}
|
|
27082
|
+
return true;
|
|
27083
|
+
}), map(progression => {
|
|
27084
|
+
// Ensure visible
|
|
27085
|
+
this.visible = true;
|
|
27086
|
+
// Get current progression object
|
|
27087
|
+
const currentProgression = this.getProgression(id);
|
|
27088
|
+
if (!currentProgression) {
|
|
27089
|
+
// add it
|
|
27090
|
+
this.jobProgressions.push(progression);
|
|
27091
|
+
if (this.debug) {
|
|
27092
|
+
console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
|
|
27093
|
+
}
|
|
27094
|
+
}
|
|
27095
|
+
else {
|
|
27096
|
+
// update current
|
|
27097
|
+
Object.assign(currentProgression, progression);
|
|
27098
|
+
if (this.debug) {
|
|
27099
|
+
console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
|
|
27100
|
+
}
|
|
27101
|
+
}
|
|
27102
|
+
return progression;
|
|
27103
|
+
}))
|
|
27104
|
+
.subscribe(progression => {
|
|
27105
|
+
// update value
|
|
27106
|
+
this.updateValue();
|
|
27107
|
+
// job finished
|
|
27108
|
+
if (progression.total > 0 && progression.current == progression.total) {
|
|
27109
|
+
if (this.debug) {
|
|
27110
|
+
console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
|
|
27111
|
+
}
|
|
27112
|
+
// emit event
|
|
27113
|
+
this.jobFinished.emit(progression.id);
|
|
27114
|
+
if (this.autoRemove) {
|
|
27115
|
+
setTimeout(() => {
|
|
27116
|
+
var _a;
|
|
27117
|
+
this.removeJob(progression.id);
|
|
27118
|
+
// If last job
|
|
27119
|
+
if (this.autoHide && !((_a = this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
27120
|
+
setTimeout(() => {
|
|
27121
|
+
this.visible = false;
|
|
27122
|
+
this.markForCheck();
|
|
27123
|
+
}, this.autoHideDelay);
|
|
27124
|
+
}
|
|
27125
|
+
}, this.autoRemoveDelay);
|
|
27126
|
+
}
|
|
27127
|
+
}
|
|
27128
|
+
});
|
|
27129
|
+
this._subscriptionsById[id] = sub;
|
|
27130
|
+
this._subscriptions.add(sub);
|
|
27131
|
+
}
|
|
27132
|
+
removeJob(id) {
|
|
27133
|
+
if (this.debug) {
|
|
27134
|
+
console.debug(`${this._logPrefix}Remove job id=${id}`);
|
|
27135
|
+
}
|
|
27136
|
+
const sub = this._subscriptionsById[id];
|
|
27137
|
+
if (sub) {
|
|
27138
|
+
this._subscriptions.remove(sub);
|
|
27139
|
+
sub.unsubscribe();
|
|
27140
|
+
}
|
|
27141
|
+
const progression = this.getProgression(id);
|
|
27142
|
+
if (progression) {
|
|
27143
|
+
this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
|
|
27144
|
+
}
|
|
27145
|
+
this.updateValue();
|
|
27146
|
+
}
|
|
27147
|
+
getProgression(id) {
|
|
27148
|
+
return this.jobProgressions.find(progression => progression.id === id);
|
|
27149
|
+
}
|
|
27150
|
+
updateValue() {
|
|
27151
|
+
if (this.debug) {
|
|
27152
|
+
console.debug(`${this._logPrefix}Updating value`);
|
|
27153
|
+
}
|
|
27154
|
+
let value = 0;
|
|
27155
|
+
const nbProgression = arraySize(this.jobProgressions);
|
|
27156
|
+
let allIndeterminate = nbProgression > 0;
|
|
27157
|
+
this.jobProgressions.forEach(progression => {
|
|
27158
|
+
const indeterminate = progression.total === 0;
|
|
27159
|
+
allIndeterminate = allIndeterminate && indeterminate;
|
|
27160
|
+
if (!indeterminate) {
|
|
27161
|
+
value = value + progression.current * 100 / progression.total;
|
|
27162
|
+
}
|
|
27163
|
+
});
|
|
27164
|
+
this.value = nbProgression > 0 ? value / nbProgression : 0;
|
|
27165
|
+
this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
|
|
27166
|
+
if (this.debug) {
|
|
27167
|
+
console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
|
|
27168
|
+
}
|
|
27169
|
+
this.markForCheck();
|
|
27170
|
+
}
|
|
27171
|
+
showList(event) {
|
|
27172
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27173
|
+
const popover = yield this.popoverController.create({
|
|
27174
|
+
component: JobProgressionList,
|
|
27175
|
+
componentProps: {
|
|
27176
|
+
titleI18n: this.titleI18n,
|
|
27177
|
+
jobProgressions: this.jobProgressions
|
|
27178
|
+
},
|
|
27179
|
+
backdropDismiss: true,
|
|
27180
|
+
keyboardClose: true,
|
|
27181
|
+
event,
|
|
27182
|
+
translucent: true,
|
|
27183
|
+
cssClass: 'popover-large'
|
|
27184
|
+
});
|
|
27185
|
+
yield popover.present();
|
|
27186
|
+
});
|
|
27187
|
+
}
|
|
27188
|
+
markForCheck() {
|
|
27189
|
+
this.cd.markForCheck();
|
|
27190
|
+
}
|
|
27191
|
+
ngOnDestroy() {
|
|
27192
|
+
if (this.debug) {
|
|
27193
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
27194
|
+
}
|
|
27195
|
+
this._subscriptions.unsubscribe();
|
|
27196
|
+
}
|
|
27197
|
+
}
|
|
27198
|
+
JobProgressionComponent.decorators = [
|
|
27199
|
+
{ type: Component, args: [{
|
|
27200
|
+
selector: 'app-job-progression',
|
|
27201
|
+
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",
|
|
27202
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27203
|
+
styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
|
|
27204
|
+
},] }
|
|
27205
|
+
];
|
|
27206
|
+
JobProgressionComponent.ctorParameters = () => [
|
|
27207
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [JobProgressionServiceToken,] }] },
|
|
27208
|
+
{ type: PopoverController },
|
|
27209
|
+
{ type: ChangeDetectorRef }
|
|
27210
|
+
];
|
|
27211
|
+
JobProgressionComponent.propDecorators = {
|
|
27212
|
+
debug: [{ type: Input }],
|
|
27213
|
+
titleI18n: [{ type: Input }],
|
|
27214
|
+
options: [{ type: Input }],
|
|
27215
|
+
jobFinished: [{ type: Output }]
|
|
27216
|
+
};
|
|
27217
|
+
|
|
27218
|
+
class JobModule {
|
|
27219
|
+
}
|
|
27220
|
+
JobModule.decorators = [
|
|
27221
|
+
{ type: NgModule, args: [{
|
|
27222
|
+
imports: [
|
|
27223
|
+
CommonModule,
|
|
27224
|
+
SharedModule,
|
|
27225
|
+
TranslateModule.forChild(),
|
|
27226
|
+
],
|
|
27227
|
+
declarations: [
|
|
27228
|
+
JobProgressionComponent,
|
|
27229
|
+
JobProgressionList
|
|
27230
|
+
],
|
|
27231
|
+
exports: [
|
|
27232
|
+
JobProgressionComponent
|
|
27233
|
+
]
|
|
27234
|
+
},] }
|
|
27235
|
+
];
|
|
27236
|
+
|
|
27237
|
+
const SocialModuleOptionsToken = new InjectionToken("SocialModuleOptions");
|
|
27238
|
+
class SocialModule {
|
|
27239
|
+
}
|
|
27240
|
+
SocialModule.decorators = [
|
|
27241
|
+
{ type: NgModule, args: [{
|
|
27242
|
+
imports: [
|
|
27243
|
+
CommonModule,
|
|
27244
|
+
CoreModule,
|
|
27245
|
+
SharedModule,
|
|
27246
|
+
UserEventModule,
|
|
27247
|
+
JobModule,
|
|
27248
|
+
MessageModule,
|
|
27249
|
+
],
|
|
27250
|
+
},] }
|
|
27251
|
+
];
|
|
27252
|
+
|
|
26612
27253
|
const Mutations = {
|
|
26613
27254
|
send: gql `mutation SendMessage($data: MessageVOInput){
|
|
26614
27255
|
done: sendMessage(message: $data)
|
|
@@ -27254,12 +27895,10 @@ class AutocompleteTestPage {
|
|
|
27254
27895
|
});
|
|
27255
27896
|
}
|
|
27256
27897
|
ngAfterViewInit() {
|
|
27257
|
-
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
}, 2000);
|
|
27262
|
-
}
|
|
27898
|
+
setTimeout(() => {
|
|
27899
|
+
this.farEntityField.suggestLengthThreshold = 2;
|
|
27900
|
+
this.farEntityField.reloadItems();
|
|
27901
|
+
}, 2000);
|
|
27263
27902
|
setTimeout(() => this.loadData(), 1000);
|
|
27264
27903
|
}
|
|
27265
27904
|
// Load the form with data
|
|
@@ -27347,7 +27986,7 @@ class AutocompleteTestPage {
|
|
|
27347
27986
|
AutocompleteTestPage.decorators = [
|
|
27348
27987
|
{ type: Component, args: [{
|
|
27349
27988
|
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"
|
|
27989
|
+
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
27990
|
},] }
|
|
27352
27991
|
];
|
|
27353
27992
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -27423,13 +28062,13 @@ LatLongTestPage.ctorParameters = () => [
|
|
|
27423
28062
|
{ type: FormBuilder }
|
|
27424
28063
|
];
|
|
27425
28064
|
|
|
27426
|
-
const moment$
|
|
28065
|
+
const moment$7 = momentImported;
|
|
27427
28066
|
class SwipeTestPage {
|
|
27428
28067
|
constructor(formBuilder, dateFormatPipe) {
|
|
27429
28068
|
this.formBuilder = formBuilder;
|
|
27430
28069
|
this.dateFormatPipe = dateFormatPipe;
|
|
27431
28070
|
this.$dates = new BehaviorSubject(undefined);
|
|
27432
|
-
this._today = moment$
|
|
28071
|
+
this._today = moment$7().startOf('day');
|
|
27433
28072
|
this.form = formBuilder.group({
|
|
27434
28073
|
empty: [null, Validators.required],
|
|
27435
28074
|
date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
|
|
@@ -27442,7 +28081,7 @@ class SwipeTestPage {
|
|
|
27442
28081
|
ngOnInit() {
|
|
27443
28082
|
const dates = [];
|
|
27444
28083
|
for (let d = 0; d < 7; d++) {
|
|
27445
|
-
dates[d] = moment$
|
|
28084
|
+
dates[d] = moment$7(this._today).add(d - 3, 'day');
|
|
27446
28085
|
}
|
|
27447
28086
|
this.$dates.next(dates);
|
|
27448
28087
|
this.loadData();
|
|
@@ -27483,7 +28122,7 @@ SwipeTestPage.ctorParameters = () => [
|
|
|
27483
28122
|
{ type: DateFormatPipe }
|
|
27484
28123
|
];
|
|
27485
28124
|
|
|
27486
|
-
const moment$
|
|
28125
|
+
const moment$8 = momentImported;
|
|
27487
28126
|
class DateTimeTestPage {
|
|
27488
28127
|
constructor(platform, formBuilder, cd) {
|
|
27489
28128
|
this.platform = platform;
|
|
@@ -27515,7 +28154,7 @@ class DateTimeTestPage {
|
|
|
27515
28154
|
// Load the form with data
|
|
27516
28155
|
loadData() {
|
|
27517
28156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27518
|
-
const now = moment$
|
|
28157
|
+
const now = moment$8();
|
|
27519
28158
|
const data = {
|
|
27520
28159
|
empty: null,
|
|
27521
28160
|
emptyRequired: null,
|
|
@@ -27761,7 +28400,7 @@ NumpadTestPage.ctorParameters = () => [
|
|
|
27761
28400
|
{ type: FormBuilder }
|
|
27762
28401
|
];
|
|
27763
28402
|
|
|
27764
|
-
const moment$
|
|
28403
|
+
const moment$9 = momentImported;
|
|
27765
28404
|
class DateTestPage {
|
|
27766
28405
|
constructor(formBuilder, cd) {
|
|
27767
28406
|
this.formBuilder = formBuilder;
|
|
@@ -27794,7 +28433,7 @@ class DateTestPage {
|
|
|
27794
28433
|
// Load the form with data
|
|
27795
28434
|
loadData() {
|
|
27796
28435
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27797
|
-
const now = moment$
|
|
28436
|
+
const now = moment$9();
|
|
27798
28437
|
const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
|
|
27799
28438
|
const data = {
|
|
27800
28439
|
empty: null,
|
|
@@ -28540,5 +29179,5 @@ CoreTestingModule.decorators = [
|
|
|
28540
29179
|
* Generated bundle index. Do not edit.
|
|
28541
29180
|
*/
|
|
28542
29181
|
|
|
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,
|
|
29182
|
+
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
29183
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|