|
|
|
@ -3,7 +3,10 @@ import { |
|
|
|
|
Injector, |
|
|
|
|
} from '@angular/core'; |
|
|
|
|
import { |
|
|
|
|
distinctUntilChanged, |
|
|
|
|
map, |
|
|
|
|
pluck, |
|
|
|
|
share, |
|
|
|
|
switchMap, |
|
|
|
|
take, |
|
|
|
|
} from 'rxjs/operators'; |
|
|
|
@ -32,22 +35,45 @@ import { |
|
|
|
|
IanCenterStore, |
|
|
|
|
InAppNotificationFacet, |
|
|
|
|
} from './ian-center.store'; |
|
|
|
|
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; |
|
|
|
|
import { UIRouterGlobals } from '@uirouter/core'; |
|
|
|
|
import { StateService } from '@uirouter/angular'; |
|
|
|
|
import idFromLink from 'core-app/features/hal/helpers/id-from-link'; |
|
|
|
|
|
|
|
|
|
@Injectable() |
|
|
|
|
@EffectHandler |
|
|
|
|
export class IanCenterService { |
|
|
|
|
export class IanCenterService extends UntilDestroyedMixin { |
|
|
|
|
readonly id = 'ian-center'; |
|
|
|
|
|
|
|
|
|
readonly store = new IanCenterStore(); |
|
|
|
|
|
|
|
|
|
readonly query = new IanCenterQuery(this.store, this.resourceService); |
|
|
|
|
|
|
|
|
|
public selectedNotificationIndex = 0; |
|
|
|
|
|
|
|
|
|
stateChanged$ = this.uiRouterGlobals.params$?.pipe( |
|
|
|
|
this.untilDestroyed(), |
|
|
|
|
pluck('workPackageId'), |
|
|
|
|
distinctUntilChanged(), |
|
|
|
|
map((workPackageId:string) => (workPackageId ? this.apiV3Service.work_packages.id(workPackageId).path : undefined)), |
|
|
|
|
share(), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
constructor( |
|
|
|
|
readonly injector:Injector, |
|
|
|
|
readonly resourceService:InAppNotificationsResourceService, |
|
|
|
|
readonly actions$:ActionsService, |
|
|
|
|
readonly apiV3Service:APIV3Service, |
|
|
|
|
readonly uiRouterGlobals:UIRouterGlobals, |
|
|
|
|
readonly state:StateService, |
|
|
|
|
) { |
|
|
|
|
super(); |
|
|
|
|
|
|
|
|
|
if (this.stateChanged$) { |
|
|
|
|
this.stateChanged$.subscribe(() => { |
|
|
|
|
this.updateSelectedNotificationIndex(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setFilters(filters:INotificationPageQueryParameters):void { |
|
|
|
@ -76,30 +102,57 @@ export class IanCenterService { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
openSplitScreen(wpId:string|null):void { |
|
|
|
|
void this.state.go( |
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/restrict-template-expressions
|
|
|
|
|
`${this.state.current.data.baseRoute}.details.tabs`, |
|
|
|
|
{ workPackageId: wpId, tabIdentifier: 'activity' }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
showNextNotification():void { |
|
|
|
|
void this |
|
|
|
|
.query |
|
|
|
|
.notifications$ |
|
|
|
|
.pipe( |
|
|
|
|
take(1), |
|
|
|
|
).subscribe((notifications:InAppNotification[][]) => { |
|
|
|
|
if (notifications.length <= 0) { |
|
|
|
|
void this.state.go( |
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/restrict-template-expressions
|
|
|
|
|
`${this.state.current.data.baseRoute}`, |
|
|
|
|
); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (notifications[0][0]._links.resource || notifications[this.selectedNotificationIndex][0]._links.resource) { |
|
|
|
|
const wpId = idFromLink(notifications[this.selectedNotificationIndex >= notifications.length ? 0 : this.selectedNotificationIndex][0]._links.resource.href); |
|
|
|
|
this.openSplitScreen(wpId); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Reload after notifications were successfully marked as read |
|
|
|
|
*/ |
|
|
|
|
@EffectCallback(notificationsMarkedRead) |
|
|
|
|
private reloadOnNotificationRead(action:ReturnType<typeof notificationsMarkedRead>) { |
|
|
|
|
if (action.origin === this.id) { |
|
|
|
|
this |
|
|
|
|
.resourceService |
|
|
|
|
.removeFromCollection(this.query.params, action.notifications); |
|
|
|
|
} else { |
|
|
|
|
this.debouncedReload(); |
|
|
|
|
} |
|
|
|
|
this |
|
|
|
|
.resourceService |
|
|
|
|
.removeFromCollection(this.query.params, action.notifications); |
|
|
|
|
this.showNextNotification(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private debouncedReload = _.debounce(() => { this.reload(); }); |
|
|
|
|
private debouncedReload = _.debounce(() => { this.reload().subscribe(); }); |
|
|
|
|
|
|
|
|
|
private reload() { |
|
|
|
|
this.resourceService |
|
|
|
|
return this.resourceService |
|
|
|
|
.fetchNotifications(this.query.params) |
|
|
|
|
.pipe( |
|
|
|
|
setLoading(this.store), |
|
|
|
|
switchMap((results) => from(this.sideLoadInvolvedWorkPackages(results._embedded.elements))), |
|
|
|
|
) |
|
|
|
|
.subscribe(); |
|
|
|
|
switchMap(() => this.query.notifications$), |
|
|
|
|
take(1), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private sideLoadInvolvedWorkPackages(elements:InAppNotification[]):Promise<unknown> { |
|
|
|
@ -126,4 +179,21 @@ export class IanCenterService { |
|
|
|
|
|
|
|
|
|
return promise; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private updateSelectedNotificationIndex() { |
|
|
|
|
this |
|
|
|
|
.query |
|
|
|
|
.notifications$ |
|
|
|
|
.pipe( |
|
|
|
|
take(1), |
|
|
|
|
).subscribe((notifications:InAppNotification[][]) => { |
|
|
|
|
for (let i = 0; i < notifications.length; ++i) { |
|
|
|
|
if (notifications[i][0]._links.resource |
|
|
|
|
&& idFromLink(notifications[i][0]._links.resource.href) === this.uiRouterGlobals.params.workPackageId) { |
|
|
|
|
this.selectedNotificationIndex = i; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|