@sumaris-net/ngx-components 1.21.7 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/sumaris-net.ngx-components.umd.js +1305 -200
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +3 -0
- package/esm2015/public_api.js +8 -1
- package/esm2015/src/app/core/form/editor.class.js +7 -11
- package/esm2015/src/app/core/icon/icon.component.js +5 -2
- package/esm2015/src/app/core/menu/menu.component.js +2 -2
- package/esm2015/src/app/shared/pipes/date-diff-duration.pipe.js +9 -5
- package/esm2015/src/app/shared/types.js +1 -1
- package/esm2015/src/app/social/job/job.model.js +26 -0
- package/esm2015/src/app/social/job/job.module.js +25 -0
- package/esm2015/src/app/social/job/job.service.js +54 -0
- package/esm2015/src/app/social/job/progression/job-progression.component.js +200 -0
- package/esm2015/src/app/social/job/progression/job-progression.list.js +20 -0
- package/esm2015/src/app/social/message/message.module.js +25 -0
- package/esm2015/src/app/social/social.errors.js +5 -2
- package/esm2015/src/app/social/social.module.js +10 -15
- package/esm2015/src/app/social/user-event/notification/user-event-notification.component.js +89 -0
- package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +78 -0
- package/esm2015/src/app/social/user-event/testing/user-event.testing.service.js +73 -0
- package/esm2015/src/app/social/user-event/user-event.model.js +58 -2
- package/esm2015/src/app/social/user-event/user-event.module.js +33 -0
- package/esm2015/src/app/social/user-event/user-event.service.js +412 -173
- package/esm2015/src/app/social/user-event/user-events.table.js +18 -13
- package/esm2015/sumaris-net.ngx-components.js +9 -6
- package/fesm2015/sumaris-net.ngx-components.js +1122 -259
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +7 -0
- package/src/app/core/icon/icon.component.d.ts +4 -4
- package/src/app/shared/material/badge/badge-icon.test.d.ts +1 -1
- package/src/app/shared/pipes/date-diff-duration.pipe.d.ts +6 -2
- package/src/app/shared/types.d.ts +4 -0
- package/src/app/social/job/job.model.d.ts +33 -0
- package/src/app/social/job/job.module.d.ts +2 -0
- package/src/app/social/job/job.service.d.ts +23 -0
- package/src/app/social/job/progression/job-progression.component.d.ts +44 -0
- package/src/app/social/job/progression/job-progression.list.d.ts +12 -0
- package/src/app/social/message/message.module.d.ts +2 -0
- package/src/app/social/social.errors.d.ts +3 -0
- package/src/app/social/social.module.d.ts +8 -0
- package/src/app/social/user-event/notification/user-event-notification.component.d.ts +22 -0
- package/src/app/social/user-event/notification/user-event-notification.list.d.ts +30 -0
- package/src/app/social/user-event/testing/user-event.testing.service.d.ts +35 -0
- package/src/app/social/user-event/user-event.model.d.ts +52 -8
- package/src/app/social/user-event/user-event.module.d.ts +2 -0
- package/src/app/social/user-event/user-event.service.d.ts +101 -51
- package/src/app/social/user-event/user-events.table.d.ts +6 -6
- package/src/assets/i18n/en-US.json +15 -2
- package/src/assets/i18n/en.json +16 -2
- package/src/assets/i18n/fr.json +15 -1
- package/src/theme/_ngx-components.scss +8 -0
- package/sumaris-net.ngx-components.d.ts +8 -5
- package/sumaris-net.ngx-components.metadata.json +1 -1
|
@@ -1966,17 +1966,21 @@ class DateDiffDurationPipe {
|
|
|
1966
1966
|
return '';
|
|
1967
1967
|
const startDate = this.dateAdapter.parse(value.startValue, DATE_ISO_PATTERN);
|
|
1968
1968
|
const endDate = this.dateAdapter.parse(value.endValue, DATE_ISO_PATTERN);
|
|
1969
|
-
return this.format(startDate, endDate);
|
|
1969
|
+
return this.format(startDate, endDate, args);
|
|
1970
1970
|
}
|
|
1971
|
-
format(startDate, endDate) {
|
|
1971
|
+
format(startDate, endDate, args) {
|
|
1972
1972
|
const duration = moment.duration(endDate.diff(startDate));
|
|
1973
1973
|
if (duration.asMinutes() < 0)
|
|
1974
1974
|
return '';
|
|
1975
|
+
const withSeconds = args === null || args === void 0 ? void 0 : args.seconds;
|
|
1975
1976
|
const timeDuration = moment(0)
|
|
1976
1977
|
.hour(duration.hours())
|
|
1977
1978
|
.minute(duration.minutes());
|
|
1979
|
+
if (withSeconds) {
|
|
1980
|
+
timeDuration.second(duration.seconds());
|
|
1981
|
+
}
|
|
1978
1982
|
const days = Math.floor(duration.asDays());
|
|
1979
|
-
return (days > 0 ? days.toString() + (this.dayUnit + ' ') : '') + timeDuration.format('HH:mm');
|
|
1983
|
+
return (days > 0 ? days.toString() + (this.dayUnit + ' ') : '') + timeDuration.format(withSeconds ? 'HH:mm:ss' : 'HH:mm');
|
|
1980
1984
|
}
|
|
1981
1985
|
}
|
|
1982
1986
|
DateDiffDurationPipe.ɵprov = ɵɵdefineInjectable({ factory: function DateDiffDurationPipe_Factory() { return new DateDiffDurationPipe(ɵɵinject(DateAdapter), ɵɵinject(TranslateService)); }, token: DateDiffDurationPipe, providedIn: "root" });
|
|
@@ -21477,7 +21481,7 @@ class MenuComponent {
|
|
|
21477
21481
|
MenuComponent.decorators = [
|
|
21478
21482
|
{ type: Component, args: [{
|
|
21479
21483
|
selector: 'app-menu',
|
|
21480
|
-
template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\" @fadeInAnimation\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n\n <ion-list lines=\"none\">\n <ion-menu-toggle auto-hide=\"false\"\n [class.flex-spacer]=\"item.cssClass == 'flex-spacer'\"\n *ngFor=\"let item of $items | async\">\n\n <!-- link -->\n <ion-item *ngIf=\"!loading && item.path\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/')}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"!loading && item.action\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!loading && !item.path && !item.action\">\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item-divider>\n\n </ion-menu-toggle>\n </ion-list>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n",
|
|
21484
|
+
template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" contentId=\"menu-content\">\n <ion-header>\n\n <ion-toolbar @fadeInAnimation *ngIf=\"isLogin; else notLogin\" class=\"ion-toolbar-top\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px;\"/>\n <span *ngIf=\"!logo\" width=\"108px;\">{{appName}}</span>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n\n<!-- todo ajouter ici les 2 composants du module social ??? -->\n\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\" @fadeInAnimation\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n\n <ion-list lines=\"none\">\n <ion-menu-toggle auto-hide=\"false\"\n [class.flex-spacer]=\"item.cssClass == 'flex-spacer'\"\n *ngFor=\"let item of $items | async\">\n\n <!-- link -->\n <ion-item *ngIf=\"!loading && item.path\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n [routerLink]=\"item.path\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/')}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"!loading && item.action\"\n @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!loading && !item.path && !item.action\">\n <ion-label translate>{{item.title}}</ion-label>\n </ion-item-divider>\n\n </ion-menu-toggle>\n </ion-list>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n",
|
|
21481
21485
|
animations: [fadeInAnimation],
|
|
21482
21486
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21483
21487
|
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)}}"]
|
|
@@ -21541,13 +21545,14 @@ class AppIconComponent {
|
|
|
21541
21545
|
this.icon = value.icon;
|
|
21542
21546
|
this.matIcon = value.matIcon;
|
|
21543
21547
|
this.matSvgIcon = value.matSvgIcon;
|
|
21548
|
+
this.color = value.color;
|
|
21544
21549
|
}
|
|
21545
21550
|
;
|
|
21546
21551
|
}
|
|
21547
21552
|
AppIconComponent.decorators = [
|
|
21548
21553
|
{ type: Component, args: [{
|
|
21549
21554
|
selector: 'app-icon',
|
|
21550
|
-
template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\">{{matIcon}}</mat-icon>\n</ng-template>\n\n"
|
|
21555
|
+
template: "<ion-icon *ngIf=\"icon; else matIconTemplate\" slot=\"icon-only\"\n [color]=\"color\"\n [name]=\"icon\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n></ion-icon>\n<ng-template #matIconTemplate>\n <mat-icon [svgIcon]=\"matSvgIcon\"\n [style.color]=\"'var(--ion-color-'+color+')'\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n [style.font-size.px]=\"height || width\"\n >{{matIcon}}</mat-icon>\n</ng-template>\n\n"
|
|
21551
21556
|
},] }
|
|
21552
21557
|
];
|
|
21553
21558
|
AppIconComponent.propDecorators = {
|
|
@@ -21555,6 +21560,8 @@ AppIconComponent.propDecorators = {
|
|
|
21555
21560
|
matIcon: [{ type: Input }],
|
|
21556
21561
|
matSvgIcon: [{ type: Input }],
|
|
21557
21562
|
color: [{ type: Input }],
|
|
21563
|
+
height: [{ type: Input }],
|
|
21564
|
+
width: [{ type: Input }],
|
|
21558
21565
|
ref: [{ type: Input }]
|
|
21559
21566
|
};
|
|
21560
21567
|
|
|
@@ -24229,8 +24236,7 @@ class AppEditor {
|
|
|
24229
24236
|
return this._children && this._children.filter(c => c instanceof AppEditor);
|
|
24230
24237
|
}
|
|
24231
24238
|
get dirty() {
|
|
24232
|
-
|
|
24233
|
-
return this._dirty || (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(c => c.enabled && c.dirty)) !== -1) || false;
|
|
24239
|
+
return this._dirty || (this._children && this._children.findIndex(c => c.enabled && c.dirty) !== -1) || false;
|
|
24234
24240
|
}
|
|
24235
24241
|
/**
|
|
24236
24242
|
* Is valid (tables and forms)
|
|
@@ -24240,16 +24246,13 @@ class AppEditor {
|
|
|
24240
24246
|
return !this._children || this._children.findIndex(c => c.enabled && !c.valid) === -1;
|
|
24241
24247
|
}
|
|
24242
24248
|
get invalid() {
|
|
24243
|
-
|
|
24244
|
-
return (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(c => c.enabled && c.invalid)) !== -1) || false;
|
|
24249
|
+
return (this._children && this._children.findIndex(c => c.enabled && c.invalid) !== -1) || false;
|
|
24245
24250
|
}
|
|
24246
24251
|
get pending() {
|
|
24247
|
-
|
|
24248
|
-
return (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(c => c.enabled && c.pending)) !== -1) || false;
|
|
24252
|
+
return (this._children && this._children.findIndex(c => c.enabled && c.pending) !== -1) || false;
|
|
24249
24253
|
}
|
|
24250
24254
|
get loading() {
|
|
24251
|
-
|
|
24252
|
-
return this.loadingSubject.value || (((_a = this._children) === null || _a === void 0 ? void 0 : _a.findIndex(c => c.enabled && c.loading)) !== -1) || false;
|
|
24255
|
+
return this.loadingSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.loading) !== -1) || false;
|
|
24253
24256
|
}
|
|
24254
24257
|
get enabled() {
|
|
24255
24258
|
return this._enabled;
|
|
@@ -24403,10 +24406,11 @@ class AppEditor {
|
|
|
24403
24406
|
* @param opts
|
|
24404
24407
|
*/
|
|
24405
24408
|
unload(opts) {
|
|
24409
|
+
var _a;
|
|
24406
24410
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24407
24411
|
console.debug('[tab-page] Unloading data...');
|
|
24408
24412
|
this.markAsLoading();
|
|
24409
|
-
this._children.forEach(f => {
|
|
24413
|
+
(_a = this._children) === null || _a === void 0 ? void 0 : _a.forEach(f => {
|
|
24410
24414
|
if (f instanceof AppForm) {
|
|
24411
24415
|
f.reset(null, opts);
|
|
24412
24416
|
}
|
|
@@ -24414,7 +24418,6 @@ class AppEditor {
|
|
|
24414
24418
|
f.dataSource.disconnect();
|
|
24415
24419
|
}
|
|
24416
24420
|
});
|
|
24417
|
-
// TODO: find a way to remove current page from the navigation history
|
|
24418
24421
|
});
|
|
24419
24422
|
}
|
|
24420
24423
|
reloadWithConfirmation(confirm) {
|
|
@@ -25923,7 +25926,10 @@ AppInMemoryTable.propDecorators = {
|
|
|
25923
25926
|
const SocialErrorCodes = {
|
|
25924
25927
|
LOAD_USER_EVENTS_ERROR: 50000,
|
|
25925
25928
|
SAVE_USER_EVENT_ERROR: 50001,
|
|
25926
|
-
|
|
25929
|
+
COUNT_USER_EVENT_ERROR: 50002,
|
|
25930
|
+
SEND_MESSAGE_ERROR: 50003,
|
|
25931
|
+
SUBSCRIBE_USER_EVENTS_ERROR: 50005,
|
|
25932
|
+
SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010
|
|
25927
25933
|
};
|
|
25928
25934
|
|
|
25929
25935
|
var UserEvent_1;
|
|
@@ -25938,16 +25944,23 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25938
25944
|
}
|
|
25939
25945
|
asObject(opts) {
|
|
25940
25946
|
const target = super.asObject(opts);
|
|
25947
|
+
target.creationDate = toDateISOString(this.creationDate);
|
|
25948
|
+
target.readDate = toDateISOString(this.readDate);
|
|
25941
25949
|
// Serialize content
|
|
25942
25950
|
if (typeof target.content === 'object') {
|
|
25943
25951
|
target.content = JSON.stringify(target.content);
|
|
25944
25952
|
}
|
|
25953
|
+
delete target.avatar;
|
|
25954
|
+
delete target.avatarIcon;
|
|
25955
|
+
delete target.icon;
|
|
25956
|
+
delete target.actions;
|
|
25945
25957
|
return target;
|
|
25946
25958
|
}
|
|
25947
25959
|
fromObject(source) {
|
|
25948
25960
|
Object.assign(this, source); // Copy all properties
|
|
25949
25961
|
super.fromObject(source);
|
|
25950
25962
|
this.creationDate = fromDateISOString(source.creationDate);
|
|
25963
|
+
this.readDate = fromDateISOString(source.readDate);
|
|
25951
25964
|
try {
|
|
25952
25965
|
// Deserialize content
|
|
25953
25966
|
if (typeof source.content === 'string' && source.content.startsWith('{')) {
|
|
@@ -25966,6 +25979,52 @@ let UserEvent = UserEvent_1 = class UserEvent extends Entity {
|
|
|
25966
25979
|
UserEvent = UserEvent_1 = __decorate([
|
|
25967
25980
|
EntityClass({ typename: 'UserEventVO' })
|
|
25968
25981
|
], UserEvent);
|
|
25982
|
+
// @dynamic
|
|
25983
|
+
let UserEventFilter = class UserEventFilter extends EntityFilter {
|
|
25984
|
+
constructor() {
|
|
25985
|
+
super(...arguments);
|
|
25986
|
+
this.types = [];
|
|
25987
|
+
this.levels = [];
|
|
25988
|
+
this.issuers = [];
|
|
25989
|
+
this.recipients = [];
|
|
25990
|
+
this.startDate = null;
|
|
25991
|
+
this.excludeRead = false;
|
|
25992
|
+
}
|
|
25993
|
+
fromObject(source, opts) {
|
|
25994
|
+
super.fromObject(source, opts);
|
|
25995
|
+
this.types = source.types || [];
|
|
25996
|
+
this.levels = source.levels || [];
|
|
25997
|
+
this.issuers = source.issuers || [];
|
|
25998
|
+
this.recipients = source.recipients || [];
|
|
25999
|
+
this.startDate = fromDateISOString(source.startDate);
|
|
26000
|
+
this.excludeRead = source.excludeRead || false;
|
|
26001
|
+
}
|
|
26002
|
+
buildFilter() {
|
|
26003
|
+
const filterFns = super.buildFilter();
|
|
26004
|
+
if (isNotEmptyArray(this.types)) {
|
|
26005
|
+
filterFns.push(t => this.types.includes(t.type));
|
|
26006
|
+
}
|
|
26007
|
+
if (isNotEmptyArray(this.levels)) {
|
|
26008
|
+
filterFns.push(t => this.levels.includes(t.level));
|
|
26009
|
+
}
|
|
26010
|
+
if (isNotEmptyArray(this.issuers)) {
|
|
26011
|
+
filterFns.push(t => this.issuers.includes(t.issuer));
|
|
26012
|
+
}
|
|
26013
|
+
if (isNotEmptyArray(this.recipients)) {
|
|
26014
|
+
filterFns.push(t => this.recipients.includes(t.recipient));
|
|
26015
|
+
}
|
|
26016
|
+
if (isNotNil(this.startDate)) {
|
|
26017
|
+
filterFns.push(t => this.startDate.isSameOrBefore(t.creationDate));
|
|
26018
|
+
}
|
|
26019
|
+
if (this.excludeRead === true) {
|
|
26020
|
+
filterFns.push(t => isNil(t.readSignature)); // todo or t.signature ?
|
|
26021
|
+
}
|
|
26022
|
+
return filterFns;
|
|
26023
|
+
}
|
|
26024
|
+
};
|
|
26025
|
+
UserEventFilter = __decorate([
|
|
26026
|
+
EntityClass({ typename: 'UserEventFilterVO' })
|
|
26027
|
+
], UserEventFilter);
|
|
25969
26028
|
|
|
25970
26029
|
const UserEventFragments = {
|
|
25971
26030
|
userEvent: gql `fragment UserEventFragment on UserEventVO {
|
|
@@ -25993,179 +26052,206 @@ const UserEventFragments = {
|
|
|
25993
26052
|
}`
|
|
25994
26053
|
};
|
|
25995
26054
|
|
|
25996
|
-
|
|
25997
|
-
|
|
25998
|
-
|
|
25999
|
-
|
|
26000
|
-
this.issuer = null;
|
|
26001
|
-
this.recipient = null;
|
|
26002
|
-
}
|
|
26003
|
-
fromObject(source, opts) {
|
|
26004
|
-
super.fromObject(source, opts);
|
|
26005
|
-
this.issuer = source.issuer;
|
|
26006
|
-
this.recipient = source.recipient;
|
|
26007
|
-
}
|
|
26008
|
-
buildFilter() {
|
|
26009
|
-
const filterFns = super.buildFilter();
|
|
26010
|
-
// issuer
|
|
26011
|
-
if (this.issuer) {
|
|
26012
|
-
filterFns.push(t => (t.issuer === this.issuer));
|
|
26013
|
-
}
|
|
26014
|
-
if (this.recipient) {
|
|
26015
|
-
filterFns.push(t => (t.recipient === this.recipient));
|
|
26016
|
-
}
|
|
26017
|
-
return filterFns;
|
|
26018
|
-
}
|
|
26019
|
-
};
|
|
26020
|
-
UserEventFilter = __decorate([
|
|
26021
|
-
EntityClass({ typename: 'UserEventFilterVO' })
|
|
26022
|
-
], UserEventFilter);
|
|
26023
|
-
const SaveQuery = gql `
|
|
26024
|
-
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26025
|
-
data: saveUserEvent(userEvent: $data){
|
|
26026
|
-
...UserEventFragment
|
|
26027
|
-
}
|
|
26028
|
-
}
|
|
26029
|
-
${UserEventFragments.userEvent}
|
|
26030
|
-
`;
|
|
26031
|
-
const LoadAllQuery = gql `
|
|
26032
|
-
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26033
|
-
data: userEvents(filter: $filter, page: $page){
|
|
26034
|
-
...LightUserEventFragment
|
|
26035
|
-
}
|
|
26036
|
-
}
|
|
26037
|
-
${UserEventFragments.lightUserEvent}
|
|
26038
|
-
`;
|
|
26039
|
-
const DeleteByIdsMutation = gql `
|
|
26040
|
-
mutation DeleteUserEvents($ids:[Int]){
|
|
26041
|
-
deleteUserEvents(ids: $ids)
|
|
26042
|
-
}
|
|
26043
|
-
`;
|
|
26044
|
-
const LoadAllWithContentQuery = gql `
|
|
26045
|
-
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26046
|
-
data: userEvents(filter: $filter, page: $page){
|
|
26047
|
-
...UserEventFragment
|
|
26048
|
-
}
|
|
26049
|
-
}
|
|
26050
|
-
${UserEventFragments.userEvent}
|
|
26051
|
-
`;
|
|
26052
|
-
class UserEventService extends BaseGraphqlService {
|
|
26053
|
-
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26055
|
+
const moment$6 = momentImported;
|
|
26056
|
+
const UserEventServiceToken = new InjectionToken('UserEventService');
|
|
26057
|
+
class AbstractUserEventService extends BaseGraphqlService {
|
|
26058
|
+
constructor(graphql, accountService, network, translate, queries, mutations, subscriptions, environment) {
|
|
26054
26059
|
super(graphql, environment);
|
|
26055
26060
|
this.graphql = graphql;
|
|
26056
26061
|
this.accountService = accountService;
|
|
26057
26062
|
this.network = network;
|
|
26058
26063
|
this.translate = translate;
|
|
26059
|
-
this.
|
|
26064
|
+
this.queries = queries;
|
|
26065
|
+
this.mutations = mutations;
|
|
26066
|
+
this.subscriptions = subscriptions;
|
|
26060
26067
|
this.environment = environment;
|
|
26061
|
-
this.
|
|
26068
|
+
this.count$ = new BehaviorSubject(0);
|
|
26069
|
+
this.listeners = [];
|
|
26070
|
+
this._subscriptions = new Subscription();
|
|
26071
|
+
this._logPrefix = '[user-event-service] ';
|
|
26062
26072
|
// For DEV only
|
|
26063
|
-
this._debug = environment
|
|
26073
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
26074
|
+
}
|
|
26075
|
+
get userEventCount() {
|
|
26076
|
+
return this.count$.asObservable();
|
|
26077
|
+
}
|
|
26078
|
+
ngOnStart() {
|
|
26079
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26080
|
+
// Update component when refresh is need (=login events)
|
|
26081
|
+
this._subscriptions.add(merge(this.accountService.onLogin, this.accountService.onLogout)
|
|
26082
|
+
.pipe(
|
|
26083
|
+
// Wait account service ready (can be restarted)
|
|
26084
|
+
mergeMap(() => this.accountService.ready()), map(() => this.accountService.isLogin()), distinctUntilChanged())
|
|
26085
|
+
.subscribe(login => {
|
|
26086
|
+
if (login) {
|
|
26087
|
+
this.onLogin();
|
|
26088
|
+
}
|
|
26089
|
+
else {
|
|
26090
|
+
this.onLogout();
|
|
26091
|
+
}
|
|
26092
|
+
}));
|
|
26093
|
+
// First attempt if account is ready
|
|
26094
|
+
yield this.accountService.ready();
|
|
26095
|
+
if (this.accountService.isLogin()) {
|
|
26096
|
+
setTimeout(() => this.onLogin());
|
|
26097
|
+
}
|
|
26098
|
+
});
|
|
26099
|
+
}
|
|
26100
|
+
ngOnDestroy() {
|
|
26101
|
+
this._subscriptions.unsubscribe();
|
|
26064
26102
|
}
|
|
26065
|
-
/**
|
|
26066
|
-
*
|
|
26067
|
-
* @param offset
|
|
26068
|
-
* @param size
|
|
26069
|
-
* @param sortBy
|
|
26070
|
-
* @param sortDirection
|
|
26071
|
-
* @param filter
|
|
26072
|
-
* @param options
|
|
26073
|
-
* @deprecated use watchPage() instead
|
|
26074
|
-
*/
|
|
26075
26103
|
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
26076
26104
|
return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
|
|
26077
26105
|
}
|
|
26078
26106
|
watchPage(page, filter, options) {
|
|
26107
|
+
var _a;
|
|
26079
26108
|
let now = this._debug && Date.now();
|
|
26080
|
-
|
|
26081
|
-
|
|
26109
|
+
if (!filter) {
|
|
26110
|
+
filter = this.defaultFilter();
|
|
26111
|
+
}
|
|
26112
|
+
console.debug(`${this._logPrefix}Loading user events...`, filter);
|
|
26082
26113
|
filter = this.asFilter(filter);
|
|
26083
26114
|
// Force recipient to current issuer, if not admin and not specified
|
|
26084
|
-
if (
|
|
26085
|
-
const recipient = this.
|
|
26086
|
-
if (
|
|
26115
|
+
if (isEmptyArray(filter === null || filter === void 0 ? void 0 : filter.recipients) || !this.accountService.isAdmin()) {
|
|
26116
|
+
const recipient = this.defaultRecipient();
|
|
26117
|
+
if (!((_a = filter === null || filter === void 0 ? void 0 : filter.recipients) === null || _a === void 0 ? void 0 : _a.includes(recipient))) {
|
|
26087
26118
|
console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
|
|
26088
|
-
filter.
|
|
26119
|
+
filter.recipients = [recipient];
|
|
26089
26120
|
}
|
|
26090
26121
|
}
|
|
26091
|
-
const withContent = options
|
|
26122
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26092
26123
|
return this.mutableWatchQuery({
|
|
26093
26124
|
queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
|
|
26094
|
-
query: withContent ?
|
|
26125
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26095
26126
|
variables: {
|
|
26096
|
-
page: Object.assign(Object.assign({ sortBy: '
|
|
26127
|
+
page: Object.assign(Object.assign({ sortBy: 'creationDate' }, page), {
|
|
26128
|
+
// @ts-ignore
|
|
26129
|
+
sortDirection: (page.sortDirection || 'desc').toUpperCase() }),
|
|
26097
26130
|
filter: filter && filter.asPodObject()
|
|
26098
26131
|
},
|
|
26099
26132
|
arrayFieldName: 'data',
|
|
26100
26133
|
error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
|
|
26101
|
-
fetchPolicy: options
|
|
26134
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'cache-first'
|
|
26102
26135
|
})
|
|
26103
26136
|
.pipe(map(res => {
|
|
26104
|
-
|
|
26137
|
+
let data = ((res === null || res === void 0 ? void 0 : res.data) || []).map(value => this.processUserEvent(value, this));
|
|
26105
26138
|
if (now) {
|
|
26106
|
-
console.debug(
|
|
26139
|
+
console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);
|
|
26107
26140
|
now = null;
|
|
26108
26141
|
}
|
|
26142
|
+
// Must re-order because of listenChanges result will add new event at the end
|
|
26143
|
+
data = EntityUtils.sort(data, page.sortBy, page.sortDirection);
|
|
26109
26144
|
return {
|
|
26110
26145
|
data,
|
|
26111
|
-
total: res
|
|
26146
|
+
total: toNumber(res === null || res === void 0 ? void 0 : res.total, data.length)
|
|
26112
26147
|
};
|
|
26113
26148
|
}));
|
|
26114
26149
|
}
|
|
26115
|
-
|
|
26116
|
-
|
|
26117
|
-
|
|
26150
|
+
add(entity) {
|
|
26151
|
+
// TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
26152
|
+
entity = this.processUserEvent(entity);
|
|
26153
|
+
const withContent = !!entity.content;
|
|
26154
|
+
// Add user event locally
|
|
26155
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26156
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26157
|
+
data: entity
|
|
26158
|
+
});
|
|
26159
|
+
// Update count
|
|
26160
|
+
this.count$.next(this.count$.value + 1);
|
|
26118
26161
|
}
|
|
26119
|
-
|
|
26120
|
-
|
|
26121
|
-
*
|
|
26122
|
-
* @param entity
|
|
26123
|
-
*/
|
|
26124
|
-
save(entity, options) {
|
|
26162
|
+
count(filter, options) {
|
|
26163
|
+
var _a;
|
|
26125
26164
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26126
|
-
this.
|
|
26127
|
-
|
|
26128
|
-
|
|
26129
|
-
|
|
26130
|
-
|
|
26165
|
+
if (!((_a = this.queries) === null || _a === void 0 ? void 0 : _a.count)) {
|
|
26166
|
+
console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);
|
|
26167
|
+
return undefined;
|
|
26168
|
+
}
|
|
26169
|
+
if (!filter)
|
|
26170
|
+
filter = this.defaultFilter();
|
|
26171
|
+
// Apply last reset date as start date
|
|
26172
|
+
filter.startDate = this.resetCountDate;
|
|
26173
|
+
filter = this.asFilter(filter);
|
|
26131
26174
|
if (this._debug)
|
|
26132
|
-
console.debug(
|
|
26133
|
-
yield this.graphql.
|
|
26134
|
-
|
|
26175
|
+
console.debug(`${this._logPrefix}Counting user events with filter:`, filter);
|
|
26176
|
+
const res = yield this.graphql.query({
|
|
26177
|
+
query: this.queries.count,
|
|
26135
26178
|
variables: {
|
|
26136
|
-
|
|
26179
|
+
filter: filter.asPodObject()
|
|
26137
26180
|
},
|
|
26138
|
-
error: { code: SocialErrorCodes.
|
|
26139
|
-
|
|
26140
|
-
// Update entity
|
|
26141
|
-
const savedEntity = data && data.data;
|
|
26142
|
-
if (savedEntity) {
|
|
26143
|
-
if (this._debug)
|
|
26144
|
-
console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
|
|
26145
|
-
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26146
|
-
// Add to cache
|
|
26147
|
-
if (isNew) {
|
|
26148
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26149
|
-
query: LoadAllQuery,
|
|
26150
|
-
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26151
|
-
});
|
|
26152
|
-
this.insertIntoMutableCachedQueries(proxy, {
|
|
26153
|
-
query: LoadAllWithContentQuery,
|
|
26154
|
-
data: savedEntity
|
|
26155
|
-
});
|
|
26156
|
-
}
|
|
26157
|
-
}
|
|
26158
|
-
}
|
|
26181
|
+
error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },
|
|
26182
|
+
fetchPolicy: (options === null || options === void 0 ? void 0 : options.fetchPolicy) || 'network-only'
|
|
26159
26183
|
});
|
|
26160
|
-
return
|
|
26184
|
+
return res.total;
|
|
26185
|
+
});
|
|
26186
|
+
}
|
|
26187
|
+
listenCountChanges(filter, options) {
|
|
26188
|
+
var _a;
|
|
26189
|
+
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenCountChanges)) {
|
|
26190
|
+
console.warn(`${this._logPrefix}Subscription query 'listenCountChanges' not provided, skip.`);
|
|
26191
|
+
return of();
|
|
26192
|
+
}
|
|
26193
|
+
if (!filter)
|
|
26194
|
+
filter = this.defaultFilter();
|
|
26195
|
+
// Apply last reset date as start date
|
|
26196
|
+
filter.startDate = this.resetCountDate;
|
|
26197
|
+
filter = this.asFilter(filter);
|
|
26198
|
+
if (this._debug)
|
|
26199
|
+
console.debug(`${this._logPrefix}[WS] Listening count changes for user events with filter:`, filter);
|
|
26200
|
+
return this.graphql.subscribe({
|
|
26201
|
+
query: this.subscriptions.listenCountChanges,
|
|
26202
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26203
|
+
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26204
|
+
error: {
|
|
26205
|
+
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26206
|
+
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26207
|
+
}
|
|
26208
|
+
}).pipe(map(({ total }) => {
|
|
26209
|
+
if (total && this._debug)
|
|
26210
|
+
console.debug(`${this._logPrefix}Received new user events count:`, total);
|
|
26211
|
+
// update count
|
|
26212
|
+
this.count$.next(total);
|
|
26213
|
+
return total;
|
|
26214
|
+
}));
|
|
26215
|
+
}
|
|
26216
|
+
listenChanges(filter, options) {
|
|
26217
|
+
var _a;
|
|
26218
|
+
if (!((_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.listenChanges)) {
|
|
26219
|
+
console.warn(`${this._logPrefix}Subscription query 'listenChanges' not provided, skip.`);
|
|
26220
|
+
return of();
|
|
26221
|
+
}
|
|
26222
|
+
if (!filter)
|
|
26223
|
+
filter = this.defaultFilter();
|
|
26224
|
+
filter = this.asFilter(filter);
|
|
26225
|
+
const withContent = (options === null || options === void 0 ? void 0 : options.withContent) === true;
|
|
26226
|
+
if (this._debug)
|
|
26227
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);
|
|
26228
|
+
return this.graphql.subscribe({
|
|
26229
|
+
query: this.subscriptions.listenChanges,
|
|
26230
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
26231
|
+
variables: { filter: filter.asPodObject(), interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
26232
|
+
error: {
|
|
26233
|
+
code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,
|
|
26234
|
+
message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'
|
|
26235
|
+
}
|
|
26236
|
+
}).pipe(map(({ data }) => {
|
|
26237
|
+
if (data && this._debug)
|
|
26238
|
+
console.debug(`${this._logPrefix}Received new user events:`, data);
|
|
26239
|
+
const updatedData = data === null || data === void 0 ? void 0 : data.map(value => this.processUserEvent(value, this));
|
|
26240
|
+
// Update cache
|
|
26241
|
+
this.insertIntoMutableCachedQueries(this.graphql.cache, {
|
|
26242
|
+
query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
|
|
26243
|
+
data: updatedData
|
|
26244
|
+
});
|
|
26245
|
+
return updatedData;
|
|
26246
|
+
}));
|
|
26247
|
+
}
|
|
26248
|
+
delete(entity) {
|
|
26249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26250
|
+
if (!entity)
|
|
26251
|
+
return; // skip
|
|
26252
|
+
yield this.deleteAll([entity]);
|
|
26161
26253
|
});
|
|
26162
26254
|
}
|
|
26163
|
-
/**
|
|
26164
|
-
* Save many trips
|
|
26165
|
-
*
|
|
26166
|
-
* @param entities
|
|
26167
|
-
* @param opts
|
|
26168
|
-
*/
|
|
26169
26255
|
deleteAll(entities, opts) {
|
|
26170
26256
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26171
26257
|
const ids = entities && entities
|
|
@@ -26174,122 +26260,346 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26174
26260
|
return; // stop, if nothing else to do
|
|
26175
26261
|
const now = Date.now();
|
|
26176
26262
|
if (this._debug)
|
|
26177
|
-
console.debug(
|
|
26263
|
+
console.debug(`${this._logPrefix}Deleting events... ids:`, ids);
|
|
26178
26264
|
yield this.graphql.mutate({
|
|
26179
|
-
mutation:
|
|
26265
|
+
mutation: this.mutations.deleteByIds,
|
|
26180
26266
|
variables: {
|
|
26181
26267
|
ids
|
|
26182
26268
|
},
|
|
26183
26269
|
update: (proxy) => {
|
|
26184
26270
|
// Remove from caches
|
|
26185
26271
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26186
|
-
query:
|
|
26272
|
+
query: this.queries.loadAll,
|
|
26187
26273
|
ids
|
|
26188
26274
|
});
|
|
26189
26275
|
this.removeFromMutableCachedQueriesByIds(proxy, {
|
|
26190
|
-
query:
|
|
26276
|
+
query: this.queries.loadAllWithContent,
|
|
26191
26277
|
ids
|
|
26192
26278
|
});
|
|
26193
26279
|
if (this._debug)
|
|
26194
|
-
console.debug(
|
|
26280
|
+
console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
|
|
26195
26281
|
}
|
|
26196
26282
|
});
|
|
26197
26283
|
});
|
|
26198
26284
|
}
|
|
26199
|
-
|
|
26200
|
-
* Delete userEvent entities
|
|
26201
|
-
*/
|
|
26202
|
-
delete(data) {
|
|
26285
|
+
save(entity, options) {
|
|
26203
26286
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26204
|
-
|
|
26205
|
-
|
|
26206
|
-
|
|
26287
|
+
this.fillDefaultProperties(entity);
|
|
26288
|
+
// Transform into json
|
|
26289
|
+
const withContent = !!entity.content;
|
|
26290
|
+
const json = entity.asObject();
|
|
26291
|
+
const now = Date.now();
|
|
26292
|
+
if (this._debug)
|
|
26293
|
+
console.debug(`${this._logPrefix}Saving user event...`, json);
|
|
26294
|
+
yield this.graphql.mutate({
|
|
26295
|
+
mutation: this.mutations.save,
|
|
26296
|
+
variables: {
|
|
26297
|
+
data: json
|
|
26298
|
+
},
|
|
26299
|
+
error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
|
|
26300
|
+
update: (proxy, { data }) => {
|
|
26301
|
+
// Update entity
|
|
26302
|
+
const savedEntity = data && data.data;
|
|
26303
|
+
if (savedEntity) {
|
|
26304
|
+
if (this._debug)
|
|
26305
|
+
console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
|
|
26306
|
+
this.copyIdAndUpdateDate(savedEntity, entity);
|
|
26307
|
+
// Add to cache
|
|
26308
|
+
if (withContent) {
|
|
26309
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26310
|
+
query: this.queries.loadAllWithContent,
|
|
26311
|
+
data: savedEntity
|
|
26312
|
+
});
|
|
26313
|
+
}
|
|
26314
|
+
else {
|
|
26315
|
+
this.insertIntoMutableCachedQueries(proxy, {
|
|
26316
|
+
query: this.queries.loadAll,
|
|
26317
|
+
data: Object.assign(Object.assign({}, savedEntity), { content: null })
|
|
26318
|
+
});
|
|
26319
|
+
}
|
|
26320
|
+
}
|
|
26321
|
+
}
|
|
26322
|
+
});
|
|
26323
|
+
return entity;
|
|
26207
26324
|
});
|
|
26208
26325
|
}
|
|
26209
|
-
|
|
26210
|
-
|
|
26211
|
-
|
|
26212
|
-
|
|
26213
|
-
|
|
26214
|
-
registerAction(definition) {
|
|
26215
|
-
console.info(`[user-event-service] Registering action ${definition.name} for ${definition.__typename}`);
|
|
26216
|
-
this._userEventActions.push(definition);
|
|
26217
|
-
}
|
|
26218
|
-
getActionsByTypename(typename) {
|
|
26219
|
-
return this._userEventActions.filter(def => def.__typename === typename);
|
|
26326
|
+
saveAll(entities, opts) {
|
|
26327
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26328
|
+
return Promise.all(entities
|
|
26329
|
+
.map(entity => this.save(entity, opts)));
|
|
26330
|
+
});
|
|
26220
26331
|
}
|
|
26221
|
-
|
|
26332
|
+
markAsRead(entities) {
|
|
26222
26333
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26223
|
-
|
|
26224
|
-
|
|
26225
|
-
|
|
26226
|
-
|
|
26227
|
-
|
|
26228
|
-
|
|
26229
|
-
|
|
26230
|
-
|
|
26231
|
-
return;
|
|
26232
|
-
}
|
|
26233
|
-
// Translate the message (to be able to extract details content)
|
|
26234
|
-
message = this.translate.instant(message);
|
|
26235
|
-
// Clean details parts
|
|
26236
|
-
if (message && message.indexOf('<small>') !== -1) {
|
|
26237
|
-
message = message.substr(0, message.indexOf('<small>') - 1);
|
|
26238
|
-
}
|
|
26239
|
-
const res = yield this.showToast({
|
|
26240
|
-
type: 'error',
|
|
26241
|
-
duration: 15000,
|
|
26242
|
-
message: message + '<br/><br/><b>' + this.translate.instant('CONFIRM.SEND_DEBUG_DATA') + '</b>',
|
|
26243
|
-
buttons: [{
|
|
26244
|
-
icon: 'bug',
|
|
26245
|
-
text: this.translate.instant('COMMON.BTN_SEND'),
|
|
26246
|
-
role: 'send'
|
|
26247
|
-
}]
|
|
26248
|
-
});
|
|
26249
|
-
if (!res || res.role !== 'send')
|
|
26250
|
-
return;
|
|
26251
|
-
// Send debug data
|
|
26252
|
-
try {
|
|
26253
|
-
if (this._debug)
|
|
26254
|
-
console.debug('Sending debug data...');
|
|
26255
|
-
// Call content factory
|
|
26256
|
-
let context = opts && opts.context;
|
|
26257
|
-
if (typeof context === 'function') {
|
|
26258
|
-
context = context();
|
|
26334
|
+
const userEventWithoutReadListeners = [];
|
|
26335
|
+
for (const entity of (entities || [])) {
|
|
26336
|
+
// Get onRead listeners
|
|
26337
|
+
const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));
|
|
26338
|
+
if (onReadListeners.length) {
|
|
26339
|
+
for (const listener of onReadListeners) {
|
|
26340
|
+
yield listener.onRead(entity);
|
|
26341
|
+
}
|
|
26259
26342
|
}
|
|
26260
|
-
|
|
26261
|
-
|
|
26343
|
+
else {
|
|
26344
|
+
// Add to this list for default operation
|
|
26345
|
+
userEventWithoutReadListeners.push(entity);
|
|
26262
26346
|
}
|
|
26263
|
-
// Send the message
|
|
26264
|
-
const userEvent = yield this.sendDataForDebug({
|
|
26265
|
-
message,
|
|
26266
|
-
error: opts.error || undefined,
|
|
26267
|
-
context: this.convertObjectToString(context)
|
|
26268
|
-
});
|
|
26269
|
-
console.info('Debug data successfully sent to admin', userEvent);
|
|
26270
|
-
this.showToast({
|
|
26271
|
-
type: 'info',
|
|
26272
|
-
message: 'INFO.DEBUG_DATA_SEND',
|
|
26273
|
-
showCloseButton: true
|
|
26274
|
-
});
|
|
26275
|
-
}
|
|
26276
|
-
catch (err) {
|
|
26277
|
-
console.error('Error while sending debug data:', err);
|
|
26278
26347
|
}
|
|
26348
|
+
// Use default
|
|
26349
|
+
yield this.defaultMarkAsRead(userEventWithoutReadListeners);
|
|
26279
26350
|
});
|
|
26280
26351
|
}
|
|
26281
|
-
|
|
26282
|
-
|
|
26283
|
-
|
|
26284
|
-
|
|
26285
|
-
return this.save(userEvent);
|
|
26352
|
+
registerListener(listener) {
|
|
26353
|
+
if (!this.listeners)
|
|
26354
|
+
this.listeners = [];
|
|
26355
|
+
this.listeners.push(listener);
|
|
26286
26356
|
}
|
|
26287
|
-
|
|
26288
|
-
|
|
26357
|
+
resetCount() {
|
|
26358
|
+
this.count$.next(undefined);
|
|
26359
|
+
this.resetCountDate = moment$6();
|
|
26360
|
+
// restart listening count changes
|
|
26361
|
+
this.startListenCountChanges();
|
|
26289
26362
|
}
|
|
26290
26363
|
/* -- protected methods -- */
|
|
26291
|
-
|
|
26292
|
-
|
|
26364
|
+
onLogin() {
|
|
26365
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26366
|
+
// Get first count
|
|
26367
|
+
const count = yield this.count(undefined);
|
|
26368
|
+
if (this._debug)
|
|
26369
|
+
console.debug(`${this._logPrefix}Receiving user events count`, count);
|
|
26370
|
+
// Update count
|
|
26371
|
+
this.count$.next(count);
|
|
26372
|
+
// Then listen changes
|
|
26373
|
+
this.startListenCountChanges();
|
|
26374
|
+
});
|
|
26375
|
+
}
|
|
26376
|
+
onLogout() {
|
|
26377
|
+
this.stopListenCountChanges();
|
|
26378
|
+
}
|
|
26379
|
+
startListenCountChanges() {
|
|
26380
|
+
this.stopListenCountChanges();
|
|
26381
|
+
this._listenSubscription = this.listenCountChanges(undefined).subscribe();
|
|
26382
|
+
}
|
|
26383
|
+
stopListenCountChanges() {
|
|
26384
|
+
var _a;
|
|
26385
|
+
(_a = this._listenSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
26386
|
+
this._listenSubscription = undefined;
|
|
26387
|
+
}
|
|
26388
|
+
processUserEvent(source, that) {
|
|
26389
|
+
that = that || this;
|
|
26390
|
+
// Convert json source to IUserEvent
|
|
26391
|
+
let target = that.fromObject(source);
|
|
26392
|
+
// Get listeners
|
|
26393
|
+
const listeners = (that.listeners || []).filter(listener => listener.onReceived).filter(listener => listener.accept(target));
|
|
26394
|
+
for (const listener of listeners) {
|
|
26395
|
+
if (target) {
|
|
26396
|
+
target = listener.onReceived(target);
|
|
26397
|
+
}
|
|
26398
|
+
else {
|
|
26399
|
+
if (that._debug)
|
|
26400
|
+
console.debug(`${that._logPrefix}Event has been rejected by a listener`, source);
|
|
26401
|
+
break;
|
|
26402
|
+
}
|
|
26403
|
+
}
|
|
26404
|
+
return target;
|
|
26405
|
+
}
|
|
26406
|
+
defaultMarkAsRead(userEvents) {
|
|
26407
|
+
var _a;
|
|
26408
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26409
|
+
if (!userEvents)
|
|
26410
|
+
throw new Error(`${this._logPrefix}Invalid event to save`);
|
|
26411
|
+
if (!userEvents.length)
|
|
26412
|
+
return;
|
|
26413
|
+
// set read date
|
|
26414
|
+
userEvents.forEach(userEvent => userEvent.readDate = moment$6());
|
|
26415
|
+
// split local/remote entities
|
|
26416
|
+
const localEntities = userEvents.filter(userEvent => !userEvent.id || userEvent.id < 0);
|
|
26417
|
+
const remoteEntities = userEvents.filter(userEvent => userEvent.id > 0);
|
|
26418
|
+
// save local entities
|
|
26419
|
+
if (localEntities.length) {
|
|
26420
|
+
if (this._debug)
|
|
26421
|
+
console.debug(`${this._logPrefix}Save local user event`);
|
|
26422
|
+
// TODO !!!!!!!!!!!!!
|
|
26423
|
+
}
|
|
26424
|
+
// mark remote entities as read
|
|
26425
|
+
if (remoteEntities.length) {
|
|
26426
|
+
if (!((_a = this.mutations) === null || _a === void 0 ? void 0 : _a.markAsRead)) {
|
|
26427
|
+
console.warn(`${this._logPrefix}Mutation query 'markAsRead' not provided, skip.`);
|
|
26428
|
+
return;
|
|
26429
|
+
}
|
|
26430
|
+
// Collect ids
|
|
26431
|
+
const ids = remoteEntities.map(value => value.id);
|
|
26432
|
+
const now = Date.now();
|
|
26433
|
+
if (this._debug)
|
|
26434
|
+
console.debug(`${this._logPrefix}Mark user events as read...`, ids);
|
|
26435
|
+
yield this.graphql.mutate({
|
|
26436
|
+
mutation: this.mutations.markAsRead,
|
|
26437
|
+
variables: {
|
|
26438
|
+
ids
|
|
26439
|
+
},
|
|
26440
|
+
error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
|
|
26441
|
+
});
|
|
26442
|
+
if (this._debug)
|
|
26443
|
+
console.debug(`${this._logPrefix}User events marked as read in ${Date.now() - now}ms`, ids);
|
|
26444
|
+
}
|
|
26445
|
+
});
|
|
26446
|
+
}
|
|
26447
|
+
defaultFilter() {
|
|
26448
|
+
// By default
|
|
26449
|
+
return {
|
|
26450
|
+
recipients: [this.defaultRecipient()]
|
|
26451
|
+
};
|
|
26452
|
+
}
|
|
26453
|
+
defaultRecipient() {
|
|
26454
|
+
return this.accountService.person.pubkey;
|
|
26455
|
+
}
|
|
26456
|
+
fillDefaultProperties(entity) {
|
|
26457
|
+
}
|
|
26458
|
+
unreadEvents(events) {
|
|
26459
|
+
// default calculation on unread events from a list
|
|
26460
|
+
if (isEmptyArray(events))
|
|
26461
|
+
return undefined;
|
|
26462
|
+
const lastReadDate = events
|
|
26463
|
+
.filter(event => isNotNil(event.readDate))
|
|
26464
|
+
.reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined);
|
|
26465
|
+
return events
|
|
26466
|
+
.filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;
|
|
26467
|
+
}
|
|
26468
|
+
copyIdAndUpdateDate(source, target) {
|
|
26469
|
+
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26470
|
+
}
|
|
26471
|
+
}
|
|
26472
|
+
AbstractUserEventService.decorators = [
|
|
26473
|
+
{ type: Directive }
|
|
26474
|
+
];
|
|
26475
|
+
AbstractUserEventService.ctorParameters = () => [
|
|
26476
|
+
{ type: GraphqlService },
|
|
26477
|
+
{ type: AccountService },
|
|
26478
|
+
{ type: NetworkService },
|
|
26479
|
+
{ type: TranslateService },
|
|
26480
|
+
{ type: undefined },
|
|
26481
|
+
{ type: undefined },
|
|
26482
|
+
{ type: undefined },
|
|
26483
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
26484
|
+
];
|
|
26485
|
+
const userEventQueries = {
|
|
26486
|
+
loadAll: gql `
|
|
26487
|
+
query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26488
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26489
|
+
...LightUserEventFragment
|
|
26490
|
+
}
|
|
26491
|
+
}
|
|
26492
|
+
${UserEventFragments.lightUserEvent}
|
|
26493
|
+
`,
|
|
26494
|
+
loadAllWithContent: gql `
|
|
26495
|
+
query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
|
|
26496
|
+
data: userEvents(filter: $filter, page: $page){
|
|
26497
|
+
...UserEventFragment
|
|
26498
|
+
}
|
|
26499
|
+
}
|
|
26500
|
+
${UserEventFragments.userEvent}
|
|
26501
|
+
`
|
|
26502
|
+
};
|
|
26503
|
+
const userEventMutations = {
|
|
26504
|
+
deleteByIds: gql `
|
|
26505
|
+
mutation DeleteUserEvents($ids:[Int]){
|
|
26506
|
+
deleteUserEvents(ids: $ids)
|
|
26507
|
+
}
|
|
26508
|
+
`,
|
|
26509
|
+
save: gql `
|
|
26510
|
+
mutation SaveUserEvent($data: UserEventVOInput){
|
|
26511
|
+
data: saveUserEvent(userEvent: $data){
|
|
26512
|
+
...UserEventFragment
|
|
26513
|
+
}
|
|
26514
|
+
}
|
|
26515
|
+
${UserEventFragments.userEvent}
|
|
26516
|
+
`
|
|
26517
|
+
};
|
|
26518
|
+
class UserEventService extends AbstractUserEventService {
|
|
26519
|
+
constructor(graphql, accountService, network, translate, toastController, environment) {
|
|
26520
|
+
super(graphql, accountService, network, translate, userEventQueries, userEventMutations, undefined, environment);
|
|
26521
|
+
this.graphql = graphql;
|
|
26522
|
+
this.accountService = accountService;
|
|
26523
|
+
this.network = network;
|
|
26524
|
+
this.translate = translate;
|
|
26525
|
+
this.toastController = toastController;
|
|
26526
|
+
this.environment = environment;
|
|
26527
|
+
}
|
|
26528
|
+
showToastErrorWithContext(opts) {
|
|
26529
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26530
|
+
let message = opts.message || (opts.error && opts.error.message || opts.error);
|
|
26531
|
+
// Make sure message a string
|
|
26532
|
+
if (!message || typeof message !== 'string') {
|
|
26533
|
+
message = 'ERROR.UNKNOWN_TECHNICAL_ERROR';
|
|
26534
|
+
}
|
|
26535
|
+
// If offline, display a simple alert
|
|
26536
|
+
if (this.network.offline) {
|
|
26537
|
+
this.showToast({ message, type: 'error' });
|
|
26538
|
+
return;
|
|
26539
|
+
}
|
|
26540
|
+
// Translate the message (to be able to extract details content)
|
|
26541
|
+
message = this.translate.instant(message);
|
|
26542
|
+
// Clean details parts
|
|
26543
|
+
if (message && message.indexOf('<small>') !== -1) {
|
|
26544
|
+
message = message.substr(0, message.indexOf('<small>') - 1);
|
|
26545
|
+
}
|
|
26546
|
+
const res = yield this.showToast({
|
|
26547
|
+
type: 'error',
|
|
26548
|
+
duration: 15000,
|
|
26549
|
+
message: message + '<br/><br/><b>' + this.translate.instant('CONFIRM.SEND_DEBUG_DATA') + '</b>',
|
|
26550
|
+
buttons: [{
|
|
26551
|
+
icon: 'bug',
|
|
26552
|
+
text: this.translate.instant('COMMON.BTN_SEND'),
|
|
26553
|
+
role: 'send'
|
|
26554
|
+
}]
|
|
26555
|
+
});
|
|
26556
|
+
if (!res || res.role !== 'send')
|
|
26557
|
+
return;
|
|
26558
|
+
// Send debug data
|
|
26559
|
+
try {
|
|
26560
|
+
if (this._debug)
|
|
26561
|
+
console.debug('Sending debug data...');
|
|
26562
|
+
// Call content factory
|
|
26563
|
+
let context = opts && opts.context;
|
|
26564
|
+
if (typeof context === 'function') {
|
|
26565
|
+
context = context();
|
|
26566
|
+
}
|
|
26567
|
+
if (context instanceof Promise) {
|
|
26568
|
+
context = yield context;
|
|
26569
|
+
}
|
|
26570
|
+
// Send the message
|
|
26571
|
+
const userEvent = yield this.sendDataForDebug({
|
|
26572
|
+
message,
|
|
26573
|
+
error: opts.error || undefined,
|
|
26574
|
+
context: this.convertObjectToString(context)
|
|
26575
|
+
});
|
|
26576
|
+
console.info('Debug data successfully sent to admin', userEvent);
|
|
26577
|
+
this.showToast({
|
|
26578
|
+
type: 'info',
|
|
26579
|
+
message: 'INFO.DEBUG_DATA_SEND',
|
|
26580
|
+
showCloseButton: true
|
|
26581
|
+
});
|
|
26582
|
+
}
|
|
26583
|
+
catch (err) {
|
|
26584
|
+
console.error('Error while sending debug data:', err);
|
|
26585
|
+
}
|
|
26586
|
+
});
|
|
26587
|
+
}
|
|
26588
|
+
sendDataForDebug(data) {
|
|
26589
|
+
const userEvent = new UserEvent();
|
|
26590
|
+
userEvent.type = UserEventTypes.DEBUG_DATA;
|
|
26591
|
+
userEvent.content = this.convertObjectToString(data);
|
|
26592
|
+
return this.save(userEvent);
|
|
26593
|
+
}
|
|
26594
|
+
asFilter(filter) {
|
|
26595
|
+
return UserEventFilter.fromObject(filter);
|
|
26596
|
+
}
|
|
26597
|
+
fromObject(source) {
|
|
26598
|
+
return UserEvent.fromObject(source);
|
|
26599
|
+
}
|
|
26600
|
+
/* -- protected methods -- */
|
|
26601
|
+
convertObjectToString(data) {
|
|
26602
|
+
if (typeof data === 'string') {
|
|
26293
26603
|
return data;
|
|
26294
26604
|
}
|
|
26295
26605
|
// Serialize content into string
|
|
@@ -26315,13 +26625,9 @@ class UserEventService extends BaseGraphqlService {
|
|
|
26315
26625
|
// TODO: compute sign
|
|
26316
26626
|
console.warn('TODO: sign user event before sending');
|
|
26317
26627
|
}
|
|
26318
|
-
copyIdAndUpdateDate(source, target) {
|
|
26319
|
-
EntityUtils.copyIdAndUpdateDate(source, target);
|
|
26320
|
-
}
|
|
26321
26628
|
}
|
|
26322
|
-
UserEventService.ɵprov = ɵɵdefineInjectable({ factory: function UserEventService_Factory() { return new UserEventService(ɵɵinject(GraphqlService), ɵɵinject(AccountService), ɵɵinject(NetworkService), ɵɵinject(TranslateService), ɵɵinject(ToastController), ɵɵinject(ENVIRONMENT, 8)); }, token: UserEventService, providedIn: "root" });
|
|
26323
26629
|
UserEventService.decorators = [
|
|
26324
|
-
{ type: Injectable
|
|
26630
|
+
{ type: Injectable }
|
|
26325
26631
|
];
|
|
26326
26632
|
UserEventService.ctorParameters = () => [
|
|
26327
26633
|
{ type: GraphqlService },
|
|
@@ -26334,7 +26640,7 @@ UserEventService.ctorParameters = () => [
|
|
|
26334
26640
|
|
|
26335
26641
|
const ICONS_MAP = {
|
|
26336
26642
|
DEBUG_DATA: { matIcon: 'bug_report' },
|
|
26337
|
-
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26643
|
+
INBOX_MESSAGE: { matIcon: 'mail' }
|
|
26338
26644
|
};
|
|
26339
26645
|
// TODO: refactor with a registration done by data service:
|
|
26340
26646
|
// - userEventService.registerEventAction({__typename: 'TripVO', ...})
|
|
@@ -26400,7 +26706,7 @@ class UserEventsTable extends AppTable {
|
|
|
26400
26706
|
}
|
|
26401
26707
|
}));
|
|
26402
26708
|
const filter = this.filter || new UserEventFilter();
|
|
26403
|
-
filter.
|
|
26709
|
+
filter.recipients = [this.recipient];
|
|
26404
26710
|
this.setFilter(filter, { emitEvent: true });
|
|
26405
26711
|
}
|
|
26406
26712
|
start() {
|
|
@@ -26413,17 +26719,17 @@ class UserEventsTable extends AppTable {
|
|
|
26413
26719
|
});
|
|
26414
26720
|
}
|
|
26415
26721
|
getIcon(source) {
|
|
26416
|
-
return ICONS_MAP[source.
|
|
26722
|
+
return ICONS_MAP[source.type];
|
|
26417
26723
|
}
|
|
26418
26724
|
getDetail(source) {
|
|
26419
26725
|
if (!source)
|
|
26420
26726
|
return undefined;
|
|
26421
|
-
if (source.content && source.
|
|
26727
|
+
if (source.content && source.type === UserEventTypes.DEBUG_DATA) {
|
|
26422
26728
|
const context = source.content.context;
|
|
26423
26729
|
if (context && context.__typename) {
|
|
26424
|
-
const actions = this.service.getActionsByTypename(context.__typename);
|
|
26730
|
+
// const actions = this.service.getActionsByTypename(context.__typename);
|
|
26425
26731
|
return {
|
|
26426
|
-
actions,
|
|
26732
|
+
// actions,
|
|
26427
26733
|
title: source.content.error && source.content.error.message || source.content.message,
|
|
26428
26734
|
description: source.content.error && source.content.error.details || undefined
|
|
26429
26735
|
};
|
|
@@ -26435,11 +26741,11 @@ class UserEventsTable extends AppTable {
|
|
|
26435
26741
|
doAction(action, row) {
|
|
26436
26742
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26437
26743
|
const event = row.currentData;
|
|
26438
|
-
const context = event.content && event.content.context;
|
|
26744
|
+
// const context = event.content && event.content.context;
|
|
26439
26745
|
this.markAsLoading();
|
|
26440
26746
|
if (action && typeof action.executeAction === 'function') {
|
|
26441
26747
|
try {
|
|
26442
|
-
let res = action.executeAction(event
|
|
26748
|
+
let res = action.executeAction(event /*, context*/);
|
|
26443
26749
|
res = (res instanceof Promise) ? yield res : res;
|
|
26444
26750
|
}
|
|
26445
26751
|
catch (err) {
|
|
@@ -26456,15 +26762,20 @@ class UserEventsTable extends AppTable {
|
|
|
26456
26762
|
UserEventsTable.decorators = [
|
|
26457
26763
|
{ type: Component, args: [{
|
|
26458
26764
|
selector: 'app-user-events-table',
|
|
26459
|
-
template: "\n<!-- Type = options menu -->\n<mat-menu #optionsMenu=\"matMenu\" xPosition=\"after\">\n\n <!-- display columns -->\n <button mat-menu-item\n (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n</mat-menu>\n\n<!-- top header -->\n<mat-toolbar>\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <button mat-icon-button [title]=\"'COMMON.BTN_REFRESH'|translate\" (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button class=\"hidden-xs hidden-sm\" *ngIf=\"canDelete\"\n [title]=\"'COMMON.BTN_DELETE'|translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" hidden-xs hidden-sm hidden-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS'|translate\"\n [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n</mat-toolbar>\n\n\n<mat-table [dataSource]=\"dataSource\" matSort\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <!-- select -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <!-- id -->\n <ng-container matColumnDef=\"id\">\n <mat-header-cell *matHeaderCellDef mat-sort-header [class.cdk-visually-hidden]=\"!isAdmin\">\n <app-loading-spinner [loading]=\"loadingSubject|async\"><ion-label>#</ion-label></app-loading-spinner>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!isAdmin\">{{ row.currentData.id | mathAbs }}</mat-cell>\n </ng-container>\n\n <!-- creationDate -->\n <ng-container matColumnDef=\"creationDate\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.CREATION_DATE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ion-text>\n {{row.currentData.creationDate | dateFromNow }}<br/>\n <ion-text color=\"medium\"><small>{{row.currentData.creationDate | dateFormat: {time: true} }}</small></ion-text>\n </ion-text>\n </mat-cell>\n </ng-container>\n\n <!-- icon -->\n <ng-container matColumnDef=\"icon\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getIcon(row.currentData); let details\">\n <ion-icon slot=\"start\" *ngIf=\"details.icon\" [name]=\"details.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"details.matIcon\">{{details.matIcon}}</mat-icon>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- event type -->\n <ng-container matColumnDef=\"eventType\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.EVENT_TYPE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <span>{{'SOCIAL.USER_EVENT.TYPE_ENUM.' + row.currentData.eventType | translate}}</span>\n </mat-cell>\n </ng-container>\n\n <!-- message -->\n <ng-container matColumnDef=\"message\">\n <mat-header-cell *matHeaderCellDef>\n <ion-label translate>SOCIAL.USER_EVENT.MESSAGE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <ion-text [innerHTML]=\"details.title|translate\">\n </ion-text>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- Actions buttons column -->\n <ng-container matColumnDef=\"actions\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <button mat-icon-button color=\"light\"\n *ngFor=\"let action of details.actions\"\n [title]=\"action.title |translate\"\n [color]=\"action.color\"\n (click)=\"doAction(action, row)\">\n <
|
|
26765
|
+
template: "\n<!-- Type = options menu -->\n<mat-menu #optionsMenu=\"matMenu\" xPosition=\"after\">\n\n <!-- display columns -->\n <button mat-menu-item\n (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n</mat-menu>\n\n<!-- top header -->\n<mat-toolbar>\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <button mat-icon-button [title]=\"'COMMON.BTN_REFRESH'|translate\" (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button class=\"hidden-xs hidden-sm\" *ngIf=\"canDelete\"\n [title]=\"'COMMON.BTN_DELETE'|translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" hidden-xs hidden-sm hidden-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS'|translate\"\n [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n</mat-toolbar>\n\n\n<mat-table [dataSource]=\"dataSource\" matSort\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <!-- select -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <!-- id -->\n <ng-container matColumnDef=\"id\">\n <mat-header-cell *matHeaderCellDef mat-sort-header [class.cdk-visually-hidden]=\"!isAdmin\">\n <app-loading-spinner [loading]=\"loadingSubject|async\"><ion-label>#</ion-label></app-loading-spinner>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!isAdmin\">{{ row.currentData.id | mathAbs }}</mat-cell>\n </ng-container>\n\n <!-- creationDate -->\n <ng-container matColumnDef=\"creationDate\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.CREATION_DATE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ion-text>\n {{row.currentData.creationDate | dateFromNow }}<br/>\n <ion-text color=\"medium\"><small>{{row.currentData.creationDate | dateFormat: {time: true} }}</small></ion-text>\n </ion-text>\n </mat-cell>\n </ng-container>\n\n <!-- icon -->\n <ng-container matColumnDef=\"icon\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getIcon(row.currentData); let details\">\n <ion-icon slot=\"start\" *ngIf=\"details.icon\" [name]=\"details.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"details.matIcon\">{{details.matIcon}}</mat-icon>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- event type -->\n <ng-container matColumnDef=\"eventType\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.EVENT_TYPE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <span>{{'SOCIAL.USER_EVENT.TYPE_ENUM.' + row.currentData.eventType | translate}}</span>\n </mat-cell>\n </ng-container>\n\n <!-- message -->\n <ng-container matColumnDef=\"message\">\n <mat-header-cell *matHeaderCellDef>\n <ion-label translate>SOCIAL.USER_EVENT.MESSAGE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <ion-text [innerHTML]=\"details.title|translate\">\n </ion-text>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- Actions buttons column -->\n <ng-container matColumnDef=\"actions\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <button mat-icon-button color=\"light\"\n *ngFor=\"let action of details.actions\"\n [title]=\"action.title |translate\"\n [color]=\"action.color\"\n (click)=\"doAction(action, row)\">\n <app-icon slot=\"start\" *ngIf=\"action.iconRef\" [ref]=\"action.iconRef\"></app-icon>\n </button>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n class=\"mat-row-disabled\"\n (click)=\"clickRow($event, row)\"></mat-row>\n\n</mat-table>\n\n<ion-row class=\"ion-no-padding\">\n <ion-col></ion-col>\n <ion-col class=\"ion-no-padding\" size=\"auto\">\n <mat-paginator [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n </ion-col>\n</ion-row>\n",
|
|
26460
26766
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26767
|
+
providers: [
|
|
26768
|
+
{
|
|
26769
|
+
provide: UserEventServiceToken, useClass: UserEventService
|
|
26770
|
+
}
|
|
26771
|
+
],
|
|
26461
26772
|
styles: [".mat-header-row .mat-column-icon,.mat-row .mat-column-icon{max-width:40px;padding-left:0}.mat-header-row .mat-column-icon ion-icon,.mat-header-row .mat-column-icon mat-icon,.mat-row .mat-column-icon ion-icon,.mat-row .mat-column-icon mat-icon{font-size:1.2em;height:1.2em;width:1.2em}.mat-header-row .mat-column-creationDate,.mat-row .mat-column-creationDate{min-width:100px;max-width:120px}"]
|
|
26462
26773
|
},] }
|
|
26463
26774
|
];
|
|
26464
26775
|
UserEventsTable.ctorParameters = () => [
|
|
26465
26776
|
{ type: Injector },
|
|
26466
26777
|
{ type: AccountService },
|
|
26467
|
-
{ type:
|
|
26778
|
+
{ type: undefined, decorators: [{ type: Inject, args: [UserEventServiceToken,] }] },
|
|
26468
26779
|
{ type: EntitiesStorage },
|
|
26469
26780
|
{ type: ChangeDetectorRef },
|
|
26470
26781
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
@@ -26476,6 +26787,248 @@ UserEventsTable.propDecorators = {
|
|
|
26476
26787
|
defaultSortDirection: [{ type: Input }]
|
|
26477
26788
|
};
|
|
26478
26789
|
|
|
26790
|
+
class UserEventNotificationList {
|
|
26791
|
+
constructor(cd, popoverController, userEventService) {
|
|
26792
|
+
this.cd = cd;
|
|
26793
|
+
this.popoverController = popoverController;
|
|
26794
|
+
this.userEventService = userEventService;
|
|
26795
|
+
this.debug = false;
|
|
26796
|
+
this.userEvents = new BehaviorSubject(undefined);
|
|
26797
|
+
this.subscriptions = new Subscription();
|
|
26798
|
+
}
|
|
26799
|
+
ngOnInit() {
|
|
26800
|
+
// Watch all user events
|
|
26801
|
+
this.subscriptions.add(this.userEventService
|
|
26802
|
+
.watchAll(0, 10, 'creationDate', "desc", undefined)
|
|
26803
|
+
.subscribe(result => {
|
|
26804
|
+
if (this.debug)
|
|
26805
|
+
console.debug(`[user-event-notification-list] receiving ${result.total} user events`, result.data);
|
|
26806
|
+
this.userEvents.next(result.data);
|
|
26807
|
+
this.markForCheck();
|
|
26808
|
+
}));
|
|
26809
|
+
// Listen changes
|
|
26810
|
+
this.subscriptions.add(this.userEventService.listenChanges(undefined)
|
|
26811
|
+
.subscribe(data => {
|
|
26812
|
+
if (this.debug)
|
|
26813
|
+
console.debug(`[user-event-notification-list] receiving ${data.length} new user events`, data);
|
|
26814
|
+
}));
|
|
26815
|
+
}
|
|
26816
|
+
ngOnDestroy() {
|
|
26817
|
+
this.subscriptions.unsubscribe();
|
|
26818
|
+
}
|
|
26819
|
+
read(event, userEvent) {
|
|
26820
|
+
var _a;
|
|
26821
|
+
if (userEvent === null || userEvent === void 0 ? void 0 : userEvent.readDate)
|
|
26822
|
+
return;
|
|
26823
|
+
(_a = this.readEvent) === null || _a === void 0 ? void 0 : _a.emit(userEvent);
|
|
26824
|
+
}
|
|
26825
|
+
readAll(event) {
|
|
26826
|
+
var _a;
|
|
26827
|
+
const unreadUserEvents = (this.userEvents.value || []).filter(value => !value.readDate);
|
|
26828
|
+
if (!unreadUserEvents.length)
|
|
26829
|
+
return;
|
|
26830
|
+
(_a = this.readEvents) === null || _a === void 0 ? void 0 : _a.emit(unreadUserEvents);
|
|
26831
|
+
}
|
|
26832
|
+
executeAction(action, userEvent) {
|
|
26833
|
+
// Execute then close popover
|
|
26834
|
+
action.executeAction(userEvent);
|
|
26835
|
+
this.dismiss();
|
|
26836
|
+
}
|
|
26837
|
+
dismiss() {
|
|
26838
|
+
this.popoverController.dismiss();
|
|
26839
|
+
}
|
|
26840
|
+
markForCheck() {
|
|
26841
|
+
this.cd.markForCheck();
|
|
26842
|
+
}
|
|
26843
|
+
}
|
|
26844
|
+
UserEventNotificationList.decorators = [
|
|
26845
|
+
{ type: Component, args: [{
|
|
26846
|
+
selector: 'app-user-event-notification-list',
|
|
26847
|
+
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-col class=\"top-action\">\n <a (click)=\"readAll($event)\">{{'SOCIAL.USER_EVENT.NOTIFICATION.READ_ALL' | translate}}</a>\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 message\">\n <ion-row>\n <ion-col>\n <p [class.unread]=\"!userEvent.readDate\" [innerHTML]=\"userEvent.message\"></p>\n </ion-col>\n </ion-row>\n <ion-row *ngIf=\"userEvent.actions?.length\">\n <ion-col>\n <span *ngFor=\"let action of userEvent.actions\" class=\"action\">\n <a (click)=\"executeAction(action, userEvent)\">\n <app-icon *ngIf=\"action.iconRef\" slot=\"start\" height=\"20\" width=\"20\" [ref]=\"action.iconRef\"></app-icon>\n {{ action.name }}\n </a>\n </span>\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; margin-right: 3px\"\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-row>\n\n</ion-list>\n",
|
|
26848
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26849
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.unread{font-weight:700}.message{font-size:.9em}.message p{margin-top:5px;margin-bottom:5px}.top-action{text-align:end;margin-right:8px}.top-action a{cursor:pointer;color:#f5f5f5;font-style:italic}.action a{margin-right:10px;cursor:pointer}.action app-icon{vertical-align:middle}"]
|
|
26850
|
+
},] }
|
|
26851
|
+
];
|
|
26852
|
+
UserEventNotificationList.ctorParameters = () => [
|
|
26853
|
+
{ type: ChangeDetectorRef },
|
|
26854
|
+
{ type: PopoverController },
|
|
26855
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] }
|
|
26856
|
+
];
|
|
26857
|
+
UserEventNotificationList.propDecorators = {
|
|
26858
|
+
debug: [{ type: Input }],
|
|
26859
|
+
titleI18n: [{ type: Input }],
|
|
26860
|
+
readEvent: [{ type: Output }],
|
|
26861
|
+
readEvents: [{ type: Output }]
|
|
26862
|
+
};
|
|
26863
|
+
|
|
26864
|
+
class UserEventNotificationComponent {
|
|
26865
|
+
constructor(userEventService, accountService, popoverController) {
|
|
26866
|
+
this.userEventService = userEventService;
|
|
26867
|
+
this.accountService = accountService;
|
|
26868
|
+
this.popoverController = popoverController;
|
|
26869
|
+
this.debug = false;
|
|
26870
|
+
this.titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';
|
|
26871
|
+
this.disabled = false;
|
|
26872
|
+
this._logPrefix = '[user-event-notification] ';
|
|
26873
|
+
this._readEvent = new EventEmitter();
|
|
26874
|
+
this._readEvents = new EventEmitter();
|
|
26875
|
+
}
|
|
26876
|
+
get count() {
|
|
26877
|
+
var _a;
|
|
26878
|
+
return (_a = this.userEventService) === null || _a === void 0 ? void 0 : _a.userEventCount.pipe(map(value => value === 0 ? undefined : value));
|
|
26879
|
+
}
|
|
26880
|
+
ngOnInit() {
|
|
26881
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26882
|
+
if (isNil(this.userEventService)) {
|
|
26883
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
26884
|
+
this.disabled = true;
|
|
26885
|
+
return;
|
|
26886
|
+
}
|
|
26887
|
+
// Wait service
|
|
26888
|
+
yield this.userEventService.ready();
|
|
26889
|
+
// Subscribe to read event
|
|
26890
|
+
this._readEvent.subscribe(value => {
|
|
26891
|
+
// default: mark event as read
|
|
26892
|
+
this.userEventService.markAsRead([value]);
|
|
26893
|
+
});
|
|
26894
|
+
this._readEvents.subscribe(value => {
|
|
26895
|
+
this.userEventService.markAsRead(value);
|
|
26896
|
+
});
|
|
26897
|
+
});
|
|
26898
|
+
}
|
|
26899
|
+
showList(event) {
|
|
26900
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26901
|
+
// Reset count
|
|
26902
|
+
this.userEventService.resetCount();
|
|
26903
|
+
const popover = yield this.popoverController.create({
|
|
26904
|
+
component: UserEventNotificationList,
|
|
26905
|
+
componentProps: {
|
|
26906
|
+
debug: this.debug,
|
|
26907
|
+
titleI18n: this.titleI18n,
|
|
26908
|
+
readEvent: this._readEvent,
|
|
26909
|
+
readEvents: this._readEvents
|
|
26910
|
+
},
|
|
26911
|
+
backdropDismiss: true,
|
|
26912
|
+
keyboardClose: true,
|
|
26913
|
+
event,
|
|
26914
|
+
translucent: true,
|
|
26915
|
+
cssClass: 'popover-large'
|
|
26916
|
+
});
|
|
26917
|
+
yield popover.present();
|
|
26918
|
+
});
|
|
26919
|
+
}
|
|
26920
|
+
ngOnDestroy() {
|
|
26921
|
+
if (this.debug) {
|
|
26922
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
26923
|
+
}
|
|
26924
|
+
}
|
|
26925
|
+
}
|
|
26926
|
+
UserEventNotificationComponent.decorators = [
|
|
26927
|
+
{ type: Component, args: [{
|
|
26928
|
+
selector: 'app-user-event-notification-component',
|
|
26929
|
+
template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n (click)=\"showList($event)\"\n>\n <mat-icon\n [matBadge]=\"count | async\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n >notifications\n </mat-icon>\n</button>\n\n",
|
|
26930
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
26931
|
+
styles: [""]
|
|
26932
|
+
},] }
|
|
26933
|
+
];
|
|
26934
|
+
UserEventNotificationComponent.ctorParameters = () => [
|
|
26935
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [UserEventServiceToken,] }] },
|
|
26936
|
+
{ type: AccountService },
|
|
26937
|
+
{ type: PopoverController }
|
|
26938
|
+
];
|
|
26939
|
+
UserEventNotificationComponent.propDecorators = {
|
|
26940
|
+
debug: [{ type: Input }],
|
|
26941
|
+
titleI18n: [{ type: Input }],
|
|
26942
|
+
disabled: [{ type: Input }]
|
|
26943
|
+
};
|
|
26944
|
+
|
|
26945
|
+
class UserEventTestService extends AbstractUserEventService {
|
|
26946
|
+
constructor(graphql, accountService, network, translate, environment) {
|
|
26947
|
+
super(graphql, accountService, network, translate, undefined, undefined, undefined, environment);
|
|
26948
|
+
this.graphql = graphql;
|
|
26949
|
+
this.accountService = accountService;
|
|
26950
|
+
this.network = network;
|
|
26951
|
+
this.translate = translate;
|
|
26952
|
+
this.environment = environment;
|
|
26953
|
+
this.userEvents = [];
|
|
26954
|
+
}
|
|
26955
|
+
fromObject(source) {
|
|
26956
|
+
return UserEvent.fromObject(source);
|
|
26957
|
+
}
|
|
26958
|
+
add(entity) {
|
|
26959
|
+
entity = this.processUserEvent(entity);
|
|
26960
|
+
entity.id = this.userEvents.length + 1;
|
|
26961
|
+
this.userEvents.push(entity);
|
|
26962
|
+
this.count$.next(this.userEvents.length);
|
|
26963
|
+
}
|
|
26964
|
+
asFilter(filter) {
|
|
26965
|
+
return filter;
|
|
26966
|
+
}
|
|
26967
|
+
count(filter, options) {
|
|
26968
|
+
return Promise.resolve(this.userEvents.length);
|
|
26969
|
+
}
|
|
26970
|
+
delete(entity) {
|
|
26971
|
+
return Promise.resolve(undefined);
|
|
26972
|
+
}
|
|
26973
|
+
deleteAll(data, opts) {
|
|
26974
|
+
return Promise.resolve(undefined);
|
|
26975
|
+
}
|
|
26976
|
+
listenChanges(filter, options) {
|
|
26977
|
+
return of();
|
|
26978
|
+
}
|
|
26979
|
+
save(entity, options) {
|
|
26980
|
+
var _a;
|
|
26981
|
+
const toSave = (_a = this.userEvents) === null || _a === void 0 ? void 0 : _a.find(value => value.id == (entity === null || entity === void 0 ? void 0 : entity.id));
|
|
26982
|
+
Object.assign(toSave, entity);
|
|
26983
|
+
return entity;
|
|
26984
|
+
}
|
|
26985
|
+
saveAll(data, opts) {
|
|
26986
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26987
|
+
for (const entity of (data || [])) {
|
|
26988
|
+
yield this.save(entity);
|
|
26989
|
+
}
|
|
26990
|
+
return Promise.resolve(this.userEvents);
|
|
26991
|
+
});
|
|
26992
|
+
}
|
|
26993
|
+
watchAll(offset, size, sortBy, sortDirection, filter, options) {
|
|
26994
|
+
return of({ data: this.userEvents });
|
|
26995
|
+
}
|
|
26996
|
+
}
|
|
26997
|
+
UserEventTestService.decorators = [
|
|
26998
|
+
{ type: Injectable }
|
|
26999
|
+
];
|
|
27000
|
+
UserEventTestService.ctorParameters = () => [
|
|
27001
|
+
{ type: GraphqlService },
|
|
27002
|
+
{ type: AccountService },
|
|
27003
|
+
{ type: NetworkService },
|
|
27004
|
+
{ type: TranslateService },
|
|
27005
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27006
|
+
];
|
|
27007
|
+
|
|
27008
|
+
class UserEventModule {
|
|
27009
|
+
}
|
|
27010
|
+
UserEventModule.decorators = [
|
|
27011
|
+
{ type: NgModule, args: [{
|
|
27012
|
+
imports: [
|
|
27013
|
+
CommonModule,
|
|
27014
|
+
CoreModule,
|
|
27015
|
+
SharedModule
|
|
27016
|
+
],
|
|
27017
|
+
declarations: [
|
|
27018
|
+
UserEventsTable,
|
|
27019
|
+
UserEventNotificationComponent,
|
|
27020
|
+
UserEventNotificationList,
|
|
27021
|
+
],
|
|
27022
|
+
exports: [
|
|
27023
|
+
UserEventsTable,
|
|
27024
|
+
UserEventNotificationComponent
|
|
27025
|
+
],
|
|
27026
|
+
providers: [
|
|
27027
|
+
{ provide: UserEventServiceToken, useClass: UserEventTestService }
|
|
27028
|
+
]
|
|
27029
|
+
},] }
|
|
27030
|
+
];
|
|
27031
|
+
|
|
26479
27032
|
const MessageTypes = {
|
|
26480
27033
|
INBOX_MESSAGE: 'INBOX_MESSAGE',
|
|
26481
27034
|
EMAIL: 'EMAIL',
|
|
@@ -26687,9 +27240,9 @@ MessageForm.propDecorators = {
|
|
|
26687
27240
|
canSelectType: [{ type: Input }]
|
|
26688
27241
|
};
|
|
26689
27242
|
|
|
26690
|
-
class
|
|
27243
|
+
class MessageModule {
|
|
26691
27244
|
}
|
|
26692
|
-
|
|
27245
|
+
MessageModule.decorators = [
|
|
26693
27246
|
{ type: NgModule, args: [{
|
|
26694
27247
|
imports: [
|
|
26695
27248
|
CommonModule,
|
|
@@ -26697,17 +27250,327 @@ SocialModule.decorators = [
|
|
|
26697
27250
|
SharedModule
|
|
26698
27251
|
],
|
|
26699
27252
|
declarations: [
|
|
26700
|
-
UserEventsTable,
|
|
26701
27253
|
MessageModal,
|
|
26702
27254
|
MessageForm
|
|
26703
27255
|
],
|
|
26704
27256
|
exports: [
|
|
26705
|
-
UserEventsTable,
|
|
26706
27257
|
MessageModal
|
|
26707
27258
|
]
|
|
26708
27259
|
},] }
|
|
26709
27260
|
];
|
|
26710
27261
|
|
|
27262
|
+
var JobProgression_1;
|
|
27263
|
+
// todo use entity
|
|
27264
|
+
class Job {
|
|
27265
|
+
}
|
|
27266
|
+
// @dynamic
|
|
27267
|
+
let JobProgression = JobProgression_1 = class JobProgression extends Entity {
|
|
27268
|
+
constructor(id) {
|
|
27269
|
+
super(JobProgression_1.TYPENAME);
|
|
27270
|
+
this.id = id;
|
|
27271
|
+
}
|
|
27272
|
+
fromObject(source) {
|
|
27273
|
+
super.fromObject(source);
|
|
27274
|
+
this.name = source.name;
|
|
27275
|
+
this.message = source.message;
|
|
27276
|
+
this.current = source.current;
|
|
27277
|
+
this.total = source.total;
|
|
27278
|
+
}
|
|
27279
|
+
};
|
|
27280
|
+
JobProgression = JobProgression_1 = __decorate([
|
|
27281
|
+
EntityClass({ typename: 'JobProgressionVO' })
|
|
27282
|
+
], JobProgression);
|
|
27283
|
+
|
|
27284
|
+
const JobProgressionServiceToken = new InjectionToken('JobProgressionService');
|
|
27285
|
+
const jobProgressionSubscription = gql `subscription UpdateJobProgression($id: Int!, $interval: Int){
|
|
27286
|
+
data: updateJobProgression(id: $id, interval: $interval) {
|
|
27287
|
+
id
|
|
27288
|
+
name
|
|
27289
|
+
message
|
|
27290
|
+
current
|
|
27291
|
+
total
|
|
27292
|
+
}
|
|
27293
|
+
}`;
|
|
27294
|
+
class JobProgressionService extends BaseGraphqlService {
|
|
27295
|
+
constructor(graphql, environment) {
|
|
27296
|
+
super(graphql, environment);
|
|
27297
|
+
this.graphql = graphql;
|
|
27298
|
+
this.environment = environment;
|
|
27299
|
+
this._logPrefix = '[job-progression-service] ';
|
|
27300
|
+
// For DEV only
|
|
27301
|
+
this._debug = !(environment === null || environment === void 0 ? void 0 : environment.production);
|
|
27302
|
+
}
|
|
27303
|
+
listenChanges(id, options) {
|
|
27304
|
+
if (isNil(id))
|
|
27305
|
+
throw new Error(`${this._logPrefix}Missing argument 'id'`);
|
|
27306
|
+
if (this._debug)
|
|
27307
|
+
console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);
|
|
27308
|
+
return this.graphql.subscribe({
|
|
27309
|
+
query: jobProgressionSubscription,
|
|
27310
|
+
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
27311
|
+
variables: { id, interval: toNumber(options === null || options === void 0 ? void 0 : options.interval, 10) },
|
|
27312
|
+
error: { code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR' }
|
|
27313
|
+
}).pipe(map(({ data }) => {
|
|
27314
|
+
const progression = data && JobProgression.fromObject(data);
|
|
27315
|
+
if (progression && this._debug)
|
|
27316
|
+
console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);
|
|
27317
|
+
return progression;
|
|
27318
|
+
}));
|
|
27319
|
+
}
|
|
27320
|
+
}
|
|
27321
|
+
JobProgressionService.decorators = [
|
|
27322
|
+
{ type: Injectable }
|
|
27323
|
+
];
|
|
27324
|
+
JobProgressionService.ctorParameters = () => [
|
|
27325
|
+
{ type: GraphqlService },
|
|
27326
|
+
{ type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
|
|
27327
|
+
];
|
|
27328
|
+
|
|
27329
|
+
class JobProgressionList {
|
|
27330
|
+
constructor() {
|
|
27331
|
+
}
|
|
27332
|
+
ngOnInit() {
|
|
27333
|
+
}
|
|
27334
|
+
}
|
|
27335
|
+
JobProgressionList.decorators = [
|
|
27336
|
+
{ type: Component, args: [{
|
|
27337
|
+
selector: 'app-job-progression-list',
|
|
27338
|
+
template: "<ion-list class=\"ion-list-popover\">\n\n <ion-row class=\"ion-list-header column\">\n <ion-col>\n <ion-label>{{titleI18n | translate}}</ion-label>\n </ion-col>\n </ion-row>\n\n <ion-item *ngIf=\"!jobProgressions?.length\">\n {{'SOCIAL.JOB.PROGRESSION.EMPTY' | translate}}\n </ion-item>\n <ion-item *ngFor=\"let jobProgression of jobProgressions\" class=\"ion-item-job-progression\">\n <ion-grid class=\"ion-no-margin\">\n <ion-row class=\"name\">\n <ion-col>\n {{jobProgression.name}}\n </ion-col>\n </ion-row>\n <ion-row class=\"message\">\n <ion-col>\n {{jobProgression.message}}\n </ion-col>\n </ion-row>\n <ion-row class=\"progress-bar\">\n <ion-col>\n <ion-progress-bar\n [value]=\"jobProgression.total > 0 ? jobProgression.current / jobProgression.total : undefined\"\n [type]=\"jobProgression.total > 0 ? 'determinate' : 'indeterminate'\">\n </ion-progress-bar>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-item>\n\n</ion-list>\n",
|
|
27339
|
+
styles: [":host(.popover-viewport){overflow-y:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.ion-item-job-progression{font-size:.9em}.ion-item-job-progression .message{font-style:italic}.ion-item-job-progression .progress-bar{margin-top:5px;margin-bottom:5px}"]
|
|
27340
|
+
},] }
|
|
27341
|
+
];
|
|
27342
|
+
JobProgressionList.ctorParameters = () => [];
|
|
27343
|
+
JobProgressionList.propDecorators = {
|
|
27344
|
+
titleI18n: [{ type: Input }],
|
|
27345
|
+
jobProgressions: [{ type: Input }]
|
|
27346
|
+
};
|
|
27347
|
+
|
|
27348
|
+
class JobProgressionComponent {
|
|
27349
|
+
constructor(jobProgressionService, popoverController, cd) {
|
|
27350
|
+
this.jobProgressionService = jobProgressionService;
|
|
27351
|
+
this.popoverController = popoverController;
|
|
27352
|
+
this.cd = cd;
|
|
27353
|
+
this.debug = false;
|
|
27354
|
+
this.titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';
|
|
27355
|
+
this.jobFinished = new EventEmitter();
|
|
27356
|
+
this.disabled = true;
|
|
27357
|
+
this.color = 'accent';
|
|
27358
|
+
this.mode = 'determinate';
|
|
27359
|
+
this.value = 0;
|
|
27360
|
+
this.jobProgressions = [];
|
|
27361
|
+
this._subscriptions = new Subscription();
|
|
27362
|
+
this._subscriptionsById = {};
|
|
27363
|
+
this._logPrefix = '[job-progression] ';
|
|
27364
|
+
}
|
|
27365
|
+
ngOnInit() {
|
|
27366
|
+
var _a, _b, _c, _d;
|
|
27367
|
+
if (isNil(this.jobProgressionService)) {
|
|
27368
|
+
console.warn(`${this._logPrefix}No service injected`);
|
|
27369
|
+
}
|
|
27370
|
+
// parse options
|
|
27371
|
+
this.autoHide = toBoolean((_a = this.options) === null || _a === void 0 ? void 0 : _a.autoHide, false);
|
|
27372
|
+
this.visible = !this.autoHide;
|
|
27373
|
+
this.autoHideDelay = toNumber((_b = this.options) === null || _b === void 0 ? void 0 : _b.autoHideDelay, 1000);
|
|
27374
|
+
this.autoRemove = toBoolean((_c = this.options) === null || _c === void 0 ? void 0 : _c.autoRemove, true);
|
|
27375
|
+
this.autoRemoveDelay = toNumber((_d = this.options) === null || _d === void 0 ? void 0 : _d.autoRemoveDelay, 1000);
|
|
27376
|
+
}
|
|
27377
|
+
addJob(id) {
|
|
27378
|
+
if (isNil(this.jobProgressionService)) {
|
|
27379
|
+
console.warn(`${this._logPrefix}No service injected. Can't add a job`);
|
|
27380
|
+
return;
|
|
27381
|
+
}
|
|
27382
|
+
if (!!this.getProgression(id)) {
|
|
27383
|
+
console.warn(`${this._logPrefix}Job (id=${id}) already present`);
|
|
27384
|
+
return;
|
|
27385
|
+
}
|
|
27386
|
+
if (this.debug) {
|
|
27387
|
+
console.debug(`${this._logPrefix}Add job id=${id}`);
|
|
27388
|
+
}
|
|
27389
|
+
// Adding empty job progression
|
|
27390
|
+
const progression = new JobProgression(id);
|
|
27391
|
+
this.jobProgressions.push(progression);
|
|
27392
|
+
this.disabled = false;
|
|
27393
|
+
const sub = this.jobProgressionService.listenChanges(id)
|
|
27394
|
+
.pipe(filter(progression => {
|
|
27395
|
+
if (id !== progression.id) {
|
|
27396
|
+
console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);
|
|
27397
|
+
return false;
|
|
27398
|
+
}
|
|
27399
|
+
return true;
|
|
27400
|
+
}), map(progression => {
|
|
27401
|
+
// Ensure visible
|
|
27402
|
+
this.visible = true;
|
|
27403
|
+
// Get current progression object
|
|
27404
|
+
const currentProgression = this.getProgression(id);
|
|
27405
|
+
if (!currentProgression) {
|
|
27406
|
+
// add it if absent
|
|
27407
|
+
this.jobProgressions.push(progression);
|
|
27408
|
+
if (this.debug) {
|
|
27409
|
+
console.debug(`${this._logPrefix}Progression added id=${id}`, progression);
|
|
27410
|
+
}
|
|
27411
|
+
}
|
|
27412
|
+
else {
|
|
27413
|
+
// update current
|
|
27414
|
+
Object.assign(currentProgression, progression);
|
|
27415
|
+
if (this.debug) {
|
|
27416
|
+
console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);
|
|
27417
|
+
}
|
|
27418
|
+
}
|
|
27419
|
+
return progression;
|
|
27420
|
+
}))
|
|
27421
|
+
.subscribe(progression => {
|
|
27422
|
+
// update value
|
|
27423
|
+
this.updateValue();
|
|
27424
|
+
// job finished
|
|
27425
|
+
if (progression.total > 0 && progression.current == progression.total) {
|
|
27426
|
+
if (this.debug) {
|
|
27427
|
+
console.debug(`${this._logPrefix}Finished job id=${progression.id}`);
|
|
27428
|
+
}
|
|
27429
|
+
// emit event
|
|
27430
|
+
this.jobFinished.emit(progression.id);
|
|
27431
|
+
if (this.autoRemove) {
|
|
27432
|
+
setTimeout(() => {
|
|
27433
|
+
var _a;
|
|
27434
|
+
this.removeJob(progression.id);
|
|
27435
|
+
// If last job
|
|
27436
|
+
if (this.autoHide && !((_a = this.jobProgressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
27437
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
27438
|
+
var _b;
|
|
27439
|
+
(_b = this._listPopover) === null || _b === void 0 ? void 0 : _b.dismiss();
|
|
27440
|
+
this.visible = false;
|
|
27441
|
+
this.markForCheck();
|
|
27442
|
+
}), this.autoHideDelay);
|
|
27443
|
+
}
|
|
27444
|
+
}, this.autoRemoveDelay);
|
|
27445
|
+
}
|
|
27446
|
+
}
|
|
27447
|
+
});
|
|
27448
|
+
this._subscriptionsById[id] = sub;
|
|
27449
|
+
this._subscriptions.add(sub);
|
|
27450
|
+
}
|
|
27451
|
+
removeJob(id) {
|
|
27452
|
+
if (this.debug) {
|
|
27453
|
+
console.debug(`${this._logPrefix}Remove job id=${id}`);
|
|
27454
|
+
}
|
|
27455
|
+
const sub = this._subscriptionsById[id];
|
|
27456
|
+
if (sub) {
|
|
27457
|
+
this._subscriptions.remove(sub);
|
|
27458
|
+
sub.unsubscribe();
|
|
27459
|
+
}
|
|
27460
|
+
const progression = this.getProgression(id);
|
|
27461
|
+
if (progression) {
|
|
27462
|
+
this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);
|
|
27463
|
+
}
|
|
27464
|
+
this.updateValue();
|
|
27465
|
+
}
|
|
27466
|
+
getProgression(id) {
|
|
27467
|
+
return this.jobProgressions.find(progression => progression.id === id);
|
|
27468
|
+
}
|
|
27469
|
+
updateValue() {
|
|
27470
|
+
if (this.debug) {
|
|
27471
|
+
console.debug(`${this._logPrefix}Updating value`);
|
|
27472
|
+
}
|
|
27473
|
+
let value = 0;
|
|
27474
|
+
const nbProgression = arraySize(this.jobProgressions);
|
|
27475
|
+
let allIndeterminate = nbProgression > 0;
|
|
27476
|
+
this.jobProgressions.forEach(progression => {
|
|
27477
|
+
const indeterminate = progression.total === 0;
|
|
27478
|
+
allIndeterminate = allIndeterminate && indeterminate;
|
|
27479
|
+
if (!indeterminate) {
|
|
27480
|
+
value = value + progression.current * 100 / progression.total;
|
|
27481
|
+
}
|
|
27482
|
+
});
|
|
27483
|
+
this.value = nbProgression > 0 ? value / nbProgression : 0;
|
|
27484
|
+
this.mode = allIndeterminate ? 'indeterminate' : 'determinate';
|
|
27485
|
+
if (this.debug) {
|
|
27486
|
+
console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);
|
|
27487
|
+
}
|
|
27488
|
+
this.markForCheck();
|
|
27489
|
+
}
|
|
27490
|
+
showList(event) {
|
|
27491
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27492
|
+
this._listPopover = yield this.popoverController.create({
|
|
27493
|
+
component: JobProgressionList,
|
|
27494
|
+
componentProps: {
|
|
27495
|
+
titleI18n: this.titleI18n,
|
|
27496
|
+
jobProgressions: this.jobProgressions
|
|
27497
|
+
},
|
|
27498
|
+
backdropDismiss: true,
|
|
27499
|
+
keyboardClose: true,
|
|
27500
|
+
event,
|
|
27501
|
+
translucent: true,
|
|
27502
|
+
cssClass: 'popover-large'
|
|
27503
|
+
});
|
|
27504
|
+
yield this._listPopover.present();
|
|
27505
|
+
yield this._listPopover.onDidDismiss();
|
|
27506
|
+
this._listPopover = undefined;
|
|
27507
|
+
});
|
|
27508
|
+
}
|
|
27509
|
+
markForCheck() {
|
|
27510
|
+
this.cd.markForCheck();
|
|
27511
|
+
}
|
|
27512
|
+
ngOnDestroy() {
|
|
27513
|
+
if (this.debug) {
|
|
27514
|
+
console.debug(`${this._logPrefix}Destroying`);
|
|
27515
|
+
}
|
|
27516
|
+
this._subscriptions.unsubscribe();
|
|
27517
|
+
}
|
|
27518
|
+
}
|
|
27519
|
+
JobProgressionComponent.decorators = [
|
|
27520
|
+
{ type: Component, args: [{
|
|
27521
|
+
selector: 'app-job-progression',
|
|
27522
|
+
template: "<button\n #button\n mat-icon-button\n [title]=\"titleI18n | translate\"\n [disabled]=\"disabled\"\n *ngIf=\"visible\"\n (click)=\"showList($event)\"\n>\n <mat-icon\n [matBadge]=\"jobProgressions?.length\"\n [matBadgeHidden]=\"!jobProgressions?.length\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n >{{ disabled || jobProgressions?.length ? 'schedule' : 'task_alt' }}\n </mat-icon>\n <mat-spinner\n #spinner\n *ngIf=\"jobProgressions?.length\"\n class=\"floating-spinner\"\n [color]=\"color\"\n [mode]=\"mode\"\n [value]=\"value\"\n diameter=\"30\"\n strokeWidth=\"3\"\n ></mat-spinner>\n</button>\n\n",
|
|
27523
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27524
|
+
styles: [".floating-spinner{position:absolute;top:6px;left:5px}"]
|
|
27525
|
+
},] }
|
|
27526
|
+
];
|
|
27527
|
+
JobProgressionComponent.ctorParameters = () => [
|
|
27528
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [JobProgressionServiceToken,] }] },
|
|
27529
|
+
{ type: PopoverController },
|
|
27530
|
+
{ type: ChangeDetectorRef }
|
|
27531
|
+
];
|
|
27532
|
+
JobProgressionComponent.propDecorators = {
|
|
27533
|
+
debug: [{ type: Input }],
|
|
27534
|
+
titleI18n: [{ type: Input }],
|
|
27535
|
+
options: [{ type: Input }],
|
|
27536
|
+
jobFinished: [{ type: Output }]
|
|
27537
|
+
};
|
|
27538
|
+
|
|
27539
|
+
class JobModule {
|
|
27540
|
+
}
|
|
27541
|
+
JobModule.decorators = [
|
|
27542
|
+
{ type: NgModule, args: [{
|
|
27543
|
+
imports: [
|
|
27544
|
+
CommonModule,
|
|
27545
|
+
SharedModule,
|
|
27546
|
+
TranslateModule.forChild(),
|
|
27547
|
+
],
|
|
27548
|
+
declarations: [
|
|
27549
|
+
JobProgressionComponent,
|
|
27550
|
+
JobProgressionList
|
|
27551
|
+
],
|
|
27552
|
+
exports: [
|
|
27553
|
+
JobProgressionComponent
|
|
27554
|
+
]
|
|
27555
|
+
},] }
|
|
27556
|
+
];
|
|
27557
|
+
|
|
27558
|
+
const SocialModuleOptionsToken = new InjectionToken("SocialModuleOptions");
|
|
27559
|
+
class SocialModule {
|
|
27560
|
+
}
|
|
27561
|
+
SocialModule.decorators = [
|
|
27562
|
+
{ type: NgModule, args: [{
|
|
27563
|
+
imports: [
|
|
27564
|
+
CommonModule,
|
|
27565
|
+
CoreModule,
|
|
27566
|
+
SharedModule,
|
|
27567
|
+
UserEventModule,
|
|
27568
|
+
JobModule,
|
|
27569
|
+
MessageModule,
|
|
27570
|
+
],
|
|
27571
|
+
},] }
|
|
27572
|
+
];
|
|
27573
|
+
|
|
26711
27574
|
const Mutations = {
|
|
26712
27575
|
send: gql `mutation SendMessage($data: MessageVOInput){
|
|
26713
27576
|
done: sendMessage(message: $data)
|
|
@@ -27522,13 +28385,13 @@ LatLongTestPage.ctorParameters = () => [
|
|
|
27522
28385
|
{ type: FormBuilder }
|
|
27523
28386
|
];
|
|
27524
28387
|
|
|
27525
|
-
const moment$
|
|
28388
|
+
const moment$7 = momentImported;
|
|
27526
28389
|
class SwipeTestPage {
|
|
27527
28390
|
constructor(formBuilder, dateFormatPipe) {
|
|
27528
28391
|
this.formBuilder = formBuilder;
|
|
27529
28392
|
this.dateFormatPipe = dateFormatPipe;
|
|
27530
28393
|
this.$dates = new BehaviorSubject(undefined);
|
|
27531
|
-
this._today = moment$
|
|
28394
|
+
this._today = moment$7().startOf('day');
|
|
27532
28395
|
this.form = formBuilder.group({
|
|
27533
28396
|
empty: [null, Validators.required],
|
|
27534
28397
|
date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],
|
|
@@ -27541,7 +28404,7 @@ class SwipeTestPage {
|
|
|
27541
28404
|
ngOnInit() {
|
|
27542
28405
|
const dates = [];
|
|
27543
28406
|
for (let d = 0; d < 7; d++) {
|
|
27544
|
-
dates[d] = moment$
|
|
28407
|
+
dates[d] = moment$7(this._today).add(d - 3, 'day');
|
|
27545
28408
|
}
|
|
27546
28409
|
this.$dates.next(dates);
|
|
27547
28410
|
this.loadData();
|
|
@@ -27582,7 +28445,7 @@ SwipeTestPage.ctorParameters = () => [
|
|
|
27582
28445
|
{ type: DateFormatPipe }
|
|
27583
28446
|
];
|
|
27584
28447
|
|
|
27585
|
-
const moment$
|
|
28448
|
+
const moment$8 = momentImported;
|
|
27586
28449
|
class DateTimeTestPage {
|
|
27587
28450
|
constructor(platform, formBuilder, cd) {
|
|
27588
28451
|
this.platform = platform;
|
|
@@ -27614,7 +28477,7 @@ class DateTimeTestPage {
|
|
|
27614
28477
|
// Load the form with data
|
|
27615
28478
|
loadData() {
|
|
27616
28479
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27617
|
-
const now = moment$
|
|
28480
|
+
const now = moment$8();
|
|
27618
28481
|
const data = {
|
|
27619
28482
|
empty: null,
|
|
27620
28483
|
emptyRequired: null,
|
|
@@ -27860,7 +28723,7 @@ NumpadTestPage.ctorParameters = () => [
|
|
|
27860
28723
|
{ type: FormBuilder }
|
|
27861
28724
|
];
|
|
27862
28725
|
|
|
27863
|
-
const moment$
|
|
28726
|
+
const moment$9 = momentImported;
|
|
27864
28727
|
class DateTestPage {
|
|
27865
28728
|
constructor(formBuilder, cd) {
|
|
27866
28729
|
this.formBuilder = formBuilder;
|
|
@@ -27893,7 +28756,7 @@ class DateTestPage {
|
|
|
27893
28756
|
// Load the form with data
|
|
27894
28757
|
loadData() {
|
|
27895
28758
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27896
|
-
const now = moment$
|
|
28759
|
+
const now = moment$9();
|
|
27897
28760
|
const nowAtMahe = now.clone().tz(this.timezone).startOf('day');
|
|
27898
28761
|
const data = {
|
|
27899
28762
|
empty: null,
|
|
@@ -28639,5 +29502,5 @@ CoreTestingModule.decorators = [
|
|
|
28639
29502
|
* Generated bundle index. Do not edit.
|
|
28640
29503
|
*/
|
|
28641
29504
|
|
|
28642
|
-
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj,
|
|
29505
|
+
export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AndroidOsEnvironment, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, Fragments$1 as Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, Job, JobModule, JobProgression, JobProgressionComponent, JobProgressionService, JobProgressionServiceToken, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBadgeIconDirective, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItems, MenuService, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NetworkService, NgInitDirective, NgVarDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, ResizableComponent, ResizableDirective, ResizableModule, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBadgeIconModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, Software, StartableService, StatusById, StatusIds, StatusList, StrIncludesPipe, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TextForm, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEvent, UserEventFilter, UserEventFragments, UserEventModule, UserEventNotificationComponent, UserEventService, UserEventServiceToken, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isAndroid, isBlankString, isControlHasInput, isCordova, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isProgressEvent, isResponseEvent, isTouchUi, isWindows, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moment$5 as moment, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, tz, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending, ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, isFocusableElement as ɵc, RegisterForm as ɵd, AccountValidatorService as ɵe, RegisterModal as ɵf, UserSettingsValidatorService as ɵg, LocalSettingsValidatorService as ɵh, AppUpdateOfflineModeCard as ɵi, AppIconComponent as ɵj, UserEventNotificationList as ɵk, UserEventTestService as ɵl, JobProgressionList as ɵm, DateTestPage as ɵn, NumpadTestPage as ɵo, MatBadgeIconTestPage as ɵp, ToastTestingModule as ɵq, ToastTestingPage as ɵr };
|
|
28643
29506
|
//# sourceMappingURL=sumaris-net.ngx-components.js.map
|