@sumaris-net/ngx-components 1.22.11-rc11 → 1.22.11-rc14

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 (25) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +286 -125
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +1 -1
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/esm2015/src/app/admin/users/list/users.js +2 -3
  6. package/esm2015/src/app/core/menu/menu.component.js +1 -1
  7. package/esm2015/src/app/core/services/model/person.model.js +4 -2
  8. package/esm2015/src/app/shared/file/file.utils.js +1 -1
  9. package/esm2015/src/app/social/user-event/notification/user-event-notification.icon.js +3 -2
  10. package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +48 -24
  11. package/esm2015/src/app/social/user-event/testing/user-event.testing.js +53 -2
  12. package/esm2015/src/app/social/user-event/testing/user-event.testing.service.js +37 -28
  13. package/esm2015/src/app/social/user-event/user-event.model.js +1 -1
  14. package/esm2015/src/app/social/user-event/user-event.module.js +4 -2
  15. package/esm2015/src/app/social/user-event/user-event.service.js +59 -43
  16. package/fesm2015/sumaris-net.ngx-components.js +196 -96
  17. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/app/admin/users/list/users.d.ts +0 -2
  20. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +15 -11
  21. package/src/app/social/user-event/testing/user-event.testing.d.ts +9 -1
  22. package/src/app/social/user-event/testing/user-event.testing.service.d.ts +3 -2
  23. package/src/app/social/user-event/user-event.model.d.ts +1 -0
  24. package/src/app/social/user-event/user-event.service.d.ts +5 -4
  25. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -15009,7 +15009,9 @@
15009
15009
  return expectedProfileIndex !== -1 && PersonUtils.getMainProfileIndex(actualProfiles) <= expectedProfileIndex;
15010
15010
  };
15011
15011
  PersonUtils.personToString = function (obj) {
15012
- return obj && obj.id && (obj.lastName + ' ' + obj.firstName) || undefined;
15012
+ if (!obj || !obj.id)
15013
+ return undefined;
15014
+ return obj.lastName + ' ' + obj.firstName;
15013
15015
  };
15014
15016
  PersonUtils.personsToString = function (data, separator) {
15015
15017
  return (data || []).map(PersonUtils.personToString).join(separator || ', ');
@@ -24837,7 +24839,7 @@
24837
24839
  template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" [contentId]=\"contentId\">\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 [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\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\" style=\"width: 108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col>\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\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 </ion-col>\n\n <!-- Insertion headerBottomRight -->\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"headerBottomRight\"></ng-container>\n </ion-col>\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\n<ng-template #headerBottomRight>\n <ng-content select=\"[headerBottomRight]\"></ng-content>\n</ng-template>\n",
24838
24840
  animations: [fadeInAnimation],
24839
24841
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
24840
- 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-avatar:hover{background-color:var(--ion-color-secondary-shade);border:2px solid var(--ion-color-primary-shade)}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)}}"]
24842
+ 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 rgba(var(--ion-color-secondary-rgb),.5);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-avatar:hover{background-color:var(--ion-color-secondary-shade);border:2px solid var(--ion-color-secondary-shade)}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)}}"]
24841
24843
  },] }
24842
24844
  ];
24843
24845
  MenuComponent.ctorParameters = function () { return [
@@ -30329,27 +30331,35 @@
30329
30331
  fetchPolicy: (opts === null || opts === void 0 ? void 0 : opts.fetchPolicy) || 'cache-first',
30330
30332
  insertFilterFn: filter && filter.asFilterFn()
30331
30333
  })
30332
- .pipe(operators.map(function (res) {
30333
- var data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(function (value) { return _this.processUserEvent(value, _this); });
30334
- if (now) {
30335
- console.debug("" + _this._logPrefix + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30336
- now = null;
30337
- }
30338
- // Must re-order because of listenAllChanges result will add new event at the end
30339
- data = EntityUtils.sort(data, page.sortBy, page.sortDirection);
30340
- var result = {
30341
- data: data,
30342
- total: toNumber(res === null || res === void 0 ? void 0 : res.total, data.length)
30343
- };
30344
- // Add fetch more capability, if total was fetched
30345
- if (isNotNil(res.total)) {
30346
- var nextOffset_1 = (page.offset || 0) + data.length;
30347
- if (nextOffset_1 < result.total) {
30348
- result.fetchMore = function (_) { return _this.loadPage(Object.assign(Object.assign({}, page), { offset: nextOffset_1 }), filter, Object.assign(Object.assign({}, opts), { fetchPolicy: 'no-cache' })); };
30334
+ .pipe(operators.mergeMap(function (res) { return __awaiter(_this, void 0, void 0, function () {
30335
+ var data, result, nextOffset_1;
30336
+ var _this = this;
30337
+ return __generator(this, function (_b) {
30338
+ switch (_b.label) {
30339
+ case 0: return [4 /*yield*/, Promise.all(((res === null || res === void 0 ? void 0 : res.data) || []).map(function (value) { return _this.processUserEvent(value, _this); }))];
30340
+ case 1:
30341
+ data = _b.sent();
30342
+ if (now) {
30343
+ console.debug("" + this._logPrefix + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30344
+ now = null;
30345
+ }
30346
+ // Must re-order because of listenAllChanges result will add new event at the end
30347
+ data = EntityUtils.sort(data, page.sortBy, page.sortDirection);
30348
+ result = {
30349
+ data: data,
30350
+ total: toNumber(res === null || res === void 0 ? void 0 : res.total, data.length)
30351
+ };
30352
+ // Add fetch more capability, if total was fetched
30353
+ if (isNotNil(res.total)) {
30354
+ nextOffset_1 = (page.offset || 0) + data.length;
30355
+ if (nextOffset_1 < result.total) {
30356
+ result.fetchMore = function (_) { return _this.loadPage(Object.assign(Object.assign({}, page), { offset: nextOffset_1 }), filter, Object.assign(Object.assign({}, opts), { fetchPolicy: 'no-cache' })); };
30357
+ }
30358
+ }
30359
+ return [2 /*return*/, result];
30349
30360
  }
30350
- }
30351
- return result;
30352
- }));
30361
+ });
30362
+ }); }));
30353
30363
  };
30354
30364
  AbstractUserEventService.prototype.loadPage = function (page, filter, opts) {
30355
30365
  var _a;
@@ -30387,7 +30397,9 @@
30387
30397
  })];
30388
30398
  case 1:
30389
30399
  res = _b.sent();
30390
- data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(function (value) { return _this.processUserEvent(value, _this); });
30400
+ return [4 /*yield*/, Promise.all(((res === null || res === void 0 ? void 0 : res.data) || []).map(function (value) { return _this.processUserEvent(value, _this); }))];
30401
+ case 2:
30402
+ data = _b.sent();
30391
30403
  if (now)
30392
30404
  console.debug("" + this._logPrefix + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30393
30405
  // Must re-order because of listenAllChanges result will add new event at the end
@@ -30409,16 +30421,28 @@
30409
30421
  });
30410
30422
  };
30411
30423
  AbstractUserEventService.prototype.add = function (entity) {
30412
- // TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
30413
- entity = this.processUserEvent(entity);
30414
- var withContent = !!entity.content;
30415
- // Add user event locally
30416
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
30417
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30418
- data: entity
30424
+ return __awaiter(this, void 0, void 0, function () {
30425
+ var withContent;
30426
+ return __generator(this, function (_b) {
30427
+ switch (_b.label) {
30428
+ case 0: return [4 /*yield*/, this.processUserEvent(entity)];
30429
+ case 1:
30430
+ // TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
30431
+ entity = _b.sent();
30432
+ if (!entity)
30433
+ return [2 /*return*/]; // Rejected
30434
+ withContent = !!entity.content;
30435
+ // Add user event locally
30436
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
30437
+ query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30438
+ data: entity
30439
+ });
30440
+ // Update count
30441
+ this._countSubject.next(this._countSubject.value + 1);
30442
+ return [2 /*return*/];
30443
+ }
30444
+ });
30419
30445
  });
30420
- // Update count
30421
- this._countSubject.next(this._countSubject.value + 1);
30422
30446
  };
30423
30447
  AbstractUserEventService.prototype.count = function (filter, options) {
30424
30448
  var _a;
@@ -30485,7 +30509,7 @@
30485
30509
  return total;
30486
30510
  }));
30487
30511
  };
30488
- AbstractUserEventService.prototype.listenAllChanges = function (filter, options) {
30512
+ AbstractUserEventService.prototype.listenAllChanges = function (filter, opts) {
30489
30513
  var _this = this;
30490
30514
  var _a;
30491
30515
  if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenAllChanges)) {
@@ -30495,28 +30519,40 @@
30495
30519
  if (!filter)
30496
30520
  filter = this.defaultFilter();
30497
30521
  filter = this.asFilter(filter);
30498
- var withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
30522
+ var withContent = (opts === null || opts === void 0 ? void 0 : opts.withContent) === true;
30499
30523
  if (this._debug)
30500
30524
  console.debug(this._logPrefix + "[WS] Listening changes for user events with filter:", filter);
30501
30525
  return this.graphql.subscribe({
30502
30526
  query: this.subscriptions.listenAllChanges,
30503
- fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
30504
- variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
30527
+ fetchPolicy: opts === null || opts === void 0 ? void 0 : opts.fetchPolicy,
30528
+ variables: { filter: filter.asPodObject(), interval: toNumber(opts === null || opts === void 0 ? void 0 : opts.interval, 10) },
30505
30529
  error: {
30506
30530
  code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
30507
30531
  message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
30508
30532
  }
30509
- }).pipe(operators.map(function (_b) {
30533
+ }).pipe(operators.mergeMap(function (_b) {
30510
30534
  var data = _b.data;
30511
- if (data && _this._debug)
30512
- console.debug(_this._logPrefix + "Received new user events:", data);
30513
- var updatedData = data === null || data === void 0 ? void 0 : data.map(function (value) { return _this.processUserEvent(value, _this); });
30514
- // Update cache
30515
- _this.insertIntoMutableCachedQueries(_this.graphql.cache, {
30516
- query: withContent ? _this.queries.loadAllWithContent : _this.queries.loadAll,
30517
- data: updatedData
30518
- });
30519
- return updatedData;
30535
+ return __awaiter(_this, void 0, void 0, function () {
30536
+ var _this = this;
30537
+ return __generator(this, function (_b) {
30538
+ switch (_b.label) {
30539
+ case 0:
30540
+ if (data && this._debug)
30541
+ console.debug(this._logPrefix + "Received new user events:", data);
30542
+ // Update cache (will update watchAll queries)
30543
+ if (isNotEmptyArray(data)) {
30544
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
30545
+ query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30546
+ data: data
30547
+ });
30548
+ }
30549
+ if (!(!opts || opts.toEntity !== false)) return [3 /*break*/, 2];
30550
+ return [4 /*yield*/, Promise.all((data || []).map(function (value) { return _this.processUserEvent(value, _this); }))];
30551
+ case 1: return [2 /*return*/, _b.sent()];
30552
+ case 2: return [2 /*return*/, data];
30553
+ }
30554
+ });
30555
+ });
30520
30556
  }));
30521
30557
  };
30522
30558
  AbstractUserEventService.prototype.delete = function (entity) {
@@ -30766,33 +30802,60 @@
30766
30802
  this._listenSubscription = undefined;
30767
30803
  };
30768
30804
  AbstractUserEventService.prototype.processUserEvent = function (source, that) {
30769
- var e_3, _b;
30770
- that = that || this;
30771
- // Convert json source to IUserEvent
30772
- var target = that.fromObject(source);
30773
- // Get listeners
30774
- var listeners = (that.listeners || []).filter(function (listener) { return listener.onReceived; }).filter(function (listener) { return listener.accept(target); });
30775
- try {
30776
- for (var listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next(); !listeners_1_1.done; listeners_1_1 = listeners_1.next()) {
30777
- var listener = listeners_1_1.value;
30778
- if (target) {
30779
- target = listener.onReceived(target);
30780
- }
30781
- else {
30782
- if (that._debug)
30783
- console.debug(that._logPrefix + "Event has been rejected by a listener", source);
30784
- break;
30805
+ return __awaiter(this, void 0, void 0, function () {
30806
+ var target, listeners, listeners_1, listeners_1_1, listener, res, _b, e_3_1;
30807
+ var e_3, _c;
30808
+ return __generator(this, function (_d) {
30809
+ switch (_d.label) {
30810
+ case 0:
30811
+ that = that || this;
30812
+ target = that.fromObject(source);
30813
+ listeners = (that.listeners || [])
30814
+ .filter(function (listener) { return !!listener.onReceived; })
30815
+ .filter(function (listener) { return listener.accept(target); });
30816
+ _d.label = 1;
30817
+ case 1:
30818
+ _d.trys.push([1, 9, 10, 11]);
30819
+ listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next();
30820
+ _d.label = 2;
30821
+ case 2:
30822
+ if (!!listeners_1_1.done) return [3 /*break*/, 8];
30823
+ listener = listeners_1_1.value;
30824
+ if (!target) return [3 /*break*/, 6];
30825
+ res = listener.onReceived(target);
30826
+ if (!(res instanceof Promise)) return [3 /*break*/, 4];
30827
+ return [4 /*yield*/, res];
30828
+ case 3:
30829
+ _b = _d.sent();
30830
+ return [3 /*break*/, 5];
30831
+ case 4:
30832
+ _b = res;
30833
+ _d.label = 5;
30834
+ case 5:
30835
+ target = _b;
30836
+ return [3 /*break*/, 7];
30837
+ case 6:
30838
+ if (that._debug)
30839
+ console.debug(that._logPrefix + "Event has been rejected by a listener", source);
30840
+ return [3 /*break*/, 8];
30841
+ case 7:
30842
+ listeners_1_1 = listeners_1.next();
30843
+ return [3 /*break*/, 2];
30844
+ case 8: return [3 /*break*/, 11];
30845
+ case 9:
30846
+ e_3_1 = _d.sent();
30847
+ e_3 = { error: e_3_1 };
30848
+ return [3 /*break*/, 11];
30849
+ case 10:
30850
+ try {
30851
+ if (listeners_1_1 && !listeners_1_1.done && (_c = listeners_1.return)) _c.call(listeners_1);
30852
+ }
30853
+ finally { if (e_3) throw e_3.error; }
30854
+ return [7 /*endfinally*/];
30855
+ case 11: return [2 /*return*/, target];
30785
30856
  }
30786
- }
30787
- }
30788
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
30789
- finally {
30790
- try {
30791
- if (listeners_1_1 && !listeners_1_1.done && (_b = listeners_1.return)) _b.call(listeners_1);
30792
- }
30793
- finally { if (e_3) throw e_3.error; }
30794
- }
30795
- return target;
30857
+ });
30858
+ });
30796
30859
  };
30797
30860
  AbstractUserEventService.prototype.defaultMarkAsRead = function (userEvents) {
30798
30861
  var _a;
@@ -30885,17 +30948,28 @@
30885
30948
  this.popoverController = popoverController;
30886
30949
  this.settings = settings;
30887
30950
  this.userEventService = userEventService;
30888
- this.subscriptions = new rxjs.Subscription();
30889
- this._fetchingMore = false;
30951
+ this._subscriptions = new rxjs.Subscription();
30952
+ this._$pageSize = new rxjs.BehaviorSubject(20);
30953
+ this.fetchingMore = false;
30954
+ this.$items = new rxjs.BehaviorSubject(undefined);
30955
+ this.$itemCount = new rxjs.BehaviorSubject(undefined);
30890
30956
  this.debug = false;
30891
- this.pageSize = 10;
30892
30957
  this.sortBy = 'creationDate';
30893
30958
  this.sortDirection = 'desc';
30894
30959
  this.enableInfiniteScroll = true;
30895
- this.$items = new rxjs.BehaviorSubject(undefined);
30896
- this.$itemCount = new rxjs.BehaviorSubject(undefined);
30897
30960
  this.mobile = ((_a = this.settings) === null || _a === void 0 ? void 0 : _a.mobile) || false;
30898
30961
  }
30962
+ Object.defineProperty(UserEventNotificationList.prototype, "pageSize", {
30963
+ get: function () {
30964
+ return this._$pageSize.value;
30965
+ },
30966
+ set: function (value) {
30967
+ if (value > 0 && value !== this._$pageSize.value)
30968
+ this._$pageSize.next(value);
30969
+ },
30970
+ enumerable: false,
30971
+ configurable: true
30972
+ });
30899
30973
  Object.defineProperty(UserEventNotificationList.prototype, "canFetchMore", {
30900
30974
  get: function () {
30901
30975
  return this.enableInfiniteScroll && !!this._fetchMoreFn;
@@ -30907,27 +30981,31 @@
30907
30981
  var _this = this;
30908
30982
  // Watch all user events
30909
30983
  if (this.userEventService) {
30910
- this.subscriptions.add(this.userEventService
30911
- .watchAll(0, this.pageSize, this.sortBy, this.sortDirection, this.filter)
30984
+ this._subscriptions.add(this._$pageSize.pipe(operators.distinctUntilChanged(), operators.switchMap(function (pageSize) { return _this.userEventService.watchAll(0, pageSize, _this.sortBy, _this.sortDirection, _this.filter); }))
30912
30985
  .subscribe(function (result) {
30913
30986
  var _a;
30914
30987
  if (_this.debug)
30915
- console.debug("[user-event-notification-list] receiving " + result.total + " user events", result.data);
30988
+ console.debug("[user-event-notification-list] Receiving " + result.total + " user events", result.data);
30916
30989
  _this.$items.next(result.data);
30917
30990
  _this.$itemCount.next(result.total || ((_a = result.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
30918
30991
  _this._fetchMoreFn = result.fetchMore;
30992
+ _this.fetchingMore = false; // Allow to refetch more
30919
30993
  _this.markForCheck();
30920
30994
  }));
30921
30995
  // Listen changes
30922
- this.subscriptions.add(this.userEventService.listenAllChanges(undefined)
30996
+ this._subscriptions.add(this.userEventService.listenAllChanges(this.filter)
30923
30997
  .subscribe(function (data) {
30924
30998
  if (_this.debug)
30925
- console.debug("[user-event-notification-list] receiving " + data.length + " new user events", data);
30999
+ console.debug("[user-event-notification-list] Receiving " + data.length + " new user events (by WS)", data);
30926
31000
  }));
31001
+ if (this.enableInfiniteScroll)
31002
+ this.initInfiniteScroll();
30927
31003
  }
30928
31004
  };
30929
31005
  UserEventNotificationList.prototype.ngOnDestroy = function () {
30930
- this.subscriptions.unsubscribe();
31006
+ this._subscriptions.unsubscribe();
31007
+ this.$items.complete();
31008
+ this.$itemCount.complete();
30931
31009
  };
30932
31010
  UserEventNotificationList.prototype.click = function (event, userEvent) {
30933
31011
  if (!userEvent)
@@ -30989,65 +31067,77 @@
30989
31067
  };
30990
31068
  UserEventNotificationList.prototype.dismiss = function () {
30991
31069
  this.popoverController.dismiss();
31070
+ // Reset counter (need if event has been received while popover if open)
31071
+ this.userEventService.resetCount();
30992
31072
  };
30993
31073
  UserEventNotificationList.prototype.fetchMore = function (event) {
30994
31074
  var _a;
30995
31075
  return __awaiter(this, void 0, void 0, function () {
30996
- var result, data, err_2;
31076
+ var fetchMoreFn, result, data, err_2;
30997
31077
  return __generator(this, function (_b) {
30998
31078
  switch (_b.label) {
30999
31079
  case 0:
31000
- if (!this._fetchMoreFn || this._fetchingMore)
31080
+ if (!this._fetchMoreFn || this.fetchingMore)
31001
31081
  return [2 /*return*/];
31002
31082
  console.debug('[user-event-notification-list] Fetching more notifications...', event);
31003
- this._fetchingMore = true;
31083
+ this.fetchingMore = true;
31084
+ fetchMoreFn = this._fetchMoreFn;
31004
31085
  _b.label = 1;
31005
31086
  case 1:
31006
31087
  _b.trys.push([1, 3, 4, 5]);
31007
- return [4 /*yield*/, this._fetchMoreFn()];
31088
+ return [4 /*yield*/, fetchMoreFn()];
31008
31089
  case 2:
31009
31090
  result = _b.sent();
31010
31091
  data = __spread((this.$items.value || []), result.data);
31011
31092
  // Remove duplication (e.g. when new user event was added by subscription)
31012
31093
  data = removeDuplicatesFromArray(data, 'id');
31094
+ // fetch more changes (e.g. if watchAll observable as been refreshed)
31095
+ if (fetchMoreFn !== this._fetchMoreFn)
31096
+ return [2 /*return*/]; // Skip
31013
31097
  this.$items.next(data);
31014
31098
  this.$itemCount.next(result.total || ((_a = result.data) === null || _a === void 0 ? void 0 : _a.length) || 0);
31015
31099
  this._fetchMoreFn = result.fetchMore;
31100
+ // Update the page size, to keep same scroll height, after the next refresh
31101
+ this.pageSize = Math.max(this.pageSize, data.length);
31016
31102
  return [3 /*break*/, 5];
31017
31103
  case 3:
31018
31104
  err_2 = _b.sent();
31019
31105
  console.error(err_2);
31020
- this._fetchMoreFn = undefined;
31106
+ this._fetchMoreFn = undefined; // Forget the function
31021
31107
  return [3 /*break*/, 5];
31022
31108
  case 4:
31023
31109
  this.markForCheck();
31024
- this._fetchingMore = false;
31110
+ this.fetchingMore = false;
31025
31111
  return [7 /*endfinally*/];
31026
31112
  case 5: return [2 /*return*/];
31027
31113
  }
31028
31114
  });
31029
31115
  });
31030
31116
  };
31031
- UserEventNotificationList.prototype._initInfiniteScroll = function (threshold) {
31117
+ UserEventNotificationList.prototype.trackByFn = function (index, item) {
31118
+ return item.id;
31119
+ };
31120
+ UserEventNotificationList.prototype.initInfiniteScroll = function (threshold) {
31032
31121
  return __awaiter(this, void 0, void 0, function () {
31033
31122
  var panel;
31034
31123
  var _this = this;
31035
31124
  return __generator(this, function (_b) {
31036
31125
  switch (_b.label) {
31037
31126
  case 0:
31127
+ console.debug('[user-event-notification-list] Init infinite loop');
31038
31128
  if (this._fetchMoreSubscription)
31039
31129
  this._fetchMoreSubscription.unsubscribe();
31040
31130
  threshold = threshold || (this.mobile ? '15%' : '2%');
31041
- return [4 /*yield*/, waitFor(function () { return !!_this.ionContent; })];
31131
+ return [4 /*yield*/, waitFor(function () { return !!_this.ionContent; }, { dueTime: 250, timeout: 1000 })];
31042
31132
  case 1:
31043
31133
  _b.sent();
31044
31134
  return [4 /*yield*/, this.ionContent.getScrollElement()];
31045
31135
  case 2:
31046
31136
  panel = _b.sent();
31047
31137
  // Trigger fetch more, end end scroll reached
31048
- this._fetchMoreSubscription = fromScrollEndEvent(panel, threshold, 250 /*force to check when no scrollbar - e.g. in large screen*/)
31138
+ this._fetchMoreSubscription = this.$items.pipe(operators.debounceTime(250), operators.filter(function () { return _this.canFetchMore; }), operators.switchMap(function () { return fromScrollEndEvent(panel, threshold, 250 /*force to check when no scrollbar - e.g. in large screen*/); }))
31049
31139
  .subscribe(function () { return _this.fetchMore(); });
31050
- this.subscriptions.add(this._fetchMoreSubscription);
31140
+ this._subscriptions.add(this._fetchMoreSubscription);
31051
31141
  return [2 /*return*/];
31052
31142
  }
31053
31143
  });
@@ -31061,9 +31151,9 @@
31061
31151
  UserEventNotificationList.decorators = [
31062
31152
  { type: i0.Component, args: [{
31063
31153
  selector: 'app-user-event-notification-list',
31064
- template: "<ion-content>\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-col class=\"top-action\" *ngIf=\"$items|async|isNotEmptyArray\">\n <ion-text color=\"primary\">\n <a (click)=\"markAllAsRead($event)\">{{'SOCIAL.USER_EVENT.NOTIFICATION.READ_ALL' | translate}}</a>\n </ion-text>\n </ion-col>\n </ion-row>\n\n <ion-item\n *ngFor=\"let item of $items | async; last as last\"\n [lines]=\"last ? 'none' : undefined\"\n [class.unread]=\"!item.readDate\"\n [class.tappable]=\"item.actions|arrayFilter:isDefaultAction|isNotEmptyArray\"\n (click)=\"click($event, item)\">\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"item.avatar; else avatarIcon\" src=\"{{ item.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"item.avatarIcon\"\n [ref]=\"item.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 message\">\n <ion-row>\n <ion-col size=\"12\">\n <p [class.unread]=\"!item.readDate\" [innerHTML]=\"item.message\"></p>\n </ion-col>\n </ion-row>\n\n <!-- date -->\n <ion-row>\n <ion-col size=\"12\">\n <app-icon\n *ngIf=\"item.icon\"\n [ref]=\"item.icon\"\n height=\"16\"\n width=\"16\"\n style=\"vertical-align: sub; margin-right: 3px\"\n ></app-icon>\n <small>\n <span>{{item.creationDate|dateFromNow}}</span>\n <span style=\"color: gray\">{{ ' | ' + (item.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n\n <!-- actions -->\n <ion-row *ngIf=\"item.actions|isNotEmptyArray\">\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngFor=\"let action of item.actions\">\n <a *ngIf=\"!action.default\" class=\"action\" (click)=\"executeAction($event, action, item)\" [title]=\"(action.title || action.name) |translate\">\n <app-icon *ngIf=\"action.iconRef\" slot=\"start\" height=\"20\" width=\"20\" [ref]=\"action.iconRef\"></app-icon>\n <span>{{ action.name | translate }}</span>\n </a>\n </ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <mat-icon slot=\"end\" *ngIf=\"item.actions|arrayFilter: isDefaultAction|isNotEmptyArray\">chevron_right</mat-icon>\n </ion-item>\n\n <!-- loading -->\n <ion-item *ngIf=\"!($items|async); else noResult\" lines=\"none\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </ion-item>\n\n <!-- no result -->\n <ng-template #noResult>\n <ion-item *ngIf=\"$items|async|isEmptyArray\" lines=\"none\">\n <ion-text color=\"dark\" class=\"text-italic\">{{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}</ion-text>\n </ion-item>\n </ng-template>\n\n <!-- Loading more spinner -->\n <ion-item *ngIf=\"canFetchMore\" (ngInit)=\"_initInfiniteScroll()\" lines=\"none\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </ion-item>\n\n <!-- footer -->\n <ion-row *ngIf=\"$itemCount|async; let count\"\n class=\"ion-list-footer column\">\n <ion-col>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n </ion-list>\n</ion-content>\n",
31154
+ template: "<ion-content>\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-col class=\"top-action\" *ngIf=\"$items|async|isNotEmptyArray\">\n <ion-text color=\"primary\">\n <a (click)=\"markAllAsRead($event)\">{{'SOCIAL.USER_EVENT.NOTIFICATION.READ_ALL' | translate}}</a>\n </ion-text>\n </ion-col>\n </ion-row>\n\n <ion-item\n *ngFor=\"let item of $items | async; trackBy: trackByFn; last as last\"\n [lines]=\"last ? 'none' : undefined\"\n [class.unread]=\"!item.readDate\"\n [class.tappable]=\"item.actions|arrayFilter:isDefaultAction|isNotEmptyArray\"\n (click)=\"click($event, item)\">\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"item.avatar; else avatarIcon\" src=\"{{ item.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"item.avatarIcon; else generateIcon\"\n [ref]=\"item.avatarIcon\"\n height=\"40\"\n width=\"40\"\n ></app-icon>\n </ng-template>\n\n <ng-template #generateIcon>\n <div class=\"avatar\" *ngIf=\"item.avatarJdenticon\">\n <svg width=\"40\" width=\"40\" [data-jdenticon-value]=\"item.avatarJdenticon\"></svg>\n </div>\n </ng-template>\n\n </ion-avatar>\n\n <ion-grid class=\"ion-no-margin ion-no-padding message\">\n <ion-row>\n <ion-col size=\"12\">\n <p [class.unread]=\"!item.readDate\" [innerHTML]=\"item.message\"></p>\n </ion-col>\n </ion-row>\n\n <!-- date -->\n <ion-row>\n <ion-col size=\"12\">\n <app-icon\n *ngIf=\"item.icon\"\n [ref]=\"item.icon\"\n height=\"16\"\n width=\"16\"\n style=\"vertical-align: sub; margin-right: 3px\"\n ></app-icon>\n <small>\n <span>{{item.creationDate|dateFromNow}}</span>\n <span style=\"color: gray\">{{ ' | ' + (item.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n\n <!-- actions -->\n <ion-row *ngIf=\"item.actions|isNotEmptyArray\">\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngFor=\"let action of item.actions\">\n <a *ngIf=\"!action.default\" class=\"action\" (click)=\"executeAction($event, action, item)\" [title]=\"(action.title || action.name) |translate\">\n <app-icon *ngIf=\"action.iconRef\" slot=\"start\" height=\"20\" width=\"20\" [ref]=\"action.iconRef\"></app-icon>\n <span>{{ action.name | translate }}</span>\n </a>\n </ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <mat-icon slot=\"end\" *ngIf=\"item.actions|arrayFilter: isDefaultAction|isNotEmptyArray\">chevron_right</mat-icon>\n </ion-item>\n\n <!-- loading -->\n <ng-container *ngIf=\"!($items|async); else notLoading\">\n <ng-container *ngTemplateOutlet=\"loadingItem\"></ng-container>\n </ng-container>\n\n <ng-template #notLoading>\n <!-- no result -->\n <ion-item *ngIf=\"$items|async|isEmptyArray\" lines=\"none\">\n <ion-text color=\"dark\" class=\"text-italic\">{{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}</ion-text>\n </ion-item>\n\n <!-- Fetching more -->\n <ng-container *ngIf=\"fetchingMore; else infiniteLoop\" lines=\"none\" disabled>\n <ng-container *ngTemplateOutlet=\"loadingItem\"></ng-container>\n </ng-container>\n\n <!-- Infinite loop -->\n <ng-template #infiniteLoop>\n <ng-container *ngIf=\"canFetchMore\" lines=\"none\" disabled\n [ngTemplateOutlet]=\"loadingItem\">\n </ng-container>\n </ng-template>\n </ng-template>\n\n <!-- footer -->\n <ion-row class=\"ion-list-footer column\">\n <ion-col>\n <ion-text *ngIf=\"$itemCount|async; let count\"\n class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n </ion-list>\n</ion-content>\n\n<!-- loading -->\n<ng-template #loadingItem>\n <ion-item lines=\"none\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </ion-item>\n</ng-template>\n",
31065
31155
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
31066
- styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;max-height:calc(90vh - 20px)}ion-list ion-item.tappable{cursor:pointer}ion-list ion-item.tappable:hover{--ion-item-background:var(--ion-item-background-color-hover)}.message{font-size:.9em}.message p{margin-top:5px;margin-bottom:5px}.message p.unread{font-weight:700}.top-action{text-align:end;margin-right:8px}.top-action a{cursor:pointer;color:var(--ion-color-contrast)}.top-action a:hover{text-decoration:underline}a.action{font-size:.9em;margin-right:10px;cursor:pointer}a.action:hover span{text-decoration:underline}a.action app-icon{vertical-align:middle}"]
31156
+ styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;max-height:calc(90vh - 20px)}ion-list ion-item.tappable{cursor:pointer}ion-list ion-item.tappable:hover{--ion-item-background:var(--ion-item-background-color-hover)}.message{font-size:.9em}.message p{margin-top:5px;margin-bottom:5px}.message p.unread{font-weight:700}.top-action{text-align:end;margin-right:8px}.top-action a{cursor:pointer;color:var(--ion-color-contrast)}.top-action a:hover{text-decoration:underline}a.action{font-size:.9em;margin-right:10px;cursor:pointer}a.action:hover span{text-decoration:underline}a.action app-icon{vertical-align:middle}ion-avatar .avatar svg,ion-avatar img{border:1px solid rgba(var(--ion-color-secondary-rgb,.5));border-radius:50%}"]
31067
31157
  },] }
31068
31158
  ];
31069
31159
  UserEventNotificationList.ctorParameters = function () { return [
@@ -31076,11 +31166,11 @@
31076
31166
  debug: [{ type: i0.Input }],
31077
31167
  mobile: [{ type: i0.Input }],
31078
31168
  titleI18n: [{ type: i0.Input }],
31079
- pageSize: [{ type: i0.Input }],
31080
31169
  sortBy: [{ type: i0.Input }],
31081
31170
  sortDirection: [{ type: i0.Input }],
31082
31171
  filter: [{ type: i0.Input }],
31083
31172
  enableInfiniteScroll: [{ type: i0.Input }],
31173
+ pageSize: [{ type: i0.Input }],
31084
31174
  readEvent: [{ type: i0.Output }],
31085
31175
  readEvents: [{ type: i0.Output }],
31086
31176
  ionContent: [{ type: i0.ViewChild, args: [i1$5.IonContent,] }],
@@ -31154,7 +31244,8 @@
31154
31244
  debug: this.debug,
31155
31245
  titleI18n: this.titleI18n,
31156
31246
  readEvent: this._readEvent,
31157
- readEvents: this._readEvents
31247
+ readEvents: this._readEvents,
31248
+ filter: this.filter
31158
31249
  },
31159
31250
  backdropDismiss: true,
31160
31251
  keyboardClose: true,
@@ -31208,7 +31299,8 @@
31208
31299
  imports: [
31209
31300
  i1$4.CommonModule,
31210
31301
  SharedModule,
31211
- AppIconModule
31302
+ AppIconModule,
31303
+ ngxJdenticon.NgxJdenticonModule
31212
31304
  ],
31213
31305
  declarations: [
31214
31306
  AppUserEventNotificationIcon,
@@ -32282,7 +32374,6 @@
32282
32374
  _this.statusById = StatusById;
32283
32375
  _this.filterCriteriaCount = 0;
32284
32376
  _this.useSticky = false;
32285
- _this.referentialToString = referentialToString;
32286
32377
  _this.canEdit = accountService.isAdmin();
32287
32378
  _this.canSendMessage = _this.canEdit;
32288
32379
  _this.inlineEdition = _this.canEdit;
@@ -34170,25 +34261,38 @@
34170
34261
  _this.network = network;
34171
34262
  _this.translate = translate;
34172
34263
  _this.environment = environment;
34173
- _this.userEvents = [];
34264
+ _this.$userEvents = new rxjs.BehaviorSubject([]);
34265
+ _this.$newUserEvents = new rxjs.Subject();
34174
34266
  return _this;
34175
34267
  }
34176
34268
  UserEventTestService.prototype.fromObject = function (source) {
34177
34269
  return exports.UserEvent.fromObject(source);
34178
34270
  };
34179
34271
  UserEventTestService.prototype.add = function (entity) {
34180
- entity = this.processUserEvent(entity);
34181
- entity.id = this.userEvents.length + 1;
34182
- this.userEvents = __spread([
34183
- entity
34184
- ], this.userEvents);
34185
- this._countSubject.next((this._countSubject.value || 0) + 1);
34272
+ var _a;
34273
+ return __awaiter(this, void 0, void 0, function () {
34274
+ return __generator(this, function (_b) {
34275
+ switch (_b.label) {
34276
+ case 0: return [4 /*yield*/, this.processUserEvent(entity)];
34277
+ case 1:
34278
+ entity = _b.sent();
34279
+ entity.id = (((_a = this.$userEvents.value) === null || _a === void 0 ? void 0 : _a.length) || 0) + 1;
34280
+ this.$userEvents.next(__spread([
34281
+ entity
34282
+ ], this.$userEvents.value));
34283
+ this._countSubject.next((this._countSubject.value || 0) + 1);
34284
+ this.$newUserEvents.next([entity]);
34285
+ return [2 /*return*/];
34286
+ }
34287
+ });
34288
+ });
34186
34289
  };
34187
34290
  UserEventTestService.prototype.asFilter = function (filter) {
34188
34291
  return filter;
34189
34292
  };
34190
34293
  UserEventTestService.prototype.count = function (filter, options) {
34191
- return Promise.resolve(this.userEvents.length);
34294
+ var _a;
34295
+ return Promise.resolve(((_a = this.$userEvents.value) === null || _a === void 0 ? void 0 : _a.length) || 0);
34192
34296
  };
34193
34297
  UserEventTestService.prototype.delete = function (entity) {
34194
34298
  return Promise.resolve(undefined);
@@ -34197,11 +34301,11 @@
34197
34301
  return Promise.resolve(undefined);
34198
34302
  };
34199
34303
  UserEventTestService.prototype.listenAllChanges = function (filter, options) {
34200
- return rxjs.of();
34304
+ return this.$newUserEvents.asObservable();
34201
34305
  };
34202
34306
  UserEventTestService.prototype.save = function (entity, options) {
34203
34307
  var _a;
34204
- var toSave = (_a = this.userEvents) === null || _a === void 0 ? void 0 : _a.find(function (value) { return value.id == (entity === null || entity === void 0 ? void 0 : entity.id); });
34308
+ var toSave = (_a = this.$userEvents.value) === null || _a === void 0 ? void 0 : _a.find(function (value) { return value.id == (entity === null || entity === void 0 ? void 0 : entity.id); });
34205
34309
  Object.assign(toSave, entity);
34206
34310
  return entity;
34207
34311
  };
@@ -34236,31 +34340,33 @@
34236
34340
  }
34237
34341
  finally { if (e_1) throw e_1.error; }
34238
34342
  return [7 /*endfinally*/];
34239
- case 7: return [2 /*return*/, Promise.resolve(this.userEvents)];
34343
+ case 7: return [2 /*return*/, this.$userEvents.toPromise()];
34240
34344
  }
34241
34345
  });
34242
34346
  });
34243
34347
  };
34244
34348
  UserEventTestService.prototype.watchAll = function (offset, size, sortBy, sortDirection, filter, opts) {
34245
34349
  var _this = this;
34246
- var _a;
34247
- var data = (this.userEvents || []).slice(offset || 0, offset + size);
34248
- var total = ((_a = this.userEvents) === null || _a === void 0 ? void 0 : _a.length) || 0;
34249
- var res = { data: data, total: total };
34250
- // Must re-order because of listenChanges result will add new event at the end
34251
- data = EntityUtils.sort(data, sortBy, sortDirection);
34252
- // Add fetch more
34253
- var nextOffset = offset + data.length;
34254
- if (nextOffset < res.total) {
34255
- res.fetchMore = function (_) { return _this.loadAll(nextOffset, size, sortBy, sortDirection, filter, Object.assign(Object.assign({}, opts), { fetchPolicy: 'no-cache' })); };
34256
- }
34257
- return rxjs.of(res);
34350
+ return this.$userEvents.pipe(operators.map(function (userEvents) {
34351
+ var _a;
34352
+ var data = (userEvents || []).slice(offset || 0, offset + size);
34353
+ var total = ((_a = _this.$userEvents.value) === null || _a === void 0 ? void 0 : _a.length) || 0;
34354
+ var res = { data: data, total: total };
34355
+ // Must re-order because of listenChanges result will add new event at the end
34356
+ data = EntityUtils.sort(data, sortBy, sortDirection);
34357
+ // Add fetch more
34358
+ var nextOffset = offset + data.length;
34359
+ if (nextOffset < res.total) {
34360
+ res.fetchMore = function (_) { return _this.loadAll(nextOffset, size, sortBy, sortDirection, filter, Object.assign(Object.assign({}, opts), { fetchPolicy: 'no-cache' })); };
34361
+ }
34362
+ return res;
34363
+ }));
34258
34364
  };
34259
34365
  UserEventTestService.prototype.loadAll = function (offset, size, sortBy, sortDirection, filter, opts) {
34260
34366
  var _this = this;
34261
34367
  var _a;
34262
- var data = (this.userEvents || []).slice(offset || 0, offset + size);
34263
- var total = ((_a = this.userEvents) === null || _a === void 0 ? void 0 : _a.length) || 0;
34368
+ var data = (this.$userEvents.value || []).slice(offset || 0, offset + size);
34369
+ var total = ((_a = this.$userEvents.value) === null || _a === void 0 ? void 0 : _a.length) || 0;
34264
34370
  var res = { data: data, total: total };
34265
34371
  // Must re-order because of listenChanges result will add new event at the end
34266
34372
  data = EntityUtils.sort(data, sortBy, sortDirection);
@@ -34304,6 +34410,16 @@
34304
34410
  onRead: function (userEvent) { _this.showMessage("debug message read "); }
34305
34411
  });
34306
34412
  }
34413
+ Object.defineProperty(UserEventTestingPage.prototype, "timerStarted", {
34414
+ get: function () {
34415
+ return !!this._timerSubscription;
34416
+ },
34417
+ enumerable: false,
34418
+ configurable: true
34419
+ });
34420
+ UserEventTestingPage.prototype.ngOnDestroy = function () {
34421
+ this.stopTimer();
34422
+ };
34307
34423
  UserEventTestingPage.prototype.customize = function (userEvent) {
34308
34424
  // Choose avatarIcon
34309
34425
  switch (userEvent.level) {
@@ -34420,6 +34536,51 @@
34420
34536
  ]
34421
34537
  }));
34422
34538
  };
34539
+ UserEventTestingPage.prototype.addMany = function (count) {
34540
+ count = count || 20;
34541
+ for (var i = 0; i < count; i++) {
34542
+ this.addRandom(i);
34543
+ }
34544
+ };
34545
+ UserEventTestingPage.prototype.startTimer = function (period) {
34546
+ var _this = this;
34547
+ var _a;
34548
+ (_a = this._timerSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
34549
+ period = period || 1000;
34550
+ var counter = 0;
34551
+ this._timerSubscription = rxjs.timer(period, period)
34552
+ .subscribe(function () {
34553
+ _this.addRandom(counter);
34554
+ counter++;
34555
+ });
34556
+ };
34557
+ UserEventTestingPage.prototype.stopTimer = function () {
34558
+ var _a;
34559
+ (_a = this._timerSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
34560
+ this._timerSubscription = null;
34561
+ };
34562
+ UserEventTestingPage.prototype.addRandom = function (value) {
34563
+ switch (value % 6) {
34564
+ case 0:
34565
+ this.addNotification();
34566
+ break;
34567
+ case 1:
34568
+ this.addError();
34569
+ break;
34570
+ case 2:
34571
+ this.addDebug();
34572
+ break;
34573
+ case 3:
34574
+ this.addNotificationWithLink();
34575
+ break;
34576
+ case 4:
34577
+ this.addNotificationWithAction();
34578
+ break;
34579
+ case 5:
34580
+ this.addNotificationWithDefaultAction();
34581
+ break;
34582
+ }
34583
+ };
34423
34584
  UserEventTestingPage.prototype.addNotificationWithDefaultAction = function () {
34424
34585
  var _this = this;
34425
34586
  this.userEventService.add(exports.UserEvent.fromObject({
@@ -34446,7 +34607,7 @@
34446
34607
  UserEventTestingPage.decorators = [
34447
34608
  { type: i0.Component, args: [{
34448
34609
  selector: 'job-progression-testing',
34449
- template: "<ion-toolbar color=\"primary\">\n <ion-title>User events</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n\n <app-user-event-notification-icon #notification [debug]=\"true\"></app-user-event-notification-icon>\n\n <p>\n <ion-button (click)=\"addNotification()\">Add notification</ion-button>\n <ion-button (click)=\"addError()\">Add error</ion-button>\n <ion-button (click)=\"addWarning()\">Add warning</ion-button>\n <ion-button (click)=\"addDebug()\">Add debug</ion-button>\n </p>\n <p>\n <ion-button (click)=\"addNotificationWithLink()\">Add notification with link</ion-button>\n <ion-button (click)=\"addNotificationWithAction()\">Add notification with action</ion-button>\n <ion-button (click)=\"addNotificationWithDefaultAction()\">Add notification with default action</ion-button>\n </p>\n</ion-content>\n"
34610
+ template: "<ion-toolbar color=\"primary\">\n <ion-title>User events</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n\n <app-user-event-notification-icon #notification [debug]=\"true\"></app-user-event-notification-icon>\n\n <p>\n <ion-button (click)=\"addNotification()\">Add notification</ion-button>\n <ion-button (click)=\"addError()\">Add error</ion-button>\n <ion-button (click)=\"addWarning()\">Add warning</ion-button>\n <ion-button (click)=\"addDebug()\">Add debug</ion-button>\n </p>\n <p>\n <ion-button (click)=\"addNotificationWithLink()\">Add notification with link</ion-button>\n <ion-button (click)=\"addNotificationWithAction()\">Add notification with action</ion-button>\n <ion-button (click)=\"addNotificationWithDefaultAction()\">Add notification with default action</ion-button>\n </p>\n <p>\n <ion-button (click)=\"addMany()\">Add notifications (x20)</ion-button>\n </p>\n <p>\n <ion-button (click)=\"startTimer()\" *ngIf=\"!timerStarted\">Start timer</ion-button>\n <ion-button (click)=\"stopTimer()\" *ngIf=\"timerStarted\">Stop timer</ion-button>\n </p>\n</ion-content>\n"
34450
34611
  },] }
34451
34612
  ];
34452
34613
  UserEventTestingPage.ctorParameters = function () { return [