From e2d3c99f0c8dcd6b701fa14c55f3cda1f538611a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 24 Jun 2022 17:44:51 +0300 Subject: [PATCH] RED-4361: Background refresh archive --- apps/red-ui/src/app/app.component.ts | 9 +- .../dashboard-screen.component.ts | 6 +- .../dossiers/active-dossiers.service.ts | 25 +----- .../dossiers/dossier-changes.service.ts | 88 +++++++++++++++++++ .../app/services/dossiers/dossiers.service.ts | 45 ++-------- .../app/utils/configuration.initializer.ts | 2 +- 6 files changed, 106 insertions(+), 69 deletions(-) create mode 100644 apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts diff --git a/apps/red-ui/src/app/app.component.ts b/apps/red-ui/src/app/app.component.ts index 2dbb71620..10eefc848 100644 --- a/apps/red-ui/src/app/app.component.ts +++ b/apps/red-ui/src/app/app.component.ts @@ -2,6 +2,7 @@ import { Component, ViewContainerRef } from '@angular/core'; import { RouterHistoryService } from '@services/router-history.service'; import { UserService } from '@services/user.service'; import { REDDocumentViewer } from './modules/pdf-viewer/services/document-viewer.service'; +import { DossiersChangesService } from '@services/dossiers/dossier-changes.service'; @Component({ selector: 'redaction-root', @@ -16,5 +17,11 @@ export class AppComponent { private readonly _routerHistoryService: RouterHistoryService, private readonly _userService: UserService, readonly documentViewer: REDDocumentViewer, - ) {} + private readonly _dossierChangesService: DossiersChangesService, + ) { + // TODO: Find a better place to initialize dossiers refresh + if (_userService.currentUser?.isUser) { + _dossierChangesService.initializeRefresh(); + } + } } diff --git a/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.ts b/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.ts index 3008fb1e0..94c2046d1 100644 --- a/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.ts +++ b/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { UserService } from '@services/user.service'; import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service'; import { UserPreferenceService } from '@services/user-preference.service'; -import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; @Component({ selector: 'redaction-dashboard-screen', @@ -18,10 +17,7 @@ export class DashboardScreenComponent implements OnInit { private readonly _userService: UserService, private readonly _dashboardStatsService: DashboardStatsService, private readonly _userPreferenceService: UserPreferenceService, - private readonly _activeDossiersService: ActiveDossiersService, - ) { - _activeDossiersService.initializeRefresh(); - } + ) {} async ngOnInit(): Promise { await this._userPreferenceService.saveLastDossierTemplate(null); diff --git a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts index bd85ab539..b3cc9ab59 100644 --- a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts @@ -1,35 +1,12 @@ import { Injectable, Injector } from '@angular/core'; -import { CHANGED_CHECK_INTERVAL } from '@utils/constants'; import { DossiersService } from './dossiers.service'; -import { Observable, timer } from 'rxjs'; -import { switchMap, tap } from 'rxjs/operators'; -import { Dossier, DOSSIERS_ROUTE } from '@red/domain'; +import { DOSSIERS_ROUTE } from '@red/domain'; @Injectable({ providedIn: 'root', }) export class ActiveDossiersService extends DossiersService { - private _initializedRefresh = false; - constructor(protected readonly _injector: Injector) { super(_injector, 'dossier', DOSSIERS_ROUTE); } - - initializeRefresh() { - if (this._initializedRefresh) { - return; - } - this._initializedRefresh = true; - timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL) - .pipe( - switchMap(() => this.loadOnlyChanged()), - tap(changes => this._emitFileChanges(changes)), - ) - .subscribe(); - } - - loadAll(): Observable { - this.initializeRefresh(); - return super.loadAll(); - } } diff --git a/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts b/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts new file mode 100644 index 000000000..bdaab839d --- /dev/null +++ b/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts @@ -0,0 +1,88 @@ +import { GenericService, List, QueryParam } from '@iqser/common-ui'; +import { Dossier, DossierStats, IDossierChanges } from '@red/domain'; +import { forkJoin, Observable, of, throwError, timer } from 'rxjs'; +import { catchError, filter, map, switchMap, take, tap } from 'rxjs/operators'; +import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; +import { NGXLogger } from 'ngx-logger'; +import { ActiveDossiersService } from './active-dossiers.service'; +import { ArchivedDossiersService } from './archived-dossiers.service'; +import { Injectable, Injector } from '@angular/core'; +import { DossierStatsService } from './dossier-stats.service'; +import { DashboardStatsService } from '../dossier-templates/dashboard-stats.service'; +import { CHANGED_CHECK_INTERVAL } from '@utils/constants'; + +@Injectable({ providedIn: 'root' }) +export class DossiersChangesService extends GenericService { + private _initializedRefresh = false; + + private readonly _activeDossiersService: ActiveDossiersService = this._injector.get(ActiveDossiersService); + private readonly _archivedDossiersService: ArchivedDossiersService = this._injector.get(ArchivedDossiersService); + + protected constructor( + protected readonly _injector: Injector, + private readonly _dossierStatsService: DossierStatsService, + private readonly _dashboardStatsService: DashboardStatsService, + private readonly _logger: NGXLogger, + ) { + super(_injector, 'dossier'); + } + + loadOnlyChanged(): Observable { + const removeIfNotFound = (id: string) => + catchError((error: HttpErrorResponse) => { + if (error.status === HttpStatusCode.NotFound) { + this._activeDossiersService.remove(id); + this._archivedDossiersService.remove(id); + return of([]); + } + return throwError(() => error); + }); + + const load = (changes: IDossierChanges) => + changes.map(change => this._load(change.dossierId).pipe(removeIfNotFound(change.dossierId))); + + return this.hasChangesDetails$().pipe( + tap(changes => this._logger.info('[CHANGES] ', changes)), + switchMap(dossierChanges => + forkJoin([...load(dossierChanges), this._dashboardStatsService.loadAll().pipe(take(1))]).pipe(map(() => dossierChanges)), + ), + tap(() => this._updateLastChanged()), + ); + } + + hasChangesDetails$(): Observable { + const body = { value: this._lastCheckedForChanges.get('root') ?? '0' }; + return this._post(body, `${this._defaultModelPath}/changes/details`).pipe(filter(changes => changes.length > 0)); + } + + initializeRefresh() { + if (this._initializedRefresh) { + return; + } + this._initializedRefresh = true; + timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL) + .pipe( + switchMap(() => this.loadOnlyChanged()), + tap(changes => { + this._activeDossiersService.emitFileChanges(changes); + this._archivedDossiersService.emitFileChanges(changes); + }), + ) + .subscribe(); + } + + private _load(id: string): Observable { + const queryParams: List = [{ key: 'includeArchived', value: true }]; + return super._getOne([id], this._defaultModelPath, queryParams).pipe( + map(entity => new Dossier(entity)), + switchMap((dossier: Dossier) => { + if (dossier.isArchived) { + this._activeDossiersService.remove(dossier.id); + return this._archivedDossiersService.updateDossier(dossier); + } + this._archivedDossiersService.remove(dossier.id); + return this._activeDossiersService.updateDossier(dossier); + }), + ); + } +} diff --git a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts index 5a91e82a7..5bb5fcbf6 100644 --- a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts @@ -1,7 +1,7 @@ -import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; +import { EntitiesService, mapEach, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Dossier, DossierStats, IDossier, IDossierChanges, IDossierRequest } from '@red/domain'; -import { forkJoin, Observable, of, Subject, throwError } from 'rxjs'; -import { catchError, filter, map, switchMap, take, tap } from 'rxjs/operators'; +import { Observable, of, Subject } from 'rxjs'; +import { catchError, map, switchMap, tap } from 'rxjs/operators'; import { Injector } from '@angular/core'; import { DossierStatsService } from './dossier-stats.service'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; @@ -36,28 +36,6 @@ export abstract class DossiersService extends EntitiesService ); } - loadOnlyChanged(): Observable { - const removeIfNotFound = (id: string) => - catchError((error: HttpErrorResponse) => { - if (error.status === HttpStatusCode.NotFound) { - this.remove(id); - return of([]); - } - return throwError(() => error); - }); - - const load = (changes: IDossierChanges) => - changes.map(change => this._load(change.dossierId).pipe(removeIfNotFound(change.dossierId))); - - return this.hasChangesDetails$().pipe( - tap(changes => this._logger.info('[CHANGES] ', changes)), - switchMap(dossierChanges => - forkJoin([...load(dossierChanges), this._dashboardStatsService.loadAll().pipe(take(1))]).pipe(map(() => dossierChanges)), - ), - tap(() => this._updateLastChanged()), - ); - } - loadAll(): Observable { const dossierIds = (dossiers: Dossier[]) => dossiers.map(d => d.id); return this.getAll().pipe( @@ -69,21 +47,12 @@ export abstract class DossiersService extends EntitiesService ); } - hasChangesDetails$(): Observable { - const body = { value: this._lastCheckedForChanges.get('root') ?? '0' }; - return this._post(body, `${this._defaultModelPath}/changes/details`).pipe(filter(changes => changes.length > 0)); + updateDossier(dossier: Dossier): Observable { + this.replace(dossier); + return this._dossierStatsService.getFor([dossier.id]); } - protected _emitFileChanges(dossierChanges: IDossierChanges): void { + emitFileChanges(dossierChanges: IDossierChanges): void { dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId)); } - - private _load(id: string): Observable { - const queryParams: List = [{ key: 'includeArchived', value: this._path === 'archived-dossiers' }]; - return super._getOne([id], this._defaultModelPath, queryParams).pipe( - map(entity => new Dossier(entity)), - tap(dossier => this.replace(dossier)), - switchMap(dossier => this._dossierStatsService.getFor([dossier.dossierId])), - ); - } } diff --git a/apps/red-ui/src/app/utils/configuration.initializer.ts b/apps/red-ui/src/app/utils/configuration.initializer.ts index c50088029..d39a23ebd 100644 --- a/apps/red-ui/src/app/utils/configuration.initializer.ts +++ b/apps/red-ui/src/app/utils/configuration.initializer.ts @@ -53,7 +53,7 @@ export function configurationInitializer( }), switchMap(() => languageService.chooseAndSetInitialLanguage()), tap(() => userService.initialize()), - tap(() => firstValueFrom(licenseService.loadLicense())), + switchMap(() => licenseService.loadLicense()), take(1), ); return () => firstValueFrom(setup);