diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts index 7995c6d03..9aed7b89f 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts @@ -15,9 +15,8 @@ import { FileDropOverlayService } from '@upload-download/services/file-drop-over import { FileUploadModel } from '@upload-download/model/file-upload.model'; import { FileUploadService } from '@upload-download/services/file-upload.service'; import { StatusOverlayService } from '@upload-download/services/status-overlay.service'; -import * as moment from 'moment'; -import { combineLatest, Observable } from 'rxjs'; -import { skip, switchMap, tap } from 'rxjs/operators'; +import { Observable } from 'rxjs'; +import { filter, skip, switchMap, tap } from 'rxjs/operators'; import { convertFiles, Files, handleFileDrop } from '@utils/index'; import { CircleButtonTypes, @@ -129,17 +128,17 @@ export class DossierOverviewScreenComponent extends ListingComponent imple this._fileDropOverlayService.initFileDropHandling(this.dossierId); - this.addSubscription = combineLatest([ - this._dossiersService.getEntityChanged$(this.dossierId), - this._dossierStatsService.watch$(this.dossierId), - ]) - .pipe(switchMap(() => this._reloadFiles())) - .subscribe(); - this.addSubscription = this.configService.listingMode$.subscribe(() => { this._computeAllFilters(); }); + this.addSubscription = this._dossiersService.dossierFileChanges$ + .pipe( + filter(dossierId => dossierId === this.dossierId), + switchMap(dossierId => this._filesService.loadAll(dossierId)), + ) + .subscribe(); + this.addSubscription = this._dossierTemplatesService .getEntityChanged$(this.currentDossier.dossierTemplateId) .pipe( @@ -192,9 +191,6 @@ export class DossierOverviewScreenComponent extends ListingComponent imple (this._fileInput as any).nativeElement.value = null; } - recentlyModifiedChecker = (file: File) => - moment(file.lastUpdated).add(this._appConfigService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment()); - private _updateFileAttributes(): void { this._fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(this.currentDossier.dossierTemplateId)?.fileAttributeConfigs || []; @@ -204,11 +200,6 @@ export class DossierOverviewScreenComponent extends ListingComponent imple this._computeAllFilters(); } - private async _reloadFiles() { - await this._filesService.loadAll(this.dossierId).toPromise(); - this._computeAllFilters(); - } - private _loadEntitiesFromState() { this.currentDossier = this._dossiersService.find(this.dossierId); this._computeAllFilters(); diff --git a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts index e3543d71b..5d14236fe 100644 --- a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts @@ -1,8 +1,8 @@ import { Injectable, Injector } from '@angular/core'; -import { EntitiesService, List, log, mapEach, QueryParam, RequiredParam, shareLast, Toaster, Validate } from '@iqser/common-ui'; +import { EntitiesService, List, mapEach, QueryParam, RequiredParam, shareLast, Toaster, Validate } from '@iqser/common-ui'; import { Dossier, IDossier, IDossierRequest } from '@red/domain'; import { catchError, filter, map, mapTo, switchMap, tap } from 'rxjs/operators'; -import { combineLatest, iif, Observable, of, throwError, timer } from 'rxjs'; +import { combineLatest, Observable, of, Subject, throwError, timer } from 'rxjs'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { DossierStatsService } from '@services/entity-services/dossier-stats.service'; @@ -13,6 +13,16 @@ export interface IDossiersStats { totalAnalyzedPages: number; } +interface ChangesDetails { + dossierChanges: [ + { + dossierChanges: boolean; + dossierId: string; + fileChanges: boolean; + }, + ]; +} + const DOSSIER_EXISTS_MSG = _('add-dossier-dialog.errors.dossier-already-exists'); const GENERIC_MGS = _('add-dossier-dialog.errors.generic'); @@ -21,6 +31,7 @@ const GENERIC_MGS = _('add-dossier-dialog.errors.generic'); }) export class DossiersService extends EntitiesService { readonly generalStats$ = this.all$.pipe(switchMap(entities => this._generalStats$(entities))); + readonly dossierFileChanges$ = new Subject(); constructor( private readonly _toaster: Toaster, @@ -32,7 +43,7 @@ export class DossiersService extends EntitiesService { timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL) .pipe( switchMap(() => this.loadAllIfChanged()), - log(), + tap(changes => this._emitFileChanges(changes)), ) .subscribe(); } @@ -47,8 +58,15 @@ export class DossiersService extends EntitiesService { ); } - loadAllIfChanged(): Observable { - return this.hasChanges$().pipe(switchMap(changed => iif(() => changed, this.loadAll()).pipe(mapTo(changed)))); + loadAllIfChanged(): Observable { + return this.hasChangesDetails$().pipe(switchMap(changes => this.loadAll().pipe(mapTo(changes)))); + } + + hasChangesDetails$(): Observable { + const body = { value: this._lastCheckedForChanges.get('root') ?? '0' }; + return this._post(body, `${this._defaultModelPath}/changes/details`).pipe( + filter(changes => changes.dossierChanges.length > 0), + ); } @Validate() @@ -90,6 +108,10 @@ export class DossiersService extends EntitiesService { return super.delete(body, 'deleted-dossiers/hard-delete', body).toPromise(); } + private _emitFileChanges(changes: ChangesDetails): void { + changes.dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId)); + } + private _computeStats(entities: List): IDossiersStats { let totalAnalyzedPages = 0; const totalPeople = new Set();