diff --git a/apps/red-ui/src/app/models/file/file-data.model.ts b/apps/red-ui/src/app/models/file/file-data.model.ts index 98e368e03..02b9fc014 100644 --- a/apps/red-ui/src/app/models/file/file-data.model.ts +++ b/apps/red-ui/src/app/models/file/file-data.model.ts @@ -102,7 +102,8 @@ export class FileDataModel { } get hasChangeLog() { - return true; + // TODO DELTA VIEW + return false; } private _isChangeLogEntry(redactionLogEntry: RedactionLogEntry) { diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts index c6ff0871f..0798a2591 100644 --- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts @@ -58,11 +58,16 @@ export class ReportsScreenComponent implements OnInit { async download(template: ReportTemplate) { this._loadingService.start(); - const data = await this._reportTemplateService - .downloadReportTemplate(template.dossierTemplateId, template.templateId, 'response') - .toPromise(); - this._loadingService.stop(); - download(data, template.fileName); + try { + const data = await this._reportTemplateService + .downloadReportTemplate(template.dossierTemplateId, template.templateId, 'response') + .toPromise(); + this._loadingService.stop(); + download(data, template.fileName); + } catch (e) { + this._toaster.error(_('error.http.generic')); + this._loadingService.stop(); + } } deleteTemplate(template: ReportTemplate) { diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html index c4545aa39..74539ea38 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/components/annotations-list/annotations-list.component.html @@ -11,7 +11,7 @@
- +
diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html index e64d3734b..ad93dcfe9 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html @@ -177,6 +177,7 @@ [activeViewerPage]="activeViewerPage" [annotationActionsTemplate]="annotationActionsTemplate" [annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)" + (selectAnnotations)="selectAnnotations.emit($event)" [canMultiSelect]="!isReadOnly" [selectedAnnotations]="selectedAnnotations" > 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 6e8994db1..0bc2ccfe8 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 @@ -148,7 +148,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple this.calculateData(); - this.addSubscription = timer(0, 7500).subscribe(async () => { + this.addSubscription = timer(0, 10 * 1000).subscribe(async () => { await this._appStateService.reloadActiveDossierFilesIfNecessary(); this._loadEntitiesFromState(); }); diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts index 668d0829a..7ed3f5173 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts @@ -204,22 +204,22 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni switch (this.viewMode) { case 'STANDARD': { this._setAnnotationsColor(redactions, 'annotationColor'); - const standardEntries = annotations.filter(a => !a.getCustomData('changeLogRemoved')); - const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved')); + const standardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved') === 'false'); + const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved') === 'true'); this._show(standardEntries); this._hide(nonStandardEntries); break; } case 'DELTA': { - const changeLogEntries = annotations.filter(a => a.getCustomData('changeLog')); - const nonChangeLogEntries = annotations.filter(a => !a.getCustomData('changeLog')); + const changeLogEntries = annotations.filter(a => a.getCustomData('changeLog') === 'true'); + const nonChangeLogEntries = annotations.filter(a => a.getCustomData('changeLog') === 'false'); this._setAnnotationsColor(redactions, 'annotationColor'); this._show(changeLogEntries); this._hide(nonChangeLogEntries); break; } case 'REDACTED': { - const nonRedactionEntries = annotations.filter(a => !a.getCustomData('redaction')); + const nonRedactionEntries = annotations.filter(a => a.getCustomData('redaction') === 'false'); this._setAnnotationsColor(redactions, 'redactionColor'); this._show(redactions); this._hide(nonRedactionEntries); diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts index d89f45970..9d4a1ec32 100644 --- a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts @@ -22,7 +22,7 @@ export class AnnotationDrawService { return; } const annotations = annotationWrappers.map(annotation => - this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode), + this._computeAnnotation(activeViewer, annotation, hideSkipped, compareMode), ); const annotationManager = activeViewer.Core.annotationManager; annotationManager.addAnnotations(annotations, { imported: true }); @@ -32,78 +32,11 @@ export class AnnotationDrawService { this._redactionLogControllerService .getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId) .subscribe(sectionGrid => { - this.drawSections(activeViewer, sectionGrid); + this._drawSections(activeViewer, sectionGrid); }); } } - drawSections(activeViewer: WebViewerInstance, sectionGrid: SectionGrid) { - const sections = []; - for (const page of Object.keys(sectionGrid.rectanglesPerPage)) { - const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page]; - sectionRectangles.forEach(sectionRectangle => { - sections.push(this.computeSection(activeViewer, parseInt(page, 10), sectionRectangle)); - // sectionRectangle.tableCells?.forEach(cell =>{ - // sections.push(this.computeSection(activeViewer, parseInt(page, 10), cell)); - // }) - }); - } - const annotationManager = activeViewer.Core.annotationManager; - annotationManager.addAnnotations(sections, { imported: true }); - annotationManager.drawAnnotationsFromList(sections); - } - - computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) { - const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation(); - const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber); - const rectangle = { - topLeft: sectionRectangle.topLeft, - page: pageNumber, - height: sectionRectangle.height, - width: sectionRectangle.width, - }; - rectangleAnnot.PageNumber = pageNumber; - rectangleAnnot.X = rectangle.topLeft.x - 1; - rectangleAnnot.Y = pageHeight - (rectangle.topLeft.y + rectangle.height) - 1; - rectangleAnnot.Width = rectangle.width + 2; - rectangleAnnot.Height = rectangle.height + 2; - rectangleAnnot.ReadOnly = true; - rectangleAnnot.StrokeColor = this.getColor(activeViewer, 'analysis', 'analysis'); - rectangleAnnot.StrokeThickness = 1; - - return rectangleAnnot; - } - - computeAnnotation(activeViewer: WebViewerInstance, annotationWrapper: AnnotationWrapper, hideSkipped = false, compareMode = false) { - const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber; - const highlight = new activeViewer.Core.Annotations.TextHighlightAnnotation(); - highlight.PageNumber = pageNumber; - highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type); - highlight.setContents(annotationWrapper.content); - highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber); - highlight.Id = annotationWrapper.id; - highlight.ReadOnly = true; - // change log entries are drawn lighter - highlight.Opacity = annotationWrapper.isChangeLogRemoved ? 0.2 : 1; - highlight.Hidden = - annotationWrapper.isChangeLogRemoved || - (hideSkipped && annotationWrapper.isSkipped) || - annotationWrapper.isOCR || - annotationWrapper.hidden; - highlight.setCustomData('redacto-manager', 'true'); - highlight.setCustomData('redaction', String(annotationWrapper.isRedacted)); - highlight.setCustomData('skipped', String(annotationWrapper.isSkipped)); - highlight.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry)); - highlight.setCustomData('changeLogRemoved', String(annotationWrapper.isChangeLogRemoved)); - highlight.setCustomData('redactionColor', String(this.getColor(activeViewer, 'redaction', 'redaction'))); - highlight.setCustomData( - 'annotationColor', - String(this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type)), - ); - - return highlight; - } - getColor(activeViewer: WebViewerInstance, superType: string, dictionary?: string) { let color; switch (superType) { @@ -139,6 +72,79 @@ export class AnnotationDrawService { return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4); } + private _drawSections(activeViewer: WebViewerInstance, sectionGrid: SectionGrid) { + const sections = []; + for (const page of Object.keys(sectionGrid.rectanglesPerPage)) { + const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page]; + sectionRectangles.forEach(sectionRectangle => { + sections.push(this._computeSection(activeViewer, parseInt(page, 10), sectionRectangle)); + // sectionRectangle.tableCells?.forEach(cell =>{ + // sections.push(this.computeSection(activeViewer, parseInt(page, 10), cell)); + // }) + }); + } + const annotationManager = activeViewer.Core.annotationManager; + annotationManager.addAnnotations(sections, { imported: true }); + annotationManager.drawAnnotationsFromList(sections); + } + + private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) { + const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation(); + const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber); + const rectangle = { + topLeft: sectionRectangle.topLeft, + page: pageNumber, + height: sectionRectangle.height, + width: sectionRectangle.width, + }; + rectangleAnnot.PageNumber = pageNumber; + rectangleAnnot.X = rectangle.topLeft.x - 1; + rectangleAnnot.Y = pageHeight - (rectangle.topLeft.y + rectangle.height) - 1; + rectangleAnnot.Width = rectangle.width + 2; + rectangleAnnot.Height = rectangle.height + 2; + rectangleAnnot.ReadOnly = true; + rectangleAnnot.StrokeColor = this.getColor(activeViewer, 'analysis', 'analysis'); + rectangleAnnot.StrokeThickness = 1; + + return rectangleAnnot; + } + + private _computeAnnotation( + activeViewer: WebViewerInstance, + annotationWrapper: AnnotationWrapper, + hideSkipped = false, + compareMode = false, + ) { + const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber; + const highlight = new activeViewer.Core.Annotations.TextHighlightAnnotation(); + highlight.PageNumber = pageNumber; + highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type); + highlight.setContents(annotationWrapper.content); + highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber); + highlight.Id = annotationWrapper.id; + highlight.ReadOnly = true; + // change log entries are drawn lighter + highlight.Opacity = annotationWrapper.isChangeLogRemoved ? 0.2 : 1; + highlight.Hidden = + annotationWrapper.isChangeLogRemoved || + (hideSkipped && annotationWrapper.isSkipped) || + annotationWrapper.isOCR || + annotationWrapper.hidden; + highlight.setCustomData('redacto-manager', 'true'); + highlight.setCustomData('redaction', String(annotationWrapper.isRedacted)); + highlight.setCustomData('skipped', String(annotationWrapper.isSkipped)); + // TODO once changelog is implemented + highlight.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry && false)); + highlight.setCustomData('changeLogRemoved', String(annotationWrapper.isChangeLogRemoved && false)); + highlight.setCustomData('redactionColor', String(this.getColor(activeViewer, 'redaction', 'redaction'))); + highlight.setCustomData( + 'annotationColor', + String(this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type)), + ); + + return highlight; + } + private _rectanglesToQuads(positions: Rectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] { const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber); return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight)); diff --git a/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts b/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts index 9729a3382..d249114d7 100644 --- a/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts @@ -38,8 +38,8 @@ export class PdfViewerDataService { loadActiveFileData(): Observable { const file$ = this.downloadOriginalFile(this._appStateService.activeFile); - const reactionLog$ = this.loadActiveFileRedactionLog(); - const viewedPages$ = this.getViewedPagesForActiveFile(); + const reactionLog$ = this.loadActiveFileRedactionLog().pipe(catchError(() => of({}))); + const viewedPages$ = this.getViewedPagesForActiveFile().pipe(catchError(() => of({}))); return forkJoin([file$, reactionLog$, viewedPages$]).pipe( map(data => new FileDataModel(this._appStateService.activeFile, ...data)), diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index aed8de3d8..ef99d5a43 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -94,9 +94,7 @@ export class AppStateService { } async reloadActiveDossierFilesIfNecessary() { - if (this._dossiersService.activeDossier?.hasPendingOrProcessing) { - await this.reloadActiveDossierFiles(); - } + await this.reloadActiveDossierFiles(); } getDictionaryColor(type?: string, dossierTemplateId = this._dossiersService.activeDossier?.dossierTemplateId) { diff --git a/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts b/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts index cc9afe2eb..a152d1660 100644 --- a/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts +++ b/libs/red-ui-http/src/lib/api/reportTemplateController.service.ts @@ -56,14 +56,14 @@ export class ReportTemplateControllerService { dossierTemplateId: string, templateId: string, observe?: 'response', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public deleteTemplate( dossierTemplateId: string, templateId: string, observe?: 'events', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public deleteTemplate( @@ -120,21 +120,21 @@ export class ReportTemplateControllerService { dossierTemplateId: string, templateId: string, observe?: 'body', - reportProgress?: boolean + reportProgress?: boolean, ): Observable; public downloadReportTemplate( dossierTemplateId: string, templateId: string, observe?: 'response', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public downloadReportTemplate( dossierTemplateId: string, templateId: string, observe?: 'events', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public downloadReportTemplate( @@ -160,17 +160,11 @@ export class ReportTemplateControllerService { headers = headers.set('Authorization', 'Bearer ' + accessToken); } - // to determine the Accept header - const httpHeaderAccepts: string[] = ['application/json']; - const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); - if (httpHeaderAcceptSelected !== undefined) { - headers = headers.set('Accept', httpHeaderAcceptSelected); - } - - return this.httpClient.request( + return this.httpClient.request( 'get', `${this.basePath}/templateUpload/${encodeURIComponent(String(dossierTemplateId))}/${encodeURIComponent(String(templateId))}`, { + responseType: 'blob', withCredentials: this.configuration.withCredentials, headers: headers, observe: observe, @@ -189,19 +183,19 @@ export class ReportTemplateControllerService { public getAvailablePlaceholders( dossierTemplateId: string, observe?: 'body', - reportProgress?: boolean + reportProgress?: boolean, ): Observable; public getAvailablePlaceholders( dossierTemplateId: string, observe?: 'response', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public getAvailablePlaceholders( dossierTemplateId: string, observe?: 'events', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public getAvailablePlaceholders(dossierTemplateId: string, observe: any = 'body', reportProgress: boolean = false): Observable { @@ -247,19 +241,19 @@ export class ReportTemplateControllerService { public getAvailableReportTemplates( dossierTemplateId: string, observe?: 'body', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public getAvailableReportTemplates( dossierTemplateId: string, observe?: 'response', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>>; public getAvailableReportTemplates( dossierTemplateId: string, observe?: 'events', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>>; public getAvailableReportTemplates(dossierTemplateId: string, observe: any = 'body', reportProgress: boolean = false): Observable { @@ -309,7 +303,7 @@ export class ReportTemplateControllerService { multiFileReport?: boolean, file?: Blob, observe?: 'body', - reportProgress?: boolean + reportProgress?: boolean, ): Observable; public uploadTemplateForm( @@ -317,7 +311,7 @@ export class ReportTemplateControllerService { multiFileReport?: boolean, file?: Blob, observe?: 'response', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public uploadTemplateForm( @@ -325,7 +319,7 @@ export class ReportTemplateControllerService { multiFileReport?: boolean, file?: Blob, observe?: 'events', - reportProgress?: boolean + reportProgress?: boolean, ): Observable>; public uploadTemplateForm(