@sumaris-net/ngx-components 1.20.30 → 1.21.0-beta1

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 (64) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +1044 -297
  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 +0 -3
  6. package/esm2015/public_api.js +5 -3
  7. package/esm2015/src/app/core/icon/icon.component.js +5 -2
  8. package/esm2015/src/app/shared/functions.js +60 -1
  9. package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +2 -3
  10. package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +2 -3
  11. package/esm2015/src/app/shared/material/chips/material.chips.js +2 -3
  12. package/esm2015/src/app/shared/material/chips/testing/chips.test.js +2 -3
  13. package/esm2015/src/app/shared/pipes/arrays.pipe.js +1 -1
  14. package/esm2015/src/app/shared/pipes/form.pipes.js +4 -2
  15. package/esm2015/src/app/shared/pipes/highlight.pipe.js +4 -4
  16. package/esm2015/src/app/shared/pipes/string.pipes.js +18 -7
  17. package/esm2015/src/app/shared/services/memory-entity-service.class.js +1 -13
  18. package/esm2015/src/app/shared/types.js +1 -1
  19. package/esm2015/src/app/social/job/job.model.js +24 -0
  20. package/esm2015/src/app/social/job/job.module.js +25 -0
  21. package/esm2015/src/app/social/job/job.service.js +54 -0
  22. package/esm2015/src/app/social/job/progression/job-progression.component.js +171 -0
  23. package/esm2015/src/app/social/job/progression/job-progression.list.js +20 -0
  24. package/esm2015/src/app/social/message/message.module.js +25 -0
  25. package/esm2015/src/app/social/social.errors.js +5 -2
  26. package/esm2015/src/app/social/social.module.js +8 -14
  27. package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +88 -0
  28. package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +39 -0
  29. package/esm2015/src/app/social/user-event/user-event.model.js +58 -2
  30. package/esm2015/src/app/social/user-event/user-event.module.js +28 -0
  31. package/esm2015/src/app/social/user-event/user-event.service.js +294 -166
  32. package/esm2015/src/app/social/user-event/user-events.table.js +17 -12
  33. package/esm2015/sumaris-net.ngx-components.js +11 -6
  34. package/fesm2015/sumaris-net.ngx-components.js +880 -264
  35. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  36. package/package.json +1 -1
  37. package/public_api.d.ts +4 -2
  38. package/src/app/core/icon/icon.component.d.ts +4 -4
  39. package/src/app/shared/functions.d.ts +9 -0
  40. package/src/app/shared/material/badge/badge-icon.test.d.ts +1 -1
  41. package/src/app/shared/pipes/form.pipes.d.ts +2 -1
  42. package/src/app/shared/services/memory-entity-service.class.d.ts +0 -6
  43. package/src/app/shared/types.d.ts +4 -0
  44. package/src/app/social/job/job.model.d.ts +32 -0
  45. package/src/app/social/job/job.module.d.ts +2 -0
  46. package/src/app/social/job/job.service.d.ts +23 -0
  47. package/src/app/social/job/progression/job-progression.component.d.ts +34 -0
  48. package/src/app/social/job/progression/job-progression.list.d.ts +12 -0
  49. package/src/app/social/message/message.module.d.ts +2 -0
  50. package/src/app/social/social.errors.d.ts +3 -0
  51. package/src/app/social/user-event/notification/user-event-notification.component.d.ts +26 -0
  52. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +20 -0
  53. package/src/app/social/user-event/user-event.model.d.ts +51 -6
  54. package/src/app/social/user-event/user-event.module.d.ts +2 -0
  55. package/src/app/social/user-event/user-event.service.d.ts +80 -51
  56. package/src/app/social/user-event/user-events.table.d.ts +6 -6
  57. package/src/assets/i18n/en-US.json +9 -2
  58. package/src/assets/i18n/en.json +9 -2
  59. package/src/assets/i18n/fr.json +8 -1
  60. package/src/theme/_ngx-components.scss +7 -0
  61. package/sumaris-net.ngx-components.d.ts +10 -5
  62. package/sumaris-net.ngx-components.metadata.json +1 -1
  63. package/esm2015/src/app/shared/services.js +0 -61
  64. package/src/app/shared/services.d.ts +0 -9
@@ -241,6 +241,64 @@ function changeCaseToUnderscore(value) {
241
241
  function removeDiacritics(text) {
242
242
  return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
243
243
  }
244
+ function suggestFromArray(items, value, opts) {
245
+ if (isNotNil(value) && typeof value === 'object')
246
+ return { data: [value] };
247
+ value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
248
+ const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
249
+ if (!items) {
250
+ return { data: [], total: 0 };
251
+ }
252
+ // Filter items
253
+ let filteredItems = items;
254
+ if (isNotNilOrBlank(value)) {
255
+ // If wildcard, search using regexp
256
+ if (value.indexOf('*') !== -1) {
257
+ value = value.replace(/[*]+/g, '.*');
258
+ filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
259
+ }
260
+ // Else (no wildcard), search using startsWith
261
+ else {
262
+ filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
263
+ }
264
+ }
265
+ // Exclude ids
266
+ if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
267
+ filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
268
+ }
269
+ // Sort
270
+ if (!opts || opts.skipSort !== true) {
271
+ // Make to copy input items, before sorting (if not yet already done)
272
+ if (filteredItems === items)
273
+ filteredItems = filteredItems.slice();
274
+ // Sort by keys
275
+ filteredItems.sort(propertiesPathComparator(keys));
276
+ }
277
+ const total = filteredItems.length || 0;
278
+ // Pagination (truncate if need)
279
+ let pageData = filteredItems;
280
+ if (opts) {
281
+ if ((opts.offset || 0) > 0) {
282
+ pageData = pageData.slice(opts.offset);
283
+ }
284
+ if (isNotNil(opts.size) && pageData.length > opts.size) {
285
+ pageData = pageData.slice(0, opts.size);
286
+ }
287
+ }
288
+ const result = {
289
+ data: pageData,
290
+ total
291
+ };
292
+ // Add fetch more capability, if total was fetched
293
+ const nextOffset = (opts && opts.offset || 0) + pageData.length;
294
+ if (nextOffset < total) {
295
+ result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
296
+ return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
297
+ }));
298
+ });
299
+ }
300
+ return result;
301
+ }
244
302
  function suggestFromStringArray(values, value, options) {
245
303
  value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
246
304
  if (isNilOrBlank(value))
@@ -1042,65 +1100,6 @@ const isMobile = (win) => {
1042
1100
  return _cache.mobile;
1043
1101
  };
1044
1102
 
1045
- function suggestFromArray(items, value, opts) {
1046
- if (isNotNil(value) && typeof value === 'object')
1047
- return { data: [value] };
1048
- value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
1049
- const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
1050
- if (!items) {
1051
- return { data: [], total: 0 };
1052
- }
1053
- // Filter items
1054
- let filteredItems = items;
1055
- if (isNotNilOrBlank(value)) {
1056
- // If wildcard, search using regexp
1057
- if (value.indexOf('*') !== -1) {
1058
- value = value.replace(/[*]+/g, '.*');
1059
- filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
1060
- }
1061
- // Else (no wildcard), search using startsWith
1062
- else {
1063
- filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);
1064
- }
1065
- }
1066
- // Exclude ids
1067
- if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
1068
- filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));
1069
- }
1070
- // Sort
1071
- if (!opts || opts.skipSort !== true) {
1072
- // Make to copy input items, before sorting (if not yet already done)
1073
- if (filteredItems === items)
1074
- filteredItems = filteredItems.slice();
1075
- // Sort by keys
1076
- filteredItems.sort(propertiesPathComparator(keys));
1077
- }
1078
- const total = filteredItems.length || 0;
1079
- // Pagination (truncate if need)
1080
- let pageData = filteredItems;
1081
- if (opts) {
1082
- if ((opts.offset || 0) > 0) {
1083
- pageData = pageData.slice(opts.offset);
1084
- }
1085
- if (isNotNil(opts.size) && pageData.length > opts.size) {
1086
- pageData = pageData.slice(0, opts.size);
1087
- }
1088
- }
1089
- const result = {
1090
- data: pageData,
1091
- total
1092
- };
1093
- // Add fetch more capability, if total was fetched
1094
- const nextOffset = (opts && opts.offset || 0) + pageData.length;
1095
- if (nextOffset < total) {
1096
- result.fetchMore = (_) => __awaiter(this, void 0, void 0, function* () {
1097
- return suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/, Object.assign(Object.assign({}, opts), { offset: nextOffset, skipSort: true, excludedIds: undefined // OPTIMISATION: already filtered
1098
- }));
1099
- });
1100
- }
1101
- return result;
1102
- }
1103
-
1104
1103
  class MatAutocompleteConfigHolder {
1105
1104
  constructor(options) {
1106
1105
  this.options = options;
@@ -2329,9 +2328,9 @@ class HighlightPipe {
2329
2328
  const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();
2330
2329
  const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);
2331
2330
  if (index !== -1) {
2332
- return value.substring(0, index - 1) +
2333
- '<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +
2334
- value.substring(index + cleanedSearchText.length);
2331
+ return value.substr(0, index - 1) +
2332
+ '<b>' + value.substr(index, cleanedSearchText.length) + '</b>' +
2333
+ value.substr(index + cleanedSearchText.length);
2335
2334
  }
2336
2335
  return value;
2337
2336
  }
@@ -2729,50 +2728,60 @@ class IsNotNilOrBlankPipe {
2729
2728
  return isNotNilOrBlank(value);
2730
2729
  }
2731
2730
  }
2731
+ IsNotNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNotNilOrBlankPipe_Factory() { return new IsNotNilOrBlankPipe(); }, token: IsNotNilOrBlankPipe, providedIn: "root" });
2732
2732
  IsNotNilOrBlankPipe.decorators = [
2733
2733
  { type: Pipe, args: [{
2734
2734
  name: 'isNotNilOrBlank'
2735
- },] }
2735
+ },] },
2736
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2736
2737
  ];
2737
2738
  class IsNilOrBlankPipe {
2738
2739
  transform(value) {
2739
2740
  return isNilOrBlank(value);
2740
2741
  }
2741
2742
  }
2743
+ IsNilOrBlankPipe.ɵprov = ɵɵdefineInjectable({ factory: function IsNilOrBlankPipe_Factory() { return new IsNilOrBlankPipe(); }, token: IsNilOrBlankPipe, providedIn: "root" });
2742
2744
  IsNilOrBlankPipe.decorators = [
2743
2745
  { type: Pipe, args: [{
2744
2746
  name: 'isNilOrBlank'
2745
- },] }
2747
+ },] },
2748
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2746
2749
  ];
2747
2750
  class ToStringPipe {
2748
2751
  transform(value) {
2749
2752
  return (value !== null && value !== undefined) ? value.toString() : '';
2750
2753
  }
2751
2754
  }
2755
+ ToStringPipe.ɵprov = ɵɵdefineInjectable({ factory: function ToStringPipe_Factory() { return new ToStringPipe(); }, token: ToStringPipe, providedIn: "root" });
2752
2756
  ToStringPipe.decorators = [
2753
2757
  { type: Pipe, args: [{
2754
2758
  name: 'toString'
2755
- },] }
2759
+ },] },
2760
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2756
2761
  ];
2757
2762
  class StrLengthPipe {
2758
2763
  transform(value) {
2759
2764
  return value && value.length || 0;
2760
2765
  }
2761
2766
  }
2767
+ StrLengthPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrLengthPipe_Factory() { return new StrLengthPipe(); }, token: StrLengthPipe, providedIn: "root" });
2762
2768
  StrLengthPipe.decorators = [
2763
2769
  { type: Pipe, args: [{
2764
2770
  name: 'strLength'
2765
- },] }
2771
+ },] },
2772
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2766
2773
  ];
2767
2774
  class StrIncludesPipe {
2768
2775
  transform(value, searchString, position) {
2769
2776
  return (value === null || value === void 0 ? void 0 : value.includes(searchString, position)) || false;
2770
2777
  }
2771
2778
  }
2779
+ StrIncludesPipe.ɵprov = ɵɵdefineInjectable({ factory: function StrIncludesPipe_Factory() { return new StrIncludesPipe(); }, token: StrIncludesPipe, providedIn: "root" });
2772
2780
  StrIncludesPipe.decorators = [
2773
2781
  { type: Pipe, args: [{
2774
2782
  name: 'strIncludes'
2775
- },] }
2783
+ },] },
2784
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2776
2785
  ];
2777
2786
 
2778
2787
  class TranslateContextService {
@@ -4223,7 +4232,8 @@ FormGetGroupPipe.decorators = [
4223
4232
  },] }
4224
4233
  ];
4225
4234
  class FormGetValuePipe {
4226
- constructor(_ref) {
4235
+ constructor(adapter, _ref) {
4236
+ this.adapter = adapter;
4227
4237
  this._ref = _ref;
4228
4238
  this.value = undefined;
4229
4239
  this._lastControl = null;
@@ -4288,6 +4298,7 @@ FormGetValuePipe.decorators = [
4288
4298
  },] }
4289
4299
  ];
4290
4300
  FormGetValuePipe.ctorParameters = () => [
4301
+ { type: FormErrorTranslator },
4291
4302
  { type: ChangeDetectorRef }
4292
4303
  ];
4293
4304
 
@@ -18202,18 +18213,6 @@ class InMemoryEntitiesService extends EntitiesService {
18202
18213
  return this._equalsFn(d1, d2);
18203
18214
  return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');
18204
18215
  }
18205
- /**
18206
- * Count data stored by the service (without hidden data).
18207
- * @param opts
18208
- */
18209
- get count() {
18210
- var _a;
18211
- return (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
18212
- }
18213
- get hiddenCount() {
18214
- var _a;
18215
- return ((_a = this._hiddenData) === null || _a === void 0 ? void 0 : _a.length) || 0;
18216
- }
18217
18216
  /* -- protected methods -- */
18218
18217
  filter(data, _filter, hiddenData) {
18219
18218
  // if filter is DataFilter instance, use its test function
@@ -21496,13 +21495,14 @@ class AppIconComponent {
21496
21495
  this.icon = value.icon;
21497
21496
  this.matIcon = value.matIcon;
21498
21497
  this.matSvgIcon = value.matSvgIcon;
21498
+ this.color = value.color;
21499
21499
  }
21500
21500
  ;
21501
21501
  }
21502
21502
  AppIconComponent.decorators = [
21503
21503
  { type: Component, args: [{
21504
21504
  selector: 'app-icon',
21505
- template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\">{{matIcon}}</mat-icon>\n</ng-template>\n\n"
21505
+ template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n [style.font-size.px]=\"height || width\"\n >{{matIcon}}</mat-icon>\n</ng-template>\n\n"
21506
21506
  },] }
21507
21507
  ];
21508
21508
  AppIconComponent.propDecorators = {
@@ -21510,6 +21510,8 @@ AppIconComponent.propDecorators = {
21510
21510
  matIcon: [{ type: Input }],
21511
21511
  matSvgIcon: [{ type: Input }],
21512
21512
  color: [{ type: Input }],
21513
+ height: [{ type: Input }],
21514
+ width: [{ type: Input }],
21513
21515
  ref: [{ type: Input }]
21514
21516
  };
21515
21517
 
@@ -25821,7 +25823,10 @@ AppInMemoryTable.propDecorators = {
25821
25823
  const SocialErrorCodes = {
25822
25824
  LOAD_USER_EVENTS_ERROR: 50000,
25823
25825
  SAVE_USER_EVENT_ERROR: 50001,
25824
- SEND_MESSAGE_ERROR: 50003
25826
+ COUNT_USER_EVENT_ERROR: 50002,
25827
+ SEND_MESSAGE_ERROR: 50003,
25828
+ SUBSCRIBE_USER_EVENTS_ERROR: 50005,
25829
+ SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
25825
25830
  };
25826
25831
 
25827
25832
  var UserEvent_1;
@@ -25836,16 +25841,23 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
25836
25841
  }
25837
25842
  asObject(opts) {
25838
25843
  const target = super.asObject(opts);
25844
+ target.creationDate = toDateISOString(this.creationDate);
25845
+ target.readDate = toDateISOString(this.readDate);
25839
25846
  // Serialize content
25840
25847
  if (typeof target.content === 'object') {
25841
25848
  target.content = JSON.stringify(target.content);
25842
25849
  }
25850
+ delete target.avatar;
25851
+ delete target.avatarIcon;
25852
+ delete target.icon;
25853
+ delete target.actions;
25843
25854
  return target;
25844
25855
  }
25845
25856
  fromObject(source) {
25846
25857
  Object.assign(this, source); // Copy all properties
25847
25858
  super.fromObject(source);
25848
25859
  this.creationDate = fromDateISOString(source.creationDate);
25860
+ this.readDate = fromDateISOString(source.readDate);
25849
25861
  try {
25850
25862
  // Deserialize content
25851
25863
  if (typeof source.content === 'string' && source.content.startsWith('{')) {
@@ -25864,6 +25876,52 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
25864
25876
  UserEvent = UserEvent_1 = __decorate([
25865
25877
  EntityClass({ typename: 'UserEventVO' })
25866
25878
  ], UserEvent);
25879
+ // @dynamic
25880
+ let UserEventFilter = class UserEventFilter extends EntityFilter {
25881
+ constructor() {
25882
+ super(...arguments);
25883
+ this.types = [];
25884
+ this.levels = [];
25885
+ this.issuers = [];
25886
+ this.recipients = [];
25887
+ this.startDate = null;
25888
+ this.excludeRead = false;
25889
+ }
25890
+ fromObject(source, opts) {
25891
+ super.fromObject(source, opts);
25892
+ this.types = source.types || [];
25893
+ this.levels = source.levels || [];
25894
+ this.issuers = source.issuers || [];
25895
+ this.recipients = source.recipients || [];
25896
+ this.startDate = fromDateISOString(source.startDate);
25897
+ this.excludeRead = source.excludeRead || false;
25898
+ }
25899
+ buildFilter() {
25900
+ const filterFns = super.buildFilter();
25901
+ if (isNotEmptyArray(this.types)) {
25902
+ filterFns.push(t => this.types.includes(t.type));
25903
+ }
25904
+ if (isNotEmptyArray(this.levels)) {
25905
+ filterFns.push(t => this.levels.includes(t.level));
25906
+ }
25907
+ if (isNotEmptyArray(this.issuers)) {
25908
+ filterFns.push(t => this.issuers.includes(t.issuer));
25909
+ }
25910
+ if (isNotEmptyArray(this.recipients)) {
25911
+ filterFns.push(t => this.recipients.includes(t.recipient));
25912
+ }
25913
+ if (isNotNil(this.startDate)) {
25914
+ filterFns.push(t => this.startDate.isSameOrBefore(t.creationDate));
25915
+ }
25916
+ if (this.excludeRead === true) {
25917
+ filterFns.push(t => isNil(t.readSignature)); // todo or t.signature ?
25918
+ }
25919
+ return filterFns;
25920
+ }
25921
+ };
25922
+ UserEventFilter = __decorate([
25923
+ EntityClass({ typename: 'UserEventFilterVO' })
25924
+ ], UserEventFilter);
25867
25925
 
25868
25926
  const UserEventFragments = {
25869
25927
  userEvent: gql `fragment UserEventFragment on UserEventVO {
@@ -25891,230 +25949,367 @@ const UserEventFragments = {
25891
25949
  }`
25892
25950
  };
25893
25951
 
25894
- // @dynamic
25895
- let UserEventFilter = class UserEventFilter extends EntityFilter {
25896
- constructor() {
25897
- super(...arguments);
25898
- this.issuer = null;
25899
- this.recipient = null;
25900
- }
25901
- fromObject(source, opts) {
25902
- super.fromObject(source, opts);
25903
- this.issuer = source.issuer;
25904
- this.recipient = source.recipient;
25905
- }
25906
- buildFilter() {
25907
- const filterFns = super.buildFilter();
25908
- // issuer
25909
- if (this.issuer) {
25910
- filterFns.push(t => (t.issuer === this.issuer));
25911
- }
25912
- if (this.recipient) {
25913
- filterFns.push(t => (t.recipient === this.recipient));
25914
- }
25915
- return filterFns;
25916
- }
25917
- };
25918
- UserEventFilter = __decorate([
25919
- EntityClass({ typename: 'UserEventFilterVO' })
25920
- ], UserEventFilter);
25921
- const SaveQuery = gql `
25922
- mutation SaveUserEvent($data: UserEventVOInput){
25923
- data: saveUserEvent(userEvent: $data){
25924
- ...UserEventFragment
25925
- }
25926
- }
25927
- ${UserEventFragments.userEvent}
25928
- `;
25929
- const LoadAllQuery = gql `
25930
- query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
25931
- data: userEvents(filter: $filter, page: $page){
25932
- ...LightUserEventFragment
25933
- }
25934
- }
25935
- ${UserEventFragments.lightUserEvent}
25936
- `;
25937
- const DeleteByIdsMutation = gql `
25938
- mutation DeleteUserEvents($ids:[Int]){
25939
- deleteUserEvents(ids: $ids)
25940
- }
25941
- `;
25942
- const LoadAllWithContentQuery = gql `
25943
- query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
25944
- data: userEvents(filter: $filter, page: $page){
25945
- ...UserEventFragment
25946
- }
25947
- }
25948
- ${UserEventFragments.userEvent}
25949
- `;
25950
- class UserEventService extends BaseGraphqlService {
25951
- constructor(graphql, accountService, network, translate, toastController, environment) {
25952
+ const moment$6 = momentImported;
25953
+ const UserEventServiceToken = new InjectionToken('UserEventService');
25954
+ class AbstractUserEventService extends BaseGraphqlService {
25955
+ constructor(graphql, accountService, network, translate, toastController, queries, mutations, subscriptions, environment) {
25952
25956
  super(graphql, environment);
25953
25957
  this.graphql = graphql;
25954
25958
  this.accountService = accountService;
25955
25959
  this.network = network;
25956
25960
  this.translate = translate;
25957
25961
  this.toastController = toastController;
25962
+ this.queries = queries;
25963
+ this.mutations = mutations;
25964
+ this.subscriptions = subscriptions;
25958
25965
  this.environment = environment;
25959
- this._userEventActions = [];
25966
+ this._count$ = new BehaviorSubject(0);
25967
+ this._subscriptions = new Subscription();
25968
+ this.listeners = [];
25969
+ this._logPrefix = '[user-event-service] ';
25960
25970
  // For DEV only
25961
- this._debug = environment && !environment.production;
25971
+ this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
25972
+ // listen login/logout
25973
+ this._subscriptions.add(accountService.onLogin.subscribe(() => __awaiter(this, void 0, void 0, function* () {
25974
+ const count = yield this.count(this.defaultFilter());
25975
+ if (count && this._debug) {
25976
+ console.debug(`${this._logPrefix}Received ${count} unread notifications`);
25977
+ }
25978
+ this._count$.next(count);
25979
+ })));
25980
+ }
25981
+ get userEventCount() {
25982
+ return this._count$.asObservable();
25983
+ }
25984
+ ngOnDestroy() {
25985
+ this._subscriptions.unsubscribe();
25962
25986
  }
25963
- /**
25964
- *
25965
- * @param offset
25966
- * @param size
25967
- * @param sortBy
25968
- * @param sortDirection
25969
- * @param filter
25970
- * @param options
25971
- * @deprecated use watchPage() instead
25972
- */
25973
25987
  watchAll(offset, size, sortBy, sortDirection, filter, options) {
25974
25988
  return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
25975
25989
  }
25976
25990
  watchPage(page, filter, options) {
25991
+ var _a;
25977
25992
  let now = this._debug && Date.now();
25978
25993
  //if (this._debug)
25979
- console.debug('[user-event-service] Loading user events...', filter);
25994
+ console.debug(`${this._logPrefix}Loading user events...`, filter);
25980
25995
  filter = this.asFilter(filter);
25981
25996
  // Force recipient to current issuer, if not admin and not specified
25982
- if (isNilOrBlank(filter.recipient) || !this.accountService.isAdmin()) {
25983
- const recipient = this.accountService.account.pubkey;
25984
- if (recipient !== filter.recipient) {
25997
+ if (isEmptyArray(filter.recipients) || !this.accountService.isAdmin()) {
25998
+ const recipient = this.defaultRecipient();
25999
+ if (!((_a = filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
25985
26000
  console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
25986
- filter.recipient = recipient;
26001
+ filter.recipients = [recipient];
25987
26002
  }
25988
26003
  }
25989
- const withContent = options && options.withContent === true;
26004
+ const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
25990
26005
  return this.mutableWatchQuery({
25991
26006
  queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
25992
- query: withContent ? LoadAllWithContentQuery : LoadAllQuery,
26007
+ query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
25993
26008
  variables: {
25994
- page: Object.assign(Object.assign({ sortBy: 'updateDate' }, page), { sortDirection: (page.sortDirection || 'DESC').toUpperCase() }),
26009
+ page: Object.assign({ sortBy: 'updateDate', sortDirection: 'desc' }, page),
25995
26010
  filter: filter && filter.asPodObject()
25996
26011
  },
25997
26012
  arrayFieldName: 'data',
25998
26013
  error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
25999
- fetchPolicy: options && options.fetchPolicy || undefined
26014
+ fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
26000
26015
  })
26001
26016
  .pipe(map(res => {
26002
- const data = res && (res.data || []).map(UserEvent.fromObject);
26017
+ const data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(this.processUserEvent);
26003
26018
  if (now) {
26004
- console.debug(`[user-event-service] ${data.length} user events loaded in ${Date.now() - now}ms`);
26019
+ console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);
26005
26020
  now = null;
26006
26021
  }
26022
+ const unreadCount = this.unreadEvents(data);
26007
26023
  return {
26008
26024
  data,
26009
- total: res && toNumber(res.total, data.length)
26025
+ total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
26010
26026
  };
26011
26027
  }));
26012
26028
  }
26013
- saveAll(data, options) {
26014
- return Promise.all(data
26015
- .map(entity => this.save(entity, options)));
26029
+ add(entity) {
26030
+ // TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
26031
+ entity = this.processUserEvent(entity);
26032
+ const withContent = !!entity.content;
26033
+ // Add user event locally
26034
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
26035
+ query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
26036
+ data: entity
26037
+ });
26038
+ // Update count
26039
+ this._count$.next(this._count$.value + 1);
26016
26040
  }
26017
- /**
26018
- * Save a userEvent entity
26019
- *
26020
- * @param entity
26021
- */
26022
- save(entity, options) {
26041
+ count(filter, options) {
26042
+ var _a;
26023
26043
  return __awaiter(this, void 0, void 0, function* () {
26024
- this.fillDefaultProperties(entity);
26025
- // Transform into json
26026
- const isNew = isNil(entity.id);
26027
- const json = entity.asObject();
26028
- const now = Date.now();
26044
+ if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
26045
+ console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
26046
+ return undefined;
26047
+ }
26048
+ if (!filter)
26049
+ throw new Error(`Missing argument 'filter'`);
26050
+ filter = this.asFilter(filter);
26029
26051
  if (this._debug)
26030
- console.debug(`[user-event-service] Saving user event...`, json);
26031
- yield this.graphql.mutate({
26032
- mutation: SaveQuery,
26052
+ console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
26053
+ const res = yield this.graphql.query({
26054
+ query: this.queries.count,
26033
26055
  variables: {
26034
- data: json
26056
+ filter: filter.asPodObject()
26035
26057
  },
26036
- error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
26037
- update: (proxy, { data }) => {
26038
- // Update entity
26039
- const savedEntity = data && data.data;
26040
- if (savedEntity) {
26041
- if (this._debug)
26042
- console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
26043
- this.copyIdAndUpdateDate(savedEntity, entity);
26044
- // Add to cache
26045
- if (isNew) {
26046
- this.insertIntoMutableCachedQueries(proxy, {
26047
- query: LoadAllQuery,
26048
- data: Object.assign(Object.assign({}, savedEntity), { content: null })
26049
- });
26050
- this.insertIntoMutableCachedQueries(proxy, {
26051
- query: LoadAllWithContentQuery,
26052
- data: savedEntity
26053
- });
26054
- }
26055
- }
26056
- }
26058
+ error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
26059
+ fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
26057
26060
  });
26058
- return entity;
26061
+ return res.total;
26059
26062
  });
26060
26063
  }
26061
- /**
26062
- * Save many trips
26063
- *
26064
- * @param entities
26065
- * @param opts
26066
- */
26067
- deleteAll(entities, opts) {
26068
- return __awaiter(this, void 0, void 0, function* () {
26069
- const ids = entities && entities
26070
- .map(t => t.id);
26071
- if (isEmptyArray(ids))
26072
- return; // stop, if nothing else to do
26064
+ listenChanges(filter, options) {
26065
+ var _a;
26066
+ if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
26067
+ console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
26068
+ return of();
26069
+ }
26070
+ if (!filter)
26071
+ throw new Error(`Missing argument 'filter'`);
26072
+ filter = this.asFilter(filter);
26073
+ const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
26074
+ if (this._debug)
26075
+ console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
26076
+ return this.graphql.subscribe({
26077
+ query: this.subscriptions.listenChanges,
26078
+ fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
26079
+ variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
26080
+ error: {
26081
+ code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
26082
+ message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
26083
+ }
26084
+ }).pipe(map(({ data }) => {
26085
+ if (data && this._debug)
26086
+ console.debug(`${this._logPrefix}Received new user events:`, data);
26087
+ const updatedData = data === null || data === void 0 ? void 0 : data.map(this.processUserEvent);
26088
+ // Update cache
26089
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
26090
+ query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
26091
+ data: updatedData
26092
+ });
26093
+ // update count
26094
+ this._count$.next(this.unreadEvents(updatedData));
26095
+ return updatedData;
26096
+ }));
26097
+ }
26098
+ delete(entity) {
26099
+ return __awaiter(this, void 0, void 0, function* () {
26100
+ if (!entity)
26101
+ return; // skip
26102
+ yield this.deleteAll([entity]);
26103
+ });
26104
+ }
26105
+ deleteAll(entities, opts) {
26106
+ return __awaiter(this, void 0, void 0, function* () {
26107
+ const ids = entities && entities
26108
+ .map(t => t.id);
26109
+ if (isEmptyArray(ids))
26110
+ return; // stop, if nothing else to do
26073
26111
  const now = Date.now();
26074
26112
  if (this._debug)
26075
- console.debug('[user-event-service] Deleting events... ids:', ids);
26113
+ console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
26076
26114
  yield this.graphql.mutate({
26077
- mutation: DeleteByIdsMutation,
26115
+ mutation: this.mutations.deleteByIds,
26078
26116
  variables: {
26079
26117
  ids
26080
26118
  },
26081
26119
  update: (proxy) => {
26082
26120
  // Remove from caches
26083
26121
  this.removeFromMutableCachedQueriesByIds(proxy, {
26084
- query: LoadAllQuery,
26122
+ query: this.queries.loadAll,
26085
26123
  ids
26086
26124
  });
26087
26125
  this.removeFromMutableCachedQueriesByIds(proxy, {
26088
- query: LoadAllWithContentQuery,
26126
+ query: this.queries.loadAllWithContent,
26089
26127
  ids
26090
26128
  });
26091
26129
  if (this._debug)
26092
- console.debug(`[user-event-service] Events deleted in ${Date.now() - now}ms`);
26130
+ console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
26093
26131
  }
26094
26132
  });
26095
26133
  });
26096
26134
  }
26097
- /**
26098
- * Delete userEvent entities
26099
- */
26100
- delete(data) {
26135
+ save(entity, options) {
26101
26136
  return __awaiter(this, void 0, void 0, function* () {
26102
- if (!data)
26103
- return; // skip
26104
- yield this.deleteAll([data]);
26137
+ this.fillDefaultProperties(entity);
26138
+ // Transform into json
26139
+ const isNew = isNil(entity.id);
26140
+ const json = entity.asObject();
26141
+ const now = Date.now();
26142
+ if (this._debug)
26143
+ console.debug(`${this._logPrefix}Saving user event...`, json);
26144
+ yield this.graphql.mutate({
26145
+ mutation: this.mutations.save,
26146
+ variables: {
26147
+ data: json
26148
+ },
26149
+ error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
26150
+ update: (proxy, { data }) => {
26151
+ // Update entity
26152
+ const savedEntity = data && data.data;
26153
+ if (savedEntity) {
26154
+ if (this._debug)
26155
+ console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
26156
+ this.copyIdAndUpdateDate(savedEntity, entity);
26157
+ // Add to cache
26158
+ if (isNew) {
26159
+ this.insertIntoMutableCachedQueries(proxy, {
26160
+ query: this.queries.loadAll,
26161
+ data: Object.assign(Object.assign({}, savedEntity), { content: null })
26162
+ });
26163
+ this.insertIntoMutableCachedQueries(proxy, {
26164
+ query: this.queries.loadAllWithContent,
26165
+ data: savedEntity
26166
+ });
26167
+ }
26168
+ }
26169
+ }
26170
+ });
26171
+ return entity;
26105
26172
  });
26106
26173
  }
26107
- listenChanges(id, options) {
26108
- // TODO
26109
- console.warn('TODO: implement listen changes on user events');
26110
- return of();
26174
+ saveAll(data, opts) {
26175
+ return Promise.all(data
26176
+ .map(entity => this.save(entity, opts)));
26111
26177
  }
26112
- registerAction(definition) {
26113
- console.info(`[user-event-service] Registering action ${definition.name} for ${definition.__typename}`);
26114
- this._userEventActions.push(definition);
26178
+ markAsRead(entity) {
26179
+ return __awaiter(this, void 0, void 0, function* () {
26180
+ // Get onRead listeners
26181
+ const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));
26182
+ if (onReadListeners.length) {
26183
+ for (const listener of onReadListeners) {
26184
+ yield listener.onRead(entity);
26185
+ }
26186
+ }
26187
+ else {
26188
+ // Use default
26189
+ yield this.defaultMarkAsRead(entity);
26190
+ }
26191
+ });
26115
26192
  }
26116
- getActionsByTypename(typename) {
26117
- return this._userEventActions.filter(def => def.__typename === typename);
26193
+ registerListener(listener) {
26194
+ if (!this.listeners)
26195
+ this.listeners = [];
26196
+ this.listeners.push(listener);
26197
+ }
26198
+ /* -- protected methods -- */
26199
+ processUserEvent(source) {
26200
+ // Convert json source to IUserEvent
26201
+ let target = this.fromObject(source);
26202
+ // Get listeners
26203
+ const listeners = (this.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
26204
+ for (const listener of listeners) {
26205
+ if (target) {
26206
+ target = listener.onReceived(target);
26207
+ }
26208
+ else {
26209
+ if (this._debug)
26210
+ console.debug(`${this._logPrefix}Event has been rejected by a listener`, source);
26211
+ break;
26212
+ }
26213
+ }
26214
+ return target;
26215
+ }
26216
+ defaultMarkAsRead(userEvent) {
26217
+ return __awaiter(this, void 0, void 0, function* () {
26218
+ if (!userEvent)
26219
+ throw new Error(`${this._logPrefix}Invalid event to save`);
26220
+ // set read date
26221
+ userEvent.readDate = moment$6();
26222
+ if (!userEvent.id || userEvent.id < 0) {
26223
+ if (this._debug)
26224
+ console.debug(`${this._logPrefix}Save local user event`);
26225
+ // TODO !!!!!!!!!!!!!
26226
+ }
26227
+ else {
26228
+ yield this.save(userEvent);
26229
+ }
26230
+ });
26231
+ }
26232
+ defaultFilter() {
26233
+ // By default
26234
+ return {
26235
+ recipients: [this.defaultRecipient()]
26236
+ };
26237
+ }
26238
+ defaultRecipient() {
26239
+ return this.accountService.person.pubkey;
26240
+ }
26241
+ fillDefaultProperties(entity) {
26242
+ }
26243
+ unreadEvents(events) {
26244
+ // default calculation on unread events from a list
26245
+ if (isEmptyArray(events))
26246
+ return undefined;
26247
+ const lastReadDate = events
26248
+ .filter(event => isNotNil(event.readDate))
26249
+ .reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
26250
+ return events
26251
+ .filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
26252
+ }
26253
+ copyIdAndUpdateDate(source, target) {
26254
+ EntityUtils.copyIdAndUpdateDate(source, target);
26255
+ }
26256
+ }
26257
+ AbstractUserEventService.decorators = [
26258
+ { type: Directive }
26259
+ ];
26260
+ AbstractUserEventService.ctorParameters = () => [
26261
+ { type: GraphqlService },
26262
+ { type: AccountService },
26263
+ { type: NetworkService },
26264
+ { type: TranslateService },
26265
+ { type: ToastController },
26266
+ { type: undefined },
26267
+ { type: undefined },
26268
+ { type: undefined },
26269
+ { type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
26270
+ ];
26271
+ const userEventQueries = {
26272
+ loadAll: gql `
26273
+ query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
26274
+ data: userEvents(filter: $filter, page: $page){
26275
+ ...LightUserEventFragment
26276
+ }
26277
+ }
26278
+ ${UserEventFragments.lightUserEvent}
26279
+ `,
26280
+ loadAllWithContent: gql `
26281
+ query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
26282
+ data: userEvents(filter: $filter, page: $page){
26283
+ ...UserEventFragment
26284
+ }
26285
+ }
26286
+ ${UserEventFragments.userEvent}
26287
+ `
26288
+ };
26289
+ const userEventMutations = {
26290
+ deleteByIds: gql `
26291
+ mutation DeleteUserEvents($ids:[Int]){
26292
+ deleteUserEvents(ids: $ids)
26293
+ }
26294
+ `,
26295
+ save: gql `
26296
+ mutation SaveUserEvent($data: UserEventVOInput){
26297
+ data: saveUserEvent(userEvent: $data){
26298
+ ...UserEventFragment
26299
+ }
26300
+ }
26301
+ ${UserEventFragments.userEvent}
26302
+ `
26303
+ };
26304
+ class UserEventService extends AbstractUserEventService {
26305
+ constructor(graphql, accountService, network, translate, toastController, environment) {
26306
+ super(graphql, accountService, network, translate, toastController, userEventQueries, userEventMutations, undefined, environment);
26307
+ this.graphql = graphql;
26308
+ this.accountService = accountService;
26309
+ this.network = network;
26310
+ this.translate = translate;
26311
+ this.toastController = toastController;
26312
+ this.environment = environment;
26118
26313
  }
26119
26314
  showToastErrorWithContext(opts) {
26120
26315
  return __awaiter(this, void 0, void 0, function* () {
@@ -26178,13 +26373,16 @@ class UserEventService extends BaseGraphqlService {
26178
26373
  }
26179
26374
  sendDataForDebug(data) {
26180
26375
  const userEvent = new UserEvent();
26181
- userEvent.eventType = UserEventTypes.DEBUG_DATA;
26376
+ userEvent.type = UserEventTypes.DEBUG_DATA;
26182
26377
  userEvent.content = this.convertObjectToString(data);
26183
26378
  return this.save(userEvent);
26184
26379
  }
26185
26380
  asFilter(filter) {
26186
26381
  return UserEventFilter.fromObject(filter);
26187
26382
  }
26383
+ fromObject(source) {
26384
+ return UserEvent.fromObject(source);
26385
+ }
26188
26386
  /* -- protected methods -- */
26189
26387
  convertObjectToString(data) {
26190
26388
  if (typeof data === 'string') {
@@ -26213,13 +26411,9 @@ class UserEventService extends BaseGraphqlService {
26213
26411
  // TODO: compute sign
26214
26412
  console.warn('TODO: sign user event before sending');
26215
26413
  }
26216
- copyIdAndUpdateDate(source, target) {
26217
- EntityUtils.copyIdAndUpdateDate(source, target);
26218
- }
26219
26414
  }
26220
- UserEventService.ɵprov = ɵɵdefineInjectable({ factory: function UserEventService_Factory() { return new UserEventService(ɵɵinject(GraphqlService), ɵɵinject(AccountService), ɵɵinject(NetworkService), ɵɵinject(TranslateService), ɵɵinject(ToastController), ɵɵinject(ENVIRONMENT, 8)); }, token: UserEventService, providedIn: "root" });
26221
26415
  UserEventService.decorators = [
26222
- { type: Injectable, args: [{ providedIn: 'root' },] }
26416
+ { type: Injectable }
26223
26417
  ];
26224
26418
  UserEventService.ctorParameters = () => [
26225
26419
  { type: GraphqlService },
@@ -26232,7 +26426,7 @@ UserEventService.ctorParameters = () => [
26232
26426
 
26233
26427
  const ICONS_MAP = {
26234
26428
  DEBUG_DATA: { matIcon: 'bug_report' },
26235
- INBOX_MESSAGE: { matIcon: 'mail' },
26429
+ INBOX_MESSAGE: { matIcon: 'mail' }
26236
26430
  };
26237
26431
  // TODO: refactor with a registration done by data service:
26238
26432
  // - userEventService.registerEventAction({__typename: 'TripVO', ...})
@@ -26298,7 +26492,7 @@ class UserEventsTable extends AppTable {
26298
26492
  }
26299
26493
  }));
26300
26494
  const filter = this.filter || new UserEventFilter();
26301
- filter.recipient = this.recipient;
26495
+ filter.recipients = [this.recipient];
26302
26496
  this.setFilter(filter, { emitEvent: true });
26303
26497
  }
26304
26498
  start() {
@@ -26311,17 +26505,17 @@ class UserEventsTable extends AppTable {
26311
26505
  });
26312
26506
  }
26313
26507
  getIcon(source) {
26314
- return ICONS_MAP[source.eventType];
26508
+ return ICONS_MAP[source.type];
26315
26509
  }
26316
26510
  getDetail(source) {
26317
26511
  if (!source)
26318
26512
  return undefined;
26319
- if (source.content && source.eventType === UserEventTypes.DEBUG_DATA) {
26513
+ if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
26320
26514
  const context = source.content.context;
26321
26515
  if (context && context.__typename) {
26322
- const actions = this.service.getActionsByTypename(context.__typename);
26516
+ // const actions = this.service.getActionsByTypename(context.__typename);
26323
26517
  return {
26324
- actions,
26518
+ // actions,
26325
26519
  title: source.content.error && source.content.error.message || source.content.message,
26326
26520
  description: source.content.error && source.content.error.details || undefined
26327
26521
  };
@@ -26333,11 +26527,11 @@ class UserEventsTable extends AppTable {
26333
26527
  doAction(action, row) {
26334
26528
  return __awaiter(this, void 0, void 0, function* () {
26335
26529
  const event = row.currentData;
26336
- const context = event.content && event.content.context;
26530
+ // const context = event.content && event.content.context;
26337
26531
  this.markAsLoading();
26338
26532
  if (action && typeof action.executeAction === 'function') {
26339
26533
  try {
26340
- let res = action.executeAction(event, context);
26534
+ let res = action.executeAction(event /*, context*/);
26341
26535
  res = (res instanceof Promise) ? yield res : res;
26342
26536
  }
26343
26537
  catch (err) {
@@ -26356,13 +26550,18 @@ UserEventsTable.decorators = [
26356
26550
  selector: 'app-user-events-table',
26357
26551
  template: "\n<!-- Type = options menu -->\n<mat-menu #optionsMenu=\"matMenu\" xPosition=\"after\">\n\n <!-- display columns -->\n <button mat-menu-item\n (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n</mat-menu>\n\n<!-- top header -->\n<mat-toolbar>\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <button mat-icon-button [title]=\"'COMMON.BTN_REFRESH'|translate\" (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button class=\"hidden-xs hidden-sm\" *ngIf=\"canDelete\"\n [title]=\"'COMMON.BTN_DELETE'|translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" hidden-xs hidden-sm hidden-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS'|translate\"\n [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n</mat-toolbar>\n\n\n<mat-table [dataSource]=\"dataSource\" matSort\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <!-- select -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <!-- id -->\n <ng-container matColumnDef=\"id\">\n <mat-header-cell *matHeaderCellDef mat-sort-header [class.cdk-visually-hidden]=\"!isAdmin\">\n <app-loading-spinner [loading]=\"loadingSubject|async\"><ion-label>#</ion-label></app-loading-spinner>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!isAdmin\">{{ row.currentData.id | mathAbs }}</mat-cell>\n </ng-container>\n\n <!-- creationDate -->\n <ng-container matColumnDef=\"creationDate\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.CREATION_DATE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ion-text>\n {{row.currentData.creationDate | dateFromNow }}<br/>\n <ion-text color=\"medium\"><small>{{row.currentData.creationDate | dateFormat: {time: true} }}</small></ion-text>\n </ion-text>\n </mat-cell>\n </ng-container>\n\n <!-- icon -->\n <ng-container matColumnDef=\"icon\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getIcon(row.currentData); let details\">\n <ion-icon slot=\"start\" *ngIf=\"details.icon\" [name]=\"details.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"details.matIcon\">{{details.matIcon}}</mat-icon>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- event type -->\n <ng-container matColumnDef=\"eventType\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.EVENT_TYPE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <span>{{'SOCIAL.USER_EVENT.TYPE_ENUM.' + row.currentData.eventType | translate}}</span>\n </mat-cell>\n </ng-container>\n\n <!-- message -->\n <ng-container matColumnDef=\"message\">\n <mat-header-cell *matHeaderCellDef>\n <ion-label translate>SOCIAL.USER_EVENT.MESSAGE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <ion-text [innerHTML]=\"details.title|translate\">\n </ion-text>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- Actions buttons column -->\n <ng-container matColumnDef=\"actions\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <button mat-icon-button color=\"light\"\n *ngFor=\"let action of details.actions\"\n [title]=\"action.title |translate\"\n [color]=\"action.color\"\n (click)=\"doAction(action, row)\">\n <ion-icon slot=\"start\" *ngIf=\"action.icon\" [name]=\"action.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"action.matIcon\">{{action.matIcon}}</mat-icon>\n </button>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n class=\"mat-row-disabled\"\n (click)=\"clickRow($event, row)\"></mat-row>\n\n</mat-table>\n\n<ion-row class=\"ion-no-padding\">\n <ion-col></ion-col>\n <ion-col class=\"ion-no-padding\" size=\"auto\">\n <mat-paginator [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n </ion-col>\n</ion-row>\n",
26358
26552
  changeDetection: ChangeDetectionStrategy.OnPush,
26553
+ providers: [
26554
+ {
26555
+ provide: UserEventServiceToken, useClass: UserEventService
26556
+ }
26557
+ ],
26359
26558
  styles: [".mat-header-row .mat-column-icon,.mat-row .mat-column-icon{max-width:40px;padding-left:0}.mat-header-row .mat-column-icon ion-icon,.mat-header-row .mat-column-icon mat-icon,.mat-row .mat-column-icon ion-icon,.mat-row .mat-column-icon mat-icon{font-size:1.2em;height:1.2em;width:1.2em}.mat-header-row .mat-column-creationDate,.mat-row .mat-column-creationDate{min-width:100px;max-width:120px}"]
26360
26559
  },] }
26361
26560
  ];
26362
26561
  UserEventsTable.ctorParameters = () => [
26363
26562
  { type: Injector },
26364
26563
  { type: AccountService },
26365
- { type: UserEventService },
26564
+ { type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
26366
26565
  { type: EntitiesStorage },
26367
26566
  { type: ChangeDetectorRef },
26368
26567
  { type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
@@ -26374,6 +26573,144 @@ UserEventsTable.propDecorators = {
26374
26573
  defaultSortDirection: [{ type: Input }]
26375
26574
  };
26376
26575
 
26576
+ class UserEventNotificationList {
26577
+ constructor(popoverController) {
26578
+ this.popoverController = popoverController;
26579
+ }
26580
+ ngOnInit() {
26581
+ }
26582
+ read($event, userEvent) {
26583
+ var _a;
26584
+ if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
26585
+ return;
26586
+ (_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
26587
+ }
26588
+ executeAction(action, userEvent) {
26589
+ // Execute then close popover
26590
+ action.executeAction(userEvent);
26591
+ this.dismiss();
26592
+ }
26593
+ dismiss() {
26594
+ this.popoverController.dismiss();
26595
+ }
26596
+ }
26597
+ UserEventNotificationList.decorators = [
26598
+ { type: Component, args: [{
26599
+ selector: 'app-user-event-notification-list',
26600
+ template: "\n<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!(userEvents | async)?.length\">\n {{'COMMON.NO_RESULT' | 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",
26601
+ styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
26602
+ },] }
26603
+ ];
26604
+ UserEventNotificationList.ctorParameters = () => [
26605
+ { type: PopoverController }
26606
+ ];
26607
+ UserEventNotificationList.propDecorators = {
26608
+ titleI18n: [{ type: Input }],
26609
+ userEvents: [{ type: Input }],
26610
+ readEvent: [{ type: Output }]
26611
+ };
26612
+
26613
+ class UserEventNotificationComponent {
26614
+ constructor(userEventService, accountService, popoverController, cd) {
26615
+ this.userEventService = userEventService;
26616
+ this.accountService = accountService;
26617
+ this.popoverController = popoverController;
26618
+ this.cd = cd;
26619
+ this.debug = false;
26620
+ this.titleI18n = 'SOCIAL.USER_EVENT.TITLE';
26621
+ this.disabled = false;
26622
+ this.userEventsSubject = new BehaviorSubject(undefined);
26623
+ this._subscriptions = new Subscription();
26624
+ this._logPrefix = '[user-event-notification] ';
26625
+ this._readEvent = new EventEmitter();
26626
+ }
26627
+ get count() {
26628
+ return this.userEventService.userEventCount.pipe(map(value => value === 0 ? undefined : value));
26629
+ }
26630
+ ngOnInit() {
26631
+ var _a;
26632
+ this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc", {
26633
+ recipients: [(_a = this.accountService.person) === null || _a === void 0 ? void 0 : _a.pubkey]
26634
+ }).subscribe(value => {
26635
+ const data = value.data;
26636
+ if (this.debug) {
26637
+ console.debug(`${this._logPrefix}Receiving user events`, data);
26638
+ }
26639
+ this.userEventsSubject.next(data);
26640
+ }));
26641
+ this._readEvent.subscribe(value => {
26642
+ this.userEventService.markAsRead(value);
26643
+ });
26644
+ }
26645
+ showList(event) {
26646
+ return __awaiter(this, void 0, void 0, function* () {
26647
+ const popover = yield this.popoverController.create({
26648
+ component: UserEventNotificationList,
26649
+ componentProps: {
26650
+ titleI18n: this.titleI18n,
26651
+ userEvents: this.userEventsSubject,
26652
+ readEvent: this._readEvent
26653
+ },
26654
+ backdropDismiss: true,
26655
+ keyboardClose: true,
26656
+ event,
26657
+ translucent: true,
26658
+ cssClass: 'popover-large'
26659
+ });
26660
+ yield popover.present();
26661
+ });
26662
+ }
26663
+ markForCheck() {
26664
+ this.cd.markForCheck();
26665
+ }
26666
+ ngOnDestroy() {
26667
+ if (this.debug) {
26668
+ console.debug(`${this._logPrefix}Destroying`);
26669
+ }
26670
+ this._subscriptions.unsubscribe();
26671
+ }
26672
+ }
26673
+ UserEventNotificationComponent.decorators = [
26674
+ { type: Component, args: [{
26675
+ selector: 'app-user-event-notification-component',
26676
+ 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",
26677
+ changeDetection: ChangeDetectionStrategy.OnPush,
26678
+ styles: [""]
26679
+ },] }
26680
+ ];
26681
+ UserEventNotificationComponent.ctorParameters = () => [
26682
+ { type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
26683
+ { type: AccountService },
26684
+ { type: PopoverController },
26685
+ { type: ChangeDetectorRef }
26686
+ ];
26687
+ UserEventNotificationComponent.propDecorators = {
26688
+ debug: [{ type: Input }],
26689
+ titleI18n: [{ type: Input }],
26690
+ disabled: [{ type: Input }]
26691
+ };
26692
+
26693
+ class UserEventModule {
26694
+ }
26695
+ UserEventModule.decorators = [
26696
+ { type: NgModule, args: [{
26697
+ imports: [
26698
+ CommonModule,
26699
+ CoreModule,
26700
+ SharedModule
26701
+ ],
26702
+ declarations: [
26703
+ UserEventsTable,
26704
+ UserEventNotificationComponent,
26705
+ UserEventNotificationList,
26706
+ ],
26707
+ exports: [
26708
+ UserEventsTable,
26709
+ UserEventNotificationComponent
26710
+ ]
26711
+ },] }
26712
+ ];
26713
+
26377
26714
  const MessageTypes = {
26378
26715
  INBOX_MESSAGE: 'INBOX_MESSAGE',
26379
26716
  EMAIL: 'EMAIL',
@@ -26585,9 +26922,9 @@ MessageForm.propDecorators = {
26585
26922
  canSelectType: [{ type: Input }]
26586
26923
  };
26587
26924
 
26588
- class SocialModule {
26925
+ class MessageModule {
26589
26926
  }
26590
- SocialModule.decorators = [
26927
+ MessageModule.decorators = [
26591
26928
  { type: NgModule, args: [{
26592
26929
  imports: [
26593
26930
  CommonModule,
@@ -26595,17 +26932,296 @@ SocialModule.decorators = [
26595
26932
  SharedModule
26596
26933
  ],
26597
26934
  declarations: [
26598
- UserEventsTable,
26599
26935
  MessageModal,
26600
26936
  MessageForm
26601
26937
  ],
26602
26938
  exports: [
26603
- UserEventsTable,
26604
26939
  MessageModal
26605
26940
  ]
26606
26941
  },] }
26607
26942
  ];
26608
26943
 
26944
+ var JobProgression_1;
26945
+ // todo use entity
26946
+ class Job {
26947
+ }
26948
+ // @dynamic
26949
+ let JobProgression = JobProgression_1 = class JobProgression extends Entity {
26950
+ constructor() {
26951
+ super(JobProgression_1.TYPENAME);
26952
+ }
26953
+ fromObject(source) {
26954
+ super.fromObject(source);
26955
+ this.message = source.message;
26956
+ this.current = source.current;
26957
+ this.total = source.total;
26958
+ }
26959
+ };
26960
+ JobProgression = JobProgression_1 = __decorate([
26961
+ EntityClass({ typename: 'JobProgressionVO' })
26962
+ ], JobProgression);
26963
+
26964
+ const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
26965
+ const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
26966
+ data: updateJobProgression(id: $id, interval: $interval) {
26967
+ id
26968
+ message
26969
+ current
26970
+ total
26971
+ updateDate
26972
+ }
26973
+ }`;
26974
+ class JobProgressionService extends BaseGraphqlService {
26975
+ constructor(graphql, environment) {
26976
+ super(graphql, environment);
26977
+ this.graphql = graphql;
26978
+ this.environment = environment;
26979
+ this._logPrefix = '[job-progression-service] ';
26980
+ // For DEV only
26981
+ this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
26982
+ }
26983
+ listenChanges(id, options) {
26984
+ if (isNil(id))
26985
+ throw new Error(`${this._logPrefix}Missing argument 'id'`);
26986
+ if (this._debug)
26987
+ console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
26988
+ return this.graphql.subscribe({
26989
+ query: jobProgressionSubscription,
26990
+ fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
26991
+ variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
26992
+ error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
26993
+ }).pipe(map(({ data }) => {
26994
+ const progression = data && JobProgression.fromObject(data);
26995
+ if (progression && this._debug)
26996
+ console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
26997
+ return progression;
26998
+ }));
26999
+ }
27000
+ }
27001
+ JobProgressionService.decorators = [
27002
+ { type: Injectable }
27003
+ ];
27004
+ JobProgressionService.ctorParameters = () => [
27005
+ { type: GraphqlService },
27006
+ { type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
27007
+ ];
27008
+
27009
+ class JobProgressionList {
27010
+ constructor() {
27011
+ }
27012
+ ngOnInit() {
27013
+ }
27014
+ }
27015
+ JobProgressionList.decorators = [
27016
+ { type: Component, args: [{
27017
+ selector: 'app-job-progression-list',
27018
+ 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 {{'COMMON.NO_RESULT' | 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",
27019
+ styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}"]
27020
+ },] }
27021
+ ];
27022
+ JobProgressionList.ctorParameters = () => [];
27023
+ JobProgressionList.propDecorators = {
27024
+ titleI18n: [{ type: Input }],
27025
+ jobProgressions: [{ type: Input }]
27026
+ };
27027
+
27028
+ class JobProgressionComponent {
27029
+ constructor(jobProgressionService, popoverController, cd) {
27030
+ this.jobProgressionService = jobProgressionService;
27031
+ this.popoverController = popoverController;
27032
+ this.cd = cd;
27033
+ this.debug = false;
27034
+ this.titleI18n = 'SOCIAL.JOB_PROGRESSION.TITLE';
27035
+ this.autoRemove = true;
27036
+ this.autoHide = false;
27037
+ this.autoHideDelay = 1000; // millisecond
27038
+ this.jobFinished = new EventEmitter();
27039
+ this.disabled = true;
27040
+ this.color = 'accent';
27041
+ this.mode = 'determinate';
27042
+ this.value = 0;
27043
+ this.jobProgressions = [];
27044
+ this._subscriptions = new Subscription();
27045
+ this._subscriptionsById = {};
27046
+ this._logPrefix = '[job-progression] ';
27047
+ }
27048
+ ngOnInit() {
27049
+ }
27050
+ addJob(id) {
27051
+ if (this.debug) {
27052
+ console.debug(`${this._logPrefix}Add job id=${id}`);
27053
+ }
27054
+ if (!!this.getProgression(id)) {
27055
+ console.warn(`${this._logPrefix}Job (id=${id}) already present`);
27056
+ return;
27057
+ }
27058
+ this.disabled = false;
27059
+ const sub = this.jobProgressionService.listenChanges(id)
27060
+ .pipe(filter(progression => {
27061
+ if (id !== progression.id) {
27062
+ console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
27063
+ return false;
27064
+ }
27065
+ return true;
27066
+ }), map(progression => {
27067
+ // Get current progression object
27068
+ const currentProgression = this.getProgression(id);
27069
+ if (!currentProgression) {
27070
+ // add it
27071
+ this.jobProgressions.push(progression);
27072
+ if (this.debug) {
27073
+ console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
27074
+ }
27075
+ }
27076
+ else {
27077
+ // update current
27078
+ Object.assign(currentProgression, progression);
27079
+ if (this.debug) {
27080
+ console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
27081
+ }
27082
+ }
27083
+ return progression;
27084
+ }))
27085
+ .subscribe(progression => {
27086
+ // update value
27087
+ this.updateValue();
27088
+ // job finished
27089
+ if (progression.total > 0 && progression.current == progression.total) {
27090
+ if (this.debug) {
27091
+ console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
27092
+ }
27093
+ // emit event
27094
+ this.jobFinished.emit(progression.id);
27095
+ if (this.autoRemove) {
27096
+ setTimeout(() => this.removeJob(progression.id), 1000);
27097
+ }
27098
+ }
27099
+ });
27100
+ this._subscriptionsById[id] = sub;
27101
+ this._subscriptions.add(sub);
27102
+ }
27103
+ removeJob(id) {
27104
+ if (this.debug) {
27105
+ console.debug(`${this._logPrefix}Remove job id=${id}`);
27106
+ }
27107
+ const sub = this._subscriptionsById[id];
27108
+ if (sub) {
27109
+ this._subscriptions.remove(sub);
27110
+ sub.unsubscribe();
27111
+ }
27112
+ const progression = this.getProgression(id);
27113
+ if (progression) {
27114
+ this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
27115
+ }
27116
+ this.updateValue();
27117
+ }
27118
+ getProgression(id) {
27119
+ return this.jobProgressions.find(progression => progression.id === id);
27120
+ }
27121
+ updateValue() {
27122
+ if (this.debug) {
27123
+ console.debug(`${this._logPrefix}Updating value`);
27124
+ }
27125
+ let value = 0;
27126
+ const nbProgression = arraySize(this.jobProgressions);
27127
+ let allIndeterminate = nbProgression > 0;
27128
+ this.jobProgressions.forEach(progression => {
27129
+ const indeterminate = progression.total === 0;
27130
+ allIndeterminate = allIndeterminate && indeterminate;
27131
+ if (!indeterminate) {
27132
+ value = value + progression.current * 100 / progression.total;
27133
+ }
27134
+ });
27135
+ this.value = nbProgression > 0 ? value / nbProgression : 0;
27136
+ this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
27137
+ if (this.debug) {
27138
+ console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
27139
+ }
27140
+ this.markForCheck();
27141
+ }
27142
+ showList(event) {
27143
+ return __awaiter(this, void 0, void 0, function* () {
27144
+ const popover = yield this.popoverController.create({
27145
+ component: JobProgressionList,
27146
+ componentProps: {
27147
+ titleI18n: this.titleI18n,
27148
+ jobProgressions: this.jobProgressions
27149
+ },
27150
+ backdropDismiss: true,
27151
+ keyboardClose: true,
27152
+ event,
27153
+ translucent: true,
27154
+ cssClass: 'popover-large'
27155
+ });
27156
+ yield popover.present();
27157
+ });
27158
+ }
27159
+ markForCheck() {
27160
+ this.cd.markForCheck();
27161
+ }
27162
+ ngOnDestroy() {
27163
+ if (this.debug) {
27164
+ console.debug(`${this._logPrefix}Destroying`);
27165
+ }
27166
+ this._subscriptions.unsubscribe();
27167
+ }
27168
+ }
27169
+ JobProgressionComponent.decorators = [
27170
+ { type: Component, args: [{
27171
+ selector: 'app-job-progression',
27172
+ template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n *ngIf=\"!autoHide || jobProgressions?.length\"\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",
27173
+ changeDetection: ChangeDetectionStrategy.OnPush,
27174
+ styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
27175
+ },] }
27176
+ ];
27177
+ JobProgressionComponent.ctorParameters = () => [
27178
+ { type: undefined, decorators: [{ type: Inject, args: [JobProgressionServiceToken,] }] },
27179
+ { type: PopoverController },
27180
+ { type: ChangeDetectorRef }
27181
+ ];
27182
+ JobProgressionComponent.propDecorators = {
27183
+ debug: [{ type: Input }],
27184
+ titleI18n: [{ type: Input }],
27185
+ autoRemove: [{ type: Input }],
27186
+ autoHide: [{ type: Input }],
27187
+ autoHideDelay: [{ type: Input }],
27188
+ jobFinished: [{ type: Output }]
27189
+ };
27190
+
27191
+ class JobModule {
27192
+ }
27193
+ JobModule.decorators = [
27194
+ { type: NgModule, args: [{
27195
+ imports: [
27196
+ CommonModule,
27197
+ SharedModule,
27198
+ TranslateModule.forChild(),
27199
+ ],
27200
+ declarations: [
27201
+ JobProgressionComponent,
27202
+ JobProgressionList
27203
+ ],
27204
+ exports: [
27205
+ JobProgressionComponent
27206
+ ]
27207
+ },] }
27208
+ ];
27209
+
27210
+ class SocialModule {
27211
+ }
27212
+ SocialModule.decorators = [
27213
+ { type: NgModule, args: [{
27214
+ imports: [
27215
+ CommonModule,
27216
+ CoreModule,
27217
+ SharedModule,
27218
+ UserEventModule,
27219
+ JobModule,
27220
+ MessageModule,
27221
+ ],
27222
+ },] }
27223
+ ];
27224
+
26609
27225
  const Mutations = {
26610
27226
  send: gql `mutation SendMessage($data: MessageVOInput){
26611
27227
  done: sendMessage(message: $data)
@@ -27418,13 +28034,13 @@ LatLongTestPage.ctorParameters = () => [
27418
28034
  { type: FormBuilder }
27419
28035
  ];
27420
28036
 
27421
- const moment$6 = momentImported;
28037
+ const moment$7 = momentImported;
27422
28038
  class SwipeTestPage {
27423
28039
  constructor(formBuilder, dateFormatPipe) {
27424
28040
  this.formBuilder = formBuilder;
27425
28041
  this.dateFormatPipe = dateFormatPipe;
27426
28042
  this.$dates = new BehaviorSubject(undefined);
27427
- this._today = moment$6().startOf('day');
28043
+ this._today = moment$7().startOf('day');
27428
28044
  this.form = formBuilder.group({
27429
28045
  empty: [null, Validators.required],
27430
28046
  date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
@@ -27437,7 +28053,7 @@ class SwipeTestPage {
27437
28053
  ngOnInit() {
27438
28054
  const dates = [];
27439
28055
  for (let d = 0; d < 7; d++) {
27440
- dates[d] = moment$6(this._today).add(d - 3, 'day');
28056
+ dates[d] = moment$7(this._today).add(d - 3, 'day');
27441
28057
  }
27442
28058
  this.$dates.next(dates);
27443
28059
  this.loadData();
@@ -27478,7 +28094,7 @@ SwipeTestPage.ctorParameters = () => [
27478
28094
  { type: DateFormatPipe }
27479
28095
  ];
27480
28096
 
27481
- const moment$7 = momentImported;
28097
+ const moment$8 = momentImported;
27482
28098
  class DateTimeTestPage {
27483
28099
  constructor(platform, formBuilder, cd) {
27484
28100
  this.platform = platform;
@@ -27510,7 +28126,7 @@ class DateTimeTestPage {
27510
28126
  // Load the form with data
27511
28127
  loadData() {
27512
28128
  return __awaiter(this, void 0, void 0, function* () {
27513
- const now = moment$7();
28129
+ const now = moment$8();
27514
28130
  const data = {
27515
28131
  empty: null,
27516
28132
  emptyRequired: null,
@@ -27756,7 +28372,7 @@ NumpadTestPage.ctorParameters = () => [
27756
28372
  { type: FormBuilder }
27757
28373
  ];
27758
28374
 
27759
- const moment$8 = momentImported;
28375
+ const moment$9 = momentImported;
27760
28376
  class DateTestPage {
27761
28377
  constructor(formBuilder, cd) {
27762
28378
  this.formBuilder = formBuilder;
@@ -27789,7 +28405,7 @@ class DateTestPage {
27789
28405
  // Load the form with data
27790
28406
  loadData() {
27791
28407
  return __awaiter(this, void 0, void 0, function* () {
27792
- const now = moment$8();
28408
+ const now = moment$9();
27793
28409
  const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
27794
28410
  const data = {
27795
28411
  empty: null,
@@ -28535,5 +29151,5 @@ CoreTestingModule.decorators = [
28535
29151
  * Generated bundle index. Do not edit.
28536
29152
  */
28537
29153
 
28538
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj, DateTestPage as ɵk, NumpadTestPage as ɵl, MatBadgeIconTestPage as ɵm, ToastTestingModule as ɵn, ToastTestingPage as ɵo };
29154
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, Job, JobProgression, JobProgressionComponent, JobProgressionService, JobProgressionServiceToken, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventNotificationComponent, UserEventService, UserEventServiceToken, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj, UserEventModule as ɵk, UserEventNotificationList as ɵl, JobModule as ɵm, JobProgressionList as ɵn, MessageModule as ɵo, DateTestPage as ɵp, NumpadTestPage as ɵq, MatBadgeIconTestPage as ɵr, ToastTestingModule as ɵs, ToastTestingPage as ɵt };
28539
29155
  //# sourceMappingURL=sumaris-net.ngx-components.js.map