@sumaris-net/ngx-components 1.20.35 → 1.21.0-beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/sumaris-net.ngx-components.umd.js +1100 -319
- 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/icon/icon.component.js +5 -2
- package/esm2015/src/app/core/menu/menu.component.js +9 -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/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 +931 -284
- 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))
|
|
@@ -1042,65 +1100,6 @@ const isMobile = (win) => {
|
|
|
1042
1100
|
return _cache.mobile;
|
|
1043
1101
|
};
|
|
1044
1102
|
|
|
1045
|
-
function suggestFromArray(items, value, opts) {
|
|
1046
|
-
if (isNotNil(value) && typeof value === 'object')
|
|
1047
|
-
return { data: [value] };
|
|
1048
|
-
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
1049
|
-
const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
|
|
1050
|
-
if (!items) {
|
|
1051
|
-
return { data: [], total: 0 };
|
|
1052
|
-
}
|
|
1053
|
-
// Filter items
|
|
1054
|
-
let filteredItems = items;
|
|
1055
|
-
if (isNotNilOrBlank(value)) {
|
|
1056
|
-
// If wildcard, search using regexp
|
|
1057
|
-
if (value.indexOf('*') !== -1) {
|
|
1058
|
-
value = value.replace(/[*]+/g, '.*');
|
|
1059
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1060
|
-
}
|
|
1061
|
-
// Else (no wildcard), search using startsWith
|
|
1062
|
-
else {
|
|
1063
|
-
filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
// Exclude ids
|
|
1067
|
-
if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
|
|
1068
|
-
filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
|
|
1069
|
-
}
|
|
1070
|
-
// Sort
|
|
1071
|
-
if (!opts || opts.skipSort !== true) {
|
|
1072
|
-
// Make to copy input items, before sorting (if not yet already done)
|
|
1073
|
-
if (filteredItems === items)
|
|
1074
|
-
filteredItems = filteredItems.slice();
|
|
1075
|
-
// Sort by keys
|
|
1076
|
-
filteredItems.sort(propertiesPathComparator(keys));
|
|
1077
|
-
}
|
|
1078
|
-
const total = filteredItems.length || 0;
|
|
1079
|
-
// Pagination (truncate if need)
|
|
1080
|
-
let pageData = filteredItems;
|
|
1081
|
-
if (opts) {
|
|
1082
|
-
if ((opts.offset || 0) > 0) {
|
|
1083
|
-
pageData = pageData.slice(opts.offset);
|
|
1084
|
-
}
|
|
1085
|
-
if (isNotNil(opts.size) && pageData.length > opts.size) {
|
|
1086
|
-
pageData = pageData.slice(0, opts.size);
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
const result = {
|
|
1090
|
-
data: pageData,
|
|
1091
|
-
total
|
|
1092
|
-
};
|
|
1093
|
-
// Add fetch more capability, if total was fetched
|
|
1094
|
-
const nextOffset = (opts && opts.offset || 0) + pageData.length;
|
|
1095
|
-
if (nextOffset < total) {
|
|
1096
|
-
result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
|
|
1097
|
-
return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
|
|
1098
|
-
}));
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
return result;
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
1103
|
class MatAutocompleteConfigHolder {
|
|
1105
1104
|
constructor(options) {
|
|
1106
1105
|
this.options = options;
|
|
@@ -1361,11 +1360,11 @@ class MatAutocompleteField {
|
|
|
1361
1360
|
// Search text (no distinctUntilChanged() because of the debounceTime() pipe)
|
|
1362
1361
|
this.formControl.valueChanges
|
|
1363
1362
|
.pipe(filter(value => this.enabled && isNotNilString(value)),
|
|
1364
|
-
// Mark as loading (to show loading spinner) -
|
|
1363
|
+
// Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
|
|
1365
1364
|
tap(_ => this.showLoadingSpinner && this.markAsLoading()),
|
|
1366
1365
|
// Filter if not enough character
|
|
1367
1366
|
filter(value => {
|
|
1368
|
-
if (
|
|
1367
|
+
if (value.length <= this.suggestLengthThreshold) {
|
|
1369
1368
|
// Update display value, to enable the message "not enough characters"
|
|
1370
1369
|
this.displayValue = value;
|
|
1371
1370
|
return false;
|
|
@@ -2329,9 +2328,9 @@ class HighlightPipe {
|
|
|
2329
2328
|
const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
|
|
2330
2329
|
const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
|
|
2331
2330
|
if (index !== -1) {
|
|
2332
|
-
return value.
|
|
2333
|
-
'<b>' + value.
|
|
2334
|
-
value.
|
|
2331
|
+
return value.substr(0, index - 1) +
|
|
2332
|
+
'<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
|
|
2333
|
+
value.substr(index + cleanedSearchText.length);
|
|
2335
2334
|
}
|
|
2336
2335
|
return value;
|
|
2337
2336
|
}
|
|
@@ -2729,50 +2728,60 @@ class IsNotNilOrBlankPipe {
|
|
|
2729
2728
|
return isNotNilOrBlank(value);
|
|
2730
2729
|
}
|
|
2731
2730
|
}
|
|
2731
|
+
IsNotNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
|
|
2732
2732
|
IsNotNilOrBlankPipe.decorators = [
|
|
2733
2733
|
{ type: Pipe, args: [{
|
|
2734
2734
|
name: 'isNotNilOrBlank'
|
|
2735
|
-
},] }
|
|
2735
|
+
},] },
|
|
2736
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2736
2737
|
];
|
|
2737
2738
|
class IsNilOrBlankPipe {
|
|
2738
2739
|
transform(value) {
|
|
2739
2740
|
return isNilOrBlank(value);
|
|
2740
2741
|
}
|
|
2741
2742
|
}
|
|
2743
|
+
IsNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
|
|
2742
2744
|
IsNilOrBlankPipe.decorators = [
|
|
2743
2745
|
{ type: Pipe, args: [{
|
|
2744
2746
|
name: 'isNilOrBlank'
|
|
2745
|
-
},] }
|
|
2747
|
+
},] },
|
|
2748
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2746
2749
|
];
|
|
2747
2750
|
class ToStringPipe {
|
|
2748
2751
|
transform(value) {
|
|
2749
2752
|
return (value !== null && value !== undefined) ? value.toString() : '';
|
|
2750
2753
|
}
|
|
2751
2754
|
}
|
|
2755
|
+
ToStringPipe.ɵprov = ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
|
|
2752
2756
|
ToStringPipe.decorators = [
|
|
2753
2757
|
{ type: Pipe, args: [{
|
|
2754
2758
|
name: 'toString'
|
|
2755
|
-
},] }
|
|
2759
|
+
},] },
|
|
2760
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2756
2761
|
];
|
|
2757
2762
|
class StrLengthPipe {
|
|
2758
2763
|
transform(value) {
|
|
2759
2764
|
return value && value.length || 0;
|
|
2760
2765
|
}
|
|
2761
2766
|
}
|
|
2767
|
+
StrLengthPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
|
|
2762
2768
|
StrLengthPipe.decorators = [
|
|
2763
2769
|
{ type: Pipe, args: [{
|
|
2764
2770
|
name: 'strLength'
|
|
2765
|
-
},] }
|
|
2771
|
+
},] },
|
|
2772
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2766
2773
|
];
|
|
2767
2774
|
class StrIncludesPipe {
|
|
2768
2775
|
transform(value, searchString, position) {
|
|
2769
2776
|
return (value === null || value === void 0 ? void 0 : value.includes(searchString, position)) || false;
|
|
2770
2777
|
}
|
|
2771
2778
|
}
|
|
2779
|
+
StrIncludesPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
|
|
2772
2780
|
StrIncludesPipe.decorators = [
|
|
2773
2781
|
{ type: Pipe, args: [{
|
|
2774
2782
|
name: 'strIncludes'
|
|
2775
|
-
},] }
|
|
2783
|
+
},] },
|
|
2784
|
+
{ type: Injectable, args: [{ providedIn: 'root' },] }
|
|
2776
2785
|
];
|
|
2777
2786
|
|
|
2778
2787
|
class TranslateContextService {
|
|
@@ -4223,7 +4232,8 @@ FormGetGroupPipe.decorators = [
|
|
|
4223
4232
|
},] }
|
|
4224
4233
|
];
|
|
4225
4234
|
class FormGetValuePipe {
|
|
4226
|
-
constructor(_ref) {
|
|
4235
|
+
constructor(adapter, _ref) {
|
|
4236
|
+
this.adapter = adapter;
|
|
4227
4237
|
this._ref = _ref;
|
|
4228
4238
|
this.value = undefined;
|
|
4229
4239
|
this._lastControl = null;
|
|
@@ -4288,6 +4298,7 @@ FormGetValuePipe.decorators = [
|
|
|
4288
4298
|
},] }
|
|
4289
4299
|
];
|
|
4290
4300
|
FormGetValuePipe.ctorParameters = () => [
|
|
4301
|
+
{ type: FormErrorTranslator },
|
|
4291
4302
|
{ type: ChangeDetectorRef }
|
|
4292
4303
|
];
|
|
4293
4304
|
|
|
@@ -5158,8 +5169,7 @@ class MatDate {
|
|
|
5158
5169
|
set tabindex(value) {
|
|
5159
5170
|
if (this._tabindex !== value) {
|
|
5160
5171
|
this._tabindex = value;
|
|
5161
|
-
|
|
5162
|
-
this.updateTabIndex();
|
|
5172
|
+
setTimeout(() => this.updateTabIndex());
|
|
5163
5173
|
}
|
|
5164
5174
|
}
|
|
5165
5175
|
get tabindex() {
|
|
@@ -5518,8 +5528,7 @@ class MatDateTime {
|
|
|
5518
5528
|
set tabindex(value) {
|
|
5519
5529
|
if (this._tabindex !== value) {
|
|
5520
5530
|
this._tabindex = value;
|
|
5521
|
-
|
|
5522
|
-
this.updateTabIndex();
|
|
5531
|
+
setTimeout(() => this.updateTabIndex());
|
|
5523
5532
|
}
|
|
5524
5533
|
}
|
|
5525
5534
|
get tabindex() {
|
|
@@ -18204,18 +18213,6 @@ class InMemoryEntitiesService extends EntitiesService {
|
|
|
18204
18213
|
return this._equalsFn(d1, d2);
|
|
18205
18214
|
return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
|
|
18206
18215
|
}
|
|
18207
|
-
/**
|
|
18208
|
-
* Count data stored by the service (without hidden data).
|
|
18209
|
-
* @param opts
|
|
18210
|
-
*/
|
|
18211
|
-
get count() {
|
|
18212
|
-
var _a;
|
|
18213
|
-
return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
|
|
18214
|
-
}
|
|
18215
|
-
get hiddenCount() {
|
|
18216
|
-
var _a;
|
|
18217
|
-
return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
18218
|
-
}
|
|
18219
18216
|
/* -- protected methods -- */
|
|
18220
18217
|
filter(data, _filter, hiddenData) {
|
|
18221
18218
|
// if filter is DataFilter instance, use its test function
|
|
@@ -21175,6 +21172,9 @@ class MenuComponent {
|
|
|
21175
21172
|
this._subscription = new Subscription();
|
|
21176
21173
|
this.loading = true;
|
|
21177
21174
|
this.isLogin = false;
|
|
21175
|
+
// showUserEventNotification: boolean;
|
|
21176
|
+
// showJobProgression: boolean;
|
|
21177
|
+
// jobProgressionOptions: JobProgressionOptions;
|
|
21178
21178
|
this.$items = new BehaviorSubject(undefined);
|
|
21179
21179
|
this.id = 'menu';
|
|
21180
21180
|
this.menuId = 'left';
|
|
@@ -21188,6 +21188,10 @@ class MenuComponent {
|
|
|
21188
21188
|
this.splitPane.when = yield firstNotNilPromise(this.menuService.splitPaneWhen);
|
|
21189
21189
|
// Wait platform started
|
|
21190
21190
|
yield this.platformService.ready();
|
|
21191
|
+
// Init social options
|
|
21192
|
+
// this.showUserEventNotification = toBoolean(this.socialModuleOptions?.showUserEventNotification, false);
|
|
21193
|
+
// this.showJobProgression = toBoolean(this.socialModuleOptions?.showJobProgression, false);
|
|
21194
|
+
// this.jobProgressionOptions = this.socialModuleOptions?.jobProgressionOptions;
|
|
21191
21195
|
// Listen to menu service event
|
|
21192
21196
|
this.menuService.splitPaneWhen
|
|
21193
21197
|
.subscribe((value) => this.setSplitPaneWhen(value));
|
|
@@ -21434,7 +21438,7 @@ class MenuComponent {
|
|
|
21434
21438
|
MenuComponent.decorators = [
|
|
21435
21439
|
{ type: Component, args: [{
|
|
21436
21440
|
selector: 'app-menu',
|
|
21437
|
-
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",
|
|
21441
|
+
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",
|
|
21438
21442
|
animations: [fadeInAnimation],
|
|
21439
21443
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21440
21444
|
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)}}"]
|
|
@@ -21498,13 +21502,14 @@ class AppIconComponent {
|
|
|
21498
21502
|
this.icon = value.icon;
|
|
21499
21503
|
this.matIcon = value.matIcon;
|
|
21500
21504
|
this.matSvgIcon = value.matSvgIcon;
|
|
21505
|
+
this.color = value.color;
|
|
21501
21506
|
}
|
|
21502
21507
|
;
|
|
21503
21508
|
}
|
|
21504
21509
|
AppIconComponent.decorators = [
|
|
21505
21510
|
{ type: Component, args: [{
|
|
21506
21511
|
selector: 'app-icon',
|
|
21507
|
-
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"
|
|
21512
|
+
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"
|
|
21508
21513
|
},] }
|
|
21509
21514
|
];
|
|
21510
21515
|
AppIconComponent.propDecorators = {
|
|
@@ -21512,6 +21517,8 @@ AppIconComponent.propDecorators = {
|
|
|
21512
21517
|
matIcon: [{ type: Input }],
|
|
21513
21518
|
matSvgIcon: [{ type: Input }],
|
|
21514
21519
|
color: [{ type: Input }],
|
|
21520
|
+
height: [{ type: Input }],
|
|
21521
|
+
width: [{ type: Input }],
|
|
21515
21522
|
ref: [{ type: Input }]
|
|
21516
21523
|
};
|
|
21517
21524
|
|
|
@@ -23013,7 +23020,7 @@ class AppTable {
|
|
|
23013
23020
|
.then(() => this.editRowById(event, row.id, { focusColumn: this.lastUserColumn }));
|
|
23014
23021
|
return true;
|
|
23015
23022
|
}
|
|
23016
|
-
// Edit
|
|
23023
|
+
// Edit next row
|
|
23017
23024
|
this.editRow(event, row, { focusColumn: this.lastUserColumn });
|
|
23018
23025
|
return true;
|
|
23019
23026
|
}
|
|
@@ -23036,7 +23043,8 @@ class AppTable {
|
|
|
23036
23043
|
if (id < 0)
|
|
23037
23044
|
return;
|
|
23038
23045
|
if (id >= this.visibleRowCount) {
|
|
23039
|
-
this.
|
|
23046
|
+
this.focusColumn = opts && opts.focusColumn || this.firstUserColumn;
|
|
23047
|
+
this.addRow(event);
|
|
23040
23048
|
}
|
|
23041
23049
|
else {
|
|
23042
23050
|
const row = yield this.dataSource.getRow(id);
|
|
@@ -23109,7 +23117,7 @@ class AppTable {
|
|
|
23109
23117
|
this.cancelExistingRow(event, row, opts);
|
|
23110
23118
|
}
|
|
23111
23119
|
}
|
|
23112
|
-
addRow(event, insertAt
|
|
23120
|
+
addRow(event, insertAt) {
|
|
23113
23121
|
if (this.debug)
|
|
23114
23122
|
console.debug('[table] Asking for new row...');
|
|
23115
23123
|
if (!this._enabled)
|
|
@@ -23124,7 +23132,7 @@ class AppTable {
|
|
|
23124
23132
|
return false;
|
|
23125
23133
|
}
|
|
23126
23134
|
// Add new row
|
|
23127
|
-
this.addRowToTable(insertAt
|
|
23135
|
+
this.addRowToTable(insertAt);
|
|
23128
23136
|
return true;
|
|
23129
23137
|
}
|
|
23130
23138
|
save(opts) {
|
|
@@ -23239,7 +23247,7 @@ class AppTable {
|
|
|
23239
23247
|
* @param event
|
|
23240
23248
|
* @param row
|
|
23241
23249
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23242
|
-
*
|
|
23250
|
+
* Use skipIfLoading=false to force deletion even if table is busy
|
|
23243
23251
|
*/
|
|
23244
23252
|
deleteRow(event, row, opts) {
|
|
23245
23253
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -23252,7 +23260,7 @@ class AppTable {
|
|
|
23252
23260
|
* @param event
|
|
23253
23261
|
* @param rows
|
|
23254
23262
|
* @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
|
|
23255
|
-
*
|
|
23263
|
+
* Use skipIfLoading=false to force deletion even if table is busy
|
|
23256
23264
|
*/
|
|
23257
23265
|
deleteRows(event, rows, opts) {
|
|
23258
23266
|
var _a;
|
|
@@ -23265,8 +23273,8 @@ class AppTable {
|
|
|
23265
23273
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
23266
23274
|
if (!this._enabled || isEmptyArray(rows))
|
|
23267
23275
|
return 0; // Skip is disabled, or no rows to delete
|
|
23268
|
-
if (this.loading && (!opts || opts.
|
|
23269
|
-
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.
|
|
23276
|
+
if (this.loading && (!opts || opts.skipIfLoading !== false)) {
|
|
23277
|
+
console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.skipLoading = false to force deletion');
|
|
23270
23278
|
return 0; // Skip if loading
|
|
23271
23279
|
}
|
|
23272
23280
|
// Make sure to keep newly created row
|
|
@@ -23789,10 +23797,9 @@ class AppTable {
|
|
|
23789
23797
|
//if (this.debug) console.debug("[table] id = " + id);
|
|
23790
23798
|
return id;
|
|
23791
23799
|
}
|
|
23792
|
-
addRowToTable(insertAt
|
|
23800
|
+
addRowToTable(insertAt) {
|
|
23793
23801
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23794
23802
|
this.focusFirstColumn = true;
|
|
23795
|
-
this.focusColumn = (opts === null || opts === void 0 ? void 0 : opts.focusColumn) || this.firstUserColumn;
|
|
23796
23803
|
yield this._dataSource.asyncCreateNew(insertAt);
|
|
23797
23804
|
this.editedRow = this._dataSource.getRow(-1);
|
|
23798
23805
|
// Emit start editing event
|
|
@@ -25823,7 +25830,10 @@ AppInMemoryTable.propDecorators = {
|
|
|
25823
25830
|
const SocialErrorCodes = {
|
|
25824
25831
|
LOAD_USER_EVENTS_ERROR: 50000,
|
|
25825
25832
|
SAVE_USER_EVENT_ERROR: 50001,
|
|
25826
|
-
|
|
25833
|
+
COUNT_USER_EVENT_ERROR: 50002,
|
|
25834
|
+
SEND_MESSAGE_ERROR: 50003,
|
|
25835
|
+
SUBSCRIBE_USER_EVENTS_ERROR: 50005,
|
|
25836
|
+
SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
|
|
25827
25837
|
};
|
|
25828
25838
|
|
|
25829
25839
|
var UserEvent_1;
|
|
@@ -25838,16 +25848,23 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25838
25848
|
}
|
|
25839
25849
|
asObject(opts) {
|
|
25840
25850
|
const target = super.asObject(opts);
|
|
25851
|
+
target.creationDate = toDateISOString(this.creationDate);
|
|
25852
|
+
target.readDate = toDateISOString(this.readDate);
|
|
25841
25853
|
// Serialize content
|
|
25842
25854
|
if (typeof target.content === 'object') {
|
|
25843
25855
|
target.content = JSON.stringify(target.content);
|
|
25844
25856
|
}
|
|
25857
|
+
delete target.avatar;
|
|
25858
|
+
delete target.avatarIcon;
|
|
25859
|
+
delete target.icon;
|
|
25860
|
+
delete target.actions;
|
|
25845
25861
|
return target;
|
|
25846
25862
|
}
|
|
25847
25863
|
fromObject(source) {
|
|
25848
25864
|
Object.assign(this, source); // Copy all properties
|
|
25849
25865
|
super.fromObject(source);
|
|
25850
25866
|
this.creationDate = fromDateISOString(source.creationDate);
|
|
25867
|
+
this.readDate = fromDateISOString(source.readDate);
|
|
25851
25868
|
try {
|
|
25852
25869
|
// Deserialize content
|
|
25853
25870
|
if (typeof source.content === 'string' && source.content.startsWith('{')) {
|
|
@@ -25866,6 +25883,52 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25866
25883
|
UserEvent = UserEvent_1 = __decorate([
|
|
25867
25884
|
EntityClass({ typename: 'UserEventVO' })
|
|
25868
25885
|
], UserEvent);
|
|
25886
|
+
// @dynamic
|
|
25887
|
+
let UserEventFilter = class UserEventFilter extends EntityFilter {
|
|
25888
|
+
constructor() {
|
|
25889
|
+
super(...arguments);
|
|
25890
|
+
this.types = [];
|
|
25891
|
+
this.levels = [];
|
|
25892
|
+
this.issuers = [];
|
|
25893
|
+
this.recipients = [];
|
|
25894
|
+
this.startDate = null;
|
|
25895
|
+
this.excludeRead = false;
|
|
25896
|
+
}
|
|
25897
|
+
fromObject(source, opts) {
|
|
25898
|
+
super.fromObject(source, opts);
|
|
25899
|
+
this.types = source.types || [];
|
|
25900
|
+
this.levels = source.levels || [];
|
|
25901
|
+
this.issuers = source.issuers || [];
|
|
25902
|
+
this.recipients = source.recipients || [];
|
|
25903
|
+
this.startDate = fromDateISOString(source.startDate);
|
|
25904
|
+
this.excludeRead = source.excludeRead || false;
|
|
25905
|
+
}
|
|
25906
|
+
buildFilter() {
|
|
25907
|
+
const filterFns = super.buildFilter();
|
|
25908
|
+
if (isNotEmptyArray(this.types)) {
|
|
25909
|
+
filterFns.push(t => this.types.includes(t.type));
|
|
25910
|
+
}
|
|
25911
|
+
if (isNotEmptyArray(this.levels)) {
|
|
25912
|
+
filterFns.push(t => this.levels.includes(t.level));
|
|
25913
|
+
}
|
|
25914
|
+
if (isNotEmptyArray(this.issuers)) {
|
|
25915
|
+
filterFns.push(t => this.issuers.includes(t.issuer));
|
|
25916
|
+
}
|
|
25917
|
+
if (isNotEmptyArray(this.recipients)) {
|
|
25918
|
+
filterFns.push(t => this.recipients.includes(t.recipient));
|
|
25919
|
+
}
|
|
25920
|
+
if (isNotNil(this.startDate)) {
|
|
25921
|
+
filterFns.push(t => this.startDate.isSameOrBefore(t.creationDate));
|
|
25922
|
+
}
|
|
25923
|
+
if (this.excludeRead === true) {
|
|
25924
|
+
filterFns.push(t => isNil(t.readSignature)); // todo or t.signature ?
|
|
25925
|
+
}
|
|
25926
|
+
return filterFns;
|
|
25927
|
+
}
|
|
25928
|
+
};
|
|
25929
|
+
UserEventFilter = __decorate([
|
|
25930
|
+
EntityClass({ typename: 'UserEventFilterVO' })
|
|
25931
|
+
], UserEventFilter);
|
|
25869
25932
|
|
|
25870
25933
|
const UserEventFragments = {
|
|
25871
25934
|
userEvent: gql `fragment UserEventFragment on UserEventVO {
|
|
@@ -25893,230 +25956,367 @@ const UserEventFragments = {
|
|
|
25893
25956
|
}`
|
|
25894
25957
|
};
|
|
25895
25958
|
|
|
25896
|
-
|
|
25897
|
-
|
|
25898
|
-
|
|
25899
|
-
|
|
25900
|
-
this.issuer = null;
|
|
25901
|
-
this.recipient = null;
|
|
25902
|
-
}
|
|
25903
|
-
fromObject(source, opts) {
|
|
25904
|
-
super.fromObject(source, opts);
|
|
25905
|
-
this.issuer = source.issuer;
|
|
25906
|
-
this.recipient = source.recipient;
|
|
25907
|
-
}
|
|
25908
|
-
buildFilter() {
|
|
25909
|
-
const filterFns = super.buildFilter();
|
|
25910
|
-
// issuer
|
|
25911
|
-
if (this.issuer) {
|
|
25912
|
-
filterFns.push(t => (t.issuer === this.issuer));
|
|
25913
|
-
}
|
|
25914
|
-
if (this.recipient) {
|
|
25915
|
-
filterFns.push(t => (t.recipient === this.recipient));
|
|
25916
|
-
}
|
|
25917
|
-
return filterFns;
|
|
25918
|
-
}
|
|
25919
|
-
};
|
|
25920
|
-
UserEventFilter = __decorate([
|
|
25921
|
-
EntityClass({ typename: 'UserEventFilterVO' })
|
|
25922
|
-
], UserEventFilter);
|
|
25923
|
-
const SaveQuery = gql `
|
|
25924
|
-
mutation SaveUserEvent($data: UserEventVOInput){
|
|
25925
|
-
data: saveUserEvent(userEvent: $data){
|
|
25926
|
-
...UserEventFragment
|
|
25927
|
-
}
|
|
25928
|
-
}
|
|
25929
|
-
${UserEventFragments.userEvent}
|
|
25930
|
-
`;
|
|
25931
|
-
const LoadAllQuery = gql `
|
|
25932
|
-
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
25933
|
-
data: userEvents(filter: $filter, page: $page){
|
|
25934
|
-
...LightUserEventFragment
|
|
25935
|
-
}
|
|
25936
|
-
}
|
|
25937
|
-
${UserEventFragments.lightUserEvent}
|
|
25938
|
-
`;
|
|
25939
|
-
const DeleteByIdsMutation = gql `
|
|
25940
|
-
mutation DeleteUserEvents($ids:[Int]){
|
|
25941
|
-
deleteUserEvents(ids: $ids)
|
|
25942
|
-
}
|
|
25943
|
-
`;
|
|
25944
|
-
const LoadAllWithContentQuery = gql `
|
|
25945
|
-
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
25946
|
-
data: userEvents(filter: $filter, page: $page){
|
|
25947
|
-
...UserEventFragment
|
|
25948
|
-
}
|
|
25949
|
-
}
|
|
25950
|
-
${UserEventFragments.userEvent}
|
|
25951
|
-
`;
|
|
25952
|
-
class UserEventService extends BaseGraphqlService {
|
|
25953
|
-
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
25959
|
+
const moment$6 = momentImported;
|
|
25960
|
+
const UserEventServiceToken = new InjectionToken('UserEventService');
|
|
25961
|
+
class AbstractUserEventService extends BaseGraphqlService {
|
|
25962
|
+
constructor(graphql, accountService, network, translate, toastController, queries, mutations, subscriptions, environment) {
|
|
25954
25963
|
super(graphql, environment);
|
|
25955
25964
|
this.graphql = graphql;
|
|
25956
25965
|
this.accountService = accountService;
|
|
25957
25966
|
this.network = network;
|
|
25958
25967
|
this.translate = translate;
|
|
25959
25968
|
this.toastController = toastController;
|
|
25969
|
+
this.queries = queries;
|
|
25970
|
+
this.mutations = mutations;
|
|
25971
|
+
this.subscriptions = subscriptions;
|
|
25960
25972
|
this.environment = environment;
|
|
25961
|
-
this.
|
|
25973
|
+
this._count$ = new BehaviorSubject(0);
|
|
25974
|
+
this._subscriptions = new Subscription();
|
|
25975
|
+
this.listeners = [];
|
|
25976
|
+
this._logPrefix = '[user-event-service] ';
|
|
25962
25977
|
// For DEV only
|
|
25963
|
-
this._debug = environment
|
|
25978
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
25979
|
+
// listen login/logout
|
|
25980
|
+
this._subscriptions.add(accountService.onLogin.subscribe(() => __awaiter(this, void 0, void 0, function* () {
|
|
25981
|
+
const count = yield this.count(this.defaultFilter());
|
|
25982
|
+
if (count && this._debug) {
|
|
25983
|
+
console.debug(`${this._logPrefix}Received ${count} unread notifications`);
|
|
25984
|
+
}
|
|
25985
|
+
this._count$.next(count);
|
|
25986
|
+
})));
|
|
25987
|
+
}
|
|
25988
|
+
get userEventCount() {
|
|
25989
|
+
return this._count$.asObservable();
|
|
25990
|
+
}
|
|
25991
|
+
ngOnDestroy() {
|
|
25992
|
+
this._subscriptions.unsubscribe();
|
|
25964
25993
|
}
|
|
25965
|
-
/**
|
|
25966
|
-
*
|
|
25967
|
-
* @param offset
|
|
25968
|
-
* @param size
|
|
25969
|
-
* @param sortBy
|
|
25970
|
-
* @param sortDirection
|
|
25971
|
-
* @param filter
|
|
25972
|
-
* @param options
|
|
25973
|
-
* @deprecated use watchPage() instead
|
|
25974
|
-
*/
|
|
25975
25994
|
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
25976
25995
|
return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
|
|
25977
25996
|
}
|
|
25978
25997
|
watchPage(page, filter, options) {
|
|
25998
|
+
var _a;
|
|
25979
25999
|
let now = this._debug && Date.now();
|
|
25980
26000
|
//if (this._debug)
|
|
25981
|
-
console.debug(
|
|
26001
|
+
console.debug(`${this._logPrefix}Loading user events...`, filter);
|
|
25982
26002
|
filter = this.asFilter(filter);
|
|
25983
26003
|
// Force recipient to current issuer, if not admin and not specified
|
|
25984
|
-
if (
|
|
25985
|
-
const recipient = this.
|
|
25986
|
-
if (
|
|
26004
|
+
if (isEmptyArray(filter.recipients) || !this.accountService.isAdmin()) {
|
|
26005
|
+
const recipient = this.defaultRecipient();
|
|
26006
|
+
if (!((_a = filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
|
|
25987
26007
|
console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
|
|
25988
|
-
filter.
|
|
26008
|
+
filter.recipients = [recipient];
|
|
25989
26009
|
}
|
|
25990
26010
|
}
|
|
25991
|
-
const withContent = options
|
|
26011
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
25992
26012
|
return this.mutableWatchQuery({
|
|
25993
26013
|
queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
|
|
25994
|
-
query: withContent ?
|
|
26014
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
25995
26015
|
variables: {
|
|
25996
|
-
page: Object.assign(
|
|
26016
|
+
page: Object.assign({ sortBy: 'updateDate', sortDirection: 'desc' }, page),
|
|
25997
26017
|
filter: filter && filter.asPodObject()
|
|
25998
26018
|
},
|
|
25999
26019
|
arrayFieldName: 'data',
|
|
26000
26020
|
error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
|
|
26001
|
-
fetchPolicy: options
|
|
26021
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
|
|
26002
26022
|
})
|
|
26003
26023
|
.pipe(map(res => {
|
|
26004
|
-
const data = res
|
|
26024
|
+
const data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(this.processUserEvent);
|
|
26005
26025
|
if (now) {
|
|
26006
|
-
console.debug(
|
|
26026
|
+
console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);
|
|
26007
26027
|
now = null;
|
|
26008
26028
|
}
|
|
26029
|
+
const unreadCount = this.unreadEvents(data);
|
|
26009
26030
|
return {
|
|
26010
26031
|
data,
|
|
26011
|
-
total: res
|
|
26032
|
+
total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
|
|
26012
26033
|
};
|
|
26013
26034
|
}));
|
|
26014
26035
|
}
|
|
26015
|
-
|
|
26016
|
-
|
|
26017
|
-
|
|
26036
|
+
add(entity) {
|
|
26037
|
+
// TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
26038
|
+
entity = this.processUserEvent(entity);
|
|
26039
|
+
const withContent = !!entity.content;
|
|
26040
|
+
// Add user event locally
|
|
26041
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26042
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26043
|
+
data: entity
|
|
26044
|
+
});
|
|
26045
|
+
// Update count
|
|
26046
|
+
this._count$.next(this._count$.value + 1);
|
|
26018
26047
|
}
|
|
26019
|
-
|
|
26020
|
-
|
|
26021
|
-
*
|
|
26022
|
-
* @param entity
|
|
26023
|
-
*/
|
|
26024
|
-
save(entity, options) {
|
|
26048
|
+
count(filter, options) {
|
|
26049
|
+
var _a;
|
|
26025
26050
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26026
|
-
this.
|
|
26027
|
-
|
|
26028
|
-
|
|
26029
|
-
|
|
26030
|
-
|
|
26051
|
+
if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
|
|
26052
|
+
console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
|
|
26053
|
+
return undefined;
|
|
26054
|
+
}
|
|
26055
|
+
if (!filter)
|
|
26056
|
+
throw new Error(`Missing argument 'filter'`);
|
|
26057
|
+
filter = this.asFilter(filter);
|
|
26031
26058
|
if (this._debug)
|
|
26032
|
-
console.debug(
|
|
26033
|
-
yield this.graphql.
|
|
26034
|
-
|
|
26059
|
+
console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
|
|
26060
|
+
const res = yield this.graphql.query({
|
|
26061
|
+
query: this.queries.count,
|
|
26035
26062
|
variables: {
|
|
26036
|
-
|
|
26063
|
+
filter: filter.asPodObject()
|
|
26037
26064
|
},
|
|
26038
|
-
error: { code: SocialErrorCodes.
|
|
26039
|
-
|
|
26040
|
-
// Update entity
|
|
26041
|
-
const savedEntity = data && data.data;
|
|
26042
|
-
if (savedEntity) {
|
|
26043
|
-
if (this._debug)
|
|
26044
|
-
console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
|
|
26045
|
-
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26046
|
-
// Add to cache
|
|
26047
|
-
if (isNew) {
|
|
26048
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26049
|
-
query: LoadAllQuery,
|
|
26050
|
-
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26051
|
-
});
|
|
26052
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26053
|
-
query: LoadAllWithContentQuery,
|
|
26054
|
-
data: savedEntity
|
|
26055
|
-
});
|
|
26056
|
-
}
|
|
26057
|
-
}
|
|
26058
|
-
}
|
|
26065
|
+
error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
|
|
26066
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
|
|
26059
26067
|
});
|
|
26060
|
-
return
|
|
26068
|
+
return res.total;
|
|
26061
26069
|
});
|
|
26062
26070
|
}
|
|
26063
|
-
|
|
26064
|
-
|
|
26065
|
-
|
|
26066
|
-
|
|
26067
|
-
|
|
26068
|
-
|
|
26069
|
-
|
|
26070
|
-
|
|
26071
|
+
listenChanges(filter, options) {
|
|
26072
|
+
var _a;
|
|
26073
|
+
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
|
|
26074
|
+
console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
|
|
26075
|
+
return of();
|
|
26076
|
+
}
|
|
26077
|
+
if (!filter)
|
|
26078
|
+
throw new Error(`Missing argument 'filter'`);
|
|
26079
|
+
filter = this.asFilter(filter);
|
|
26080
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26081
|
+
if (this._debug)
|
|
26082
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
|
|
26083
|
+
return this.graphql.subscribe({
|
|
26084
|
+
query: this.subscriptions.listenChanges,
|
|
26085
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26086
|
+
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26087
|
+
error: {
|
|
26088
|
+
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26089
|
+
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26090
|
+
}
|
|
26091
|
+
}).pipe(map(({ data }) => {
|
|
26092
|
+
if (data && this._debug)
|
|
26093
|
+
console.debug(`${this._logPrefix}Received new user events:`, data);
|
|
26094
|
+
const updatedData = data === null || data === void 0 ? void 0 : data.map(this.processUserEvent);
|
|
26095
|
+
// Update cache
|
|
26096
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26097
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26098
|
+
data: updatedData
|
|
26099
|
+
});
|
|
26100
|
+
// update count
|
|
26101
|
+
this._count$.next(this.unreadEvents(updatedData));
|
|
26102
|
+
return updatedData;
|
|
26103
|
+
}));
|
|
26104
|
+
}
|
|
26105
|
+
delete(entity) {
|
|
26106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26107
|
+
if (!entity)
|
|
26108
|
+
return; // skip
|
|
26109
|
+
yield this.deleteAll([entity]);
|
|
26110
|
+
});
|
|
26111
|
+
}
|
|
26112
|
+
deleteAll(entities, opts) {
|
|
26113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26071
26114
|
const ids = entities && entities
|
|
26072
26115
|
.map(t => t.id);
|
|
26073
26116
|
if (isEmptyArray(ids))
|
|
26074
26117
|
return; // stop, if nothing else to do
|
|
26075
26118
|
const now = Date.now();
|
|
26076
26119
|
if (this._debug)
|
|
26077
|
-
console.debug(
|
|
26120
|
+
console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
|
|
26078
26121
|
yield this.graphql.mutate({
|
|
26079
|
-
mutation:
|
|
26122
|
+
mutation: this.mutations.deleteByIds,
|
|
26080
26123
|
variables: {
|
|
26081
26124
|
ids
|
|
26082
26125
|
},
|
|
26083
26126
|
update: (proxy) => {
|
|
26084
26127
|
// Remove from caches
|
|
26085
26128
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26086
|
-
query:
|
|
26129
|
+
query: this.queries.loadAll,
|
|
26087
26130
|
ids
|
|
26088
26131
|
});
|
|
26089
26132
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26090
|
-
query:
|
|
26133
|
+
query: this.queries.loadAllWithContent,
|
|
26091
26134
|
ids
|
|
26092
26135
|
});
|
|
26093
26136
|
if (this._debug)
|
|
26094
|
-
console.debug(
|
|
26137
|
+
console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
|
|
26095
26138
|
}
|
|
26096
26139
|
});
|
|
26097
26140
|
});
|
|
26098
26141
|
}
|
|
26099
|
-
|
|
26100
|
-
* Delete userEvent entities
|
|
26101
|
-
*/
|
|
26102
|
-
delete(data) {
|
|
26142
|
+
save(entity, options) {
|
|
26103
26143
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26104
|
-
|
|
26105
|
-
|
|
26106
|
-
|
|
26144
|
+
this.fillDefaultProperties(entity);
|
|
26145
|
+
// Transform into json
|
|
26146
|
+
const isNew = isNil(entity.id);
|
|
26147
|
+
const json = entity.asObject();
|
|
26148
|
+
const now = Date.now();
|
|
26149
|
+
if (this._debug)
|
|
26150
|
+
console.debug(`${this._logPrefix}Saving user event...`, json);
|
|
26151
|
+
yield this.graphql.mutate({
|
|
26152
|
+
mutation: this.mutations.save,
|
|
26153
|
+
variables: {
|
|
26154
|
+
data: json
|
|
26155
|
+
},
|
|
26156
|
+
error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
|
|
26157
|
+
update: (proxy, { data }) => {
|
|
26158
|
+
// Update entity
|
|
26159
|
+
const savedEntity = data && data.data;
|
|
26160
|
+
if (savedEntity) {
|
|
26161
|
+
if (this._debug)
|
|
26162
|
+
console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
|
|
26163
|
+
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26164
|
+
// Add to cache
|
|
26165
|
+
if (isNew) {
|
|
26166
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26167
|
+
query: this.queries.loadAll,
|
|
26168
|
+
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26169
|
+
});
|
|
26170
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26171
|
+
query: this.queries.loadAllWithContent,
|
|
26172
|
+
data: savedEntity
|
|
26173
|
+
});
|
|
26174
|
+
}
|
|
26175
|
+
}
|
|
26176
|
+
}
|
|
26177
|
+
});
|
|
26178
|
+
return entity;
|
|
26107
26179
|
});
|
|
26108
26180
|
}
|
|
26109
|
-
|
|
26110
|
-
|
|
26111
|
-
|
|
26112
|
-
|
|
26181
|
+
saveAll(data, opts) {
|
|
26182
|
+
return Promise.all(data
|
|
26183
|
+
.map(entity => this.save(entity, opts)));
|
|
26184
|
+
}
|
|
26185
|
+
markAsRead(entity) {
|
|
26186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26187
|
+
// Get onRead listeners
|
|
26188
|
+
const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));
|
|
26189
|
+
if (onReadListeners.length) {
|
|
26190
|
+
for (const listener of onReadListeners) {
|
|
26191
|
+
yield listener.onRead(entity);
|
|
26192
|
+
}
|
|
26193
|
+
}
|
|
26194
|
+
else {
|
|
26195
|
+
// Use default
|
|
26196
|
+
yield this.defaultMarkAsRead(entity);
|
|
26197
|
+
}
|
|
26198
|
+
});
|
|
26199
|
+
}
|
|
26200
|
+
registerListener(listener) {
|
|
26201
|
+
if (!this.listeners)
|
|
26202
|
+
this.listeners = [];
|
|
26203
|
+
this.listeners.push(listener);
|
|
26204
|
+
}
|
|
26205
|
+
/* -- protected methods -- */
|
|
26206
|
+
processUserEvent(source) {
|
|
26207
|
+
// Convert json source to IUserEvent
|
|
26208
|
+
let target = this.fromObject(source);
|
|
26209
|
+
// Get listeners
|
|
26210
|
+
const listeners = (this.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
|
|
26211
|
+
for (const listener of listeners) {
|
|
26212
|
+
if (target) {
|
|
26213
|
+
target = listener.onReceived(target);
|
|
26214
|
+
}
|
|
26215
|
+
else {
|
|
26216
|
+
if (this._debug)
|
|
26217
|
+
console.debug(`${this._logPrefix}Event has been rejected by a listener`, source);
|
|
26218
|
+
break;
|
|
26219
|
+
}
|
|
26220
|
+
}
|
|
26221
|
+
return target;
|
|
26222
|
+
}
|
|
26223
|
+
defaultMarkAsRead(userEvent) {
|
|
26224
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26225
|
+
if (!userEvent)
|
|
26226
|
+
throw new Error(`${this._logPrefix}Invalid event to save`);
|
|
26227
|
+
// set read date
|
|
26228
|
+
userEvent.readDate = moment$6();
|
|
26229
|
+
if (!userEvent.id || userEvent.id < 0) {
|
|
26230
|
+
if (this._debug)
|
|
26231
|
+
console.debug(`${this._logPrefix}Save local user event`);
|
|
26232
|
+
// TODO !!!!!!!!!!!!!
|
|
26233
|
+
}
|
|
26234
|
+
else {
|
|
26235
|
+
yield this.save(userEvent);
|
|
26236
|
+
}
|
|
26237
|
+
});
|
|
26113
26238
|
}
|
|
26114
|
-
|
|
26115
|
-
|
|
26116
|
-
|
|
26239
|
+
defaultFilter() {
|
|
26240
|
+
// By default
|
|
26241
|
+
return {
|
|
26242
|
+
recipients: [this.defaultRecipient()]
|
|
26243
|
+
};
|
|
26117
26244
|
}
|
|
26118
|
-
|
|
26119
|
-
return this.
|
|
26245
|
+
defaultRecipient() {
|
|
26246
|
+
return this.accountService.person.pubkey;
|
|
26247
|
+
}
|
|
26248
|
+
fillDefaultProperties(entity) {
|
|
26249
|
+
}
|
|
26250
|
+
unreadEvents(events) {
|
|
26251
|
+
// default calculation on unread events from a list
|
|
26252
|
+
if (isEmptyArray(events))
|
|
26253
|
+
return undefined;
|
|
26254
|
+
const lastReadDate = events
|
|
26255
|
+
.filter(event => isNotNil(event.readDate))
|
|
26256
|
+
.reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
|
|
26257
|
+
return events
|
|
26258
|
+
.filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
|
|
26259
|
+
}
|
|
26260
|
+
copyIdAndUpdateDate(source, target) {
|
|
26261
|
+
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26262
|
+
}
|
|
26263
|
+
}
|
|
26264
|
+
AbstractUserEventService.decorators = [
|
|
26265
|
+
{ type: Directive }
|
|
26266
|
+
];
|
|
26267
|
+
AbstractUserEventService.ctorParameters = () => [
|
|
26268
|
+
{ type: GraphqlService },
|
|
26269
|
+
{ type: AccountService },
|
|
26270
|
+
{ type: NetworkService },
|
|
26271
|
+
{ type: TranslateService },
|
|
26272
|
+
{ type: ToastController },
|
|
26273
|
+
{ type: undefined },
|
|
26274
|
+
{ type: undefined },
|
|
26275
|
+
{ type: undefined },
|
|
26276
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
26277
|
+
];
|
|
26278
|
+
const userEventQueries = {
|
|
26279
|
+
loadAll: gql `
|
|
26280
|
+
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26281
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26282
|
+
...LightUserEventFragment
|
|
26283
|
+
}
|
|
26284
|
+
}
|
|
26285
|
+
${UserEventFragments.lightUserEvent}
|
|
26286
|
+
`,
|
|
26287
|
+
loadAllWithContent: gql `
|
|
26288
|
+
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26289
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26290
|
+
...UserEventFragment
|
|
26291
|
+
}
|
|
26292
|
+
}
|
|
26293
|
+
${UserEventFragments.userEvent}
|
|
26294
|
+
`
|
|
26295
|
+
};
|
|
26296
|
+
const userEventMutations = {
|
|
26297
|
+
deleteByIds: gql `
|
|
26298
|
+
mutation DeleteUserEvents($ids:[Int]){
|
|
26299
|
+
deleteUserEvents(ids: $ids)
|
|
26300
|
+
}
|
|
26301
|
+
`,
|
|
26302
|
+
save: gql `
|
|
26303
|
+
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26304
|
+
data: saveUserEvent(userEvent: $data){
|
|
26305
|
+
...UserEventFragment
|
|
26306
|
+
}
|
|
26307
|
+
}
|
|
26308
|
+
${UserEventFragments.userEvent}
|
|
26309
|
+
`
|
|
26310
|
+
};
|
|
26311
|
+
class UserEventService extends AbstractUserEventService {
|
|
26312
|
+
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26313
|
+
super(graphql, accountService, network, translate, toastController, userEventQueries, userEventMutations, undefined, environment);
|
|
26314
|
+
this.graphql = graphql;
|
|
26315
|
+
this.accountService = accountService;
|
|
26316
|
+
this.network = network;
|
|
26317
|
+
this.translate = translate;
|
|
26318
|
+
this.toastController = toastController;
|
|
26319
|
+
this.environment = environment;
|
|
26120
26320
|
}
|
|
26121
26321
|
showToastErrorWithContext(opts) {
|
|
26122
26322
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -26180,13 +26380,16 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26180
26380
|
}
|
|
26181
26381
|
sendDataForDebug(data) {
|
|
26182
26382
|
const userEvent = new UserEvent();
|
|
26183
|
-
userEvent.
|
|
26383
|
+
userEvent.type = UserEventTypes.DEBUG_DATA;
|
|
26184
26384
|
userEvent.content = this.convertObjectToString(data);
|
|
26185
26385
|
return this.save(userEvent);
|
|
26186
26386
|
}
|
|
26187
26387
|
asFilter(filter) {
|
|
26188
26388
|
return UserEventFilter.fromObject(filter);
|
|
26189
26389
|
}
|
|
26390
|
+
fromObject(source) {
|
|
26391
|
+
return UserEvent.fromObject(source);
|
|
26392
|
+
}
|
|
26190
26393
|
/* -- protected methods -- */
|
|
26191
26394
|
convertObjectToString(data) {
|
|
26192
26395
|
if (typeof data === 'string') {
|
|
@@ -26215,13 +26418,9 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26215
26418
|
// TODO: compute sign
|
|
26216
26419
|
console.warn('TODO: sign user event before sending');
|
|
26217
26420
|
}
|
|
26218
|
-
copyIdAndUpdateDate(source, target) {
|
|
26219
|
-
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26220
|
-
}
|
|
26221
26421
|
}
|
|
26222
|
-
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" });
|
|
26223
26422
|
UserEventService.decorators = [
|
|
26224
|
-
{ type: Injectable
|
|
26423
|
+
{ type: Injectable }
|
|
26225
26424
|
];
|
|
26226
26425
|
UserEventService.ctorParameters = () => [
|
|
26227
26426
|
{ type: GraphqlService },
|
|
@@ -26234,7 +26433,7 @@ UserEventService.ctorParameters = () => [
|
|
|
26234
26433
|
|
|
26235
26434
|
const ICONS_MAP = {
|
|
26236
26435
|
DEBUG_DATA: { matIcon: 'bug_report' },
|
|
26237
|
-
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26436
|
+
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26238
26437
|
};
|
|
26239
26438
|
// TODO: refactor with a registration done by data service:
|
|
26240
26439
|
// - userEventService.registerEventAction({__typename: 'TripVO', ...})
|
|
@@ -26300,7 +26499,7 @@ class UserEventsTable extends AppTable {
|
|
|
26300
26499
|
}
|
|
26301
26500
|
}));
|
|
26302
26501
|
const filter = this.filter || new UserEventFilter();
|
|
26303
|
-
filter.
|
|
26502
|
+
filter.recipients = [this.recipient];
|
|
26304
26503
|
this.setFilter(filter, { emitEvent: true });
|
|
26305
26504
|
}
|
|
26306
26505
|
start() {
|
|
@@ -26313,17 +26512,17 @@ class UserEventsTable extends AppTable {
|
|
|
26313
26512
|
});
|
|
26314
26513
|
}
|
|
26315
26514
|
getIcon(source) {
|
|
26316
|
-
return ICONS_MAP[source.
|
|
26515
|
+
return ICONS_MAP[source.type];
|
|
26317
26516
|
}
|
|
26318
26517
|
getDetail(source) {
|
|
26319
26518
|
if (!source)
|
|
26320
26519
|
return undefined;
|
|
26321
|
-
if (source.content && source.
|
|
26520
|
+
if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
|
|
26322
26521
|
const context = source.content.context;
|
|
26323
26522
|
if (context && context.__typename) {
|
|
26324
|
-
const actions = this.service.getActionsByTypename(context.__typename);
|
|
26523
|
+
// const actions = this.service.getActionsByTypename(context.__typename);
|
|
26325
26524
|
return {
|
|
26326
|
-
actions,
|
|
26525
|
+
// actions,
|
|
26327
26526
|
title: source.content.error && source.content.error.message || source.content.message,
|
|
26328
26527
|
description: source.content.error && source.content.error.details || undefined
|
|
26329
26528
|
};
|
|
@@ -26335,11 +26534,11 @@ class UserEventsTable extends AppTable {
|
|
|
26335
26534
|
doAction(action, row) {
|
|
26336
26535
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26337
26536
|
const event = row.currentData;
|
|
26338
|
-
const context = event.content && event.content.context;
|
|
26537
|
+
// const context = event.content && event.content.context;
|
|
26339
26538
|
this.markAsLoading();
|
|
26340
26539
|
if (action && typeof action.executeAction === 'function') {
|
|
26341
26540
|
try {
|
|
26342
|
-
let res = action.executeAction(event
|
|
26541
|
+
let res = action.executeAction(event /*, context*/);
|
|
26343
26542
|
res = (res instanceof Promise) ? yield res : res;
|
|
26344
26543
|
}
|
|
26345
26544
|
catch (err) {
|
|
@@ -26358,13 +26557,18 @@ UserEventsTable.decorators = [
|
|
|
26358
26557
|
selector: 'app-user-events-table',
|
|
26359
26558
|
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",
|
|
26360
26559
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26560
|
+
providers: [
|
|
26561
|
+
{
|
|
26562
|
+
provide: UserEventServiceToken, useClass: UserEventService
|
|
26563
|
+
}
|
|
26564
|
+
],
|
|
26361
26565
|
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}"]
|
|
26362
26566
|
},] }
|
|
26363
26567
|
];
|
|
26364
26568
|
UserEventsTable.ctorParameters = () => [
|
|
26365
26569
|
{ type: Injector },
|
|
26366
26570
|
{ type: AccountService },
|
|
26367
|
-
{ type:
|
|
26571
|
+
{ type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
|
|
26368
26572
|
{ type: EntitiesStorage },
|
|
26369
26573
|
{ type: ChangeDetectorRef },
|
|
26370
26574
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
@@ -26376,6 +26580,150 @@ UserEventsTable.propDecorators = {
|
|
|
26376
26580
|
defaultSortDirection: [{ type: Input }]
|
|
26377
26581
|
};
|
|
26378
26582
|
|
|
26583
|
+
class UserEventNotificationList {
|
|
26584
|
+
constructor(popoverController) {
|
|
26585
|
+
this.popoverController = popoverController;
|
|
26586
|
+
}
|
|
26587
|
+
ngOnInit() {
|
|
26588
|
+
}
|
|
26589
|
+
read($event, userEvent) {
|
|
26590
|
+
var _a;
|
|
26591
|
+
if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
|
|
26592
|
+
return;
|
|
26593
|
+
(_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
|
|
26594
|
+
}
|
|
26595
|
+
executeAction(action, userEvent) {
|
|
26596
|
+
// Execute then close popover
|
|
26597
|
+
action.executeAction(userEvent);
|
|
26598
|
+
this.dismiss();
|
|
26599
|
+
}
|
|
26600
|
+
dismiss() {
|
|
26601
|
+
this.popoverController.dismiss();
|
|
26602
|
+
}
|
|
26603
|
+
}
|
|
26604
|
+
UserEventNotificationList.decorators = [
|
|
26605
|
+
{ type: Component, args: [{
|
|
26606
|
+
selector: 'app-user-event-notification-list',
|
|
26607
|
+
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",
|
|
26608
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
|
|
26609
|
+
},] }
|
|
26610
|
+
];
|
|
26611
|
+
UserEventNotificationList.ctorParameters = () => [
|
|
26612
|
+
{ type: PopoverController }
|
|
26613
|
+
];
|
|
26614
|
+
UserEventNotificationList.propDecorators = {
|
|
26615
|
+
titleI18n: [{ type: Input }],
|
|
26616
|
+
userEvents: [{ type: Input }],
|
|
26617
|
+
readEvent: [{ type: Output }]
|
|
26618
|
+
};
|
|
26619
|
+
|
|
26620
|
+
class UserEventNotificationComponent {
|
|
26621
|
+
constructor(userEventService, accountService, popoverController, cd) {
|
|
26622
|
+
this.userEventService = userEventService;
|
|
26623
|
+
this.accountService = accountService;
|
|
26624
|
+
this.popoverController = popoverController;
|
|
26625
|
+
this.cd = cd;
|
|
26626
|
+
this.debug = false;
|
|
26627
|
+
this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
|
|
26628
|
+
this.disabled = false;
|
|
26629
|
+
this.userEventsSubject = new BehaviorSubject(undefined);
|
|
26630
|
+
this._subscriptions = new Subscription();
|
|
26631
|
+
this._logPrefix = '[user-event-notification] ';
|
|
26632
|
+
this._readEvent = new EventEmitter();
|
|
26633
|
+
}
|
|
26634
|
+
get count() {
|
|
26635
|
+
var _a;
|
|
26636
|
+
return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(map(value => value === 0 ? undefined : value));
|
|
26637
|
+
}
|
|
26638
|
+
ngOnInit() {
|
|
26639
|
+
var _a;
|
|
26640
|
+
if (isNil(this.userEventService)) {
|
|
26641
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
26642
|
+
this.disabled = true;
|
|
26643
|
+
return;
|
|
26644
|
+
}
|
|
26645
|
+
this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc", {
|
|
26646
|
+
recipients: [(_a = this.accountService.person) === null || _a === void 0 ? void 0 : _a.pubkey]
|
|
26647
|
+
}).subscribe(value => {
|
|
26648
|
+
const data = value.data;
|
|
26649
|
+
if (this.debug) {
|
|
26650
|
+
console.debug(`${this._logPrefix}Receiving user events`, data);
|
|
26651
|
+
}
|
|
26652
|
+
this.userEventsSubject.next(data);
|
|
26653
|
+
}));
|
|
26654
|
+
this._readEvent.subscribe(value => {
|
|
26655
|
+
this.userEventService.markAsRead(value);
|
|
26656
|
+
});
|
|
26657
|
+
}
|
|
26658
|
+
showList(event) {
|
|
26659
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26660
|
+
const popover = yield this.popoverController.create({
|
|
26661
|
+
component: UserEventNotificationList,
|
|
26662
|
+
componentProps: {
|
|
26663
|
+
titleI18n: this.titleI18n,
|
|
26664
|
+
userEvents: this.userEventsSubject,
|
|
26665
|
+
readEvent: this._readEvent
|
|
26666
|
+
},
|
|
26667
|
+
backdropDismiss: true,
|
|
26668
|
+
keyboardClose: true,
|
|
26669
|
+
event,
|
|
26670
|
+
translucent: true,
|
|
26671
|
+
cssClass: 'popover-large'
|
|
26672
|
+
});
|
|
26673
|
+
yield popover.present();
|
|
26674
|
+
});
|
|
26675
|
+
}
|
|
26676
|
+
markForCheck() {
|
|
26677
|
+
this.cd.markForCheck();
|
|
26678
|
+
}
|
|
26679
|
+
ngOnDestroy() {
|
|
26680
|
+
if (this.debug) {
|
|
26681
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
26682
|
+
}
|
|
26683
|
+
this._subscriptions.unsubscribe();
|
|
26684
|
+
}
|
|
26685
|
+
}
|
|
26686
|
+
UserEventNotificationComponent.decorators = [
|
|
26687
|
+
{ type: Component, args: [{
|
|
26688
|
+
selector: 'app-user-event-notification-component',
|
|
26689
|
+
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",
|
|
26690
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26691
|
+
styles: [""]
|
|
26692
|
+
},] }
|
|
26693
|
+
];
|
|
26694
|
+
UserEventNotificationComponent.ctorParameters = () => [
|
|
26695
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] },
|
|
26696
|
+
{ type: AccountService },
|
|
26697
|
+
{ type: PopoverController },
|
|
26698
|
+
{ type: ChangeDetectorRef }
|
|
26699
|
+
];
|
|
26700
|
+
UserEventNotificationComponent.propDecorators = {
|
|
26701
|
+
debug: [{ type: Input }],
|
|
26702
|
+
titleI18n: [{ type: Input }],
|
|
26703
|
+
disabled: [{ type: Input }]
|
|
26704
|
+
};
|
|
26705
|
+
|
|
26706
|
+
class UserEventModule {
|
|
26707
|
+
}
|
|
26708
|
+
UserEventModule.decorators = [
|
|
26709
|
+
{ type: NgModule, args: [{
|
|
26710
|
+
imports: [
|
|
26711
|
+
CommonModule,
|
|
26712
|
+
CoreModule,
|
|
26713
|
+
SharedModule
|
|
26714
|
+
],
|
|
26715
|
+
declarations: [
|
|
26716
|
+
UserEventsTable,
|
|
26717
|
+
UserEventNotificationComponent,
|
|
26718
|
+
UserEventNotificationList,
|
|
26719
|
+
],
|
|
26720
|
+
exports: [
|
|
26721
|
+
UserEventsTable,
|
|
26722
|
+
UserEventNotificationComponent
|
|
26723
|
+
]
|
|
26724
|
+
},] }
|
|
26725
|
+
];
|
|
26726
|
+
|
|
26379
26727
|
const MessageTypes = {
|
|
26380
26728
|
INBOX_MESSAGE: 'INBOX_MESSAGE',
|
|
26381
26729
|
EMAIL: 'EMAIL',
|
|
@@ -26587,9 +26935,9 @@ MessageForm.propDecorators = {
|
|
|
26587
26935
|
canSelectType: [{ type: Input }]
|
|
26588
26936
|
};
|
|
26589
26937
|
|
|
26590
|
-
class
|
|
26938
|
+
class MessageModule {
|
|
26591
26939
|
}
|
|
26592
|
-
|
|
26940
|
+
MessageModule.decorators = [
|
|
26593
26941
|
{ type: NgModule, args: [{
|
|
26594
26942
|
imports: [
|
|
26595
26943
|
CommonModule,
|
|
@@ -26597,17 +26945,318 @@ SocialModule.decorators = [
|
|
|
26597
26945
|
SharedModule
|
|
26598
26946
|
],
|
|
26599
26947
|
declarations: [
|
|
26600
|
-
UserEventsTable,
|
|
26601
26948
|
MessageModal,
|
|
26602
26949
|
MessageForm
|
|
26603
26950
|
],
|
|
26604
26951
|
exports: [
|
|
26605
|
-
UserEventsTable,
|
|
26606
26952
|
MessageModal
|
|
26607
26953
|
]
|
|
26608
26954
|
},] }
|
|
26609
26955
|
];
|
|
26610
26956
|
|
|
26957
|
+
var JobProgression_1;
|
|
26958
|
+
// todo use entity
|
|
26959
|
+
class Job {
|
|
26960
|
+
}
|
|
26961
|
+
// @dynamic
|
|
26962
|
+
let JobProgression = JobProgression_1 = class JobProgression extends Entity {
|
|
26963
|
+
constructor() {
|
|
26964
|
+
super(JobProgression_1.TYPENAME);
|
|
26965
|
+
}
|
|
26966
|
+
fromObject(source) {
|
|
26967
|
+
super.fromObject(source);
|
|
26968
|
+
this.message = source.message;
|
|
26969
|
+
this.current = source.current;
|
|
26970
|
+
this.total = source.total;
|
|
26971
|
+
}
|
|
26972
|
+
};
|
|
26973
|
+
JobProgression = JobProgression_1 = __decorate([
|
|
26974
|
+
EntityClass({ typename: 'JobProgressionVO' })
|
|
26975
|
+
], JobProgression);
|
|
26976
|
+
|
|
26977
|
+
const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
|
|
26978
|
+
const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
|
|
26979
|
+
data: updateJobProgression(id: $id, interval: $interval) {
|
|
26980
|
+
id
|
|
26981
|
+
message
|
|
26982
|
+
current
|
|
26983
|
+
total
|
|
26984
|
+
updateDate
|
|
26985
|
+
}
|
|
26986
|
+
}`;
|
|
26987
|
+
class JobProgressionService extends BaseGraphqlService {
|
|
26988
|
+
constructor(graphql, environment) {
|
|
26989
|
+
super(graphql, environment);
|
|
26990
|
+
this.graphql = graphql;
|
|
26991
|
+
this.environment = environment;
|
|
26992
|
+
this._logPrefix = '[job-progression-service] ';
|
|
26993
|
+
// For DEV only
|
|
26994
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
26995
|
+
}
|
|
26996
|
+
listenChanges(id, options) {
|
|
26997
|
+
if (isNil(id))
|
|
26998
|
+
throw new Error(`${this._logPrefix}Missing argument 'id'`);
|
|
26999
|
+
if (this._debug)
|
|
27000
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
|
|
27001
|
+
return this.graphql.subscribe({
|
|
27002
|
+
query: jobProgressionSubscription,
|
|
27003
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
27004
|
+
variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
27005
|
+
error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
|
|
27006
|
+
}).pipe(map(({ data }) => {
|
|
27007
|
+
const progression = data && JobProgression.fromObject(data);
|
|
27008
|
+
if (progression && this._debug)
|
|
27009
|
+
console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
|
|
27010
|
+
return progression;
|
|
27011
|
+
}));
|
|
27012
|
+
}
|
|
27013
|
+
}
|
|
27014
|
+
JobProgressionService.decorators = [
|
|
27015
|
+
{ type: Injectable }
|
|
27016
|
+
];
|
|
27017
|
+
JobProgressionService.ctorParameters = () => [
|
|
27018
|
+
{ type: GraphqlService },
|
|
27019
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27020
|
+
];
|
|
27021
|
+
|
|
27022
|
+
class JobProgressionList {
|
|
27023
|
+
constructor() {
|
|
27024
|
+
}
|
|
27025
|
+
ngOnInit() {
|
|
27026
|
+
}
|
|
27027
|
+
}
|
|
27028
|
+
JobProgressionList.decorators = [
|
|
27029
|
+
{ type: Component, args: [{
|
|
27030
|
+
selector: 'app-job-progression-list',
|
|
27031
|
+
template: "<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!jobProgressions?.length\">\n {{'SOCIAL.JOB.PROGRESSION.EMPTY' | translate}}\n </ion-item>\n <ion-item *ngFor=\"let jobProgression of jobProgressions\">\n <ion-grid class=\"ion-no-margin\">\n <ion-row>\n <ion-col>\n {{jobProgression.message}}\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-progress-bar\n [value]=\"jobProgression.total > 0 ? jobProgression.current / jobProgression.total : undefined\"\n [type]=\"jobProgression.total > 0 ? 'determinate' : 'indeterminate'\">\n </ion-progress-bar>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
|
|
27032
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
|
|
27033
|
+
},] }
|
|
27034
|
+
];
|
|
27035
|
+
JobProgressionList.ctorParameters = () => [];
|
|
27036
|
+
JobProgressionList.propDecorators = {
|
|
27037
|
+
titleI18n: [{ type: Input }],
|
|
27038
|
+
jobProgressions: [{ type: Input }]
|
|
27039
|
+
};
|
|
27040
|
+
|
|
27041
|
+
class JobProgressionComponent {
|
|
27042
|
+
constructor(jobProgressionService, popoverController, cd) {
|
|
27043
|
+
this.jobProgressionService = jobProgressionService;
|
|
27044
|
+
this.popoverController = popoverController;
|
|
27045
|
+
this.cd = cd;
|
|
27046
|
+
this.debug = false;
|
|
27047
|
+
this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
|
|
27048
|
+
this.jobFinished = new EventEmitter();
|
|
27049
|
+
this.disabled = true;
|
|
27050
|
+
this.color = 'accent';
|
|
27051
|
+
this.mode = 'determinate';
|
|
27052
|
+
this.value = 0;
|
|
27053
|
+
this.jobProgressions = [];
|
|
27054
|
+
this._subscriptions = new Subscription();
|
|
27055
|
+
this._subscriptionsById = {};
|
|
27056
|
+
this._logPrefix = '[job-progression] ';
|
|
27057
|
+
}
|
|
27058
|
+
ngOnInit() {
|
|
27059
|
+
var _a, _b, _c, _d;
|
|
27060
|
+
if (isNil(this.jobProgressionService)) {
|
|
27061
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
27062
|
+
}
|
|
27063
|
+
// parse options
|
|
27064
|
+
this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
|
|
27065
|
+
this.visible = !this.autoHide;
|
|
27066
|
+
this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
|
|
27067
|
+
this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
|
|
27068
|
+
this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
|
|
27069
|
+
}
|
|
27070
|
+
addJob(id) {
|
|
27071
|
+
if (isNil(this.jobProgressionService)) {
|
|
27072
|
+
console.warn(`${this._logPrefix}No service injected. Can't add a job`);
|
|
27073
|
+
return;
|
|
27074
|
+
}
|
|
27075
|
+
if (this.debug) {
|
|
27076
|
+
console.debug(`${this._logPrefix}Add job id=${id}`);
|
|
27077
|
+
}
|
|
27078
|
+
if (!!this.getProgression(id)) {
|
|
27079
|
+
console.warn(`${this._logPrefix}Job (id=${id}) already present`);
|
|
27080
|
+
return;
|
|
27081
|
+
}
|
|
27082
|
+
this.disabled = false;
|
|
27083
|
+
const sub = this.jobProgressionService.listenChanges(id)
|
|
27084
|
+
.pipe(filter(progression => {
|
|
27085
|
+
if (id !== progression.id) {
|
|
27086
|
+
console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
|
|
27087
|
+
return false;
|
|
27088
|
+
}
|
|
27089
|
+
return true;
|
|
27090
|
+
}), map(progression => {
|
|
27091
|
+
// Ensure visible
|
|
27092
|
+
this.visible = true;
|
|
27093
|
+
// Get current progression object
|
|
27094
|
+
const currentProgression = this.getProgression(id);
|
|
27095
|
+
if (!currentProgression) {
|
|
27096
|
+
// add it
|
|
27097
|
+
this.jobProgressions.push(progression);
|
|
27098
|
+
if (this.debug) {
|
|
27099
|
+
console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
|
|
27100
|
+
}
|
|
27101
|
+
}
|
|
27102
|
+
else {
|
|
27103
|
+
// update current
|
|
27104
|
+
Object.assign(currentProgression, progression);
|
|
27105
|
+
if (this.debug) {
|
|
27106
|
+
console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
|
|
27107
|
+
}
|
|
27108
|
+
}
|
|
27109
|
+
return progression;
|
|
27110
|
+
}))
|
|
27111
|
+
.subscribe(progression => {
|
|
27112
|
+
// update value
|
|
27113
|
+
this.updateValue();
|
|
27114
|
+
// job finished
|
|
27115
|
+
if (progression.total > 0 && progression.current == progression.total) {
|
|
27116
|
+
if (this.debug) {
|
|
27117
|
+
console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
|
|
27118
|
+
}
|
|
27119
|
+
// emit event
|
|
27120
|
+
this.jobFinished.emit(progression.id);
|
|
27121
|
+
if (this.autoRemove) {
|
|
27122
|
+
setTimeout(() => {
|
|
27123
|
+
var _a;
|
|
27124
|
+
this.removeJob(progression.id);
|
|
27125
|
+
// If last job
|
|
27126
|
+
if (this.autoHide && !((_a = this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
27127
|
+
setTimeout(() => {
|
|
27128
|
+
this.visible = false;
|
|
27129
|
+
this.markForCheck();
|
|
27130
|
+
}, this.autoHideDelay);
|
|
27131
|
+
}
|
|
27132
|
+
}, this.autoRemoveDelay);
|
|
27133
|
+
}
|
|
27134
|
+
}
|
|
27135
|
+
});
|
|
27136
|
+
this._subscriptionsById[id] = sub;
|
|
27137
|
+
this._subscriptions.add(sub);
|
|
27138
|
+
}
|
|
27139
|
+
removeJob(id) {
|
|
27140
|
+
if (this.debug) {
|
|
27141
|
+
console.debug(`${this._logPrefix}Remove job id=${id}`);
|
|
27142
|
+
}
|
|
27143
|
+
const sub = this._subscriptionsById[id];
|
|
27144
|
+
if (sub) {
|
|
27145
|
+
this._subscriptions.remove(sub);
|
|
27146
|
+
sub.unsubscribe();
|
|
27147
|
+
}
|
|
27148
|
+
const progression = this.getProgression(id);
|
|
27149
|
+
if (progression) {
|
|
27150
|
+
this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
|
|
27151
|
+
}
|
|
27152
|
+
this.updateValue();
|
|
27153
|
+
}
|
|
27154
|
+
getProgression(id) {
|
|
27155
|
+
return this.jobProgressions.find(progression => progression.id === id);
|
|
27156
|
+
}
|
|
27157
|
+
updateValue() {
|
|
27158
|
+
if (this.debug) {
|
|
27159
|
+
console.debug(`${this._logPrefix}Updating value`);
|
|
27160
|
+
}
|
|
27161
|
+
let value = 0;
|
|
27162
|
+
const nbProgression = arraySize(this.jobProgressions);
|
|
27163
|
+
let allIndeterminate = nbProgression > 0;
|
|
27164
|
+
this.jobProgressions.forEach(progression => {
|
|
27165
|
+
const indeterminate = progression.total === 0;
|
|
27166
|
+
allIndeterminate = allIndeterminate && indeterminate;
|
|
27167
|
+
if (!indeterminate) {
|
|
27168
|
+
value = value + progression.current * 100 / progression.total;
|
|
27169
|
+
}
|
|
27170
|
+
});
|
|
27171
|
+
this.value = nbProgression > 0 ? value / nbProgression : 0;
|
|
27172
|
+
this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
|
|
27173
|
+
if (this.debug) {
|
|
27174
|
+
console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
|
|
27175
|
+
}
|
|
27176
|
+
this.markForCheck();
|
|
27177
|
+
}
|
|
27178
|
+
showList(event) {
|
|
27179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27180
|
+
const popover = yield this.popoverController.create({
|
|
27181
|
+
component: JobProgressionList,
|
|
27182
|
+
componentProps: {
|
|
27183
|
+
titleI18n: this.titleI18n,
|
|
27184
|
+
jobProgressions: this.jobProgressions
|
|
27185
|
+
},
|
|
27186
|
+
backdropDismiss: true,
|
|
27187
|
+
keyboardClose: true,
|
|
27188
|
+
event,
|
|
27189
|
+
translucent: true,
|
|
27190
|
+
cssClass: 'popover-large'
|
|
27191
|
+
});
|
|
27192
|
+
yield popover.present();
|
|
27193
|
+
});
|
|
27194
|
+
}
|
|
27195
|
+
markForCheck() {
|
|
27196
|
+
this.cd.markForCheck();
|
|
27197
|
+
}
|
|
27198
|
+
ngOnDestroy() {
|
|
27199
|
+
if (this.debug) {
|
|
27200
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
27201
|
+
}
|
|
27202
|
+
this._subscriptions.unsubscribe();
|
|
27203
|
+
}
|
|
27204
|
+
}
|
|
27205
|
+
JobProgressionComponent.decorators = [
|
|
27206
|
+
{ type: Component, args: [{
|
|
27207
|
+
selector: 'app-job-progression',
|
|
27208
|
+
template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n *ngIf=\"visible\"\n (click)=\"showList($event)\"\n>\n <mat-icon\n [matBadge]=\"jobProgressions?.length\"\n [matBadgeHidden]=\"!jobProgressions?.length\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n >{{ disabled || jobProgressions?.length ? 'schedule' : 'task_alt' }}\n </mat-icon>\n <mat-spinner\n #spinner\n *ngIf=\"jobProgressions?.length\"\n class=\"floating-spinner\"\n [color]=\"color\"\n [mode]=\"mode\"\n [value]=\"value\"\n diameter=\"30\"\n strokeWidth=\"3\"\n ></mat-spinner>\n</button>\n\n",
|
|
27209
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27210
|
+
styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
|
|
27211
|
+
},] }
|
|
27212
|
+
];
|
|
27213
|
+
JobProgressionComponent.ctorParameters = () => [
|
|
27214
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [JobProgressionServiceToken,] }] },
|
|
27215
|
+
{ type: PopoverController },
|
|
27216
|
+
{ type: ChangeDetectorRef }
|
|
27217
|
+
];
|
|
27218
|
+
JobProgressionComponent.propDecorators = {
|
|
27219
|
+
debug: [{ type: Input }],
|
|
27220
|
+
titleI18n: [{ type: Input }],
|
|
27221
|
+
options: [{ type: Input }],
|
|
27222
|
+
jobFinished: [{ type: Output }]
|
|
27223
|
+
};
|
|
27224
|
+
|
|
27225
|
+
class JobModule {
|
|
27226
|
+
}
|
|
27227
|
+
JobModule.decorators = [
|
|
27228
|
+
{ type: NgModule, args: [{
|
|
27229
|
+
imports: [
|
|
27230
|
+
CommonModule,
|
|
27231
|
+
SharedModule,
|
|
27232
|
+
TranslateModule.forChild(),
|
|
27233
|
+
],
|
|
27234
|
+
declarations: [
|
|
27235
|
+
JobProgressionComponent,
|
|
27236
|
+
JobProgressionList
|
|
27237
|
+
],
|
|
27238
|
+
exports: [
|
|
27239
|
+
JobProgressionComponent
|
|
27240
|
+
]
|
|
27241
|
+
},] }
|
|
27242
|
+
];
|
|
27243
|
+
|
|
27244
|
+
const SocialModuleOptionsToken = new InjectionToken("SocialModuleOptions");
|
|
27245
|
+
class SocialModule {
|
|
27246
|
+
}
|
|
27247
|
+
SocialModule.decorators = [
|
|
27248
|
+
{ type: NgModule, args: [{
|
|
27249
|
+
imports: [
|
|
27250
|
+
CommonModule,
|
|
27251
|
+
CoreModule,
|
|
27252
|
+
SharedModule,
|
|
27253
|
+
UserEventModule,
|
|
27254
|
+
JobModule,
|
|
27255
|
+
MessageModule,
|
|
27256
|
+
],
|
|
27257
|
+
},] }
|
|
27258
|
+
];
|
|
27259
|
+
|
|
26611
27260
|
const Mutations = {
|
|
26612
27261
|
send: gql `mutation SendMessage($data: MessageVOInput){
|
|
26613
27262
|
done: sendMessage(message: $data)
|
|
@@ -27253,12 +27902,10 @@ class AutocompleteTestPage {
|
|
|
27253
27902
|
});
|
|
27254
27903
|
}
|
|
27255
27904
|
ngAfterViewInit() {
|
|
27256
|
-
|
|
27257
|
-
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
}, 2000);
|
|
27261
|
-
}
|
|
27905
|
+
setTimeout(() => {
|
|
27906
|
+
this.farEntityField.suggestLengthThreshold = 2;
|
|
27907
|
+
this.farEntityField.reloadItems();
|
|
27908
|
+
}, 2000);
|
|
27262
27909
|
setTimeout(() => this.loadData(), 1000);
|
|
27263
27910
|
}
|
|
27264
27911
|
// Load the form with data
|
|
@@ -27346,7 +27993,7 @@ class AutocompleteTestPage {
|
|
|
27346
27993
|
AutocompleteTestPage.decorators = [
|
|
27347
27994
|
{ type: Component, args: [{
|
|
27348
27995
|
selector: 'app-autocomplete-test',
|
|
27349
|
-
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Entity far in the list (not in first page)\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre style=\"white-space: normal !important;\">value: {{stringify(form.controls.farEntity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"farEntity\" #farEntityField\n [config]=\"autocompleteFields.get('entity-far')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-far]'\"\n [debug]=\"true\"\n [required]=\"true\"\n [clearable]=\"true\"\n placeholder=\"Far entity (in the list)\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [clearable]=\"true\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-mobile-suggestLengthThreshold]'\"\n required\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"true\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-multiple]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter(filterChangeField, 'entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\" #filterChangeField\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Fullscreen\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-mobile-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [clearable]=\"true\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n [debug]=\"true\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggestLengthThreshold]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"false\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-multiple]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
27996
|
+
template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable<any[]></pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Entity far in the list (not in first page)\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre style=\"white-space: normal !important;\">value: {{stringify(form.controls.farEntity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"farEntity\" #farEntityField\n [config]=\"autocompleteFields.get('entity-far')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-far]'\"\n [debug]=\"true\"\n [required]=\"true\"\n [clearable]=\"true\"\n placeholder=\"Far entity (in the list)\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) => any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [clearable]=\"true\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-mobile-suggestLengthThreshold]'\"\n required\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"true\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-multiple]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter(filterChangeField, 'entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\" #filterChangeField\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Fullscreen\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-mobile-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [clearable]=\"true\"\n [logPrefix]=\"'[combo-desktop-suggest]'\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult<any>\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggestLengthThreshold]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Multiple value\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>multiple: true</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entities\"\n [config]=\"autocompleteFields.get('entities-items-filter')\"\n [placeholder]=\"'Multiple'\"\n mobile=\"false\"\n multiple=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-multiple]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable<any[]></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
|
|
27350
27997
|
},] }
|
|
27351
27998
|
];
|
|
27352
27999
|
AutocompleteTestPage.ctorParameters = () => [
|
|
@@ -27422,13 +28069,13 @@ LatLongTestPage.ctorParameters = () => [
|
|
|
27422
28069
|
{ type: FormBuilder }
|
|
27423
28070
|
];
|
|
27424
28071
|
|
|
27425
|
-
const moment$
|
|
28072
|
+
const moment$7 = momentImported;
|
|
27426
28073
|
class SwipeTestPage {
|
|
27427
28074
|
constructor(formBuilder, dateFormatPipe) {
|
|
27428
28075
|
this.formBuilder = formBuilder;
|
|
27429
28076
|
this.dateFormatPipe = dateFormatPipe;
|
|
27430
28077
|
this.$dates = new BehaviorSubject(undefined);
|
|
27431
|
-
this._today = moment$
|
|
28078
|
+
this._today = moment$7().startOf('day');
|
|
27432
28079
|
this.form = formBuilder.group({
|
|
27433
28080
|
empty: [null, Validators.required],
|
|
27434
28081
|
date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
|
|
@@ -27441,7 +28088,7 @@ class SwipeTestPage {
|
|
|
27441
28088
|
ngOnInit() {
|
|
27442
28089
|
const dates = [];
|
|
27443
28090
|
for (let d = 0; d < 7; d++) {
|
|
27444
|
-
dates[d] = moment$
|
|
28091
|
+
dates[d] = moment$7(this._today).add(d - 3, 'day');
|
|
27445
28092
|
}
|
|
27446
28093
|
this.$dates.next(dates);
|
|
27447
28094
|
this.loadData();
|
|
@@ -27482,7 +28129,7 @@ SwipeTestPage.ctorParameters = () => [
|
|
|
27482
28129
|
{ type: DateFormatPipe }
|
|
27483
28130
|
];
|
|
27484
28131
|
|
|
27485
|
-
const moment$
|
|
28132
|
+
const moment$8 = momentImported;
|
|
27486
28133
|
class DateTimeTestPage {
|
|
27487
28134
|
constructor(platform, formBuilder, cd) {
|
|
27488
28135
|
this.platform = platform;
|
|
@@ -27514,7 +28161,7 @@ class DateTimeTestPage {
|
|
|
27514
28161
|
// Load the form with data
|
|
27515
28162
|
loadData() {
|
|
27516
28163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27517
|
-
const now = moment$
|
|
28164
|
+
const now = moment$8();
|
|
27518
28165
|
const data = {
|
|
27519
28166
|
empty: null,
|
|
27520
28167
|
emptyRequired: null,
|
|
@@ -27760,7 +28407,7 @@ NumpadTestPage.ctorParameters = () => [
|
|
|
27760
28407
|
{ type: FormBuilder }
|
|
27761
28408
|
];
|
|
27762
28409
|
|
|
27763
|
-
const moment$
|
|
28410
|
+
const moment$9 = momentImported;
|
|
27764
28411
|
class DateTestPage {
|
|
27765
28412
|
constructor(formBuilder, cd) {
|
|
27766
28413
|
this.formBuilder = formBuilder;
|
|
@@ -27793,7 +28440,7 @@ class DateTestPage {
|
|
|
27793
28440
|
// Load the form with data
|
|
27794
28441
|
loadData() {
|
|
27795
28442
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27796
|
-
const now = moment$
|
|
28443
|
+
const now = moment$9();
|
|
27797
28444
|
const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
|
|
27798
28445
|
const data = {
|
|
27799
28446
|
empty: null,
|
|
@@ -28539,5 +29186,5 @@ CoreTestingModule.decorators = [
|
|
|
28539
29186
|
* Generated bundle index. Do not edit.
|
|
28540
29187
|
*/
|
|
28541
29188
|
|
|
28542
|
-
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj,
|
|
29189
|
+
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, Job, JobModule, JobProgression, JobProgressionComponent, JobProgressionService, JobProgressionServiceToken, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventModule, UserEventNotificationComponent, UserEventService, UserEventServiceToken, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj, UserEventNotificationList as ɵk, JobProgressionList as ɵl, DateTestPage as ɵm, NumpadTestPage as ɵn, MatBadgeIconTestPage as ɵo, ToastTestingModule as ɵp, ToastTestingPage as ɵq };
|
|
28543
29190
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|