@sumaris-net/ngx-components 1.21.0-beta2 → 1.21.0-beta22

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 (26) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +478 -156
  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/core/menu/menu.component.js +2 -9
  6. package/esm2015/src/app/social/job/job.service.js +1 -2
  7. package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +23 -31
  8. package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +47 -8
  9. package/esm2015/src/app/social/user-event/testing/user-event.testing.service.js +73 -0
  10. package/esm2015/src/app/social/user-event/user-event.model.js +1 -1
  11. package/esm2015/src/app/social/user-event/user-event.module.js +6 -1
  12. package/esm2015/src/app/social/user-event/user-event.service.js +201 -63
  13. package/esm2015/sumaris-net.ngx-components.js +8 -7
  14. package/fesm2015/sumaris-net.ngx-components.js +328 -103
  15. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/app/social/user-event/notification/user-event-notification.component.d.ts +5 -8
  18. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +18 -8
  19. package/src/app/social/user-event/testing/user-event.testing.service.d.ts +35 -0
  20. package/src/app/social/user-event/user-event.model.d.ts +1 -1
  21. package/src/app/social/user-event/user-event.service.d.ts +31 -11
  22. package/src/assets/i18n/en.json +2 -1
  23. package/src/assets/i18n/fr.json +2 -1
  24. package/src/theme/_ngx-components.scss +1 -0
  25. package/sumaris-net.ngx-components.d.ts +7 -6
  26. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -24386,9 +24386,6 @@
24386
24386
  this._subscription = new rxjs.Subscription();
24387
24387
  this.loading = true;
24388
24388
  this.isLogin = false;
24389
- // showUserEventNotification: boolean;
24390
- // showJobProgression: boolean;
24391
- // jobProgressionOptions: JobProgressionOptions;
24392
24389
  this.$items = new rxjs.BehaviorSubject(undefined);
24393
24390
  this.id = 'menu';
24394
24391
  this.menuId = 'left';
@@ -24413,10 +24410,6 @@
24413
24410
  case 2:
24414
24411
  // Wait platform started
24415
24412
  _b.sent();
24416
- // Init social options
24417
- // this.showUserEventNotification = toBoolean(this.socialModuleOptions?.showUserEventNotification, false);
24418
- // this.showJobProgression = toBoolean(this.socialModuleOptions?.showJobProgression, false);
24419
- // this.jobProgressionOptions = this.socialModuleOptions?.jobProgressionOptions;
24420
24413
  // Listen to menu service event
24421
24414
  this.menuService.splitPaneWhen
24422
24415
  .subscribe(function (value) { return _this.setSplitPaneWhen(value); });
@@ -24756,7 +24749,7 @@
24756
24749
  MenuComponent.decorators = [
24757
24750
  { type: i0.Component, args: [{
24758
24751
  selector: 'app-menu',
24759
- template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n<!-- todo ajouter ici les 2 composants du module social -->\n\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\" @fadeInAnimation\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n\n <ion-list lines=\"none\">\n <ion-menu-toggle auto-hide=\"false\"\n [class.flex-spacer]=\"item.cssClass == 'flex-spacer'\"\n *ngFor=\"let item of $items | async\">\n\n <!-- link -->\n <ion-item *ngIf=\"!loading && item.path\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/')}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"!loading && item.action\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!loading && !item.path && !item.action\">\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item-divider>\n\n </ion-menu-toggle>\n </ion-list>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '&#xab;' : '&#xbb;'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n",
24752
+ template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n<!-- todo ajouter ici les 2 composants du module social ??? -->\n\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\" @fadeInAnimation\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n\n <ion-list lines=\"none\">\n <ion-menu-toggle auto-hide=\"false\"\n [class.flex-spacer]=\"item.cssClass == 'flex-spacer'\"\n *ngFor=\"let item of $items | async\">\n\n <!-- link -->\n <ion-item *ngIf=\"!loading && item.path\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/')}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"!loading && item.action\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!loading && !item.path && !item.action\">\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item-divider>\n\n </ion-menu-toggle>\n </ion-list>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '&#xab;' : '&#xbb;'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n",
24760
24753
  animations: [fadeInAnimation],
24761
24754
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
24762
24755
  styles: ["ion-menu{--ion-item-background:transparent;--ion-item-divider-background:transparent;--ion-item-icon-color:var(--ion-color-primary-tint);--ion-item-text-color:var(--ion-color-primary-tint);--ion-item-background-selected:var(--ion-color-secondary100);--ion-item-text-color-selected:var(--ion-color-primary);--ion-item-icon-color-selected:var(--ion-color-primary);--ion-item-text-color-disable:var(--ion-color-medium);--ion-item-icon-color-disable:var(--ion-color-medium)}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:50%;background-color:var(--ion-color-secondary);border:1px solid var(--ion-color-primary);overflow:hidden!important;font-size:var(--avatar-size,60px)!important;line-height:var(--avatar-size,60px);height:var(--avatar-size,60px)!important;width:var(--avatar-size,60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size,60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu .scroll-content{margin-top:79px!important}ion-menu .has-user-header .scroll-content{margin-top:188px!important}ion-menu ion-content.has-profile-header{--offset-top:188px}ion-menu ion-content.no-profile-header{--offset-top:79px}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color:var(--ion-color-primary-tint);--ion-item-text-color:var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color:var(--ion-color-secondary-tint);--ion-item-text-color:var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color:var(--ion-color-tertiary-tint);--ion-item-text-color:var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color:var(--ion-color-danger-tint);--ion-item-text-color:var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color:var(--ion-color-medium-shade);--ion-item-text-color:var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color:var(--ion-color-dark-tint);--ion-item-text-color:var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item ion-icon,ion-menu ion-content ion-list ion-item mat-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-label,ion-menu ion-content ion-list ion-item ion-text{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover:var(--ion-item-background-selected)!important}ion-menu ion-content ion-list ion-item.selected ion-icon,ion-menu ion-content ion-list ion-item.selected mat-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-label,ion-menu ion-content ion-list ion-item.selected ion-text{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover:var(--ion-item-background-selected)!important;--ion-item-icon-color-selected:var(--ion-item-icon-color)!important;--ion-item-text-color-selected:var(--ion-item-text-color)!important}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width:40px}@media screen and (max-width:767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width:768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size,80px)!important;line-height:var(--avatar-size,80px);height:var(--avatar-size,80px)!important;width:var(--avatar-size,80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size,80px)}}"]
@@ -30179,48 +30172,63 @@
30179
30172
  var UserEventServiceToken = new i0.InjectionToken('UserEventService');
30180
30173
  var AbstractUserEventService = /** @class */ (function (_super) {
30181
30174
  __extends(AbstractUserEventService, _super);
30182
- function AbstractUserEventService(graphql, accountService, network, translate, toastController, queries, mutations, subscriptions, environment) {
30175
+ function AbstractUserEventService(graphql, accountService, network, translate, queries, mutations, subscriptions, environment) {
30183
30176
  var _this = _super.call(this, graphql, environment) || this;
30184
30177
  _this.graphql = graphql;
30185
30178
  _this.accountService = accountService;
30186
30179
  _this.network = network;
30187
30180
  _this.translate = translate;
30188
- _this.toastController = toastController;
30189
30181
  _this.queries = queries;
30190
30182
  _this.mutations = mutations;
30191
30183
  _this.subscriptions = subscriptions;
30192
30184
  _this.environment = environment;
30193
- _this._count$ = new rxjs.BehaviorSubject(0);
30194
- _this._subscriptions = new rxjs.Subscription();
30185
+ _this.count$ = new rxjs.BehaviorSubject(0);
30195
30186
  _this.listeners = [];
30187
+ _this._subscriptions = new rxjs.Subscription();
30196
30188
  _this._logPrefix = '[user-event-service] ';
30197
30189
  // For DEV only
30198
30190
  _this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
30199
- // listen login/logout
30200
- _this._subscriptions.add(accountService.onLogin.subscribe(function () { return __awaiter(_this, void 0, void 0, function () {
30201
- var count;
30202
- return __generator(this, function (_b) {
30203
- switch (_b.label) {
30204
- case 0: return [4 /*yield*/, this.count(this.defaultFilter())];
30205
- case 1:
30206
- count = _b.sent();
30207
- if (count && this._debug) {
30208
- console.debug(this._logPrefix + "Received " + count + " unread notifications");
30209
- }
30210
- this._count$.next(count);
30211
- return [2 /*return*/];
30212
- }
30213
- });
30214
- }); }));
30215
30191
  return _this;
30216
30192
  }
30217
30193
  Object.defineProperty(AbstractUserEventService.prototype, "userEventCount", {
30218
30194
  get: function () {
30219
- return this._count$.asObservable();
30195
+ return this.count$.asObservable();
30220
30196
  },
30221
30197
  enumerable: false,
30222
30198
  configurable: true
30223
30199
  });
30200
+ AbstractUserEventService.prototype.ngOnStart = function () {
30201
+ return __awaiter(this, void 0, void 0, function () {
30202
+ var _this = this;
30203
+ return __generator(this, function (_b) {
30204
+ switch (_b.label) {
30205
+ case 0:
30206
+ // Update component when refresh is need (=login events)
30207
+ this._subscriptions.add(rxjs.merge(this.accountService.onLogin, this.accountService.onLogout)
30208
+ .pipe(
30209
+ // Wait account service ready (can be restarted)
30210
+ operators.mergeMap(function () { return _this.accountService.ready(); }), operators.map(function () { return _this.accountService.isLogin(); }), operators.distinctUntilChanged())
30211
+ .subscribe(function (login) {
30212
+ if (login) {
30213
+ _this.onLogin();
30214
+ }
30215
+ else {
30216
+ _this.onLogout();
30217
+ }
30218
+ }));
30219
+ // First attempt if account is ready
30220
+ return [4 /*yield*/, this.accountService.ready()];
30221
+ case 1:
30222
+ // First attempt if account is ready
30223
+ _b.sent();
30224
+ if (this.accountService.isLogin()) {
30225
+ setTimeout(function () { return _this.onLogin(); });
30226
+ }
30227
+ return [2 /*return*/];
30228
+ }
30229
+ });
30230
+ });
30231
+ };
30224
30232
  AbstractUserEventService.prototype.ngOnDestroy = function () {
30225
30233
  this._subscriptions.unsubscribe();
30226
30234
  };
@@ -30231,13 +30239,15 @@
30231
30239
  var _this = this;
30232
30240
  var _a;
30233
30241
  var now = this._debug && Date.now();
30234
- //if (this._debug)
30242
+ if (!filter) {
30243
+ filter = this.defaultFilter();
30244
+ }
30235
30245
  console.debug(this._logPrefix + "Loading user events...", filter);
30236
30246
  filter = this.asFilter(filter);
30237
30247
  // Force recipient to current issuer, if not admin and not specified
30238
- if (isEmptyArray(filter.recipients) || !this.accountService.isAdmin()) {
30248
+ if (isEmptyArray(filter === null || filter === void 0 ? void 0 : filter.recipients) || !this.accountService.isAdmin()) {
30239
30249
  var recipient = this.defaultRecipient();
30240
- if (!((_a = filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
30250
+ if (!((_a = filter === null || filter === void 0 ? void 0 : filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
30241
30251
  console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
30242
30252
  filter.recipients = [recipient];
30243
30253
  }
@@ -30247,23 +30257,27 @@
30247
30257
  queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
30248
30258
  query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
30249
30259
  variables: {
30250
- page: Object.assign({ sortBy: 'updateDate', sortDirection: 'desc' }, page),
30260
+ page: Object.assign(Object.assign({ sortBy: 'creationDate' }, page), {
30261
+ // @ts-ignore
30262
+ sortDirection: (page.sortDirection || 'desc').toUpperCase()
30263
+ }),
30251
30264
  filter: filter && filter.asPodObject()
30252
30265
  },
30253
30266
  arrayFieldName: 'data',
30254
30267
  error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
30255
- fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || "cache-first"
30268
+ fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'cache-first'
30256
30269
  })
30257
30270
  .pipe(operators.map(function (res) {
30258
- var data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(_this.processUserEvent);
30271
+ var data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(function (value) { return _this.processUserEvent(value, _this); });
30259
30272
  if (now) {
30260
30273
  console.debug("" + _this._logPrefix + data.length + " user events loaded in " + (Date.now() - now) + "ms");
30261
30274
  now = null;
30262
30275
  }
30263
- var unreadCount = _this.unreadEvents(data);
30276
+ // Must re-order because of listenChanges result will add new event at the end
30277
+ data = EntityUtils.sort(data, page.sortBy, page.sortDirection);
30264
30278
  return {
30265
30279
  data: data,
30266
- total: toNumber(res === null || res === void 0 ? void 0 : res.total, unreadCount)
30280
+ total: toNumber(res === null || res === void 0 ? void 0 : res.total, data.length)
30267
30281
  };
30268
30282
  }));
30269
30283
  };
@@ -30277,7 +30291,7 @@
30277
30291
  data: entity
30278
30292
  });
30279
30293
  // Update count
30280
- this._count$.next(this._count$.value + 1);
30294
+ this.count$.next(this.count$.value + 1);
30281
30295
  };
30282
30296
  AbstractUserEventService.prototype.count = function (filter, options) {
30283
30297
  var _a;
@@ -30291,7 +30305,9 @@
30291
30305
  return [2 /*return*/, undefined];
30292
30306
  }
30293
30307
  if (!filter)
30294
- throw new Error("Missing argument 'filter'");
30308
+ filter = this.defaultFilter();
30309
+ // Apply last reset date as start date
30310
+ filter.startDate = this.resetCountDate;
30295
30311
  filter = this.asFilter(filter);
30296
30312
  if (this._debug)
30297
30313
  console.debug(this._logPrefix + "Counting user events with filter:", filter);
@@ -30310,6 +30326,36 @@
30310
30326
  });
30311
30327
  });
30312
30328
  };
30329
+ AbstractUserEventService.prototype.listenCountChanges = function (filter, options) {
30330
+ var _this = this;
30331
+ if (!this.subscriptions.listenCountChanges) {
30332
+ console.warn(this._logPrefix + "Subscription query 'listenCountChanges' not provided, skip.");
30333
+ return rxjs.of();
30334
+ }
30335
+ if (!filter)
30336
+ filter = this.defaultFilter();
30337
+ // Apply last reset date as start date
30338
+ filter.startDate = this.resetCountDate;
30339
+ filter = this.asFilter(filter);
30340
+ if (this._debug)
30341
+ console.debug(this._logPrefix + "[WS] Listening count changes for user events with filter:", filter);
30342
+ return this.graphql.subscribe({
30343
+ query: this.subscriptions.listenCountChanges,
30344
+ fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
30345
+ variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
30346
+ error: {
30347
+ code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
30348
+ message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
30349
+ }
30350
+ }).pipe(operators.map(function (_b) {
30351
+ var total = _b.total;
30352
+ if (total && _this._debug)
30353
+ console.debug(_this._logPrefix + "Received new user events count:", total);
30354
+ // update count
30355
+ _this.count$.next(total);
30356
+ return total;
30357
+ }));
30358
+ };
30313
30359
  AbstractUserEventService.prototype.listenChanges = function (filter, options) {
30314
30360
  var _this = this;
30315
30361
  var _a;
@@ -30318,7 +30364,7 @@
30318
30364
  return rxjs.of();
30319
30365
  }
30320
30366
  if (!filter)
30321
- throw new Error("Missing argument 'filter'");
30367
+ filter = this.defaultFilter();
30322
30368
  filter = this.asFilter(filter);
30323
30369
  var withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
30324
30370
  if (this._debug)
@@ -30335,14 +30381,12 @@
30335
30381
  var data = _b.data;
30336
30382
  if (data && _this._debug)
30337
30383
  console.debug(_this._logPrefix + "Received new user events:", data);
30338
- var updatedData = data === null || data === void 0 ? void 0 : data.map(_this.processUserEvent);
30384
+ var updatedData = data === null || data === void 0 ? void 0 : data.map(function (value) { return _this.processUserEvent(value, _this); });
30339
30385
  // Update cache
30340
30386
  _this.insertIntoMutableCachedQueries(_this.graphql.cache, {
30341
30387
  query: withContent ? _this.queries.loadAllWithContent : _this.queries.loadAll,
30342
30388
  data: updatedData
30343
30389
  });
30344
- // update count
30345
- _this._count$.next(_this.unreadEvents(updatedData));
30346
30390
  return updatedData;
30347
30391
  }));
30348
30392
  };
@@ -30403,13 +30447,21 @@
30403
30447
  };
30404
30448
  AbstractUserEventService.prototype.save = function (entity, options) {
30405
30449
  return __awaiter(this, void 0, void 0, function () {
30406
- var isNew, json, now;
30450
+ var allData, withContent, json, now;
30407
30451
  var _this = this;
30408
30452
  return __generator(this, function (_b) {
30409
30453
  switch (_b.label) {
30410
30454
  case 0:
30455
+ if (!!this.mutations.save) return [3 /*break*/, 2];
30456
+ if (!this.mutations.saveAll)
30457
+ throw new Error('Not implemented');
30458
+ return [4 /*yield*/, this.saveAll([entity], options)];
30459
+ case 1:
30460
+ allData = _b.sent();
30461
+ return [2 /*return*/, allData === null || allData === void 0 ? void 0 : allData[0]];
30462
+ case 2:
30411
30463
  this.fillDefaultProperties(entity);
30412
- isNew = isNil(entity.id);
30464
+ withContent = !!entity.content;
30413
30465
  json = entity.asObject();
30414
30466
  now = Date.now();
30415
30467
  if (this._debug)
@@ -30429,75 +30481,167 @@
30429
30481
  console.debug(_this._logPrefix + "User event saved in " + (Date.now() - now) + "ms", entity);
30430
30482
  _this.copyIdAndUpdateDate(savedEntity, entity);
30431
30483
  // Add to cache
30432
- if (isNew) {
30433
- _this.insertIntoMutableCachedQueries(proxy, {
30434
- query: _this.queries.loadAll,
30435
- data: Object.assign(Object.assign({}, savedEntity), { content: null })
30436
- });
30484
+ if (withContent) {
30437
30485
  _this.insertIntoMutableCachedQueries(proxy, {
30438
30486
  query: _this.queries.loadAllWithContent,
30439
30487
  data: savedEntity
30440
30488
  });
30441
30489
  }
30490
+ else {
30491
+ _this.insertIntoMutableCachedQueries(proxy, {
30492
+ query: _this.queries.loadAll,
30493
+ data: Object.assign(Object.assign({}, savedEntity), { content: null })
30494
+ });
30495
+ }
30442
30496
  }
30443
30497
  }
30444
30498
  })];
30445
- case 1:
30499
+ case 3:
30446
30500
  _b.sent();
30447
30501
  return [2 /*return*/, entity];
30448
30502
  }
30449
30503
  });
30450
30504
  });
30451
30505
  };
30452
- AbstractUserEventService.prototype.saveAll = function (data, opts) {
30453
- var _this = this;
30454
- return Promise.all(data
30455
- .map(function (entity) { return _this.save(entity, opts); }));
30506
+ AbstractUserEventService.prototype.saveAll = function (entities, opts) {
30507
+ return __awaiter(this, void 0, void 0, function () {
30508
+ var json, now;
30509
+ var _this = this;
30510
+ return __generator(this, function (_b) {
30511
+ switch (_b.label) {
30512
+ case 0:
30513
+ if (isEmptyArray(entities))
30514
+ return [2 /*return*/, entities];
30515
+ if (!this.mutations.saveAll) {
30516
+ if (!this.mutations.save)
30517
+ throw new Error('Not implemented');
30518
+ // Save one by one
30519
+ return [2 /*return*/, chainPromises(entities.map(function (entity) { return function () { return _this.save(entity, opts); }; }))];
30520
+ }
30521
+ json = entities.map(function (entity) {
30522
+ _this.fillDefaultProperties(entity);
30523
+ return entity.asObject();
30524
+ });
30525
+ now = Date.now();
30526
+ if (this._debug)
30527
+ console.debug(this._logPrefix + "Saving user events...", json);
30528
+ return [4 /*yield*/, this.graphql.mutate({
30529
+ mutation: this.mutations.saveAll,
30530
+ variables: {
30531
+ data: json
30532
+ },
30533
+ error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
30534
+ update: function (proxy, _b) {
30535
+ var data = _b.data;
30536
+ // Update entity
30537
+ var savedEntities = (data === null || data === void 0 ? void 0 : data.data) || [];
30538
+ if (savedEntities.length) {
30539
+ if (_this._debug)
30540
+ console.debug(_this._logPrefix + "User events saved in " + (Date.now() - now) + "ms", savedEntities);
30541
+ entities.forEach(function (entity) {
30542
+ var savedEntity = savedEntities.find(function (e) { return EntityUtils.equals(e, entity, 'id'); });
30543
+ _this.copyIdAndUpdateDate(savedEntity, entity);
30544
+ });
30545
+ // Add to cache (assuming all with content)
30546
+ _this.insertIntoMutableCachedQueries(proxy, {
30547
+ query: _this.queries.loadAllWithContent,
30548
+ data: savedEntities
30549
+ });
30550
+ }
30551
+ }
30552
+ })];
30553
+ case 1:
30554
+ _b.sent();
30555
+ return [2 /*return*/, entities];
30556
+ }
30557
+ });
30558
+ });
30456
30559
  };
30457
- AbstractUserEventService.prototype.markAsRead = function (entity) {
30560
+ AbstractUserEventService.prototype.markAsRead = function (entities) {
30458
30561
  return __awaiter(this, void 0, void 0, function () {
30459
- var onReadListeners, onReadListeners_1, onReadListeners_1_1, listener, e_1_1;
30460
- var e_1, _b;
30461
- return __generator(this, function (_c) {
30462
- switch (_c.label) {
30562
+ var userEventWithoutReadListeners, _loop_1, this_1, _b, _c, entity, e_1_1;
30563
+ var e_1, _d;
30564
+ return __generator(this, function (_e) {
30565
+ switch (_e.label) {
30463
30566
  case 0:
30464
- onReadListeners = (this.listeners || []).filter(function (listener) { return !!listener.onRead; }).filter(function (listener) { return listener.accept(entity); });
30465
- if (!onReadListeners.length) return [3 /*break*/, 9];
30466
- _c.label = 1;
30567
+ userEventWithoutReadListeners = [];
30568
+ _loop_1 = function (entity) {
30569
+ var onReadListeners, onReadListeners_1, onReadListeners_1_1, listener, e_2_1;
30570
+ var e_2, _b;
30571
+ return __generator(this, function (_c) {
30572
+ switch (_c.label) {
30573
+ case 0:
30574
+ onReadListeners = (this_1.listeners || []).filter(function (listener) { return !!listener.onRead; }).filter(function (listener) { return listener.accept(entity); });
30575
+ if (!onReadListeners.length) return [3 /*break*/, 9];
30576
+ _c.label = 1;
30577
+ case 1:
30578
+ _c.trys.push([1, 6, 7, 8]);
30579
+ onReadListeners_1 = (e_2 = void 0, __values(onReadListeners)), onReadListeners_1_1 = onReadListeners_1.next();
30580
+ _c.label = 2;
30581
+ case 2:
30582
+ if (!!onReadListeners_1_1.done) return [3 /*break*/, 5];
30583
+ listener = onReadListeners_1_1.value;
30584
+ return [4 /*yield*/, listener.onRead(entity)];
30585
+ case 3:
30586
+ _c.sent();
30587
+ _c.label = 4;
30588
+ case 4:
30589
+ onReadListeners_1_1 = onReadListeners_1.next();
30590
+ return [3 /*break*/, 2];
30591
+ case 5: return [3 /*break*/, 8];
30592
+ case 6:
30593
+ e_2_1 = _c.sent();
30594
+ e_2 = { error: e_2_1 };
30595
+ return [3 /*break*/, 8];
30596
+ case 7:
30597
+ try {
30598
+ if (onReadListeners_1_1 && !onReadListeners_1_1.done && (_b = onReadListeners_1.return)) _b.call(onReadListeners_1);
30599
+ }
30600
+ finally { if (e_2) throw e_2.error; }
30601
+ return [7 /*endfinally*/];
30602
+ case 8: return [3 /*break*/, 10];
30603
+ case 9:
30604
+ // Add to this list for default operation
30605
+ userEventWithoutReadListeners.push(entity);
30606
+ _c.label = 10;
30607
+ case 10: return [2 /*return*/];
30608
+ }
30609
+ });
30610
+ };
30611
+ this_1 = this;
30612
+ _e.label = 1;
30467
30613
  case 1:
30468
- _c.trys.push([1, 6, 7, 8]);
30469
- onReadListeners_1 = __values(onReadListeners), onReadListeners_1_1 = onReadListeners_1.next();
30470
- _c.label = 2;
30614
+ _e.trys.push([1, 6, 7, 8]);
30615
+ _b = __values((entities || [])), _c = _b.next();
30616
+ _e.label = 2;
30471
30617
  case 2:
30472
- if (!!onReadListeners_1_1.done) return [3 /*break*/, 5];
30473
- listener = onReadListeners_1_1.value;
30474
- return [4 /*yield*/, listener.onRead(entity)];
30618
+ if (!!_c.done) return [3 /*break*/, 5];
30619
+ entity = _c.value;
30620
+ return [5 /*yield**/, _loop_1(entity)];
30475
30621
  case 3:
30476
- _c.sent();
30477
- _c.label = 4;
30622
+ _e.sent();
30623
+ _e.label = 4;
30478
30624
  case 4:
30479
- onReadListeners_1_1 = onReadListeners_1.next();
30625
+ _c = _b.next();
30480
30626
  return [3 /*break*/, 2];
30481
30627
  case 5: return [3 /*break*/, 8];
30482
30628
  case 6:
30483
- e_1_1 = _c.sent();
30629
+ e_1_1 = _e.sent();
30484
30630
  e_1 = { error: e_1_1 };
30485
30631
  return [3 /*break*/, 8];
30486
30632
  case 7:
30487
30633
  try {
30488
- if (onReadListeners_1_1 && !onReadListeners_1_1.done && (_b = onReadListeners_1.return)) _b.call(onReadListeners_1);
30634
+ if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
30489
30635
  }
30490
30636
  finally { if (e_1) throw e_1.error; }
30491
30637
  return [7 /*endfinally*/];
30492
- case 8: return [3 /*break*/, 11];
30493
- case 9:
30638
+ case 8:
30494
30639
  // Use default
30495
- return [4 /*yield*/, this.defaultMarkAsRead(entity)];
30496
- case 10:
30640
+ return [4 /*yield*/, this.defaultMarkAsRead(userEventWithoutReadListeners)];
30641
+ case 9:
30497
30642
  // Use default
30498
- _c.sent();
30499
- _c.label = 11;
30500
- case 11: return [2 /*return*/];
30643
+ _e.sent();
30644
+ return [2 /*return*/];
30501
30645
  }
30502
30646
  });
30503
30647
  });
@@ -30507,13 +30651,51 @@
30507
30651
  this.listeners = [];
30508
30652
  this.listeners.push(listener);
30509
30653
  };
30654
+ AbstractUserEventService.prototype.resetCount = function () {
30655
+ this.count$.next(undefined);
30656
+ this.resetCountDate = moment$6();
30657
+ // restart listening count changes
30658
+ this.startListenCountChanges();
30659
+ };
30510
30660
  /* -- protected methods -- */
30511
- AbstractUserEventService.prototype.processUserEvent = function (source) {
30512
- var e_2, _b;
30661
+ AbstractUserEventService.prototype.onLogin = function () {
30662
+ return __awaiter(this, void 0, void 0, function () {
30663
+ var count;
30664
+ return __generator(this, function (_b) {
30665
+ switch (_b.label) {
30666
+ case 0: return [4 /*yield*/, this.count(undefined)];
30667
+ case 1:
30668
+ count = _b.sent();
30669
+ if (this._debug)
30670
+ console.debug(this._logPrefix + "Receiving user events count", count);
30671
+ // Update count
30672
+ this.count$.next(count);
30673
+ // Then listen changes
30674
+ this.startListenCountChanges();
30675
+ return [2 /*return*/];
30676
+ }
30677
+ });
30678
+ });
30679
+ };
30680
+ AbstractUserEventService.prototype.onLogout = function () {
30681
+ this.stopListenCountChanges();
30682
+ };
30683
+ AbstractUserEventService.prototype.startListenCountChanges = function () {
30684
+ this.stopListenCountChanges();
30685
+ this._listenSubscription = this.listenCountChanges(undefined).subscribe();
30686
+ };
30687
+ AbstractUserEventService.prototype.stopListenCountChanges = function () {
30688
+ var _a;
30689
+ (_a = this._listenSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
30690
+ this._listenSubscription = undefined;
30691
+ };
30692
+ AbstractUserEventService.prototype.processUserEvent = function (source, that) {
30693
+ var e_3, _b;
30694
+ that = that || this;
30513
30695
  // Convert json source to IUserEvent
30514
- var target = this.fromObject(source);
30696
+ var target = that.fromObject(source);
30515
30697
  // Get listeners
30516
- var listeners = (this.listeners || []).filter(function (listener) { return listener.onReceived; }).filter(function (listener) { return listener.accept(target); });
30698
+ var listeners = (that.listeners || []).filter(function (listener) { return listener.onReceived; }).filter(function (listener) { return listener.accept(target); });
30517
30699
  try {
30518
30700
  for (var listeners_1 = __values(listeners), listeners_1_1 = listeners_1.next(); !listeners_1_1.done; listeners_1_1 = listeners_1.next()) {
30519
30701
  var listener = listeners_1_1.value;
@@ -30521,39 +30703,47 @@
30521
30703
  target = listener.onReceived(target);
30522
30704
  }
30523
30705
  else {
30524
- if (this._debug)
30525
- console.debug(this._logPrefix + "Event has been rejected by a listener", source);
30706
+ if (that._debug)
30707
+ console.debug(that._logPrefix + "Event has been rejected by a listener", source);
30526
30708
  break;
30527
30709
  }
30528
30710
  }
30529
30711
  }
30530
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
30712
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
30531
30713
  finally {
30532
30714
  try {
30533
30715
  if (listeners_1_1 && !listeners_1_1.done && (_b = listeners_1.return)) _b.call(listeners_1);
30534
30716
  }
30535
- finally { if (e_2) throw e_2.error; }
30717
+ finally { if (e_3) throw e_3.error; }
30536
30718
  }
30537
30719
  return target;
30538
30720
  };
30539
- AbstractUserEventService.prototype.defaultMarkAsRead = function (userEvent) {
30721
+ AbstractUserEventService.prototype.defaultMarkAsRead = function (userEvents) {
30540
30722
  return __awaiter(this, void 0, void 0, function () {
30723
+ var localEntities, remoteEntities;
30541
30724
  return __generator(this, function (_b) {
30542
30725
  switch (_b.label) {
30543
30726
  case 0:
30544
- if (!userEvent)
30727
+ if (!userEvents)
30545
30728
  throw new Error(this._logPrefix + "Invalid event to save");
30729
+ if (!userEvents.length)
30730
+ return [2 /*return*/];
30546
30731
  // set read date
30547
- userEvent.readDate = moment$6();
30548
- if (!(!userEvent.id || userEvent.id < 0)) return [3 /*break*/, 1];
30549
- if (this._debug)
30550
- console.debug(this._logPrefix + "Save local user event");
30551
- return [3 /*break*/, 3];
30552
- case 1: return [4 /*yield*/, this.save(userEvent)];
30553
- case 2:
30732
+ userEvents.forEach(function (userEvent) { return userEvent.readDate = moment$6(); });
30733
+ localEntities = userEvents.filter(function (userEvent) { return !userEvent.id || userEvent.id < 0; });
30734
+ remoteEntities = userEvents.filter(function (userEvent) { return userEvent.id > 0; });
30735
+ // save local entities
30736
+ if (localEntities.length) {
30737
+ if (this._debug)
30738
+ console.debug(this._logPrefix + "Save local user event");
30739
+ // TODO !!!!!!!!!!!!!
30740
+ }
30741
+ if (!remoteEntities.length) return [3 /*break*/, 2];
30742
+ return [4 /*yield*/, this.saveAll(remoteEntities)];
30743
+ case 1:
30554
30744
  _b.sent();
30555
- _b.label = 3;
30556
- case 3: return [2 /*return*/];
30745
+ _b.label = 2;
30746
+ case 2: return [2 /*return*/];
30557
30747
  }
30558
30748
  });
30559
30749
  });
@@ -30592,7 +30782,6 @@
30592
30782
  { type: AccountService },
30593
30783
  { type: NetworkService },
30594
30784
  { type: i1$2.TranslateService },
30595
- { type: i1$5.ToastController },
30596
30785
  { type: undefined },
30597
30786
  { type: undefined },
30598
30787
  { type: undefined },
@@ -30609,7 +30798,7 @@
30609
30798
  var UserEventService = /** @class */ (function (_super) {
30610
30799
  __extends(UserEventService, _super);
30611
30800
  function UserEventService(graphql, accountService, network, translate, toastController, environment) {
30612
- var _this = _super.call(this, graphql, accountService, network, translate, toastController, userEventQueries, userEventMutations, undefined, environment) || this;
30801
+ var _this = _super.call(this, graphql, accountService, network, translate, userEventQueries, userEventMutations, undefined, environment) || this;
30613
30802
  _this.graphql = graphql;
30614
30803
  _this.accountService = accountService;
30615
30804
  _this.network = network;
@@ -30932,17 +31121,48 @@
30932
31121
  };
30933
31122
 
30934
31123
  var UserEventNotificationList = /** @class */ (function () {
30935
- function UserEventNotificationList(popoverController) {
31124
+ function UserEventNotificationList(cd, popoverController, userEventService) {
31125
+ this.cd = cd;
30936
31126
  this.popoverController = popoverController;
31127
+ this.userEventService = userEventService;
31128
+ this.debug = false;
31129
+ this.userEvents = new rxjs.BehaviorSubject(undefined);
31130
+ this.subscriptions = new rxjs.Subscription();
30937
31131
  }
30938
31132
  UserEventNotificationList.prototype.ngOnInit = function () {
31133
+ var _this = this;
31134
+ // Watch all user events
31135
+ this.subscriptions.add(this.userEventService
31136
+ .watchAll(0, 10, 'creationDate', "desc", undefined)
31137
+ .subscribe(function (result) {
31138
+ if (_this.debug)
31139
+ console.debug("[user-event-notification-list] receiving " + result.total + " user events", result.data);
31140
+ _this.userEvents.next(result.data);
31141
+ _this.markForCheck();
31142
+ }));
31143
+ // Listen changes
31144
+ this.subscriptions.add(this.userEventService.listenChanges(undefined)
31145
+ .subscribe(function (data) {
31146
+ if (_this.debug)
31147
+ console.debug("[user-event-notification-list] receiving " + data.length + " new user events", data);
31148
+ }));
31149
+ };
31150
+ UserEventNotificationList.prototype.ngOnDestroy = function () {
31151
+ this.subscriptions.unsubscribe();
30939
31152
  };
30940
- UserEventNotificationList.prototype.read = function ($event, userEvent) {
31153
+ UserEventNotificationList.prototype.read = function (event, userEvent) {
30941
31154
  var _a;
30942
31155
  if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
30943
31156
  return;
30944
31157
  (_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
30945
31158
  };
31159
+ UserEventNotificationList.prototype.readAll = function (event) {
31160
+ var _a;
31161
+ var unreadUserEvents = (this.userEvents.value || []).filter(function (value) { return !value.readDate; });
31162
+ if (!unreadUserEvents.length)
31163
+ return;
31164
+ (_a = this.readEvents) === null || _a === void 0 ? void 0 : _a.emit(unreadUserEvents);
31165
+ };
30946
31166
  UserEventNotificationList.prototype.executeAction = function (action, userEvent) {
30947
31167
  // Execute then close popover
30948
31168
  action.executeAction(userEvent);
@@ -30951,37 +31171,42 @@
30951
31171
  UserEventNotificationList.prototype.dismiss = function () {
30952
31172
  this.popoverController.dismiss();
30953
31173
  };
31174
+ UserEventNotificationList.prototype.markForCheck = function () {
31175
+ this.cd.markForCheck();
31176
+ };
30954
31177
  return UserEventNotificationList;
30955
31178
  }());
30956
31179
  UserEventNotificationList.decorators = [
30957
31180
  { type: i0.Component, args: [{
30958
31181
  selector: 'app-user-event-notification-list',
30959
- template: "\n<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!(userEvents | async)?.length\">\n {{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}\n </ion-item>\n <ion-item\n *ngFor=\"let userEvent of userEvents | async\"\n (click)=\"read($event, userEvent)\"\n >\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"userEvent.avatar; else avatarIcon\" src=\"{{ userEvent.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"userEvent.avatarIcon\"\n [ref]=\"userEvent.avatarIcon\"\n height=\"40\"\n width=\"40\"\n ></app-icon>\n </ng-template>\n\n </ion-avatar>\n\n <ion-grid class=\"ion-no-margin ion-no-padding\">\n <ion-row>\n <ion-col>\n <p [class.unread]=\"!userEvent.readDate\">\n {{userEvent.message}}\n </p>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"userEvent.actions?.length\">\n <ion-col>\n <p>\n <span *ngFor=\"let action of userEvent.actions\">\n <a\n [style.margin-right.px]=\"8\"\n [style.cursor]=\"'pointer'\"\n (click)=\"executeAction(action, userEvent)\"\n >\n {{ '&#10142;&nbsp;' + action.name}}\n </a>\n </span>\n </p>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <app-icon\n *ngIf=\"userEvent.icon\"\n [ref]=\"userEvent.icon\"\n height=\"16\"\n width=\"16\"\n [style.vertical-align]=\"'sub'\"\n ></app-icon>\n <small>\n <span>{{userEvent.creationDate|dateFromNow}}</span>\n <span [style.color]=\"'gray'\">{{ ' | ' + (userEvent.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
31182
+ template: "\n<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!(userEvents | async)?.length\">\n {{'SOCIAL.USER_EVENT.NOTIFICATION.EMPTY' | translate}}\n </ion-item>\n <ion-item\n *ngFor=\"let userEvent of userEvents | async\"\n (click)=\"read($event, userEvent)\"\n >\n\n <ion-avatar slot=\"start\">\n\n <img *ngIf=\"userEvent.avatar; else avatarIcon\" src=\"{{ userEvent.avatar }}\">\n\n <ng-template #avatarIcon>\n <app-icon\n *ngIf=\"userEvent.avatarIcon\"\n [ref]=\"userEvent.avatarIcon\"\n height=\"40\"\n width=\"40\"\n ></app-icon>\n </ng-template>\n\n </ion-avatar>\n\n <ion-grid class=\"ion-no-margin ion-no-padding\">\n <ion-row>\n <ion-col>\n <p [class.unread]=\"!userEvent.readDate\">\n {{userEvent.message}}\n </p>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"userEvent.actions?.length\">\n <ion-col>\n <p>\n <span *ngFor=\"let action of userEvent.actions\">\n <a\n [style.margin-right.px]=\"8\"\n [style.cursor]=\"'pointer'\"\n (click)=\"executeAction(action, userEvent)\"\n >\n {{ '&#10142;&nbsp;' + action.name}}\n </a>\n </span>\n </p>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <app-icon\n *ngIf=\"userEvent.icon\"\n [ref]=\"userEvent.icon\"\n height=\"16\"\n width=\"16\"\n [style.vertical-align]=\"'sub'\"\n ></app-icon>\n <small>\n <span>{{userEvent.creationDate|dateFromNow}}</span>\n <span [style.color]=\"'gray'\">{{ ' | ' + (userEvent.creationDate|dateFormat:{time:true}) }}</span>\n </small>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n <ion-row class=\"ion-list-footer column\">\n <ion-col>\n <a style=\"cursor: pointer\" (click)=\"readAll($event)\">{{'SOCIAL.USER_EVENT.NOTIFICATION.READ_ALL' | translate}}</a>\n </ion-col>\n </ion-row>\n\n</ion-list>\n",
31183
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
30960
31184
  styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}"]
30961
31185
  },] }
30962
31186
  ];
30963
31187
  UserEventNotificationList.ctorParameters = function () { return [
30964
- { type: i1$5.PopoverController }
31188
+ { type: i0.ChangeDetectorRef },
31189
+ { type: i1$5.PopoverController },
31190
+ { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [UserEventServiceToken,] }] }
30965
31191
  ]; };
30966
31192
  UserEventNotificationList.propDecorators = {
31193
+ debug: [{ type: i0.Input }],
30967
31194
  titleI18n: [{ type: i0.Input }],
30968
- userEvents: [{ type: i0.Input }],
30969
- readEvent: [{ type: i0.Output }]
31195
+ readEvent: [{ type: i0.Output }],
31196
+ readEvents: [{ type: i0.Output }]
30970
31197
  };
30971
31198
 
30972
31199
  var UserEventNotificationComponent = /** @class */ (function () {
30973
- function UserEventNotificationComponent(userEventService, accountService, popoverController, cd) {
31200
+ function UserEventNotificationComponent(userEventService, accountService, popoverController) {
30974
31201
  this.userEventService = userEventService;
30975
31202
  this.accountService = accountService;
30976
31203
  this.popoverController = popoverController;
30977
- this.cd = cd;
30978
31204
  this.debug = false;
30979
31205
  this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
30980
31206
  this.disabled = false;
30981
- this.userEventsSubject = new rxjs.BehaviorSubject(undefined);
30982
- this._subscriptions = new rxjs.Subscription();
30983
31207
  this._logPrefix = '[user-event-notification] ';
30984
31208
  this._readEvent = new i0.EventEmitter();
31209
+ this._readEvents = new i0.EventEmitter();
30985
31210
  }
30986
31211
  Object.defineProperty(UserEventNotificationComponent.prototype, "count", {
30987
31212
  get: function () {
@@ -30992,24 +31217,24 @@
30992
31217
  configurable: true
30993
31218
  });
30994
31219
  UserEventNotificationComponent.prototype.ngOnInit = function () {
30995
- var _this = this;
30996
- var _a;
30997
- if (isNil(this.userEventService)) {
30998
- console.warn(this._logPrefix + "No service injected");
30999
- this.disabled = true;
31000
- return;
31001
- }
31002
- this._subscriptions.add(this.userEventService.watchAll(0, 10, 'creationDate', "desc", {
31003
- recipients: [(_a = this.accountService.person) === null || _a === void 0 ? void 0 : _a.pubkey]
31004
- }).subscribe(function (value) {
31005
- var data = value.data;
31006
- if (_this.debug) {
31007
- console.debug(_this._logPrefix + "Receiving user events", data);
31008
- }
31009
- _this.userEventsSubject.next(data);
31010
- }));
31011
- this._readEvent.subscribe(function (value) {
31012
- _this.userEventService.markAsRead(value);
31220
+ return __awaiter(this, void 0, void 0, function () {
31221
+ var _this = this;
31222
+ return __generator(this, function (_b) {
31223
+ if (isNil(this.userEventService)) {
31224
+ console.warn(this._logPrefix + "No service injected");
31225
+ this.disabled = true;
31226
+ return [2 /*return*/];
31227
+ }
31228
+ // Subscribe to read event
31229
+ this._readEvent.subscribe(function (value) {
31230
+ // default: mark event as read
31231
+ _this.userEventService.markAsRead([value]);
31232
+ });
31233
+ this._readEvents.subscribe(function (value) {
31234
+ _this.userEventService.markAsRead(value);
31235
+ });
31236
+ return [2 /*return*/];
31237
+ });
31013
31238
  });
31014
31239
  };
31015
31240
  UserEventNotificationComponent.prototype.showList = function (event) {
@@ -31017,19 +31242,23 @@
31017
31242
  var popover;
31018
31243
  return __generator(this, function (_b) {
31019
31244
  switch (_b.label) {
31020
- case 0: return [4 /*yield*/, this.popoverController.create({
31021
- component: UserEventNotificationList,
31022
- componentProps: {
31023
- titleI18n: this.titleI18n,
31024
- userEvents: this.userEventsSubject,
31025
- readEvent: this._readEvent
31026
- },
31027
- backdropDismiss: true,
31028
- keyboardClose: true,
31029
- event: event,
31030
- translucent: true,
31031
- cssClass: 'popover-large'
31032
- })];
31245
+ case 0:
31246
+ // Reset count
31247
+ this.userEventService.resetCount();
31248
+ return [4 /*yield*/, this.popoverController.create({
31249
+ component: UserEventNotificationList,
31250
+ componentProps: {
31251
+ debug: this.debug,
31252
+ titleI18n: this.titleI18n,
31253
+ readEvent: this._readEvent,
31254
+ readEvents: this._readEvents
31255
+ },
31256
+ backdropDismiss: true,
31257
+ keyboardClose: true,
31258
+ event: event,
31259
+ translucent: true,
31260
+ cssClass: 'popover-large'
31261
+ })];
31033
31262
  case 1:
31034
31263
  popover = _b.sent();
31035
31264
  return [4 /*yield*/, popover.present()];
@@ -31040,14 +31269,10 @@
31040
31269
  });
31041
31270
  });
31042
31271
  };
31043
- UserEventNotificationComponent.prototype.markForCheck = function () {
31044
- this.cd.markForCheck();
31045
- };
31046
31272
  UserEventNotificationComponent.prototype.ngOnDestroy = function () {
31047
31273
  if (this.debug) {
31048
31274
  console.debug(this._logPrefix + "Destroying");
31049
31275
  }
31050
- this._subscriptions.unsubscribe();
31051
31276
  };
31052
31277
  return UserEventNotificationComponent;
31053
31278
  }());
@@ -31062,8 +31287,7 @@
31062
31287
  UserEventNotificationComponent.ctorParameters = function () { return [
31063
31288
  { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [UserEventServiceToken,] }] },
31064
31289
  { type: AccountService },
31065
- { type: i1$5.PopoverController },
31066
- { type: i0.ChangeDetectorRef }
31290
+ { type: i1$5.PopoverController }
31067
31291
  ]; };
31068
31292
  UserEventNotificationComponent.propDecorators = {
31069
31293
  debug: [{ type: i0.Input }],
@@ -31071,6 +31295,100 @@
31071
31295
  disabled: [{ type: i0.Input }]
31072
31296
  };
31073
31297
 
31298
+ var UserEventTestService = /** @class */ (function (_super) {
31299
+ __extends(UserEventTestService, _super);
31300
+ function UserEventTestService(graphql, accountService, network, translate, environment) {
31301
+ var _this = _super.call(this, graphql, accountService, network, translate, undefined, undefined, undefined, environment) || this;
31302
+ _this.graphql = graphql;
31303
+ _this.accountService = accountService;
31304
+ _this.network = network;
31305
+ _this.translate = translate;
31306
+ _this.environment = environment;
31307
+ _this.userEvents = [];
31308
+ return _this;
31309
+ }
31310
+ UserEventTestService.prototype.fromObject = function (source) {
31311
+ return exports.UserEvent.fromObject(source);
31312
+ };
31313
+ UserEventTestService.prototype.add = function (entity) {
31314
+ entity = this.processUserEvent(entity);
31315
+ entity.id = this.userEvents.length + 1;
31316
+ this.userEvents.push(entity);
31317
+ this.count$.next(this.userEvents.length);
31318
+ };
31319
+ UserEventTestService.prototype.asFilter = function (filter) {
31320
+ return filter;
31321
+ };
31322
+ UserEventTestService.prototype.count = function (filter, options) {
31323
+ return Promise.resolve(this.userEvents.length);
31324
+ };
31325
+ UserEventTestService.prototype.delete = function (entity) {
31326
+ return Promise.resolve(undefined);
31327
+ };
31328
+ UserEventTestService.prototype.deleteAll = function (data, opts) {
31329
+ return Promise.resolve(undefined);
31330
+ };
31331
+ UserEventTestService.prototype.listenChanges = function (filter, options) {
31332
+ return rxjs.of();
31333
+ };
31334
+ UserEventTestService.prototype.save = function (entity, options) {
31335
+ var _a;
31336
+ 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); });
31337
+ Object.assign(toSave, entity);
31338
+ return entity;
31339
+ };
31340
+ UserEventTestService.prototype.saveAll = function (data, opts) {
31341
+ return __awaiter(this, void 0, void 0, function () {
31342
+ var _b, _c, entity, e_1_1;
31343
+ var e_1, _d;
31344
+ return __generator(this, function (_e) {
31345
+ switch (_e.label) {
31346
+ case 0:
31347
+ _e.trys.push([0, 5, 6, 7]);
31348
+ _b = __values((data || [])), _c = _b.next();
31349
+ _e.label = 1;
31350
+ case 1:
31351
+ if (!!_c.done) return [3 /*break*/, 4];
31352
+ entity = _c.value;
31353
+ return [4 /*yield*/, this.save(entity)];
31354
+ case 2:
31355
+ _e.sent();
31356
+ _e.label = 3;
31357
+ case 3:
31358
+ _c = _b.next();
31359
+ return [3 /*break*/, 1];
31360
+ case 4: return [3 /*break*/, 7];
31361
+ case 5:
31362
+ e_1_1 = _e.sent();
31363
+ e_1 = { error: e_1_1 };
31364
+ return [3 /*break*/, 7];
31365
+ case 6:
31366
+ try {
31367
+ if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
31368
+ }
31369
+ finally { if (e_1) throw e_1.error; }
31370
+ return [7 /*endfinally*/];
31371
+ case 7: return [2 /*return*/, Promise.resolve(this.userEvents)];
31372
+ }
31373
+ });
31374
+ });
31375
+ };
31376
+ UserEventTestService.prototype.watchAll = function (offset, size, sortBy, sortDirection, filter, options) {
31377
+ return rxjs.of({ data: this.userEvents });
31378
+ };
31379
+ return UserEventTestService;
31380
+ }(AbstractUserEventService));
31381
+ UserEventTestService.decorators = [
31382
+ { type: i0.Injectable }
31383
+ ];
31384
+ UserEventTestService.ctorParameters = function () { return [
31385
+ { type: GraphqlService },
31386
+ { type: AccountService },
31387
+ { type: NetworkService },
31388
+ { type: i1$2.TranslateService },
31389
+ { type: Environment, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [ENVIRONMENT,] }] }
31390
+ ]; };
31391
+
31074
31392
  var UserEventModule = /** @class */ (function () {
31075
31393
  function UserEventModule() {
31076
31394
  }
@@ -31091,6 +31409,9 @@
31091
31409
  exports: [
31092
31410
  UserEventsTable,
31093
31411
  UserEventNotificationComponent
31412
+ ],
31413
+ providers: [
31414
+ { provide: UserEventServiceToken, useClass: UserEventTestService }
31094
31415
  ]
31095
31416
  },] }
31096
31417
  ];
@@ -31376,7 +31697,7 @@
31376
31697
  ], exports.JobProgression);
31377
31698
 
31378
31699
  var JobProgressionServiceToken = new i0.InjectionToken('JobProgressionService');
31379
- var jobProgressionSubscription = core.gql(templateObject_1$4 || (templateObject_1$4 = __makeTemplateObject(["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n updateDate\n }\n}"], ["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n updateDate\n }\n}"])));
31700
+ var jobProgressionSubscription = core.gql(templateObject_1$4 || (templateObject_1$4 = __makeTemplateObject(["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n }\n}"], ["subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n message\n current\n total\n }\n}"])));
31380
31701
  var JobProgressionService = /** @class */ (function (_super) {
31381
31702
  __extends(JobProgressionService, _super);
31382
31703
  function JobProgressionService(graphql, environment) {
@@ -34253,12 +34574,13 @@
34253
34574
  exports.ɵi = AppUpdateOfflineModeCard;
34254
34575
  exports.ɵj = AppIconComponent;
34255
34576
  exports.ɵk = UserEventNotificationList;
34256
- exports.ɵl = JobProgressionList;
34257
- exports.ɵm = DateTestPage;
34258
- exports.ɵn = NumpadTestPage;
34259
- exports.ɵo = MatBadgeIconTestPage;
34260
- exports.ɵp = ToastTestingModule;
34261
- exports.ɵq = ToastTestingPage;
34577
+ exports.ɵl = UserEventTestService;
34578
+ exports.ɵm = JobProgressionList;
34579
+ exports.ɵn = DateTestPage;
34580
+ exports.ɵo = NumpadTestPage;
34581
+ exports.ɵp = MatBadgeIconTestPage;
34582
+ exports.ɵq = ToastTestingModule;
34583
+ exports.ɵr = ToastTestingPage;
34262
34584
 
34263
34585
  Object.defineProperty(exports, '__esModule', { value: true });
34264
34586