@sumaris-net/ngx-components 1.21.0-beta9 → 1.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +594 -1227
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +12 -0
  6. package/esm2015/public_api.js +3 -8
  7. package/esm2015/src/app/core/account/account.js +2 -2
  8. package/esm2015/src/app/core/auth/form/form-auth.js +4 -2
  9. package/esm2015/src/app/core/form/editor.class.js +64 -20
  10. package/esm2015/src/app/core/form/entity-editor-modal.class.js +20 -15
  11. package/esm2015/src/app/core/form/entity-editor.class.js +21 -12
  12. package/esm2015/src/app/core/form/form.class.js +68 -35
  13. package/esm2015/src/app/core/graphql/graphql.service.js +5 -3
  14. package/esm2015/src/app/core/icon/icon.component.js +2 -5
  15. package/esm2015/src/app/core/menu/menu.component.js +2 -2
  16. package/esm2015/src/app/core/services/local-settings.service.js +2 -2
  17. package/esm2015/src/app/core/table/table.class.js +26 -27
  18. package/esm2015/src/app/shared/functions.js +1 -60
  19. package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +5 -4
  20. package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +10 -7
  21. package/esm2015/src/app/shared/material/chips/material.chips.js +3 -2
  22. package/esm2015/src/app/shared/material/chips/testing/chips.test.js +3 -2
  23. package/esm2015/src/app/shared/material/datetime/material.date.js +3 -2
  24. package/esm2015/src/app/shared/material/datetime/material.datetime.js +3 -2
  25. package/esm2015/src/app/shared/observables.js +13 -7
  26. package/esm2015/src/app/shared/pipes/arrays.pipe.js +1 -1
  27. package/esm2015/src/app/shared/pipes/form.pipes.js +4 -6
  28. package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
  29. package/esm2015/src/app/shared/pipes/string.pipes.js +7 -18
  30. package/esm2015/src/app/shared/services/memory-entity-service.class.js +13 -1
  31. package/esm2015/src/app/shared/services.js +61 -0
  32. package/esm2015/src/app/shared/types.js +1 -1
  33. package/esm2015/src/app/social/social.errors.js +2 -5
  34. package/esm2015/src/app/social/social.module.js +15 -10
  35. package/esm2015/src/app/social/user-event/user-event.model.js +2 -58
  36. package/esm2015/src/app/social/user-event/user-event.service.js +167 -295
  37. package/esm2015/src/app/social/user-event/user-events.table.js +12 -17
  38. package/esm2015/sumaris-net.ngx-components.js +6 -8
  39. package/fesm2015/sumaris-net.ngx-components.js +479 -1015
  40. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  41. package/package.json +3 -2
  42. package/public_api.d.ts +2 -7
  43. package/src/app/core/auth/form/form-auth.d.ts +1 -1
  44. package/src/app/core/form/editor.class.d.ts +39 -12
  45. package/src/app/core/form/entity-editor-modal.class.d.ts +4 -3
  46. package/src/app/core/form/entity-editor.class.d.ts +10 -5
  47. package/src/app/core/form/form.class.d.ts +32 -19
  48. package/src/app/core/icon/icon.component.d.ts +4 -4
  49. package/src/app/core/table/table.class.d.ts +21 -14
  50. package/src/app/shared/functions.d.ts +0 -9
  51. package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +1 -2
  52. package/src/app/shared/material/badge/badge-icon.test.d.ts +1 -1
  53. package/src/app/shared/observables.d.ts +1 -0
  54. package/src/app/shared/pipes/form.pipes.d.ts +1 -2
  55. package/src/app/shared/services/memory-entity-service.class.d.ts +6 -0
  56. package/src/app/shared/services.d.ts +9 -0
  57. package/src/app/shared/types.d.ts +0 -4
  58. package/src/app/social/social.errors.d.ts +0 -3
  59. package/src/app/social/social.module.d.ts +0 -8
  60. package/src/app/social/user-event/user-event.model.d.ts +6 -51
  61. package/src/app/social/user-event/user-event.service.d.ts +51 -79
  62. package/src/app/social/user-event/user-events.table.d.ts +6 -6
  63. package/src/assets/i18n/en-US.json +2 -15
  64. package/src/assets/i18n/en.json +2 -15
  65. package/src/assets/i18n/fr.json +1 -14
  66. package/src/theme/_ngx-components.scss +0 -7
  67. package/sumaris-net.ngx-components.d.ts +5 -7
  68. package/sumaris-net.ngx-components.metadata.json +1 -1
  69. package/esm2015/src/app/social/job/job.model.js +0 -24
  70. package/esm2015/src/app/social/job/job.module.js +0 -25
  71. package/esm2015/src/app/social/job/job.service.js +0 -53
  72. package/esm2015/src/app/social/job/progression/job-progression.component.js +0 -192
  73. package/esm2015/src/app/social/job/progression/job-progression.list.js +0 -20
  74. package/esm2015/src/app/social/message/message.module.js +0 -25
  75. package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +0 -92
  76. package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +0 -39
  77. package/esm2015/src/app/social/user-event/user-event.module.js +0 -28
  78. package/src/app/social/job/job.model.d.ts +0 -32
  79. package/src/app/social/job/job.module.d.ts +0 -2
  80. package/src/app/social/job/job.service.d.ts +0 -23
  81. package/src/app/social/job/progression/job-progression.component.d.ts +0 -43
  82. package/src/app/social/job/progression/job-progression.list.d.ts +0 -12
  83. package/src/app/social/message/message.module.d.ts +0 -2
  84. package/src/app/social/user-event/notification/user-event-notification.component.d.ts +0 -25
  85. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +0 -20
  86. package/src/app/social/user-event/user-event.module.d.ts +0 -2
@@ -46,7 +46,7 @@
46
46
  var SPACE_PLACEHOLDER_CHAR = '\u2000';
47
47
  var KEYBOARD_HIDE_DELAY_MS = 250; // 1s
48
48
 
49
- /******************************************************************************
49
+ /*! *****************************************************************************
50
50
  Copyright (c) Microsoft Corporation.
51
51
 
52
52
  Permission to use, copy, modify, and/or distribute this software for any
@@ -208,11 +208,7 @@
208
208
  var __createBinding = Object.create ? (function (o, m, k, k2) {
209
209
  if (k2 === undefined)
210
210
  k2 = k;
211
- var desc = Object.getOwnPropertyDescriptor(m, k);
212
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
213
- desc = { enumerable: true, get: function () { return m[k]; } };
214
- }
215
- Object.defineProperty(o, k2, desc);
211
+ Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
216
212
  }) : (function (o, m, k, k2) {
217
213
  if (k2 === undefined)
218
214
  k2 = k;
@@ -367,11 +363,6 @@
367
363
  throw new TypeError("Cannot write private member to an object whose class did not declare it");
368
364
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
369
365
  }
370
- function __classPrivateFieldIn(state, receiver) {
371
- if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function"))
372
- throw new TypeError("Cannot use 'in' operator on non-object");
373
- return typeof state === "function" ? receiver === state : state.has(receiver);
374
- }
375
366
 
376
367
  function isNil(obj) {
377
368
  return obj === undefined || obj === null;
@@ -509,67 +500,6 @@
509
500
  function removeDiacritics(text) {
510
501
  return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
511
502
  }
512
- function suggestFromArray(items, value, opts) {
513
- var _this = this;
514
- if (isNotNil(value) && typeof value === 'object')
515
- return { data: [value] };
516
- value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
517
- var keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
518
- if (!items) {
519
- return { data: [], total: 0 };
520
- }
521
- // Filter items
522
- var filteredItems = items;
523
- if (isNotNilOrBlank(value)) {
524
- // If wildcard, search using regexp
525
- if (value.indexOf('*') !== -1) {
526
- value = value.replace(/[*]+/g, '.*');
527
- filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return matchUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
528
- }
529
- // Else (no wildcard), search using startsWith
530
- else {
531
- filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return startsWithUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
532
- }
533
- }
534
- // Exclude ids
535
- if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
536
- filteredItems = filteredItems.filter(function (v) { return !opts.excludedIds.includes(+v['id']); });
537
- }
538
- // Sort
539
- if (!opts || opts.skipSort !== true) {
540
- // Make to copy input items, before sorting (if not yet already done)
541
- if (filteredItems === items)
542
- filteredItems = filteredItems.slice();
543
- // Sort by keys
544
- filteredItems.sort(propertiesPathComparator(keys));
545
- }
546
- var total = filteredItems.length || 0;
547
- // Pagination (truncate if need)
548
- var pageData = filteredItems;
549
- if (opts) {
550
- if ((opts.offset || 0) > 0) {
551
- pageData = pageData.slice(opts.offset);
552
- }
553
- if (isNotNil(opts.size) && pageData.length > opts.size) {
554
- pageData = pageData.slice(0, opts.size);
555
- }
556
- }
557
- var result = {
558
- data: pageData,
559
- total: total
560
- };
561
- // Add fetch more capability, if total was fetched
562
- var nextOffset = (opts && opts.offset || 0) + pageData.length;
563
- if (nextOffset < total) {
564
- result.fetchMore = function (_) { return __awaiter(_this, void 0, void 0, function () {
565
- return __generator(this, function (_b) {
566
- return [2 /*return*/, suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
567
- }))];
568
- });
569
- }); };
570
- }
571
- return result;
572
- }
573
503
  function suggestFromStringArray(values, value, options) {
574
504
  value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
575
505
  if (isNilOrBlank(value))
@@ -1117,11 +1047,11 @@
1117
1047
  }, null);
1118
1048
  }
1119
1049
  function firstTrue(obs) {
1120
- return obs.pipe(operators.first(function (v) { return v === true; }), operators.map(function (_) { }) // Convert to void
1050
+ return obs.pipe(operators.first(function (value) { return value === true; }), operators.map(function (_) { }) // Convert to void
1121
1051
  );
1122
1052
  }
1123
1053
  function firstFalse(obs) {
1124
- return obs.pipe(operators.first(function (v) { return v === false; }), operators.map(function (_) { }) // Convert to void
1054
+ return obs.pipe(operators.first(function (value) { return value === false; }), operators.map(function (_) { }) // Convert to void
1125
1055
  );
1126
1056
  }
1127
1057
  /**
@@ -1162,14 +1092,13 @@
1162
1092
  }
1163
1093
  function waitForTrue(observable, opts) {
1164
1094
  return __awaiter(this, void 0, void 0, function () {
1165
- var firstTrueObservable, $timeout;
1095
+ var $timeout;
1166
1096
  return __generator(this, function (_a) {
1167
- firstTrueObservable = firstTrue(observable);
1168
1097
  // Timeout (+ dueTime)
1169
1098
  if (opts && opts.timeout > 0) {
1170
1099
  $timeout = rxjs.timer(opts.timeout);
1171
1100
  return [2 /*return*/, rxjs.merge(rxjs.timer(opts.dueTime || 0)
1172
- .pipe(operators.switchMap(function () { return firstTrueObservable; }), operators.takeUntil($timeout)), $timeout
1101
+ .pipe(operators.switchMap(function () { return firstTrue(observable); }), operators.takeUntil($timeout)), $timeout
1173
1102
  .pipe(operators.map(function () {
1174
1103
  throw new Error("Timeout ready() - after " + opts.timeout + "ms");
1175
1104
  })))
@@ -1178,10 +1107,19 @@
1178
1107
  // dueTime (without timeout)
1179
1108
  if (opts && opts.dueTime > 0) {
1180
1109
  return [2 /*return*/, rxjs.timer(opts.dueTime)
1181
- .pipe(operators.switchMap(function () { return firstTrueObservable; }))
1110
+ .pipe(operators.switchMap(function () { return firstTrue(observable); }))
1182
1111
  .toPromise()];
1183
1112
  }
1184
- return [2 /*return*/, firstTrueObservable.toPromise()];
1113
+ return [2 /*return*/, firstTrue(observable).toPromise()];
1114
+ });
1115
+ });
1116
+ }
1117
+ function waitForFalse(observable, opts) {
1118
+ return __awaiter(this, void 0, void 0, function () {
1119
+ return __generator(this, function (_a) {
1120
+ return [2 /*return*/, waitForTrue(
1121
+ // Inverse the logic
1122
+ observable.pipe(operators.map(function (v) { return v === false; })), opts)];
1185
1123
  });
1186
1124
  });
1187
1125
  }
@@ -1386,6 +1324,68 @@
1386
1324
  return _cache.mobile;
1387
1325
  };
1388
1326
 
1327
+ function suggestFromArray(items, value, opts) {
1328
+ var _this = this;
1329
+ if (isNotNil(value) && typeof value === 'object')
1330
+ return { data: [value] };
1331
+ value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
1332
+ var keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
1333
+ if (!items) {
1334
+ return { data: [], total: 0 };
1335
+ }
1336
+ // Filter items
1337
+ var filteredItems = items;
1338
+ if (isNotNilOrBlank(value)) {
1339
+ // If wildcard, search using regexp
1340
+ if (value.indexOf('*') !== -1) {
1341
+ value = value.replace(/[*]+/g, '.*');
1342
+ filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return matchUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
1343
+ }
1344
+ // Else (no wildcard), search using startsWith
1345
+ else {
1346
+ filteredItems = filteredItems.filter(function (v) { return keys.findIndex(function (key) { return startsWithUpperCase(getPropertyByPathAsString(v, key), value); }) !== -1; });
1347
+ }
1348
+ }
1349
+ // Exclude ids
1350
+ if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
1351
+ filteredItems = filteredItems.filter(function (v) { return !opts.excludedIds.includes(+v['id']); });
1352
+ }
1353
+ // Sort
1354
+ if (!opts || opts.skipSort !== true) {
1355
+ // Make to copy input items, before sorting (if not yet already done)
1356
+ if (filteredItems === items)
1357
+ filteredItems = filteredItems.slice();
1358
+ // Sort by keys
1359
+ filteredItems.sort(propertiesPathComparator(keys));
1360
+ }
1361
+ var total = filteredItems.length || 0;
1362
+ // Pagination (truncate if need)
1363
+ var pageData = filteredItems;
1364
+ if (opts) {
1365
+ if ((opts.offset || 0) > 0) {
1366
+ pageData = pageData.slice(opts.offset);
1367
+ }
1368
+ if (isNotNil(opts.size) && pageData.length > opts.size) {
1369
+ pageData = pageData.slice(0, opts.size);
1370
+ }
1371
+ }
1372
+ var result = {
1373
+ data: pageData,
1374
+ total: total
1375
+ };
1376
+ // Add fetch more capability, if total was fetched
1377
+ var nextOffset = (opts && opts.offset || 0) + pageData.length;
1378
+ if (nextOffset < total) {
1379
+ result.fetchMore = function (_) { return __awaiter(_this, void 0, void 0, function () {
1380
+ return __generator(this, function (_a) {
1381
+ return [2 /*return*/, suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
1382
+ }))];
1383
+ });
1384
+ }); };
1385
+ }
1386
+ return result;
1387
+ }
1388
+
1389
1389
  var MatAutocompleteConfigHolder = /** @class */ (function () {
1390
1390
  function MatAutocompleteConfigHolder(options) {
1391
1391
  this.options = options;
@@ -1706,11 +1706,11 @@
1706
1706
  // Search text (no distinctUntilChanged() because of the debounceTime() pipe)
1707
1707
  this.formControl.valueChanges
1708
1708
  .pipe(operators.filter(function (value) { return _this.enabled && isNotNilString(value); }),
1709
- // Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time
1709
+ // Mark as loading (to show loading spinner) - as soon as possible, and before debounceTime
1710
1710
  operators.tap(function (_) { return _this.showLoadingSpinner && _this.markAsLoading(); }),
1711
1711
  // Filter if not enough character
1712
1712
  operators.filter(function (value) {
1713
- if (value.length <= _this.suggestLengthThreshold) {
1713
+ if (((value === null || value === void 0 ? void 0 : value.length) || 0) < _this.suggestLengthThreshold) {
1714
1714
  // Update display value, to enable the message "not enough characters"
1715
1715
  _this.displayValue = value;
1716
1716
  return false;
@@ -2709,9 +2709,9 @@
2709
2709
  var cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
2710
2710
  var index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
2711
2711
  if (index !== -1) {
2712
- return value.substr(0, index - 1) +
2713
- '<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
2714
- value.substr(index + cleanedSearchText.length);
2712
+ return value.substring(0, index - 1) +
2713
+ '<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +
2714
+ value.substring(index + cleanedSearchText.length);
2715
2715
  }
2716
2716
  return value;
2717
2717
  }
@@ -3159,12 +3159,10 @@
3159
3159
  };
3160
3160
  return IsNotNilOrBlankPipe;
3161
3161
  }());
3162
- IsNotNilOrBlankPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
3163
3162
  IsNotNilOrBlankPipe.decorators = [
3164
3163
  { type: i0.Pipe, args: [{
3165
3164
  name: 'isNotNilOrBlank'
3166
- },] },
3167
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3165
+ },] }
3168
3166
  ];
3169
3167
  var IsNilOrBlankPipe = /** @class */ (function () {
3170
3168
  function IsNilOrBlankPipe() {
@@ -3174,12 +3172,10 @@
3174
3172
  };
3175
3173
  return IsNilOrBlankPipe;
3176
3174
  }());
3177
- IsNilOrBlankPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
3178
3175
  IsNilOrBlankPipe.decorators = [
3179
3176
  { type: i0.Pipe, args: [{
3180
3177
  name: 'isNilOrBlank'
3181
- },] },
3182
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3178
+ },] }
3183
3179
  ];
3184
3180
  var ToStringPipe = /** @class */ (function () {
3185
3181
  function ToStringPipe() {
@@ -3189,12 +3185,10 @@
3189
3185
  };
3190
3186
  return ToStringPipe;
3191
3187
  }());
3192
- ToStringPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
3193
3188
  ToStringPipe.decorators = [
3194
3189
  { type: i0.Pipe, args: [{
3195
3190
  name: 'toString'
3196
- },] },
3197
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3191
+ },] }
3198
3192
  ];
3199
3193
  var StrLengthPipe = /** @class */ (function () {
3200
3194
  function StrLengthPipe() {
@@ -3204,12 +3198,10 @@
3204
3198
  };
3205
3199
  return StrLengthPipe;
3206
3200
  }());
3207
- StrLengthPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
3208
3201
  StrLengthPipe.decorators = [
3209
3202
  { type: i0.Pipe, args: [{
3210
3203
  name: 'strLength'
3211
- },] },
3212
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3204
+ },] }
3213
3205
  ];
3214
3206
  var StrIncludesPipe = /** @class */ (function () {
3215
3207
  function StrIncludesPipe() {
@@ -3219,12 +3211,10 @@
3219
3211
  };
3220
3212
  return StrIncludesPipe;
3221
3213
  }());
3222
- StrIncludesPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
3223
3214
  StrIncludesPipe.decorators = [
3224
3215
  { type: i0.Pipe, args: [{
3225
3216
  name: 'strIncludes'
3226
- },] },
3227
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3217
+ },] }
3228
3218
  ];
3229
3219
 
3230
3220
  var TranslateContextService = /** @class */ (function () {
@@ -4769,7 +4759,7 @@
4769
4759
  function FormGetControlPipe() {
4770
4760
  }
4771
4761
  FormGetControlPipe.prototype.transform = function (form, path) {
4772
- return (form && path && form.get(path) || form);
4762
+ return (form && isNotNil(path) && form.get(path) || form);
4773
4763
  };
4774
4764
  return FormGetControlPipe;
4775
4765
  }());
@@ -4805,8 +4795,7 @@
4805
4795
  },] }
4806
4796
  ];
4807
4797
  var FormGetValuePipe = /** @class */ (function () {
4808
- function FormGetValuePipe(adapter, _ref) {
4809
- this.adapter = adapter;
4798
+ function FormGetValuePipe(_ref) {
4810
4799
  this._ref = _ref;
4811
4800
  this.value = undefined;
4812
4801
  this._lastControl = null;
@@ -4874,7 +4863,6 @@
4874
4863
  },] }
4875
4864
  ];
4876
4865
  FormGetValuePipe.ctorParameters = function () { return [
4877
- { type: FormErrorTranslator },
4878
4866
  { type: i0.ChangeDetectorRef }
4879
4867
  ]; };
4880
4868
 
@@ -5796,10 +5784,10 @@
5796
5784
  return this._tabindex;
5797
5785
  },
5798
5786
  set: function (value) {
5799
- var _this = this;
5800
5787
  if (this._tabindex !== value) {
5801
5788
  this._tabindex = value;
5802
- setTimeout(function () { return _this.updateTabIndex(); });
5789
+ if (!this._writing)
5790
+ this.updateTabIndex();
5803
5791
  }
5804
5792
  },
5805
5793
  enumerable: false,
@@ -6191,10 +6179,10 @@
6191
6179
  return this._tabindex;
6192
6180
  },
6193
6181
  set: function (value) {
6194
- var _this = this;
6195
6182
  if (this._tabindex !== value) {
6196
6183
  this._tabindex = value;
6197
- setTimeout(function () { return _this.updateTabIndex(); });
6184
+ if (!this._writing)
6185
+ this.updateTabIndex();
6198
6186
  }
6199
6187
  },
6200
6188
  enumerable: false,
@@ -12044,7 +12032,7 @@
12044
12032
  Object.defineProperty(LocalSettingsService.prototype, "usageMode", {
12045
12033
  get: function () {
12046
12034
  var _a;
12047
- if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.mobile)) {
12035
+ if (isNil((_a = this._data) === null || _a === void 0 ? void 0 : _a.usageMode)) {
12048
12036
  console.warn("[settings] Accessing to property 'usageMode' BEFORE service started! Please use ready()");
12049
12037
  return isCordova(window) ? 'FIELD' : 'DESK';
12050
12038
  }
@@ -15234,7 +15222,8 @@
15234
15222
  console.debug('[graphql] Apply token authentication to headers');
15235
15223
  this.connectionParams.authToken = token;
15236
15224
  }
15237
- else {
15225
+ // Clean auth token
15226
+ else if (this.connectionParams.authToken) {
15238
15227
  console.debug('[graphql] Remove token authentication from headers');
15239
15228
  delete this.connectionParams.authToken;
15240
15229
  // Clear cache
@@ -15246,7 +15235,8 @@
15246
15235
  console.debug('[graphql] Apply basic authentication to headers');
15247
15236
  this.connectionParams.authBasic = basic;
15248
15237
  }
15249
- else {
15238
+ // Clean auth basic
15239
+ else if (this.connectionParams.authBasic) {
15250
15240
  console.debug('[graphql] Remove basic authentication from headers');
15251
15241
  delete this.connectionParams.authBasic;
15252
15242
  // Clear cache
@@ -19948,12 +19938,12 @@
19948
19938
  var AppForm = /** @class */ (function () {
19949
19939
  function AppForm(injector, form) {
19950
19940
  var _this = this;
19951
- this.error = null;
19941
+ this._subscription = new rxjs.Subscription();
19952
19942
  this._enable = false;
19953
- this._$ready = new rxjs.BehaviorSubject(false);
19954
- this._$loading = new rxjs.BehaviorSubject(true);
19955
19943
  this.i18nFieldPrefix = null;
19956
- this._subscription = new rxjs.Subscription();
19944
+ this.readySubject = new rxjs.BehaviorSubject(false);
19945
+ this.loadingSubject = new rxjs.BehaviorSubject(true);
19946
+ this.errorSubject = new rxjs.BehaviorSubject(undefined);
19957
19947
  this.debug = false;
19958
19948
  this.onCancel = new i0.EventEmitter();
19959
19949
  this.onSubmit = new i0.EventEmitter();
@@ -19972,20 +19962,57 @@
19972
19962
  * @deprecated
19973
19963
  */
19974
19964
  get: function () {
19975
- return this._$loading.value;
19965
+ return this.loadingSubject.value;
19976
19966
  },
19977
19967
  /**
19978
19968
  * @deprecated
19979
19969
  */
19980
19970
  set: function (value) {
19981
- this._$loading.next(value);
19971
+ this.loadingSubject.next(value);
19972
+ },
19973
+ enumerable: false,
19974
+ configurable: true
19975
+ });
19976
+ Object.defineProperty(AppForm.prototype, "_$ready", {
19977
+ /**
19978
+ * @deprecated
19979
+ */
19980
+ get: function () {
19981
+ return this.readySubject;
19982
+ },
19983
+ enumerable: false,
19984
+ configurable: true
19985
+ });
19986
+ Object.defineProperty(AppForm.prototype, "_$loading", {
19987
+ /**
19988
+ * @deprecated
19989
+ */
19990
+ get: function () {
19991
+ return this.loadingSubject;
19992
+ },
19993
+ enumerable: false,
19994
+ configurable: true
19995
+ });
19996
+ Object.defineProperty(AppForm.prototype, "error", {
19997
+ get: function () {
19998
+ return this.errorSubject.value;
19999
+ },
20000
+ set: function (error) {
20001
+ this.setError(error);
19982
20002
  },
19983
20003
  enumerable: false,
19984
20004
  configurable: true
19985
20005
  });
19986
20006
  Object.defineProperty(AppForm.prototype, "loading", {
19987
20007
  get: function () {
19988
- return this._$loading.value;
20008
+ return this.loadingSubject.value;
20009
+ },
20010
+ enumerable: false,
20011
+ configurable: true
20012
+ });
20013
+ Object.defineProperty(AppForm.prototype, "loaded", {
20014
+ get: function () {
20015
+ return !this.loadingSubject.value;
19989
20016
  },
19990
20017
  enumerable: false,
19991
20018
  configurable: true
@@ -20002,7 +20029,8 @@
20002
20029
  });
20003
20030
  Object.defineProperty(AppForm.prototype, "dirty", {
20004
20031
  get: function () {
20005
- return this.form && this.form.dirty;
20032
+ var _a;
20033
+ return ((_a = this.form) === null || _a === void 0 ? void 0 : _a.dirty) || false;
20006
20034
  },
20007
20035
  enumerable: false,
20008
20036
  configurable: true
@@ -20023,7 +20051,8 @@
20023
20051
  });
20024
20052
  Object.defineProperty(AppForm.prototype, "valid", {
20025
20053
  get: function () {
20026
- return this.form && this.form.valid;
20054
+ var _a;
20055
+ return ((_a = this.form) === null || _a === void 0 ? void 0 : _a.valid) || false;
20027
20056
  },
20028
20057
  enumerable: false,
20029
20058
  configurable: true
@@ -20092,17 +20121,19 @@
20092
20121
  };
20093
20122
  AppForm.prototype.ngOnDestroy = function () {
20094
20123
  this._subscription.unsubscribe();
20095
- this.onCancel.complete();
20124
+ this.readySubject.unsubscribe();
20125
+ this.loadingSubject.unsubscribe();
20126
+ this.errorSubject.unsubscribe();
20096
20127
  this.onCancel.unsubscribe();
20097
- this.onSubmit.complete();
20098
20128
  this.onSubmit.unsubscribe();
20099
- this._$ready.complete();
20100
- this._$ready.unsubscribe();
20101
- this._$loading.complete();
20102
- this._$loading.unsubscribe();
20103
20129
  };
20104
20130
  AppForm.prototype.cancel = function () {
20105
- this.onCancel.emit();
20131
+ return __awaiter(this, void 0, void 0, function () {
20132
+ return __generator(this, function (_b) {
20133
+ this.onCancel.emit();
20134
+ return [2 /*return*/];
20135
+ });
20136
+ });
20106
20137
  };
20107
20138
  /**
20108
20139
  *
@@ -20207,22 +20238,14 @@
20207
20238
  this.markForCheck();
20208
20239
  };
20209
20240
  AppForm.prototype.markAsLoading = function (opts) {
20210
- if (this._$loading.value !== true) {
20211
- this._$loading.next(true);
20212
- if (!opts || opts.emitEvent !== false)
20213
- this.markForCheck();
20214
- }
20241
+ this.setLoading(true, opts);
20215
20242
  };
20216
20243
  AppForm.prototype.markAsLoaded = function (opts) {
20217
- if (this._$loading.value !== false) {
20218
- this._$loading.next(false);
20219
- if (!opts || opts.emitEvent !== false)
20220
- this.markForCheck();
20221
- }
20244
+ this.setLoading(false, opts);
20222
20245
  };
20223
20246
  AppForm.prototype.markAsReady = function (opts) {
20224
- if (this._$ready.value !== true) {
20225
- this._$ready.next(true);
20247
+ if (this.readySubject.value !== true) {
20248
+ this.readySubject.next(true);
20226
20249
  // If subclasses implements OnReady
20227
20250
  if (typeof this['ngOnReady'] === 'function') {
20228
20251
  this.ngOnReady();
@@ -20234,18 +20257,18 @@
20234
20257
  * @param opts
20235
20258
  */
20236
20259
  AppForm.prototype.ready = function (opts) {
20237
- return waitForTrue(this._$ready, opts);
20260
+ if (this.readySubject.value)
20261
+ return Promise.resolve();
20262
+ return waitForTrue(this.readySubject, opts);
20238
20263
  };
20239
20264
  /**
20240
- * Wait form is idle (not loading)
20265
+ * Wait form is not busy (=loaded)
20241
20266
  * @param opts
20242
20267
  */
20243
20268
  AppForm.prototype.waitIdle = function (opts) {
20244
- return __awaiter(this, void 0, void 0, function () {
20245
- return __generator(this, function (_b) {
20246
- return [2 /*return*/, AppFormUtils.waitIdle(this, opts)];
20247
- });
20248
- });
20269
+ if (!this.loadingSubject.value)
20270
+ return Promise.resolve();
20271
+ return waitForFalse(this.loadingSubject, opts);
20249
20272
  };
20250
20273
  AppForm.prototype.updateValueAndValidity = function (opts) {
20251
20274
  AppFormUtils.updateValueAndValidity(this.form, opts);
@@ -20275,10 +20298,27 @@
20275
20298
  AppForm.prototype.registerAutocompleteField = function (fieldName, opts) {
20276
20299
  return this.autocompleteHelper.add(fieldName, opts);
20277
20300
  };
20301
+ AppForm.prototype.setError = function (value, opts) {
20302
+ if (this.errorSubject.value !== value) {
20303
+ this.errorSubject.next(value);
20304
+ if (!opts || opts.emitEvent !== false) {
20305
+ this.markForCheck();
20306
+ }
20307
+ }
20308
+ };
20278
20309
  AppForm.prototype.markForCheck = function () {
20279
20310
  // Should be overwritten by subclasses
20280
20311
  console.warn('markForCheck() has been called, but is not overwritten by component ' + this.constructor.name);
20281
20312
  };
20313
+ /* -- private function -- */
20314
+ AppForm.prototype.setLoading = function (value, opts) {
20315
+ if (this.loadingSubject.value !== value) {
20316
+ this.loadingSubject.next(value);
20317
+ if (!opts || opts.emitEvent !== false) {
20318
+ this.markForCheck();
20319
+ }
20320
+ }
20321
+ };
20282
20322
  return AppForm;
20283
20323
  }());
20284
20324
  AppForm.decorators = [
@@ -20739,14 +20779,14 @@
20739
20779
  }
20740
20780
  return this._onChange
20741
20781
  .pipe(operators.filter(isNotNil), operators.mergeMap(function (_) { return waitFor(function () { return !_this._saving; }); }), operators.mergeMap(function (_) { return __awaiter(_this, void 0, void 0, function () {
20742
- var excludedDataByFilter, excludedDataByPagination, data, promiseOrData, _a, total;
20743
- return __generator(this, function (_b) {
20744
- switch (_b.label) {
20782
+ var excludedDataByFilter, excludedDataByPagination, data, promiseOrData, _b, total;
20783
+ return __generator(this, function (_c) {
20784
+ switch (_c.label) {
20745
20785
  case 0:
20746
20786
  excludedDataByFilter = [];
20747
- _b.label = 1;
20787
+ _c.label = 1;
20748
20788
  case 1:
20749
- _b.trys.push([1, , 6, 7]);
20789
+ _c.trys.push([1, , 6, 7]);
20750
20790
  if (isEmptyArray(this.data)) {
20751
20791
  return [2 /*return*/, { data: [], total: 0 }];
20752
20792
  }
@@ -20756,14 +20796,14 @@
20756
20796
  if (!((promiseOrData instanceof Promise))) return [3 /*break*/, 3];
20757
20797
  return [4 /*yield*/, promiseOrData];
20758
20798
  case 2:
20759
- _a = _b.sent();
20799
+ _b = _c.sent();
20760
20800
  return [3 /*break*/, 4];
20761
20801
  case 3:
20762
- _a = promiseOrData;
20763
- _b.label = 4;
20802
+ _b = promiseOrData;
20803
+ _c.label = 4;
20764
20804
  case 4:
20765
- data = _a;
20766
- _b.label = 5;
20805
+ data = _b;
20806
+ _c.label = 5;
20767
20807
  case 5:
20768
20808
  // Apply filter (will update hiddenData)
20769
20809
  data = this.filter(data, filterData, excludedDataByFilter);
@@ -20819,16 +20859,16 @@
20819
20859
  };
20820
20860
  InMemoryEntitiesService.prototype.saveAll = function (data, options) {
20821
20861
  return __awaiter(this, void 0, void 0, function () {
20822
- var res, _a;
20823
- return __generator(this, function (_b) {
20824
- switch (_b.label) {
20862
+ var res, _b;
20863
+ return __generator(this, function (_c) {
20864
+ switch (_c.label) {
20825
20865
  case 0:
20826
20866
  if (!this.data)
20827
20867
  throw new Error('[memory-service] Could not save, because value not set');
20828
20868
  this.markAsSaving();
20829
- _b.label = 1;
20869
+ _c.label = 1;
20830
20870
  case 1:
20831
- _b.trys.push([1, , 6, 7]);
20871
+ _c.trys.push([1, , 6, 7]);
20832
20872
  // Restore hidden data
20833
20873
  if (isNotEmptyArray(this._hiddenData))
20834
20874
  data = data.concat.apply(data, __spread(this._hiddenData));
@@ -20837,14 +20877,14 @@
20837
20877
  if (!((res instanceof Promise))) return [3 /*break*/, 3];
20838
20878
  return [4 /*yield*/, res];
20839
20879
  case 2:
20840
- _a = _b.sent();
20880
+ _b = _c.sent();
20841
20881
  return [3 /*break*/, 4];
20842
20882
  case 3:
20843
- _a = res;
20844
- _b.label = 4;
20883
+ _b = res;
20884
+ _c.label = 4;
20845
20885
  case 4:
20846
- data = _a;
20847
- _b.label = 5;
20886
+ data = _b;
20887
+ _c.label = 5;
20848
20888
  case 5:
20849
20889
  this.data = data;
20850
20890
  this.dirty = true;
@@ -20861,7 +20901,7 @@
20861
20901
  return __awaiter(this, void 0, void 0, function () {
20862
20902
  var updatedData, deleteCount;
20863
20903
  var _this = this;
20864
- return __generator(this, function (_a) {
20904
+ return __generator(this, function (_b) {
20865
20905
  if (!this.data)
20866
20906
  throw new Error('[memory-service] Could not delete, because value not set');
20867
20907
  updatedData = this.data.filter(function (entity) {
@@ -20895,6 +20935,26 @@
20895
20935
  return this._equalsFn(d1, d2);
20896
20936
  return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
20897
20937
  };
20938
+ Object.defineProperty(InMemoryEntitiesService.prototype, "count", {
20939
+ /**
20940
+ * Count data stored by the service (without hidden data).
20941
+ * @param opts
20942
+ */
20943
+ get: function () {
20944
+ var _a;
20945
+ return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
20946
+ },
20947
+ enumerable: false,
20948
+ configurable: true
20949
+ });
20950
+ Object.defineProperty(InMemoryEntitiesService.prototype, "hiddenCount", {
20951
+ get: function () {
20952
+ var _a;
20953
+ return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
20954
+ },
20955
+ enumerable: false,
20956
+ configurable: true
20957
+ });
20898
20958
  /* -- protected methods -- */
20899
20959
  InMemoryEntitiesService.prototype.filter = function (data, _filter, hiddenData) {
20900
20960
  // if filter is DataFilter instance, use its test function
@@ -21522,7 +21582,12 @@
21522
21582
  }
21523
21583
  };
21524
21584
  AuthForm.prototype.cancel = function () {
21525
- this.onCancel.emit();
21585
+ return __awaiter(this, void 0, void 0, function () {
21586
+ return __generator(this, function (_a) {
21587
+ this.onCancel.emit();
21588
+ return [2 /*return*/];
21589
+ });
21590
+ });
21526
21591
  };
21527
21592
  AuthForm.prototype.doSubmit = function (event) {
21528
21593
  return __awaiter(this, void 0, void 0, function () {
@@ -22541,8 +22606,12 @@
22541
22606
  });
22542
22607
  return __awaiter(this, void 0, void 0, function () {
22543
22608
  return __generator(this, function (_c) {
22544
- _super.cancel.call(this);
22545
- return [2 /*return*/];
22609
+ switch (_c.label) {
22610
+ case 0: return [4 /*yield*/, _super.cancel.call(this)];
22611
+ case 1:
22612
+ _c.sent();
22613
+ return [2 /*return*/];
22614
+ }
22546
22615
  });
22547
22616
  });
22548
22617
  };
@@ -24749,7 +24818,7 @@
24749
24818
  MenuComponent.decorators = [
24750
24819
  { type: i0.Component, args: [{
24751
24820
  selector: 'app-menu',
24752
- 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 ? '&#xab;' : '&#xbb;'}}</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",
24821
+ 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 ? '&#xab;' : '&#xbb;'}}</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",
24753
24822
  animations: [fadeInAnimation],
24754
24823
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
24755
24824
  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)}}"]
@@ -24817,7 +24886,6 @@
24817
24886
  this.icon = value.icon;
24818
24887
  this.matIcon = value.matIcon;
24819
24888
  this.matSvgIcon = value.matSvgIcon;
24820
- this.color = value.color;
24821
24889
  },
24822
24890
  enumerable: false,
24823
24891
  configurable: true
@@ -24828,7 +24896,7 @@
24828
24896
  AppIconComponent.decorators = [
24829
24897
  { type: i0.Component, args: [{
24830
24898
  selector: 'app-icon',
24831
- 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"
24899
+ 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"
24832
24900
  },] }
24833
24901
  ];
24834
24902
  AppIconComponent.propDecorators = {
@@ -24836,8 +24904,6 @@
24836
24904
  matIcon: [{ type: i0.Input }],
24837
24905
  matSvgIcon: [{ type: i0.Input }],
24838
24906
  color: [{ type: i0.Input }],
24839
- height: [{ type: i0.Input }],
24840
- width: [{ type: i0.Input }],
24841
24907
  ref: [{ type: i0.Input }]
24842
24908
  };
24843
24909
 
@@ -26074,10 +26140,6 @@
26074
26140
  get: function () {
26075
26141
  return this.errorSubject.value;
26076
26142
  },
26077
- /**
26078
- * @deprecated
26079
- * @param error
26080
- */
26081
26143
  set: function (error) {
26082
26144
  this.setError(error);
26083
26145
  },
@@ -26085,6 +26147,9 @@
26085
26147
  configurable: true
26086
26148
  });
26087
26149
  Object.defineProperty(AppTable.prototype, "error$", {
26150
+ /**
26151
+ * @deprecated
26152
+ */
26088
26153
  get: function () {
26089
26154
  return this.errorSubject.asObservable();
26090
26155
  },
@@ -26092,6 +26157,9 @@
26092
26157
  configurable: true
26093
26158
  });
26094
26159
  Object.defineProperty(AppTable.prototype, "loading$", {
26160
+ /**
26161
+ * @deprecated
26162
+ */
26095
26163
  get: function () {
26096
26164
  return this.loadingSubject.asObservable();
26097
26165
  },
@@ -26099,6 +26167,9 @@
26099
26167
  configurable: true
26100
26168
  });
26101
26169
  Object.defineProperty(AppTable.prototype, "saving$", {
26170
+ /**
26171
+ * @deprecated
26172
+ */
26102
26173
  get: function () {
26103
26174
  return this.savingSubject.asObservable();
26104
26175
  },
@@ -26268,17 +26339,15 @@
26268
26339
  if (this.savingSubject.value !== true) {
26269
26340
  this.focusColumn = undefined; // unselect focus column
26270
26341
  this.savingSubject.next(true);
26271
- if (!opts || opts.emitEvent !== false) {
26342
+ if (!opts || opts.emitEvent !== false)
26272
26343
  this.markForCheck();
26273
- }
26274
26344
  }
26275
26345
  };
26276
26346
  AppTable.prototype.markAsSaved = function (opts) {
26277
26347
  if (this.savingSubject.value !== false) {
26278
26348
  this.savingSubject.next(false);
26279
- if (!opts || opts.emitEvent !== false) {
26349
+ if (!opts || opts.emitEvent !== false)
26280
26350
  this.markForCheck();
26281
- }
26282
26351
  }
26283
26352
  };
26284
26353
  AppTable.prototype.markAsLoading = function (opts) {
@@ -26603,7 +26672,7 @@
26603
26672
  .then(function () { return _this.editRowById(event, row.id, { focusColumn: _this.lastUserColumn }); });
26604
26673
  return true;
26605
26674
  }
26606
- // Edit next row
26675
+ // Edit previous row
26607
26676
  this.editRow(event, row, { focusColumn: this.lastUserColumn });
26608
26677
  return true;
26609
26678
  };
@@ -26631,8 +26700,7 @@
26631
26700
  if (id < 0)
26632
26701
  return [2 /*return*/];
26633
26702
  if (!(id >= this.visibleRowCount)) return [3 /*break*/, 1];
26634
- this.focusColumn = opts && opts.focusColumn || this.firstUserColumn;
26635
- this.addRow(event);
26703
+ this.addRow(event, undefined, opts);
26636
26704
  return [3 /*break*/, 3];
26637
26705
  case 1: return [4 /*yield*/, this.dataSource.getRow(id)];
26638
26706
  case 2:
@@ -26710,7 +26778,7 @@
26710
26778
  this.cancelExistingRow(event, row, opts);
26711
26779
  }
26712
26780
  };
26713
- AppTable.prototype.addRow = function (event, insertAt) {
26781
+ AppTable.prototype.addRow = function (event, insertAt, opts) {
26714
26782
  if (this.debug)
26715
26783
  console.debug('[table] Asking for new row...');
26716
26784
  if (!this._enabled)
@@ -26725,7 +26793,7 @@
26725
26793
  return false;
26726
26794
  }
26727
26795
  // Add new row
26728
- this.addRowToTable(insertAt);
26796
+ this.addRowToTable(insertAt, opts);
26729
26797
  return true;
26730
26798
  };
26731
26799
  AppTable.prototype.save = function (opts) {
@@ -26870,7 +26938,7 @@
26870
26938
  * @param event
26871
26939
  * @param row
26872
26940
  * @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
26873
- * Use skipIfLoading=false to force deletion even if table is busy
26941
+ * And to force deletion even if table is busy
26874
26942
  */
26875
26943
  AppTable.prototype.deleteRow = function (event, row, opts) {
26876
26944
  return __awaiter(this, void 0, void 0, function () {
@@ -26890,7 +26958,7 @@
26890
26958
  * @param event
26891
26959
  * @param rows
26892
26960
  * @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)
26893
- * Use skipIfLoading=false to force deletion even if table is busy
26961
+ * And to force deletion even if table is busy
26894
26962
  */
26895
26963
  AppTable.prototype.deleteRows = function (event, rows, opts) {
26896
26964
  var _a;
@@ -26908,8 +26976,8 @@
26908
26976
  event === null || event === void 0 ? void 0 : event.preventDefault();
26909
26977
  if (!this._enabled || isEmptyArray(rows))
26910
26978
  return [2 /*return*/, 0]; // Skip is disabled, or no rows to delete
26911
- if (this.loading && (!opts || opts.skipIfLoading !== false)) {
26912
- console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.skipLoading = false to force deletion');
26979
+ if (this.loading && (!opts || opts.interactive !== false)) {
26980
+ console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.interactive = false to force deletion');
26913
26981
  return [2 /*return*/, 0]; // Skip if loading
26914
26982
  }
26915
26983
  // Make sure to keep newly created row
@@ -27068,29 +27136,11 @@
27068
27136
  AppTable.prototype.moveRow = function (id, direction) {
27069
27137
  this.dataSource.move(id, direction);
27070
27138
  };
27071
- AppTable.prototype.ready = function () {
27072
- return __awaiter(this, void 0, void 0, function () {
27073
- return __generator(this, function (_e) {
27074
- switch (_e.label) {
27075
- case 0: return [4 /*yield*/, firstTruePromise(this.readySubject)];
27076
- case 1:
27077
- _e.sent();
27078
- return [2 /*return*/];
27079
- }
27080
- });
27081
- });
27139
+ AppTable.prototype.ready = function (opts) {
27140
+ return waitForTrue(this.readySubject, opts);
27082
27141
  };
27083
27142
  AppTable.prototype.waitIdle = function (opts) {
27084
- return __awaiter(this, void 0, void 0, function () {
27085
- return __generator(this, function (_e) {
27086
- switch (_e.label) {
27087
- case 0: return [4 /*yield*/, firstFalsePromise(this.loadingSubject)];
27088
- case 1:
27089
- _e.sent();
27090
- return [2 /*return*/];
27091
- }
27092
- });
27093
- });
27143
+ return waitForFalse(this.loadingSubject, opts);
27094
27144
  };
27095
27145
  AppTable.prototype.openSelectColumnsModal = function (event) {
27096
27146
  return __awaiter(this, void 0, void 0, function () {
@@ -27548,12 +27598,13 @@
27548
27598
  //if (this.debug) console.debug("[table] id = " + id);
27549
27599
  return id;
27550
27600
  };
27551
- AppTable.prototype.addRowToTable = function (insertAt) {
27601
+ AppTable.prototype.addRowToTable = function (insertAt, opts) {
27552
27602
  return __awaiter(this, void 0, void 0, function () {
27553
27603
  return __generator(this, function (_e) {
27554
27604
  switch (_e.label) {
27555
27605
  case 0:
27556
27606
  this.focusFirstColumn = true;
27607
+ this.focusColumn = (opts === null || opts === void 0 ? void 0 : opts.focusColumn) || this.firstUserColumn;
27557
27608
  return [4 /*yield*/, this._dataSource.asyncCreateNew(insertAt)];
27558
27609
  case 1:
27559
27610
  _e.sent();
@@ -27934,8 +27985,9 @@
27934
27985
  this._subscription = new rxjs.Subscription();
27935
27986
  this._enabled = false;
27936
27987
  this._dirty = false;
27937
- this._$ready = new rxjs.BehaviorSubject(false);
27938
- this._$loading = new rxjs.BehaviorSubject(true);
27988
+ this.readySubject = new rxjs.BehaviorSubject(false);
27989
+ this.loadingSubject = new rxjs.BehaviorSubject(true);
27990
+ this.errorSubject = new rxjs.BehaviorSubject(undefined);
27939
27991
  this.debug = false;
27940
27992
  this.submitted = false;
27941
27993
  this.toolbar = null;
@@ -27946,13 +27998,43 @@
27946
27998
  * @deprecated
27947
27999
  */
27948
28000
  get: function () {
27949
- return this._$loading.value;
28001
+ return this.loadingSubject.value;
27950
28002
  },
27951
28003
  /**
27952
28004
  * @deprecated
27953
28005
  */
27954
28006
  set: function (value) {
27955
- this._$loading.next(value);
28007
+ this.loadingSubject.next(value);
28008
+ },
28009
+ enumerable: false,
28010
+ configurable: true
28011
+ });
28012
+ Object.defineProperty(AppEditor.prototype, "_$ready", {
28013
+ /**
28014
+ * @deprecated
28015
+ */
28016
+ get: function () {
28017
+ return this.readySubject;
28018
+ },
28019
+ enumerable: false,
28020
+ configurable: true
28021
+ });
28022
+ Object.defineProperty(AppEditor.prototype, "_$loading", {
28023
+ /**
28024
+ * @deprecated
28025
+ */
28026
+ get: function () {
28027
+ return this.loadingSubject;
28028
+ },
28029
+ enumerable: false,
28030
+ configurable: true
28031
+ });
28032
+ Object.defineProperty(AppEditor.prototype, "error", {
28033
+ get: function () {
28034
+ return this.errorSubject.value;
28035
+ },
28036
+ set: function (error) {
28037
+ this.setError(error);
27956
28038
  },
27957
28039
  enumerable: false,
27958
28040
  configurable: true
@@ -28009,7 +28091,7 @@
28009
28091
  Object.defineProperty(AppEditor.prototype, "loading", {
28010
28092
  get: function () {
28011
28093
  var _a;
28012
- return this._$loading.value || (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(function (c) { return c.enabled && c.loading; })) !== -1) || false;
28094
+ return this.loadingSubject.value || (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(function (c) { return c.enabled && c.loading; })) !== -1) || false;
28013
28095
  },
28014
28096
  enumerable: false,
28015
28097
  configurable: true
@@ -28053,10 +28135,9 @@
28053
28135
  };
28054
28136
  AppEditor.prototype.ngOnDestroy = function () {
28055
28137
  this._subscription.unsubscribe();
28056
- this._$ready.complete();
28057
- this._$ready.unsubscribe();
28058
- this._$loading.complete();
28059
- this._$loading.unsubscribe();
28138
+ this.readySubject.unsubscribe();
28139
+ this.loadingSubject.unsubscribe();
28140
+ this.errorSubject.unsubscribe();
28060
28141
  };
28061
28142
  AppEditor.prototype.addChildForm = function (form) {
28062
28143
  if (!form)
@@ -28126,16 +28207,16 @@
28126
28207
  this.markForCheck();
28127
28208
  };
28128
28209
  AppEditor.prototype.markAsLoading = function (opts) {
28129
- if (!this._loading) {
28130
- this._loading = true;
28210
+ if (!this.loadingSubject.value) {
28211
+ this.loadingSubject.next(true);
28131
28212
  if (!opts || opts.emitEvent !== false)
28132
28213
  this.markForCheck();
28133
28214
  }
28134
28215
  };
28135
28216
  AppEditor.prototype.markAsLoaded = function (opts) {
28136
28217
  var _a;
28137
- if (this._loading) {
28138
- this._loading = false;
28218
+ if (this.loadingSubject.value) {
28219
+ this.loadingSubject.next(false);
28139
28220
  if (!opts || opts.onlySelf !== true) {
28140
28221
  // Emit to children forms
28141
28222
  // Tables should be changed by parent
@@ -28149,17 +28230,17 @@
28149
28230
  AppEditor.prototype.markAsReady = function (opts) {
28150
28231
  var _a;
28151
28232
  (_a = this._children) === null || _a === void 0 ? void 0 : _a.forEach(function (c) { return c.markAsReady(opts); });
28152
- this._$ready.next(true);
28233
+ this.readySubject.next(true);
28153
28234
  };
28154
28235
  AppEditor.prototype.ready = function (opts) {
28155
- return __awaiter(this, void 0, void 0, function () {
28156
- return __generator(this, function (_b) {
28157
- return [2 /*return*/, waitForTrue(this._$ready, opts)];
28158
- });
28159
- });
28236
+ if (this.readySubject.value)
28237
+ return Promise.resolve();
28238
+ return waitForTrue(this.readySubject, opts);
28160
28239
  };
28161
28240
  AppEditor.prototype.waitIdle = function (opts) {
28162
- return AppFormUtils.waitIdle(this, opts);
28241
+ if (!this.loadingSubject.value)
28242
+ return Promise.resolve();
28243
+ return waitForFalse(this.loadingSubject, opts);
28163
28244
  };
28164
28245
  AppEditor.prototype.cancel = function (event) {
28165
28246
  return __awaiter(this, void 0, void 0, function () {
@@ -28415,6 +28496,14 @@
28415
28496
  console.warn(prefix + " Unknown children sub-form: ", c);
28416
28497
  }
28417
28498
  };
28499
+ AppEditor.prototype.setError = function (value, opts) {
28500
+ if (this.errorSubject.value !== value) {
28501
+ this.errorSubject.next(value);
28502
+ if (!opts || opts.emitEvent !== false) {
28503
+ this.markForCheck();
28504
+ }
28505
+ }
28506
+ };
28418
28507
  AppEditor.prototype.markForCheck = function () {
28419
28508
  // Should be override by subclasses, if change detection is Push
28420
28509
  };
@@ -28487,6 +28576,8 @@
28487
28576
  AppTabEditor.prototype.ngOnDestroy = function () {
28488
28577
  _super_1.prototype.ngOnDestroy.call(this);
28489
28578
  this.selectedTabIndexChange.complete();
28579
+ this.loadingSubject.unsubscribe();
28580
+ this.errorSubject.unsubscribe();
28490
28581
  };
28491
28582
  AppTabEditor.prototype.setSelectedTabIndex = function (value, opts) {
28492
28583
  var _this = this;
@@ -28510,6 +28601,10 @@
28510
28601
  this.markForCheck();
28511
28602
  }
28512
28603
  };
28604
+ AppTabEditor.prototype.realignInkBar = function () {
28605
+ var _a;
28606
+ (_a = this.tabGroup) === null || _a === void 0 ? void 0 : _a.realignInkBar();
28607
+ };
28513
28608
  AppTabEditor.prototype.onTabChange = function (event, queryTabIndexParamName) {
28514
28609
  queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;
28515
28610
  if (!queryTabIndexParamName || !this.route)
@@ -28588,6 +28683,22 @@
28588
28683
  });
28589
28684
  });
28590
28685
  };
28686
+ AppTabEditor.prototype.saveDirtyTables = function () {
28687
+ return __awaiter(this, void 0, void 0, function () {
28688
+ var results, saved;
28689
+ return __generator(this, function (_b) {
28690
+ switch (_b.label) {
28691
+ case 0: return [4 /*yield*/, Promise.all((this.tables || [])
28692
+ .filter(function (c) { return c.dirty; })
28693
+ .map(function (c) { return c.save(); }))];
28694
+ case 1:
28695
+ results = _b.sent();
28696
+ saved = results.findIndex(function (result) { return result !== true; }) === -1;
28697
+ return [2 /*return*/, saved];
28698
+ }
28699
+ });
28700
+ });
28701
+ };
28591
28702
  return AppTabEditor;
28592
28703
  }(AppEditor));
28593
28704
  AppTabEditor.decorators = [
@@ -28624,7 +28735,7 @@
28624
28735
  _this = _super.call(this, injector.get(i3.ActivatedRoute), injector.get(i3.Router), injector.get(i1$5.AlertController), injector.get(i1$2.TranslateService), options) || this;
28625
28736
  _this.dataType = dataType;
28626
28737
  _this.dataService = dataService;
28627
- _this.saving = false;
28738
+ _this.savingSubject = new rxjs.BehaviorSubject(false);
28628
28739
  _this.$title = new rxjs.Subject();
28629
28740
  _this.onUpdateView = new i0.EventEmitter();
28630
28741
  _this.environement = injector.get(ENVIRONMENT);
@@ -28682,7 +28793,14 @@
28682
28793
  });
28683
28794
  Object.defineProperty(AppEntityEditor.prototype, "loading", {
28684
28795
  get: function () {
28685
- return this._loading;
28796
+ return this.loadingSubject.value;
28797
+ },
28798
+ enumerable: false,
28799
+ configurable: true
28800
+ });
28801
+ Object.defineProperty(AppEntityEditor.prototype, "saving", {
28802
+ get: function () {
28803
+ return this.savingSubject.value;
28686
28804
  },
28687
28805
  enumerable: false,
28688
28806
  configurable: true
@@ -28695,15 +28813,15 @@
28695
28813
  configurable: true
28696
28814
  });
28697
28815
  AppEntityEditor.prototype.markAsSaving = function (opts) {
28698
- if (!this.saving) {
28699
- this.saving = true;
28816
+ if (this.savingSubject.value !== true) {
28817
+ this.savingSubject.next(true);
28700
28818
  if (!opts || opts.emitEvent !== false)
28701
28819
  this.markForCheck();
28702
28820
  }
28703
28821
  };
28704
28822
  AppEntityEditor.prototype.markAsSaved = function (opts) {
28705
- if (this.saving) {
28706
- this.saving = false;
28823
+ if (this.savingSubject.value !== false) {
28824
+ this.savingSubject.next(false);
28707
28825
  if (!opts || opts.emitEvent !== false)
28708
28826
  this.markForCheck();
28709
28827
  }
@@ -28733,12 +28851,12 @@
28733
28851
  this.$title.unsubscribe();
28734
28852
  this.onUpdateView.complete();
28735
28853
  this.onUpdateView.unsubscribe();
28854
+ this.savingSubject.unsubscribe();
28736
28855
  };
28737
28856
  AppEntityEditor.prototype.waitIdle = function (opts) {
28738
- var _this = this;
28739
28857
  // Wait end of saving
28740
28858
  if (this.saving)
28741
- return waitFor(function () { return _this.saving !== true; });
28859
+ return waitForFalse(this.savingSubject);
28742
28860
  return _super.prototype.waitIdle.call(this, opts);
28743
28861
  };
28744
28862
  /**
@@ -29025,7 +29143,7 @@
29025
29143
  */
29026
29144
  AppEntityEditor.prototype.save = function (event, opts) {
29027
29145
  return __awaiter(this, void 0, void 0, function () {
29028
- var nextTabIndex, data, updatedData, err_3;
29146
+ var nextTabIndex, saved, data, updatedData, err_3;
29029
29147
  return __generator(this, function (_c) {
29030
29148
  switch (_c.label) {
29031
29149
  case 0:
@@ -29044,9 +29162,10 @@
29044
29162
  _c.sent();
29045
29163
  // If invalid
29046
29164
  if (this.invalid) {
29047
- this.markAllAsTouched();
29048
29165
  this.logFormErrors();
29049
29166
  this.openFirstInvalidTab();
29167
+ this.scrollToTop();
29168
+ this.markAllAsTouched();
29050
29169
  this.submitted = true;
29051
29170
  return [2 /*return*/, false];
29052
29171
  }
@@ -29056,24 +29175,29 @@
29056
29175
  console.debug('[data-editor] Saving data...');
29057
29176
  _c.label = 2;
29058
29177
  case 2:
29059
- _c.trys.push([2, 7, 8, 9]);
29178
+ _c.trys.push([2, 8, 9, 10]);
29060
29179
  nextTabIndex = this._autoOpenNextTab && isNil(this.previousDataId) && this.computeNextTabIndex();
29061
- return [4 /*yield*/, this.getValue()];
29180
+ return [4 /*yield*/, this.saveDirtyTables()];
29062
29181
  case 3:
29182
+ saved = _c.sent();
29183
+ if (!saved)
29184
+ return [2 /*return*/, false];
29185
+ return [4 /*yield*/, this.getValue()];
29186
+ case 4:
29063
29187
  data = _c.sent();
29064
29188
  this.disable();
29065
29189
  return [4 /*yield*/, this.dataService.save(data, opts)];
29066
- case 4:
29190
+ case 5:
29067
29191
  updatedData = _c.sent();
29068
29192
  return [4 /*yield*/, this.onEntitySaved(updatedData)];
29069
- case 5:
29193
+ case 6:
29070
29194
  _c.sent();
29071
29195
  // Update the view (e.g metadata)
29072
29196
  return [4 /*yield*/, this.updateView(updatedData, Object.assign({
29073
29197
  // Open next tab only if user has not changed it
29074
29198
  openTabIndex: nextTabIndex > this._selectedTabIndex ? nextTabIndex : undefined
29075
29199
  }, opts))];
29076
- case 6:
29200
+ case 7:
29077
29201
  // Update the view (e.g metadata)
29078
29202
  _c.sent();
29079
29203
  // Subscribe to remote changes
@@ -29081,7 +29205,7 @@
29081
29205
  this.startListenRemoteChanges();
29082
29206
  this.submitted = false;
29083
29207
  return [2 /*return*/, true];
29084
- case 7:
29208
+ case 8:
29085
29209
  err_3 = _c.sent();
29086
29210
  this.submitted = true;
29087
29211
  this.setError(err_3);
@@ -29097,10 +29221,10 @@
29097
29221
  });
29098
29222
  }
29099
29223
  return [2 /*return*/, false];
29100
- case 8:
29224
+ case 9:
29101
29225
  this.markAsSaved();
29102
29226
  return [7 /*endfinally*/];
29103
- case 9: return [2 /*return*/];
29227
+ case 10: return [2 /*return*/];
29104
29228
  }
29105
29229
  });
29106
29230
  });
@@ -29219,7 +29343,7 @@
29219
29343
  this.registerForms();
29220
29344
  this._dirty = false;
29221
29345
  this.data = null;
29222
- this.saving = false;
29346
+ this.savingSubject.next(false);
29223
29347
  return [2 /*return*/];
29224
29348
  });
29225
29349
  });
@@ -29482,7 +29606,7 @@
29482
29606
  function AppEntityEditorModal(injector, dataType, options) {
29483
29607
  var _this = _super_1.call(this, null, injector.get(i3.Router), injector.get(i1$5.AlertController), injector.get(i1$2.TranslateService), options) || this;
29484
29608
  _this.dataType = dataType;
29485
- _this.saving = false;
29609
+ _this.savingSubject = new rxjs.BehaviorSubject(false);
29486
29610
  _this.$title = new rxjs.Subject();
29487
29611
  _this.i18nSuffix = null;
29488
29612
  _this.environement = injector.get(ENVIRONMENT);
@@ -29532,16 +29656,23 @@
29532
29656
  enumerable: false,
29533
29657
  configurable: true
29534
29658
  });
29659
+ Object.defineProperty(AppEntityEditorModal.prototype, "saving", {
29660
+ get: function () {
29661
+ return this.savingSubject.value;
29662
+ },
29663
+ enumerable: false,
29664
+ configurable: true
29665
+ });
29535
29666
  AppEntityEditorModal.prototype.markAsSaving = function (opts) {
29536
- if (!this.saving) {
29537
- this.saving = true;
29667
+ if (this.savingSubject.value !== true) {
29668
+ this.savingSubject.next(true);
29538
29669
  if (!opts || opts.emitEvent !== false)
29539
29670
  this.markForCheck();
29540
29671
  }
29541
29672
  };
29542
29673
  AppEntityEditorModal.prototype.markAsSaved = function (opts) {
29543
- if (this.saving) {
29544
- this.saving = false;
29674
+ if (this.savingSubject.value !== false) {
29675
+ this.savingSubject.next(false);
29545
29676
  if (!opts || opts.emitEvent !== false)
29546
29677
  this.markForCheck();
29547
29678
  }
@@ -29590,12 +29721,12 @@
29590
29721
  _super_1.prototype.ngOnDestroy.call(this);
29591
29722
  this.$title.complete();
29592
29723
  this.$title.unsubscribe();
29724
+ this.savingSubject.unsubscribe();
29593
29725
  };
29594
29726
  AppEntityEditorModal.prototype.waitIdle = function (opts) {
29595
- var _this = this;
29596
29727
  // Wait end of saving
29597
29728
  if (this.saving)
29598
- return waitFor(function () { return _this.saving !== true; });
29729
+ return waitForFalse(this.savingSubject);
29599
29730
  return _super_1.prototype.waitIdle.call(this, opts);
29600
29731
  };
29601
29732
  AppEntityEditorModal.prototype.load = function () {
@@ -29745,9 +29876,9 @@
29745
29876
  if (this.invalid) {
29746
29877
  this.logFormErrors();
29747
29878
  this.setError('COMMON.FORM.HAS_ERROR');
29748
- this.markAllAsTouched();
29749
29879
  this.openFirstInvalidTab();
29750
29880
  this.scrollToTop();
29881
+ this.markAllAsTouched();
29751
29882
  this.submitted = true;
29752
29883
  return [2 /*return*/, false];
29753
29884
  }
@@ -29757,18 +29888,22 @@
29757
29888
  console.debug(this._logPrefix + 'Saving data...');
29758
29889
  _c.label = 2;
29759
29890
  case 2:
29760
- _c.trys.push([2, 4, 5, 6]);
29761
- saved = Promise.all((this.tables || [])
29762
- .filter(function (c) { return c.dirty; })
29763
- .map(function (c) { return c.save(); }))
29764
- .then(function (res) { return res.findIndex(function (r) { return r !== true; }) === -1; });
29891
+ _c.trys.push([2, 5, 6, 7]);
29892
+ return [4 /*yield*/, this.saveDirtyTables()];
29893
+ case 3:
29894
+ saved = _c.sent();
29895
+ if (!saved)
29896
+ return [2 /*return*/, false];
29897
+ // Fill data
29765
29898
  _b = this;
29766
29899
  return [4 /*yield*/, this.getValue()];
29767
- case 3:
29900
+ case 4:
29901
+ // Fill data
29768
29902
  _b.data = _c.sent();
29903
+ // Mark as submitted
29769
29904
  this.submitted = true;
29770
- return [2 /*return*/, saved];
29771
- case 4:
29905
+ return [2 /*return*/, true];
29906
+ case 5:
29772
29907
  err_2 = _c.sent();
29773
29908
  this.submitted = true;
29774
29909
  this.setError(err_2);
@@ -29777,10 +29912,10 @@
29777
29912
  this.markAsDirty();
29778
29913
  this.enable();
29779
29914
  return [2 /*return*/, false];
29780
- case 5:
29915
+ case 6:
29781
29916
  this.markAsSaved();
29782
29917
  return [7 /*endfinally*/];
29783
- case 6: return [2 /*return*/];
29918
+ case 7: return [2 /*return*/];
29784
29919
  }
29785
29920
  });
29786
29921
  });
@@ -30056,10 +30191,7 @@
30056
30191
  var SocialErrorCodes = {
30057
30192
  LOAD_USER_EVENTS_ERROR: 50000,
30058
30193
  SAVE_USER_EVENT_ERROR: 50001,
30059
- COUNT_USER_EVENT_ERROR: 50002,
30060
- SEND_MESSAGE_ERROR: 50003,
30061
- SUBSCRIBE_USER_EVENTS_ERROR: 50005,
30062
- SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
30194
+ SEND_MESSAGE_ERROR: 50003
30063
30195
  };
30064
30196
 
30065
30197
  var UserEvent_1;
@@ -30075,23 +30207,16 @@
30075
30207
  }
30076
30208
  UserEvent.prototype.asObject = function (opts) {
30077
30209
  var target = _super.prototype.asObject.call(this, opts);
30078
- target.creationDate = toDateISOString(this.creationDate);
30079
- target.readDate = toDateISOString(this.readDate);
30080
30210
  // Serialize content
30081
30211
  if (typeof target.content === 'object') {
30082
30212
  target.content = JSON.stringify(target.content);
30083
30213
  }
30084
- delete target.avatar;
30085
- delete target.avatarIcon;
30086
- delete target.icon;
30087
- delete target.actions;
30088
30214
  return target;
30089
30215
  };
30090
30216
  UserEvent.prototype.fromObject = function (source) {
30091
30217
  Object.assign(this, source); // Copy all properties
30092
30218
  _super.prototype.fromObject.call(this, source);
30093
30219
  this.creationDate = fromDateISOString(source.creationDate);
30094
- this.readDate = fromDateISOString(source.readDate);
30095
30220
  try {
30096
30221
  // Deserialize content
30097
30222
  if (typeof source.content === 'string' && source.content.startsWith('{')) {
@@ -30111,48 +30236,36 @@
30111
30236
  exports.UserEvent = UserEvent_1 = __decorate([
30112
30237
  EntityClass({ typename: 'UserEventVO' })
30113
30238
  ], exports.UserEvent);
30239
+
30240
+ var UserEventFragments = {
30241
+ userEvent: core.gql(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["fragment UserEventFragment on UserEventVO {\n id\n issuer\n updateDate\n creationDate\n eventType\n recipient\n content\n hash\n signature\n readSignature\n __typename\n }"], ["fragment UserEventFragment on UserEventVO {\n id\n issuer\n updateDate\n creationDate\n eventType\n recipient\n content\n hash\n signature\n readSignature\n __typename\n }"]))),
30242
+ lightUserEvent: core.gql(templateObject_2$2 || (templateObject_2$2 = __makeTemplateObject(["fragment LightUserEventFragment on UserEventVO {\n id\n issuer\n recipient\n updateDate\n creationDate\n eventType\n readSignature\n __typename\n }"], ["fragment LightUserEventFragment on UserEventVO {\n id\n issuer\n recipient\n updateDate\n creationDate\n eventType\n readSignature\n __typename\n }"])))
30243
+ };
30244
+ var templateObject_1$2, templateObject_2$2;
30245
+
30114
30246
  // @dynamic
30115
30247
  exports.UserEventFilter = /** @class */ (function (_super) {
30116
30248
  __extends(UserEventFilter, _super);
30117
30249
  function UserEventFilter() {
30118
30250
  var _this = _super.apply(this, __spread(arguments)) || this;
30119
- _this.types = [];
30120
- _this.levels = [];
30121
- _this.issuers = [];
30122
- _this.recipients = [];
30123
- _this.startDate = null;
30124
- _this.excludeRead = false;
30251
+ _this.issuer = null;
30252
+ _this.recipient = null;
30125
30253
  return _this;
30126
30254
  }
30127
30255
  UserEventFilter.prototype.fromObject = function (source, opts) {
30128
30256
  _super.prototype.fromObject.call(this, source, opts);
30129
- this.types = source.types || [];
30130
- this.levels = source.levels || [];
30131
- this.issuers = source.issuers || [];
30132
- this.recipients = source.recipients || [];
30133
- this.startDate = fromDateISOString(source.startDate);
30134
- this.excludeRead = source.excludeRead || false;
30257
+ this.issuer = source.issuer;
30258
+ this.recipient = source.recipient;
30135
30259
  };
30136
30260
  UserEventFilter.prototype.buildFilter = function () {
30137
30261
  var _this = this;
30138
30262
  var filterFns = _super.prototype.buildFilter.call(this);
30139
- if (isNotEmptyArray(this.types)) {
30140
- filterFns.push(function (t) { return _this.types.includes(t.type); });
30141
- }
30142
- if (isNotEmptyArray(this.levels)) {
30143
- filterFns.push(function (t) { return _this.levels.includes(t.level); });
30263
+ // issuer
30264
+ if (this.issuer) {
30265
+ filterFns.push(function (t) { return (t.issuer === _this.issuer); });
30144
30266
  }
30145
- if (isNotEmptyArray(this.issuers)) {
30146
- filterFns.push(function (t) { return _this.issuers.includes(t.issuer); });
30147
- }
30148
- if (isNotEmptyArray(this.recipients)) {
30149
- filterFns.push(function (t) { return _this.recipients.includes(t.recipient); });
30150
- }
30151
- if (isNotNil(this.startDate)) {
30152
- filterFns.push(function (t) { return _this.startDate.isSameOrBefore(t.creationDate); });
30153
- }
30154
- if (this.excludeRead === true) {
30155
- filterFns.push(function (t) { return isNil(t.readSignature); }); // todo or t.signature ?
30267
+ if (this.recipient) {
30268
+ filterFns.push(function (t) { return (t.recipient === _this.recipient); });
30156
30269
  }
30157
30270
  return filterFns;
30158
30271
  };
@@ -30161,276 +30274,120 @@
30161
30274
  exports.UserEventFilter = __decorate([
30162
30275
  EntityClass({ typename: 'UserEventFilterVO' })
30163
30276
  ], exports.UserEventFilter);
30164
-
30165
- var UserEventFragments = {
30166
- userEvent: core.gql(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["fragment UserEventFragment on UserEventVO {\n id\n issuer\n updateDate\n creationDate\n eventType\n recipient\n content\n hash\n signature\n readSignature\n __typename\n }"], ["fragment UserEventFragment on UserEventVO {\n id\n issuer\n updateDate\n creationDate\n eventType\n recipient\n content\n hash\n signature\n readSignature\n __typename\n }"]))),
30167
- lightUserEvent: core.gql(templateObject_2$2 || (templateObject_2$2 = __makeTemplateObject(["fragment LightUserEventFragment on UserEventVO {\n id\n issuer\n recipient\n updateDate\n creationDate\n eventType\n readSignature\n __typename\n }"], ["fragment LightUserEventFragment on UserEventVO {\n id\n issuer\n recipient\n updateDate\n creationDate\n eventType\n readSignature\n __typename\n }"])))
30168
- };
30169
- var templateObject_1$2, templateObject_2$2;
30170
-
30171
- var moment$6 = momentImported__namespace;
30172
- var UserEventServiceToken = new i0.InjectionToken('UserEventService');
30173
- var AbstractUserEventService = /** @class */ (function (_super) {
30174
- __extends(AbstractUserEventService, _super);
30175
- function AbstractUserEventService(graphql, accountService, network, translate, queries, mutations, subscriptions, environment) {
30277
+ var SaveQuery = core.gql(templateObject_1$3 || (templateObject_1$3 = __makeTemplateObject(["\n mutation SaveUserEvent($data: UserEventVOInput){\n data: saveUserEvent(userEvent: $data){\n ...UserEventFragment\n }\n }\n ", "\n"], ["\n mutation SaveUserEvent($data: UserEventVOInput){\n data: saveUserEvent(userEvent: $data){\n ...UserEventFragment\n }\n }\n ", "\n"])), UserEventFragments.userEvent);
30278
+ var LoadAllQuery = core.gql(templateObject_2$3 || (templateObject_2$3 = __makeTemplateObject(["\n query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...LightUserEventFragment\n }\n }\n ", "\n"], ["\n query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...LightUserEventFragment\n }\n }\n ", "\n"])), UserEventFragments.lightUserEvent);
30279
+ var DeleteByIdsMutation = core.gql(templateObject_3$2 || (templateObject_3$2 = __makeTemplateObject(["\n mutation DeleteUserEvents($ids:[Int]){\n deleteUserEvents(ids: $ids)\n }\n"], ["\n mutation DeleteUserEvents($ids:[Int]){\n deleteUserEvents(ids: $ids)\n }\n"])));
30280
+ var LoadAllWithContentQuery = core.gql(templateObject_4$2 || (templateObject_4$2 = __makeTemplateObject(["\n query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...UserEventFragment\n }\n }\n ", "\n"], ["\n query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...UserEventFragment\n }\n }\n ", "\n"])), UserEventFragments.userEvent);
30281
+ var UserEventService = /** @class */ (function (_super) {
30282
+ __extends(UserEventService, _super);
30283
+ function UserEventService(graphql, accountService, network, translate, toastController, environment) {
30176
30284
  var _this = _super.call(this, graphql, environment) || this;
30177
30285
  _this.graphql = graphql;
30178
30286
  _this.accountService = accountService;
30179
30287
  _this.network = network;
30180
30288
  _this.translate = translate;
30181
- _this.queries = queries;
30182
- _this.mutations = mutations;
30183
- _this.subscriptions = subscriptions;
30289
+ _this.toastController = toastController;
30184
30290
  _this.environment = environment;
30185
- _this._count$ = new rxjs.BehaviorSubject(0);
30186
- _this._subscriptions = new rxjs.Subscription();
30187
- _this.listeners = [];
30188
- _this._logPrefix = '[user-event-service] ';
30291
+ _this._userEventActions = [];
30189
30292
  // For DEV only
30190
- _this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
30191
- // listen login/logout
30192
- _this._subscriptions.add(accountService.onLogin.subscribe(function () { return __awaiter(_this, void 0, void 0, function () {
30193
- var count;
30194
- return __generator(this, function (_b) {
30195
- switch (_b.label) {
30196
- case 0: return [4 /*yield*/, this.count(this.defaultFilter())];
30197
- case 1:
30198
- count = _b.sent();
30199
- if (count && this._debug) {
30200
- console.debug(this._logPrefix + "Received " + count + " unread notifications");
30201
- }
30202
- this._count$.next(count);
30203
- return [2 /*return*/];
30204
- }
30205
- });
30206
- }); }));
30293
+ _this._debug = environment && !environment.production;
30207
30294
  return _this;
30208
30295
  }
30209
- Object.defineProperty(AbstractUserEventService.prototype, "userEventCount", {
30210
- get: function () {
30211
- return this._count$.asObservable();
30212
- },
30213
- enumerable: false,
30214
- configurable: true
30215
- });
30216
- AbstractUserEventService.prototype.ngOnDestroy = function () {
30217
- this._subscriptions.unsubscribe();
30218
- };
30219
- AbstractUserEventService.prototype.watchAll = function (offset, size, sortBy, sortDirection, filter, options) {
30296
+ /**
30297
+ *
30298
+ * @param offset
30299
+ * @param size
30300
+ * @param sortBy
30301
+ * @param sortDirection
30302
+ * @param filter
30303
+ * @param options
30304
+ * @deprecated use watchPage() instead
30305
+ */
30306
+ UserEventService.prototype.watchAll = function (offset, size, sortBy, sortDirection, filter, options) {
30220
30307
  return this.watchPage({ offset: offset, size: size, sortBy: sortBy, sortDirection: sortDirection }, filter, options);
30221
30308
  };
30222
- AbstractUserEventService.prototype.watchPage = function (page, filter, options) {
30223
- var _this = this;
30224
- var _a;
30309
+ UserEventService.prototype.watchPage = function (page, filter, options) {
30225
30310
  var now = this._debug && Date.now();
30226
30311
  //if (this._debug)
30227
- console.debug(this._logPrefix + "Loading user events...", filter);
30312
+ console.debug('[user-event-service] Loading user events...', filter);
30228
30313
  filter = this.asFilter(filter);
30229
30314
  // Force recipient to current issuer, if not admin and not specified
30230
- if (isEmptyArray(filter === null || filter === void 0 ? void 0 : filter.recipients) || !this.accountService.isAdmin()) {
30231
- var recipient = this.defaultRecipient();
30232
- if (!((_a = filter === null || filter === void 0 ? void 0 : filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
30315
+ if (isNilOrBlank(filter.recipient) || !this.accountService.isAdmin()) {
30316
+ var recipient = this.accountService.account.pubkey;
30317
+ if (recipient !== filter.recipient) {
30233
30318
  console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
30234
- filter.recipients = [recipient];
30319
+ filter.recipient = recipient;
30235
30320
  }
30236
30321
  }
30237
- var withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
30322
+ var withContent = options && options.withContent === true;
30238
30323
  return this.mutableWatchQuery({
30239
30324
  queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
30240
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30325
+ query: withContent ? LoadAllWithContentQuery : LoadAllQuery,
30241
30326
  variables: {
30242
- page: Object.assign(Object.assign({ sortBy: 'creationDate' }, page), {
30243
- // @ts-ignore
30244
- sortDirection: (page.sortDirection || 'desc').toUpperCase()
30245
- }),
30327
+ page: Object.assign(Object.assign({ sortBy: 'updateDate' }, page), { sortDirection: (page.sortDirection || 'DESC').toUpperCase() }),
30246
30328
  filter: filter && filter.asPodObject()
30247
30329
  },
30248
30330
  arrayFieldName: 'data',
30249
30331
  error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
30250
- fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
30332
+ fetchPolicy: options && options.fetchPolicy || undefined
30251
30333
  })
30252
30334
  .pipe(operators.map(function (res) {
30253
- var data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(_this.processUserEvent);
30335
+ var data = res && (res.data || []).map(exports.UserEvent.fromObject);
30254
30336
  if (now) {
30255
- console.debug("" + _this._logPrefix + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30337
+ console.debug("[user-event-service] " + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30256
30338
  now = null;
30257
30339
  }
30258
- var unreadCount = _this.unreadEvents(data);
30259
30340
  return {
30260
30341
  data: data,
30261
- total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
30342
+ total: res && toNumber(res.total, data.length)
30262
30343
  };
30263
30344
  }));
30264
30345
  };
30265
- AbstractUserEventService.prototype.add = function (entity) {
30266
- // TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
30267
- entity = this.processUserEvent(entity);
30268
- var withContent = !!entity.content;
30269
- // Add user event locally
30270
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
30271
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30272
- data: entity
30273
- });
30274
- // Update count
30275
- this._count$.next(this._count$.value + 1);
30276
- };
30277
- AbstractUserEventService.prototype.count = function (filter, options) {
30278
- var _a;
30279
- return __awaiter(this, void 0, void 0, function () {
30280
- var res;
30281
- return __generator(this, function (_b) {
30282
- switch (_b.label) {
30283
- case 0:
30284
- if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
30285
- console.warn(this._logPrefix + "Query 'count' not provided, skip.");
30286
- return [2 /*return*/, undefined];
30287
- }
30288
- if (!filter)
30289
- throw new Error("Missing argument 'filter'");
30290
- filter = this.asFilter(filter);
30291
- if (this._debug)
30292
- console.debug(this._logPrefix + "Counting user events with filter:", filter);
30293
- return [4 /*yield*/, this.graphql.query({
30294
- query: this.queries.count,
30295
- variables: {
30296
- filter: filter.asPodObject()
30297
- },
30298
- error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
30299
- fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
30300
- })];
30301
- case 1:
30302
- res = _b.sent();
30303
- return [2 /*return*/, res.total];
30304
- }
30305
- });
30306
- });
30307
- };
30308
- AbstractUserEventService.prototype.listenChanges = function (filter, options) {
30346
+ UserEventService.prototype.saveAll = function (data, options) {
30309
30347
  var _this = this;
30310
- var _a;
30311
- if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
30312
- console.warn(this._logPrefix + "Subscription query 'listenChanges' not provided, skip.");
30313
- return rxjs.of();
30314
- }
30315
- if (!filter)
30316
- throw new Error("Missing argument 'filter'");
30317
- filter = this.asFilter(filter);
30318
- var withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
30319
- if (this._debug)
30320
- console.debug(this._logPrefix + "[WS] Listening changes for user events with filter:", filter);
30321
- return this.graphql.subscribe({
30322
- query: this.subscriptions.listenChanges,
30323
- fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
30324
- variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
30325
- error: {
30326
- code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
30327
- message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
30328
- }
30329
- }).pipe(operators.map(function (_b) {
30330
- var data = _b.data;
30331
- if (data && _this._debug)
30332
- console.debug(_this._logPrefix + "Received new user events:", data);
30333
- var updatedData = data === null || data === void 0 ? void 0 : data.map(_this.processUserEvent);
30334
- // Update cache
30335
- _this.insertIntoMutableCachedQueries(_this.graphql.cache, {
30336
- query: withContent ? _this.queries.loadAllWithContent : _this.queries.loadAll,
30337
- data: updatedData
30338
- });
30339
- // update count
30340
- _this._count$.next(_this.unreadEvents(updatedData));
30341
- return updatedData;
30342
- }));
30343
- };
30344
- AbstractUserEventService.prototype.delete = function (entity) {
30345
- return __awaiter(this, void 0, void 0, function () {
30346
- return __generator(this, function (_b) {
30347
- switch (_b.label) {
30348
- case 0:
30349
- if (!entity)
30350
- return [2 /*return*/]; // skip
30351
- return [4 /*yield*/, this.deleteAll([entity])];
30352
- case 1:
30353
- _b.sent();
30354
- return [2 /*return*/];
30355
- }
30356
- });
30357
- });
30358
- };
30359
- AbstractUserEventService.prototype.deleteAll = function (entities, opts) {
30360
- return __awaiter(this, void 0, void 0, function () {
30361
- var ids, now;
30362
- var _this = this;
30363
- return __generator(this, function (_b) {
30364
- switch (_b.label) {
30365
- case 0:
30366
- ids = entities && entities
30367
- .map(function (t) { return t.id; });
30368
- if (isEmptyArray(ids))
30369
- return [2 /*return*/]; // stop, if nothing else to do
30370
- now = Date.now();
30371
- if (this._debug)
30372
- console.debug(this._logPrefix + "Deleting events... ids:", ids);
30373
- return [4 /*yield*/, this.graphql.mutate({
30374
- mutation: this.mutations.deleteByIds,
30375
- variables: {
30376
- ids: ids
30377
- },
30378
- update: function (proxy) {
30379
- // Remove from caches
30380
- _this.removeFromMutableCachedQueriesByIds(proxy, {
30381
- query: _this.queries.loadAll,
30382
- ids: ids
30383
- });
30384
- _this.removeFromMutableCachedQueriesByIds(proxy, {
30385
- query: _this.queries.loadAllWithContent,
30386
- ids: ids
30387
- });
30388
- if (_this._debug)
30389
- console.debug(_this._logPrefix + "Events deleted in " + (Date.now() - now) + "ms");
30390
- }
30391
- })];
30392
- case 1:
30393
- _b.sent();
30394
- return [2 /*return*/];
30395
- }
30396
- });
30397
- });
30348
+ return Promise.all(data
30349
+ .map(function (entity) { return _this.save(entity, options); }));
30398
30350
  };
30399
- AbstractUserEventService.prototype.save = function (entity, options) {
30351
+ /**
30352
+ * Save a userEvent entity
30353
+ *
30354
+ * @param entity
30355
+ */
30356
+ UserEventService.prototype.save = function (entity, options) {
30400
30357
  return __awaiter(this, void 0, void 0, function () {
30401
30358
  var isNew, json, now;
30402
30359
  var _this = this;
30403
- return __generator(this, function (_b) {
30404
- switch (_b.label) {
30360
+ return __generator(this, function (_a) {
30361
+ switch (_a.label) {
30405
30362
  case 0:
30406
30363
  this.fillDefaultProperties(entity);
30407
30364
  isNew = isNil(entity.id);
30408
30365
  json = entity.asObject();
30409
30366
  now = Date.now();
30410
30367
  if (this._debug)
30411
- console.debug(this._logPrefix + "Saving user event...", json);
30368
+ console.debug("[user-event-service] Saving user event...", json);
30412
30369
  return [4 /*yield*/, this.graphql.mutate({
30413
- mutation: this.mutations.save,
30370
+ mutation: SaveQuery,
30414
30371
  variables: {
30415
30372
  data: json
30416
30373
  },
30417
30374
  error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
30418
- update: function (proxy, _b) {
30419
- var data = _b.data;
30375
+ update: function (proxy, _a) {
30376
+ var data = _a.data;
30420
30377
  // Update entity
30421
30378
  var savedEntity = data && data.data;
30422
30379
  if (savedEntity) {
30423
30380
  if (_this._debug)
30424
- console.debug(_this._logPrefix + "User event saved in " + (Date.now() - now) + "ms", entity);
30381
+ console.debug("[user-event-service] User event saved in " + (Date.now() - now) + "ms", entity);
30425
30382
  _this.copyIdAndUpdateDate(savedEntity, entity);
30426
30383
  // Add to cache
30427
30384
  if (isNew) {
30428
30385
  _this.insertIntoMutableCachedQueries(proxy, {
30429
- query: _this.queries.loadAll,
30386
+ query: LoadAllQuery,
30430
30387
  data: Object.assign(Object.assign({}, savedEntity), { content: null })
30431
30388
  });
30432
30389
  _this.insertIntoMutableCachedQueries(proxy, {
30433
- query: _this.queries.loadAllWithContent,
30390
+ query: LoadAllWithContentQuery,
30434
30391
  data: savedEntity
30435
30392
  });
30436
30393
  }
@@ -30438,185 +30395,93 @@
30438
30395
  }
30439
30396
  })];
30440
30397
  case 1:
30441
- _b.sent();
30398
+ _a.sent();
30442
30399
  return [2 /*return*/, entity];
30443
30400
  }
30444
30401
  });
30445
30402
  });
30446
30403
  };
30447
- AbstractUserEventService.prototype.saveAll = function (data, opts) {
30448
- var _this = this;
30449
- return Promise.all(data
30450
- .map(function (entity) { return _this.save(entity, opts); }));
30451
- };
30452
- AbstractUserEventService.prototype.markAsRead = function (entity) {
30404
+ /**
30405
+ * Save many trips
30406
+ *
30407
+ * @param entities
30408
+ * @param opts
30409
+ */
30410
+ UserEventService.prototype.deleteAll = function (entities, opts) {
30453
30411
  return __awaiter(this, void 0, void 0, function () {
30454
- var onReadListeners, onReadListeners_1, onReadListeners_1_1, listener, e_1_1;
30455
- var e_1, _b;
30456
- return __generator(this, function (_c) {
30457
- switch (_c.label) {
30412
+ var ids, now;
30413
+ var _this = this;
30414
+ return __generator(this, function (_a) {
30415
+ switch (_a.label) {
30458
30416
  case 0:
30459
- onReadListeners = (this.listeners || []).filter(function (listener) { return !!listener.onRead; }).filter(function (listener) { return listener.accept(entity); });
30460
- if (!onReadListeners.length) return [3 /*break*/, 9];
30461
- _c.label = 1;
30417
+ ids = entities && entities
30418
+ .map(function (t) { return t.id; });
30419
+ if (isEmptyArray(ids))
30420
+ return [2 /*return*/]; // stop, if nothing else to do
30421
+ now = Date.now();
30422
+ if (this._debug)
30423
+ console.debug('[user-event-service] Deleting events... ids:', ids);
30424
+ return [4 /*yield*/, this.graphql.mutate({
30425
+ mutation: DeleteByIdsMutation,
30426
+ variables: {
30427
+ ids: ids
30428
+ },
30429
+ update: function (proxy) {
30430
+ // Remove from caches
30431
+ _this.removeFromMutableCachedQueriesByIds(proxy, {
30432
+ query: LoadAllQuery,
30433
+ ids: ids
30434
+ });
30435
+ _this.removeFromMutableCachedQueriesByIds(proxy, {
30436
+ query: LoadAllWithContentQuery,
30437
+ ids: ids
30438
+ });
30439
+ if (_this._debug)
30440
+ console.debug("[user-event-service] Events deleted in " + (Date.now() - now) + "ms");
30441
+ }
30442
+ })];
30462
30443
  case 1:
30463
- _c.trys.push([1, 6, 7, 8]);
30464
- onReadListeners_1 = __values(onReadListeners), onReadListeners_1_1 = onReadListeners_1.next();
30465
- _c.label = 2;
30466
- case 2:
30467
- if (!!onReadListeners_1_1.done) return [3 /*break*/, 5];
30468
- listener = onReadListeners_1_1.value;
30469
- return [4 /*yield*/, listener.onRead(entity)];
30470
- case 3:
30471
- _c.sent();
30472
- _c.label = 4;
30473
- case 4:
30474
- onReadListeners_1_1 = onReadListeners_1.next();
30475
- return [3 /*break*/, 2];
30476
- case 5: return [3 /*break*/, 8];
30477
- case 6:
30478
- e_1_1 = _c.sent();
30479
- e_1 = { error: e_1_1 };
30480
- return [3 /*break*/, 8];
30481
- case 7:
30482
- try {
30483
- if (onReadListeners_1_1 && !onReadListeners_1_1.done && (_b = onReadListeners_1.return)) _b.call(onReadListeners_1);
30484
- }
30485
- finally { if (e_1) throw e_1.error; }
30486
- return [7 /*endfinally*/];
30487
- case 8: return [3 /*break*/, 11];
30488
- case 9:
30489
- // Use default
30490
- return [4 /*yield*/, this.defaultMarkAsRead(entity)];
30491
- case 10:
30492
- // Use default
30493
- _c.sent();
30494
- _c.label = 11;
30495
- case 11: return [2 /*return*/];
30444
+ _a.sent();
30445
+ return [2 /*return*/];
30496
30446
  }
30497
30447
  });
30498
30448
  });
30499
30449
  };
30500
- AbstractUserEventService.prototype.registerListener = function (listener) {
30501
- if (!this.listeners)
30502
- this.listeners = [];
30503
- this.listeners.push(listener);
30504
- };
30505
- /* -- protected methods -- */
30506
- AbstractUserEventService.prototype.processUserEvent = function (source) {
30507
- var e_2, _b;
30508
- // Convert json source to IUserEvent
30509
- var target = this.fromObject(source);
30510
- // Get listeners
30511
- var listeners = (this.listeners || []).filter(function (listener) { return listener.onReceived; }).filter(function (listener) { return listener.accept(target); });
30512
- try {
30513
- for (var listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next(); !listeners_1_1.done; listeners_1_1 = listeners_1.next()) {
30514
- var listener = listeners_1_1.value;
30515
- if (target) {
30516
- target = listener.onReceived(target);
30517
- }
30518
- else {
30519
- if (this._debug)
30520
- console.debug(this._logPrefix + "Event has been rejected by a listener", source);
30521
- break;
30522
- }
30523
- }
30524
- }
30525
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
30526
- finally {
30527
- try {
30528
- if (listeners_1_1 && !listeners_1_1.done && (_b = listeners_1.return)) _b.call(listeners_1);
30529
- }
30530
- finally { if (e_2) throw e_2.error; }
30531
- }
30532
- return target;
30533
- };
30534
- AbstractUserEventService.prototype.defaultMarkAsRead = function (userEvent) {
30450
+ /**
30451
+ * Delete userEvent entities
30452
+ */
30453
+ UserEventService.prototype.delete = function (data) {
30535
30454
  return __awaiter(this, void 0, void 0, function () {
30536
- return __generator(this, function (_b) {
30537
- switch (_b.label) {
30455
+ return __generator(this, function (_a) {
30456
+ switch (_a.label) {
30538
30457
  case 0:
30539
- if (!userEvent)
30540
- throw new Error(this._logPrefix + "Invalid event to save");
30541
- // set read date
30542
- userEvent.readDate = moment$6();
30543
- if (!(!userEvent.id || userEvent.id < 0)) return [3 /*break*/, 1];
30544
- if (this._debug)
30545
- console.debug(this._logPrefix + "Save local user event");
30546
- return [3 /*break*/, 3];
30547
- case 1: return [4 /*yield*/, this.save(userEvent)];
30548
- case 2:
30549
- _b.sent();
30550
- _b.label = 3;
30551
- case 3: return [2 /*return*/];
30458
+ if (!data)
30459
+ return [2 /*return*/]; // skip
30460
+ return [4 /*yield*/, this.deleteAll([data])];
30461
+ case 1:
30462
+ _a.sent();
30463
+ return [2 /*return*/];
30552
30464
  }
30553
30465
  });
30554
30466
  });
30555
30467
  };
30556
- AbstractUserEventService.prototype.defaultFilter = function () {
30557
- // By default
30558
- return {
30559
- recipients: [this.defaultRecipient()]
30560
- };
30561
- };
30562
- AbstractUserEventService.prototype.defaultRecipient = function () {
30563
- return this.accountService.person.pubkey;
30468
+ UserEventService.prototype.listenChanges = function (id, options) {
30469
+ // TODO
30470
+ console.warn('TODO: implement listen changes on user events');
30471
+ return rxjs.of();
30564
30472
  };
30565
- AbstractUserEventService.prototype.fillDefaultProperties = function (entity) {
30473
+ UserEventService.prototype.registerAction = function (definition) {
30474
+ console.info("[user-event-service] Registering action " + definition.name + " for " + definition.__typename);
30475
+ this._userEventActions.push(definition);
30566
30476
  };
30567
- AbstractUserEventService.prototype.unreadEvents = function (events) {
30568
- // default calculation on unread events from a list
30569
- if (isEmptyArray(events))
30570
- return undefined;
30571
- var lastReadDate = events
30572
- .filter(function (event) { return isNotNil(event.readDate); })
30573
- .reduce(function (lastDate, event) { return DateUtils.max(lastDate, event.readDate); }, undefined);
30574
- return events
30575
- .filter(function (event) { return event.creationDate.isSameOrAfter(lastReadDate); }).length;
30477
+ UserEventService.prototype.getActionsByTypename = function (typename) {
30478
+ return this._userEventActions.filter(function (def) { return def.__typename === typename; });
30576
30479
  };
30577
- AbstractUserEventService.prototype.copyIdAndUpdateDate = function (source, target) {
30578
- EntityUtils.copyIdAndUpdateDate(source, target);
30579
- };
30580
- return AbstractUserEventService;
30581
- }(BaseGraphqlService));
30582
- AbstractUserEventService.decorators = [
30583
- { type: i0.Directive }
30584
- ];
30585
- AbstractUserEventService.ctorParameters = function () { return [
30586
- { type: GraphqlService },
30587
- { type: AccountService },
30588
- { type: NetworkService },
30589
- { type: i1$2.TranslateService },
30590
- { type: undefined },
30591
- { type: undefined },
30592
- { type: undefined },
30593
- { type: Environment, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [ENVIRONMENT,] }] }
30594
- ]; };
30595
- var userEventQueries = {
30596
- loadAll: core.gql(templateObject_1$3 || (templateObject_1$3 = __makeTemplateObject(["\n query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...LightUserEventFragment\n }\n }\n ", "\n "], ["\n query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...LightUserEventFragment\n }\n }\n ", "\n "])), UserEventFragments.lightUserEvent),
30597
- loadAllWithContent: core.gql(templateObject_2$3 || (templateObject_2$3 = __makeTemplateObject(["\n query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...UserEventFragment\n }\n }\n ", "\n "], ["\n query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){\n data: userEvents(filter: $filter, page: $page){\n ...UserEventFragment\n }\n }\n ", "\n "])), UserEventFragments.userEvent)
30598
- };
30599
- var userEventMutations = {
30600
- deleteByIds: core.gql(templateObject_3$2 || (templateObject_3$2 = __makeTemplateObject(["\n mutation DeleteUserEvents($ids:[Int]){\n deleteUserEvents(ids: $ids)\n }\n "], ["\n mutation DeleteUserEvents($ids:[Int]){\n deleteUserEvents(ids: $ids)\n }\n "]))),
30601
- save: core.gql(templateObject_4$2 || (templateObject_4$2 = __makeTemplateObject(["\n mutation SaveUserEvent($data: UserEventVOInput){\n data: saveUserEvent(userEvent: $data){\n ...UserEventFragment\n }\n }\n ", "\n "], ["\n mutation SaveUserEvent($data: UserEventVOInput){\n data: saveUserEvent(userEvent: $data){\n ...UserEventFragment\n }\n }\n ", "\n "])), UserEventFragments.userEvent)
30602
- };
30603
- var UserEventService = /** @class */ (function (_super) {
30604
- __extends(UserEventService, _super);
30605
- function UserEventService(graphql, accountService, network, translate, toastController, environment) {
30606
- var _this = _super.call(this, graphql, accountService, network, translate, userEventQueries, userEventMutations, undefined, environment) || this;
30607
- _this.graphql = graphql;
30608
- _this.accountService = accountService;
30609
- _this.network = network;
30610
- _this.translate = translate;
30611
- _this.toastController = toastController;
30612
- _this.environment = environment;
30613
- return _this;
30614
- }
30615
30480
  UserEventService.prototype.showToastErrorWithContext = function (opts) {
30616
30481
  return __awaiter(this, void 0, void 0, function () {
30617
30482
  var message, res, context, userEvent, err_1;
30618
- return __generator(this, function (_b) {
30619
- switch (_b.label) {
30483
+ return __generator(this, function (_a) {
30484
+ switch (_a.label) {
30620
30485
  case 0:
30621
30486
  message = opts.message || (opts.error && opts.error.message || opts.error);
30622
30487
  // Make sure message a string
@@ -30645,12 +30510,12 @@
30645
30510
  }]
30646
30511
  })];
30647
30512
  case 1:
30648
- res = _b.sent();
30513
+ res = _a.sent();
30649
30514
  if (!res || res.role !== 'send')
30650
30515
  return [2 /*return*/];
30651
- _b.label = 2;
30516
+ _a.label = 2;
30652
30517
  case 2:
30653
- _b.trys.push([2, 6, , 7]);
30518
+ _a.trys.push([2, 6, , 7]);
30654
30519
  if (this._debug)
30655
30520
  console.debug('Sending debug data...');
30656
30521
  context = opts && opts.context;
@@ -30660,15 +30525,15 @@
30660
30525
  if (!(context instanceof Promise)) return [3 /*break*/, 4];
30661
30526
  return [4 /*yield*/, context];
30662
30527
  case 3:
30663
- context = _b.sent();
30664
- _b.label = 4;
30528
+ context = _a.sent();
30529
+ _a.label = 4;
30665
30530
  case 4: return [4 /*yield*/, this.sendDataForDebug({
30666
30531
  message: message,
30667
30532
  error: opts.error || undefined,
30668
30533
  context: this.convertObjectToString(context)
30669
30534
  })];
30670
30535
  case 5:
30671
- userEvent = _b.sent();
30536
+ userEvent = _a.sent();
30672
30537
  console.info('Debug data successfully sent to admin', userEvent);
30673
30538
  this.showToast({
30674
30539
  type: 'info',
@@ -30677,7 +30542,7 @@
30677
30542
  });
30678
30543
  return [3 /*break*/, 7];
30679
30544
  case 6:
30680
- err_1 = _b.sent();
30545
+ err_1 = _a.sent();
30681
30546
  console.error('Error while sending debug data:', err_1);
30682
30547
  return [3 /*break*/, 7];
30683
30548
  case 7: return [2 /*return*/];
@@ -30687,16 +30552,13 @@
30687
30552
  };
30688
30553
  UserEventService.prototype.sendDataForDebug = function (data) {
30689
30554
  var userEvent = new exports.UserEvent();
30690
- userEvent.type = UserEventTypes.DEBUG_DATA;
30555
+ userEvent.eventType = UserEventTypes.DEBUG_DATA;
30691
30556
  userEvent.content = this.convertObjectToString(data);
30692
30557
  return this.save(userEvent);
30693
30558
  };
30694
30559
  UserEventService.prototype.asFilter = function (filter) {
30695
30560
  return exports.UserEventFilter.fromObject(filter);
30696
30561
  };
30697
- UserEventService.prototype.fromObject = function (source) {
30698
- return exports.UserEvent.fromObject(source);
30699
- };
30700
30562
  /* -- protected methods -- */
30701
30563
  UserEventService.prototype.convertObjectToString = function (data) {
30702
30564
  if (typeof data === 'string') {
@@ -30714,13 +30576,13 @@
30714
30576
  };
30715
30577
  UserEventService.prototype.showToast = function (opts) {
30716
30578
  return __awaiter(this, void 0, void 0, function () {
30717
- return __generator(this, function (_b) {
30718
- switch (_b.label) {
30579
+ return __generator(this, function (_a) {
30580
+ switch (_a.label) {
30719
30581
  case 0:
30720
30582
  if (!this.toastController)
30721
30583
  throw new Error('Missing toastController in component\'s constructor');
30722
30584
  return [4 /*yield*/, Toasts.show(this.toastController, this.translate, opts)];
30723
- case 1: return [2 /*return*/, _b.sent()];
30585
+ case 1: return [2 /*return*/, _a.sent()];
30724
30586
  }
30725
30587
  });
30726
30588
  });
@@ -30731,10 +30593,14 @@
30731
30593
  // TODO: compute sign
30732
30594
  console.warn('TODO: sign user event before sending');
30733
30595
  };
30596
+ UserEventService.prototype.copyIdAndUpdateDate = function (source, target) {
30597
+ EntityUtils.copyIdAndUpdateDate(source, target);
30598
+ };
30734
30599
  return UserEventService;
30735
- }(AbstractUserEventService));
30600
+ }(BaseGraphqlService));
30601
+ UserEventService.ɵprov = i0.ɵɵdefineInjectable({ factory: function UserEventService_Factory() { return new UserEventService(i0.ɵɵinject(GraphqlService), i0.ɵɵinject(AccountService), i0.ɵɵinject(NetworkService), i0.ɵɵinject(i1$2.TranslateService), i0.ɵɵinject(i1$5.ToastController), i0.ɵɵinject(ENVIRONMENT, 8)); }, token: UserEventService, providedIn: "root" });
30736
30602
  UserEventService.decorators = [
30737
- { type: i0.Injectable }
30603
+ { type: i0.Injectable, args: [{ providedIn: 'root' },] }
30738
30604
  ];
30739
30605
  UserEventService.ctorParameters = function () { return [
30740
30606
  { type: GraphqlService },
@@ -30748,7 +30614,7 @@
30748
30614
 
30749
30615
  var ICONS_MAP = {
30750
30616
  DEBUG_DATA: { matIcon: 'bug_report' },
30751
- INBOX_MESSAGE: { matIcon: 'mail' }
30617
+ INBOX_MESSAGE: { matIcon: 'mail' },
30752
30618
  };
30753
30619
  // TODO: refactor with a registration done by data service:
30754
30620
  // - userEventService.registerEventAction({__typename: 'TripVO', ...})
@@ -30816,7 +30682,7 @@
30816
30682
  }
30817
30683
  }));
30818
30684
  var filter = this.filter || new exports.UserEventFilter();
30819
- filter.recipients = [this.recipient];
30685
+ filter.recipient = this.recipient;
30820
30686
  this.setFilter(filter, { emitEvent: true });
30821
30687
  };
30822
30688
  UserEventsTable.prototype.start = function () {
@@ -30838,17 +30704,17 @@
30838
30704
  });
30839
30705
  };
30840
30706
  UserEventsTable.prototype.getIcon = function (source) {
30841
- return ICONS_MAP[source.type];
30707
+ return ICONS_MAP[source.eventType];
30842
30708
  };
30843
30709
  UserEventsTable.prototype.getDetail = function (source) {
30844
30710
  if (!source)
30845
30711
  return undefined;
30846
- if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
30712
+ if (source.content && source.eventType === UserEventTypes.DEBUG_DATA) {
30847
30713
  var context = source.content.context;
30848
30714
  if (context && context.__typename) {
30849
- // const actions = this.service.getActionsByTypename(context.__typename);
30715
+ var actions = this.service.getActionsByTypename(context.__typename);
30850
30716
  return {
30851
- // actions,
30717
+ actions: actions,
30852
30718
  title: source.content.error && source.content.error.message || source.content.message,
30853
30719
  description: source.content.error && source.content.error.details || undefined
30854
30720
  };
@@ -30859,18 +30725,18 @@
30859
30725
  };
30860
30726
  UserEventsTable.prototype.doAction = function (action, row) {
30861
30727
  return __awaiter(this, void 0, void 0, function () {
30862
- var event, res, _a, err_1;
30728
+ var event, context, res, _a, err_1;
30863
30729
  return __generator(this, function (_b) {
30864
30730
  switch (_b.label) {
30865
30731
  case 0:
30866
30732
  event = row.currentData;
30867
- // const context = event.content && event.content.context;
30733
+ context = event.content && event.content.context;
30868
30734
  this.markAsLoading();
30869
30735
  if (!(action && typeof action.executeAction === 'function')) return [3 /*break*/, 7];
30870
30736
  _b.label = 1;
30871
30737
  case 1:
30872
30738
  _b.trys.push([1, 5, 6, 7]);
30873
- res = action.executeAction(event /*, context*/);
30739
+ res = action.executeAction(event, context);
30874
30740
  if (!(res instanceof Promise)) return [3 /*break*/, 3];
30875
30741
  return [4 /*yield*/, res];
30876
30742
  case 2:
@@ -30902,18 +30768,13 @@
30902
30768
  selector: 'app-user-events-table',
30903
30769
  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",
30904
30770
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
30905
- providers: [
30906
- {
30907
- provide: UserEventServiceToken, useClass: UserEventService
30908
- }
30909
- ],
30910
30771
  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}"]
30911
30772
  },] }
30912
30773
  ];
30913
30774
  UserEventsTable.ctorParameters = function () { return [
30914
30775
  { type: i0.Injector },
30915
30776
  { type: AccountService },
30916
- { type: undefined, decorators: [{ type: i0.Inject, args: [UserEventServiceToken,] }] },
30777
+ { type: UserEventService },
30917
30778
  { type: EntitiesStorage },
30918
30779
  { type: i0.ChangeDetectorRef },
30919
30780
  { type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] }
@@ -30925,167 +30786,6 @@
30925
30786
  defaultSortDirection: [{ type: i0.Input }]
30926
30787
  };
30927
30788
 
30928
- var UserEventNotificationList = /** @class */ (function () {
30929
- function UserEventNotificationList(popoverController) {
30930
- this.popoverController = popoverController;
30931
- }
30932
- UserEventNotificationList.prototype.ngOnInit = function () {
30933
- };
30934
- UserEventNotificationList.prototype.read = function ($event, userEvent) {
30935
- var _a;
30936
- if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
30937
- return;
30938
- (_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
30939
- };
30940
- UserEventNotificationList.prototype.executeAction = function (action, userEvent) {
30941
- // Execute then close popover
30942
- action.executeAction(userEvent);
30943
- this.dismiss();
30944
- };
30945
- UserEventNotificationList.prototype.dismiss = function () {
30946
- this.popoverController.dismiss();
30947
- };
30948
- return UserEventNotificationList;
30949
- }());
30950
- UserEventNotificationList.decorators = [
30951
- { type: i0.Component, args: [{
30952
- selector: 'app-user-event-notification-list',
30953
- 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 {{ '&#10142;&nbsp;' + 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",
30954
- styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
30955
- },] }
30956
- ];
30957
- UserEventNotificationList.ctorParameters = function () { return [
30958
- { type: i1$5.PopoverController }
30959
- ]; };
30960
- UserEventNotificationList.propDecorators = {
30961
- titleI18n: [{ type: i0.Input }],
30962
- userEvents: [{ type: i0.Input }],
30963
- readEvent: [{ type: i0.Output }]
30964
- };
30965
-
30966
- var UserEventNotificationComponent = /** @class */ (function () {
30967
- function UserEventNotificationComponent(userEventService, accountService, popoverController, cd) {
30968
- this.userEventService = userEventService;
30969
- this.accountService = accountService;
30970
- this.popoverController = popoverController;
30971
- this.cd = cd;
30972
- this.debug = false;
30973
- this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
30974
- this.disabled = false;
30975
- this.userEventsSubject = new rxjs.BehaviorSubject(undefined);
30976
- this._subscriptions = new rxjs.Subscription();
30977
- this._logPrefix = '[user-event-notification] ';
30978
- this._readEvent = new i0.EventEmitter();
30979
- }
30980
- Object.defineProperty(UserEventNotificationComponent.prototype, "count", {
30981
- get: function () {
30982
- var _a;
30983
- return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(operators.map(function (value) { return value === 0 ? undefined : value; }));
30984
- },
30985
- enumerable: false,
30986
- configurable: true
30987
- });
30988
- UserEventNotificationComponent.prototype.ngOnInit = function () {
30989
- var _this = this;
30990
- if (isNil(this.userEventService)) {
30991
- console.warn(this._logPrefix + "No service injected");
30992
- this.disabled = true;
30993
- return;
30994
- }
30995
- this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc").subscribe(function (value) {
30996
- var data = value.data;
30997
- if (_this.debug) {
30998
- console.debug(_this._logPrefix + "Receiving user events", data);
30999
- }
31000
- _this.userEventsSubject.next(data);
31001
- }));
31002
- this._readEvent.subscribe(function (value) {
31003
- _this.userEventService.markAsRead(value);
31004
- });
31005
- };
31006
- UserEventNotificationComponent.prototype.showList = function (event) {
31007
- return __awaiter(this, void 0, void 0, function () {
31008
- var popover;
31009
- return __generator(this, function (_b) {
31010
- switch (_b.label) {
31011
- case 0: return [4 /*yield*/, this.popoverController.create({
31012
- component: UserEventNotificationList,
31013
- componentProps: {
31014
- titleI18n: this.titleI18n,
31015
- userEvents: this.userEventsSubject,
31016
- readEvent: this._readEvent
31017
- },
31018
- backdropDismiss: true,
31019
- keyboardClose: true,
31020
- event: event,
31021
- translucent: true,
31022
- cssClass: 'popover-large'
31023
- })];
31024
- case 1:
31025
- popover = _b.sent();
31026
- return [4 /*yield*/, popover.present()];
31027
- case 2:
31028
- _b.sent();
31029
- return [2 /*return*/];
31030
- }
31031
- });
31032
- });
31033
- };
31034
- UserEventNotificationComponent.prototype.markForCheck = function () {
31035
- this.cd.markForCheck();
31036
- };
31037
- UserEventNotificationComponent.prototype.ngOnDestroy = function () {
31038
- if (this.debug) {
31039
- console.debug(this._logPrefix + "Destroying");
31040
- }
31041
- this._subscriptions.unsubscribe();
31042
- };
31043
- return UserEventNotificationComponent;
31044
- }());
31045
- UserEventNotificationComponent.decorators = [
31046
- { type: i0.Component, args: [{
31047
- selector: 'app-user-event-notification-component',
31048
- 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",
31049
- changeDetection: i0.ChangeDetectionStrategy.OnPush,
31050
- styles: [""]
31051
- },] }
31052
- ];
31053
- UserEventNotificationComponent.ctorParameters = function () { return [
31054
- { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [UserEventServiceToken,] }] },
31055
- { type: AccountService },
31056
- { type: i1$5.PopoverController },
31057
- { type: i0.ChangeDetectorRef }
31058
- ]; };
31059
- UserEventNotificationComponent.propDecorators = {
31060
- debug: [{ type: i0.Input }],
31061
- titleI18n: [{ type: i0.Input }],
31062
- disabled: [{ type: i0.Input }]
31063
- };
31064
-
31065
- var UserEventModule = /** @class */ (function () {
31066
- function UserEventModule() {
31067
- }
31068
- return UserEventModule;
31069
- }());
31070
- UserEventModule.decorators = [
31071
- { type: i0.NgModule, args: [{
31072
- imports: [
31073
- i1$4.CommonModule,
31074
- CoreModule,
31075
- SharedModule
31076
- ],
31077
- declarations: [
31078
- UserEventsTable,
31079
- UserEventNotificationComponent,
31080
- UserEventNotificationList,
31081
- ],
31082
- exports: [
31083
- UserEventsTable,
31084
- UserEventNotificationComponent
31085
- ]
31086
- },] }
31087
- ];
31088
-
31089
30789
  var MessageTypes = {
31090
30790
  INBOX_MESSAGE: 'INBOX_MESSAGE',
31091
30791
  EMAIL: 'EMAIL',
@@ -31319,12 +31019,12 @@
31319
31019
  canSelectType: [{ type: i0.Input }]
31320
31020
  };
31321
31021
 
31322
- var MessageModule = /** @class */ (function () {
31323
- function MessageModule() {
31022
+ var SocialModule = /** @class */ (function () {
31023
+ function SocialModule() {
31324
31024
  }
31325
- return MessageModule;
31025
+ return SocialModule;
31326
31026
  }());
31327
- MessageModule.decorators = [
31027
+ SocialModule.decorators = [
31328
31028
  { type: i0.NgModule, args: [{
31329
31029
  imports: [
31330
31030
  i1$4.CommonModule,
@@ -31332,342 +31032,19 @@
31332
31032
  SharedModule
31333
31033
  ],
31334
31034
  declarations: [
31035
+ UserEventsTable,
31335
31036
  MessageModal,
31336
31037
  MessageForm
31337
31038
  ],
31338
31039
  exports: [
31040
+ UserEventsTable,
31339
31041
  MessageModal
31340
31042
  ]
31341
31043
  },] }
31342
31044
  ];
31343
31045
 
31344
- var JobProgression_1;
31345
- // todo use entity
31346
- var Job = /** @class */ (function () {
31347
- function Job() {
31348
- }
31349
- return Job;
31350
- }());
31351
- // @dynamic
31352
- exports.JobProgression = JobProgression_1 = /** @class */ (function (_super) {
31353
- __extends(JobProgression, _super);
31354
- function JobProgression() {
31355
- return _super.call(this, JobProgression_1.TYPENAME) || this;
31356
- }
31357
- JobProgression.prototype.fromObject = function (source) {
31358
- _super.prototype.fromObject.call(this, source);
31359
- this.message = source.message;
31360
- this.current = source.current;
31361
- this.total = source.total;
31362
- };
31363
- return JobProgression;
31364
- }(Entity));
31365
- exports.JobProgression = JobProgression_1 = __decorate([
31366
- EntityClass({ typename: 'JobProgressionVO' })
31367
- ], exports.JobProgression);
31368
-
31369
- var JobProgressionServiceToken = new i0.InjectionToken('JobProgressionService');
31370
- var jobProgressionSubscription = core.gql(templateObject_1$4 || (templateObject_1$4 = __makeTemplateObject(["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n }\n}"], ["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n }\n}"])));
31371
- var JobProgressionService = /** @class */ (function (_super) {
31372
- __extends(JobProgressionService, _super);
31373
- function JobProgressionService(graphql, environment) {
31374
- var _this = _super.call(this, graphql, environment) || this;
31375
- _this.graphql = graphql;
31376
- _this.environment = environment;
31377
- _this._logPrefix = '[job-progression-service] ';
31378
- // For DEV only
31379
- _this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
31380
- return _this;
31381
- }
31382
- JobProgressionService.prototype.listenChanges = function (id, options) {
31383
- var _this = this;
31384
- if (isNil(id))
31385
- throw new Error(this._logPrefix + "Missing argument 'id'");
31386
- if (this._debug)
31387
- console.debug(this._logPrefix + "[WS] Listening changes for job progression {" + id + "}...");
31388
- return this.graphql.subscribe({
31389
- query: jobProgressionSubscription,
31390
- fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
31391
- variables: { id: id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
31392
- error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
31393
- }).pipe(operators.map(function (_a) {
31394
- var data = _a.data;
31395
- var progression = data && exports.JobProgression.fromObject(data);
31396
- if (progression && _this._debug)
31397
- console.debug(_this._logPrefix + "Job progression " + id + " updated on server", progression);
31398
- return progression;
31399
- }));
31400
- };
31401
- return JobProgressionService;
31402
- }(BaseGraphqlService));
31403
- JobProgressionService.decorators = [
31404
- { type: i0.Injectable }
31405
- ];
31406
- JobProgressionService.ctorParameters = function () { return [
31407
- { type: GraphqlService },
31408
- { type: Environment, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [ENVIRONMENT,] }] }
31409
- ]; };
31410
- var templateObject_1$4;
31411
-
31412
- var JobProgressionList = /** @class */ (function () {
31413
- function JobProgressionList() {
31414
- }
31415
- JobProgressionList.prototype.ngOnInit = function () {
31416
- };
31417
- return JobProgressionList;
31418
- }());
31419
- JobProgressionList.decorators = [
31420
- { type: i0.Component, args: [{
31421
- selector: 'app-job-progression-list',
31422
- 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",
31423
- styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
31424
- },] }
31425
- ];
31426
- JobProgressionList.ctorParameters = function () { return []; };
31427
- JobProgressionList.propDecorators = {
31428
- titleI18n: [{ type: i0.Input }],
31429
- jobProgressions: [{ type: i0.Input }]
31430
- };
31431
-
31432
- var JobProgressionComponent = /** @class */ (function () {
31433
- function JobProgressionComponent(jobProgressionService, popoverController, cd) {
31434
- this.jobProgressionService = jobProgressionService;
31435
- this.popoverController = popoverController;
31436
- this.cd = cd;
31437
- this.debug = false;
31438
- this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
31439
- this.jobFinished = new i0.EventEmitter();
31440
- this.disabled = true;
31441
- this.color = 'accent';
31442
- this.mode = 'determinate';
31443
- this.value = 0;
31444
- this.jobProgressions = [];
31445
- this._subscriptions = new rxjs.Subscription();
31446
- this._subscriptionsById = {};
31447
- this._logPrefix = '[job-progression] ';
31448
- }
31449
- JobProgressionComponent.prototype.ngOnInit = function () {
31450
- var _a, _b, _c, _d;
31451
- if (isNil(this.jobProgressionService)) {
31452
- console.warn(this._logPrefix + "No service injected");
31453
- }
31454
- // parse options
31455
- this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
31456
- this.visible = !this.autoHide;
31457
- this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
31458
- this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
31459
- this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
31460
- };
31461
- JobProgressionComponent.prototype.addJob = function (id) {
31462
- var _this = this;
31463
- if (isNil(this.jobProgressionService)) {
31464
- console.warn(this._logPrefix + "No service injected. Can't add a job");
31465
- return;
31466
- }
31467
- if (this.debug) {
31468
- console.debug(this._logPrefix + "Add job id=" + id);
31469
- }
31470
- if (!!this.getProgression(id)) {
31471
- console.warn(this._logPrefix + "Job (id=" + id + ") already present");
31472
- return;
31473
- }
31474
- this.disabled = false;
31475
- var sub = this.jobProgressionService.listenChanges(id)
31476
- .pipe(operators.filter(function (progression) {
31477
- if (id !== progression.id) {
31478
- console.error(_this._logPrefix + "Job progression (id=" + progression.id + ") doesn't match expected job (id=" + id + ")");
31479
- return false;
31480
- }
31481
- return true;
31482
- }), operators.map(function (progression) {
31483
- // Ensure visible
31484
- _this.visible = true;
31485
- // Get current progression object
31486
- var currentProgression = _this.getProgression(id);
31487
- if (!currentProgression) {
31488
- // add it
31489
- _this.jobProgressions.push(progression);
31490
- if (_this.debug) {
31491
- console.debug(_this._logPrefix + "Progression added id=" + id, progression);
31492
- }
31493
- }
31494
- else {
31495
- // update current
31496
- Object.assign(currentProgression, progression);
31497
- if (_this.debug) {
31498
- console.debug(_this._logPrefix + "Progression updated id=" + id, progression);
31499
- }
31500
- }
31501
- return progression;
31502
- }))
31503
- .subscribe(function (progression) {
31504
- // update value
31505
- _this.updateValue();
31506
- // job finished
31507
- if (progression.total > 0 && progression.current == progression.total) {
31508
- if (_this.debug) {
31509
- console.debug(_this._logPrefix + "Finished job id=" + progression.id);
31510
- }
31511
- // emit event
31512
- _this.jobFinished.emit(progression.id);
31513
- if (_this.autoRemove) {
31514
- setTimeout(function () {
31515
- var _a;
31516
- _this.removeJob(progression.id);
31517
- // If last job
31518
- if (_this.autoHide && !((_a = _this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
31519
- setTimeout(function () {
31520
- _this.visible = false;
31521
- _this.markForCheck();
31522
- }, _this.autoHideDelay);
31523
- }
31524
- }, _this.autoRemoveDelay);
31525
- }
31526
- }
31527
- });
31528
- this._subscriptionsById[id] = sub;
31529
- this._subscriptions.add(sub);
31530
- };
31531
- JobProgressionComponent.prototype.removeJob = function (id) {
31532
- if (this.debug) {
31533
- console.debug(this._logPrefix + "Remove job id=" + id);
31534
- }
31535
- var sub = this._subscriptionsById[id];
31536
- if (sub) {
31537
- this._subscriptions.remove(sub);
31538
- sub.unsubscribe();
31539
- }
31540
- var progression = this.getProgression(id);
31541
- if (progression) {
31542
- this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
31543
- }
31544
- this.updateValue();
31545
- };
31546
- JobProgressionComponent.prototype.getProgression = function (id) {
31547
- return this.jobProgressions.find(function (progression) { return progression.id === id; });
31548
- };
31549
- JobProgressionComponent.prototype.updateValue = function () {
31550
- if (this.debug) {
31551
- console.debug(this._logPrefix + "Updating value");
31552
- }
31553
- var value = 0;
31554
- var nbProgression = arraySize(this.jobProgressions);
31555
- var allIndeterminate = nbProgression > 0;
31556
- this.jobProgressions.forEach(function (progression) {
31557
- var indeterminate = progression.total === 0;
31558
- allIndeterminate = allIndeterminate && indeterminate;
31559
- if (!indeterminate) {
31560
- value = value + progression.current * 100 / progression.total;
31561
- }
31562
- });
31563
- this.value = nbProgression > 0 ? value / nbProgression : 0;
31564
- this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
31565
- if (this.debug) {
31566
- console.debug(this._logPrefix + "Setting value=" + this.value + ", mode=" + this.mode);
31567
- }
31568
- this.markForCheck();
31569
- };
31570
- JobProgressionComponent.prototype.showList = function (event) {
31571
- return __awaiter(this, void 0, void 0, function () {
31572
- var popover;
31573
- return __generator(this, function (_e) {
31574
- switch (_e.label) {
31575
- case 0: return [4 /*yield*/, this.popoverController.create({
31576
- component: JobProgressionList,
31577
- componentProps: {
31578
- titleI18n: this.titleI18n,
31579
- jobProgressions: this.jobProgressions
31580
- },
31581
- backdropDismiss: true,
31582
- keyboardClose: true,
31583
- event: event,
31584
- translucent: true,
31585
- cssClass: 'popover-large'
31586
- })];
31587
- case 1:
31588
- popover = _e.sent();
31589
- return [4 /*yield*/, popover.present()];
31590
- case 2:
31591
- _e.sent();
31592
- return [2 /*return*/];
31593
- }
31594
- });
31595
- });
31596
- };
31597
- JobProgressionComponent.prototype.markForCheck = function () {
31598
- this.cd.markForCheck();
31599
- };
31600
- JobProgressionComponent.prototype.ngOnDestroy = function () {
31601
- if (this.debug) {
31602
- console.debug(this._logPrefix + "Destroying");
31603
- }
31604
- this._subscriptions.unsubscribe();
31605
- };
31606
- return JobProgressionComponent;
31607
- }());
31608
- JobProgressionComponent.decorators = [
31609
- { type: i0.Component, args: [{
31610
- selector: 'app-job-progression',
31611
- 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",
31612
- changeDetection: i0.ChangeDetectionStrategy.OnPush,
31613
- styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
31614
- },] }
31615
- ];
31616
- JobProgressionComponent.ctorParameters = function () { return [
31617
- { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [JobProgressionServiceToken,] }] },
31618
- { type: i1$5.PopoverController },
31619
- { type: i0.ChangeDetectorRef }
31620
- ]; };
31621
- JobProgressionComponent.propDecorators = {
31622
- debug: [{ type: i0.Input }],
31623
- titleI18n: [{ type: i0.Input }],
31624
- options: [{ type: i0.Input }],
31625
- jobFinished: [{ type: i0.Output }]
31626
- };
31627
-
31628
- var JobModule = /** @class */ (function () {
31629
- function JobModule() {
31630
- }
31631
- return JobModule;
31632
- }());
31633
- JobModule.decorators = [
31634
- { type: i0.NgModule, args: [{
31635
- imports: [
31636
- i1$4.CommonModule,
31637
- SharedModule,
31638
- i1$2.TranslateModule.forChild(),
31639
- ],
31640
- declarations: [
31641
- JobProgressionComponent,
31642
- JobProgressionList
31643
- ],
31644
- exports: [
31645
- JobProgressionComponent
31646
- ]
31647
- },] }
31648
- ];
31649
-
31650
- var SocialModuleOptionsToken = new i0.InjectionToken("SocialModuleOptions");
31651
- var SocialModule = /** @class */ (function () {
31652
- function SocialModule() {
31653
- }
31654
- return SocialModule;
31655
- }());
31656
- SocialModule.decorators = [
31657
- { type: i0.NgModule, args: [{
31658
- imports: [
31659
- i1$4.CommonModule,
31660
- CoreModule,
31661
- SharedModule,
31662
- UserEventModule,
31663
- JobModule,
31664
- MessageModule,
31665
- ],
31666
- },] }
31667
- ];
31668
-
31669
31046
  var Mutations = {
31670
- send: core.gql(templateObject_1$5 || (templateObject_1$5 = __makeTemplateObject(["mutation SendMessage($data: MessageVOInput){\n done: sendMessage(message: $data)\n }"], ["mutation SendMessage($data: MessageVOInput){\n done: sendMessage(message: $data)\n }"])))
31047
+ send: core.gql(templateObject_1$4 || (templateObject_1$4 = __makeTemplateObject(["mutation SendMessage($data: MessageVOInput){\n done: sendMessage(message: $data)\n }"], ["mutation SendMessage($data: MessageVOInput){\n done: sendMessage(message: $data)\n }"])))
31671
31048
  };
31672
31049
  var MessageService = /** @class */ (function (_super) {
31673
31050
  __extends(MessageService, _super);
@@ -31751,7 +31128,7 @@
31751
31128
  { type: i1$5.ToastController },
31752
31129
  { type: Environment, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [ENVIRONMENT,] }] }
31753
31130
  ]; };
31754
- var templateObject_1$5;
31131
+ var templateObject_1$4;
31755
31132
 
31756
31133
  var PersonFilter_1;
31757
31134
  // @dynamic
@@ -31810,7 +31187,7 @@
31810
31187
  ], exports.PersonFilter);
31811
31188
 
31812
31189
  var PersonFragments = {
31813
- person: core.gql(templateObject_1$6 || (templateObject_1$6 = __makeTemplateObject(["fragment PersonFragment on PersonVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n username\n usernameExtranet\n department {\n id\n label\n name\n logo\n __typename\n }\n __typename\n }"], ["fragment PersonFragment on PersonVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n username\n usernameExtranet\n department {\n id\n label\n name\n logo\n __typename\n }\n __typename\n }"])))
31190
+ person: core.gql(templateObject_1$5 || (templateObject_1$5 = __makeTemplateObject(["fragment PersonFragment on PersonVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n username\n usernameExtranet\n department {\n id\n label\n name\n logo\n __typename\n }\n __typename\n }"], ["fragment PersonFragment on PersonVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n username\n usernameExtranet\n department {\n id\n label\n name\n logo\n __typename\n }\n __typename\n }"])))
31814
31191
  };
31815
31192
  // Load persons query
31816
31193
  var PersonQueries = {
@@ -31950,7 +31327,7 @@
31950
31327
  { type: NetworkService },
31951
31328
  { type: EntitiesStorage }
31952
31329
  ]; };
31953
- var templateObject_1$6, templateObject_2$4, templateObject_3$3, templateObject_4$3, templateObject_5$2;
31330
+ var templateObject_1$5, templateObject_2$4, templateObject_3$3, templateObject_4$3, templateObject_5$2;
31954
31331
 
31955
31332
  var PersonValidatorService = /** @class */ (function () {
31956
31333
  function PersonValidatorService(formBuilder, accountValidatorService) {
@@ -32360,10 +31737,12 @@
32360
31737
  };
32361
31738
  AutocompleteTestPage.prototype.ngAfterViewInit = function () {
32362
31739
  var _this = this;
32363
- setTimeout(function () {
32364
- _this.farEntityField.suggestLengthThreshold = 2;
32365
- _this.farEntityField.reloadItems();
32366
- }, 2000);
31740
+ if (this.farEntityField) {
31741
+ setTimeout(function () {
31742
+ _this.farEntityField.suggestLengthThreshold = 2;
31743
+ _this.farEntityField.reloadItems();
31744
+ }, 2000);
31745
+ }
32367
31746
  setTimeout(function () { return _this.loadData(); }, 1000);
32368
31747
  };
32369
31748
  // Load the form with data
@@ -32470,7 +31849,7 @@
32470
31849
  AutocompleteTestPage.decorators = [
32471
31850
  { type: i0.Component, args: [{
32472
31851
  selector: 'app-autocomplete-test',
32473
- 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&lt;any[]&gt;</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) =&gt; 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&lt;any[]&gt;</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&lt;any[]&gt;</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&lt;any&gt;\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&lt;any&gt;</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&lt;any&gt;\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&lt;any[]&gt;</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&lt;any[]&gt;</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"
31852
+ 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&lt;any[]&gt;</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) =&gt; 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&lt;any[]&gt;</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&lt;any[]&gt;</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&lt;any&gt;\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&lt;any&gt;</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&lt;any&gt;\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&lt;any[]&gt;</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&lt;any[]&gt;</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"
32474
31853
  },] }
32475
31854
  ];
32476
31855
  AutocompleteTestPage.ctorParameters = function () { return [
@@ -32552,13 +31931,13 @@
32552
31931
  { type: i1.FormBuilder }
32553
31932
  ]; };
32554
31933
 
32555
- var moment$7 = momentImported__namespace;
31934
+ var moment$6 = momentImported__namespace;
32556
31935
  var SwipeTestPage = /** @class */ (function () {
32557
31936
  function SwipeTestPage(formBuilder, dateFormatPipe) {
32558
31937
  this.formBuilder = formBuilder;
32559
31938
  this.dateFormatPipe = dateFormatPipe;
32560
31939
  this.$dates = new rxjs.BehaviorSubject(undefined);
32561
- this._today = moment$7().startOf('day');
31940
+ this._today = moment$6().startOf('day');
32562
31941
  this.form = formBuilder.group({
32563
31942
  empty: [null, i1.Validators.required],
32564
31943
  date: [null, i1.Validators.compose([i1.Validators.required, SharedValidators.validDate])],
@@ -32572,7 +31951,7 @@
32572
31951
  var _this = this;
32573
31952
  var dates = [];
32574
31953
  for (var d = 0; d < 7; d++) {
32575
- dates[d] = moment$7(this._today).add(d - 3, 'day');
31954
+ dates[d] = moment$6(this._today).add(d - 3, 'day');
32576
31955
  }
32577
31956
  this.$dates.next(dates);
32578
31957
  this.loadData();
@@ -32619,7 +31998,7 @@
32619
31998
  { type: DateFormatPipe }
32620
31999
  ]; };
32621
32000
 
32622
- var moment$8 = momentImported__namespace;
32001
+ var moment$7 = momentImported__namespace;
32623
32002
  var DateTimeTestPage = /** @class */ (function () {
32624
32003
  function DateTimeTestPage(platform, formBuilder, cd) {
32625
32004
  this.platform = platform;
@@ -32655,7 +32034,7 @@
32655
32034
  var now, data;
32656
32035
  var _this = this;
32657
32036
  return __generator(this, function (_a) {
32658
- now = moment$8();
32037
+ now = moment$7();
32659
32038
  data = {
32660
32039
  empty: null,
32661
32040
  emptyRequired: null,
@@ -32933,7 +32312,7 @@
32933
32312
  { type: i1.FormBuilder }
32934
32313
  ]; };
32935
32314
 
32936
- var moment$9 = momentImported__namespace;
32315
+ var moment$8 = momentImported__namespace;
32937
32316
  var DateTestPage = /** @class */ (function () {
32938
32317
  function DateTestPage(formBuilder, cd) {
32939
32318
  this.formBuilder = formBuilder;
@@ -32970,7 +32349,7 @@
32970
32349
  var now, nowAtMahe, data;
32971
32350
  var _this = this;
32972
32351
  return __generator(this, function (_a) {
32973
- now = moment$9();
32352
+ now = moment$8();
32974
32353
  nowAtMahe = now.clone().tz(this.timezone).startOf('day');
32975
32354
  data = {
32976
32355
  empty: null,
@@ -33809,7 +33188,6 @@
33809
33188
  exports.APP_MENU_ITEMS = APP_MENU_ITEMS;
33810
33189
  exports.APP_TESTING_PAGES = APP_TESTING_PAGES;
33811
33190
  exports.AboutModal = AboutModal;
33812
- exports.AbstractUserEventService = AbstractUserEventService;
33813
33191
  exports.AccountPage = AccountPage;
33814
33192
  exports.AccountService = AccountService;
33815
33193
  exports.AccountToStringPipe = AccountToStringPipe;
@@ -33936,11 +33314,6 @@
33936
33314
  exports.IsNotNilOrBlankPipe = IsNotNilOrBlankPipe;
33937
33315
  exports.IsNotOnFieldModePipe = IsNotOnFieldModePipe;
33938
33316
  exports.IsOnFieldModePipe = IsOnFieldModePipe;
33939
- exports.Job = Job;
33940
- exports.JobModule = JobModule;
33941
- exports.JobProgressionComponent = JobProgressionComponent;
33942
- exports.JobProgressionService = JobProgressionService;
33943
- exports.JobProgressionServiceToken = JobProgressionServiceToken;
33944
33317
  exports.JobUtils = JobUtils;
33945
33318
  exports.KEYBOARD_HIDE_DELAY_MS = KEYBOARD_HIDE_DELAY_MS;
33946
33319
  exports.LAT_LONG_DEFAULT_MAX_DECIMALS = LAT_LONG_DEFAULT_MAX_DECIMALS;
@@ -33978,7 +33351,6 @@
33978
33351
  exports.MenuService = MenuService;
33979
33352
  exports.MessageForm = MessageForm;
33980
33353
  exports.MessageModal = MessageModal;
33981
- exports.MessageModule = MessageModule;
33982
33354
  exports.MessageService = MessageService;
33983
33355
  exports.MessageTypeList = MessageTypeList;
33984
33356
  exports.MessageTypes = MessageTypes;
@@ -34046,7 +33418,6 @@
34046
33418
  exports.SharedValidators = SharedValidators;
34047
33419
  exports.SocialErrorCodes = SocialErrorCodes;
34048
33420
  exports.SocialModule = SocialModule;
34049
- exports.SocialModuleOptionsToken = SocialModuleOptionsToken;
34050
33421
  exports.StartableService = StartableService;
34051
33422
  exports.StatusById = StatusById;
34052
33423
  exports.StatusIds = StatusIds;
@@ -34075,10 +33446,7 @@
34075
33446
  exports.UploadFileTestingPage = UploadFileTestingPage;
34076
33447
  exports.UriUtils = UriUtils;
34077
33448
  exports.UserEventFragments = UserEventFragments;
34078
- exports.UserEventModule = UserEventModule;
34079
- exports.UserEventNotificationComponent = UserEventNotificationComponent;
34080
33449
  exports.UserEventService = UserEventService;
34081
- exports.UserEventServiceToken = UserEventServiceToken;
34082
33450
  exports.UserEventTypes = UserEventTypes;
34083
33451
  exports.UserEventsTable = UserEventsTable;
34084
33452
  exports.UsersPage = UsersPage;
@@ -34229,6 +33597,7 @@
34229
33597
  exports.uncapitalizeFirstLetter = uncapitalizeFirstLetter;
34230
33598
  exports.updateValueAndValidity = updateValueAndValidity;
34231
33599
  exports.waitFor = waitFor;
33600
+ exports.waitForFalse = waitForFalse;
34232
33601
  exports.waitForTrue = waitForTrue;
34233
33602
  exports.waitIdle = waitIdle;
34234
33603
  exports.waitWhilePending = waitWhilePending;
@@ -34243,13 +33612,11 @@
34243
33612
  exports.ɵh = LocalSettingsValidatorService;
34244
33613
  exports.ɵi = AppUpdateOfflineModeCard;
34245
33614
  exports.ɵj = AppIconComponent;
34246
- exports.ɵk = UserEventNotificationList;
34247
- exports.ɵl = JobProgressionList;
34248
- exports.ɵm = DateTestPage;
34249
- exports.ɵn = NumpadTestPage;
34250
- exports.ɵo = MatBadgeIconTestPage;
34251
- exports.ɵp = ToastTestingModule;
34252
- exports.ɵq = ToastTestingPage;
33615
+ exports.ɵk = DateTestPage;
33616
+ exports.ɵl = NumpadTestPage;
33617
+ exports.ɵm = MatBadgeIconTestPage;
33618
+ exports.ɵn = ToastTestingModule;
33619
+ exports.ɵo = ToastTestingPage;
34253
33620
 
34254
33621
  Object.defineProperty(exports, '__esModule', { value: true });
34255
33622