delta view corrections
This commit is contained in:
parent
e05bbb017e
commit
d7fefef737
@ -3,34 +3,34 @@ import { AnnotationWrapper } from './annotation.wrapper';
|
|||||||
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
|
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
export class AnnotationData {
|
|
||||||
visibleAnnotations: AnnotationWrapper[];
|
|
||||||
allAnnotations: AnnotationWrapper[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FileDataModel {
|
export class FileDataModel {
|
||||||
static readonly DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes;
|
static readonly DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes;
|
||||||
|
|
||||||
hasChangeLog: boolean;
|
hasChangeLog: boolean;
|
||||||
|
allAnnotations: AnnotationWrapper[];
|
||||||
|
|
||||||
constructor(public file: File, public fileData: Blob, public redactionLog: IRedactionLog, public viewedPages?: IViewedPage[]) {}
|
constructor(
|
||||||
|
public file: File,
|
||||||
|
public fileData: Blob,
|
||||||
|
private _redactionLog: IRedactionLog,
|
||||||
|
public viewedPages?: IViewedPage[],
|
||||||
|
private _dictionaryData?: { [p: string]: Dictionary },
|
||||||
|
private _areDevFeaturesEnabled?: boolean,
|
||||||
|
) {
|
||||||
|
this._buildAllAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
getAnnotations(
|
set redactionLog(redactionLog: IRedactionLog) {
|
||||||
dictionaryData: { [p: string]: Dictionary },
|
this._redactionLog = redactionLog;
|
||||||
currentUser: User,
|
this._buildAllAnnotations();
|
||||||
viewMode: ViewMode,
|
}
|
||||||
areDevFeaturesEnabled: boolean,
|
|
||||||
): AnnotationData {
|
|
||||||
const entries: RedactionLogEntryWrapper[] = this._convertData(dictionaryData);
|
|
||||||
let allAnnotations = entries
|
|
||||||
.map(entry => AnnotationWrapper.fromData(entry))
|
|
||||||
.filter(ann => ann.manual || !this.file.excludedPages.includes(ann.pageNumber));
|
|
||||||
|
|
||||||
if (!areDevFeaturesEnabled) {
|
get redactionLog() {
|
||||||
allAnnotations = allAnnotations.filter(annotation => !annotation.isFalsePositive);
|
return this._redactionLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
const visibleAnnotations = allAnnotations.filter(annotation => {
|
getVisibleAnnotations(viewMode: ViewMode) {
|
||||||
|
return this.allAnnotations.filter(annotation => {
|
||||||
if (viewMode === 'STANDARD') {
|
if (viewMode === 'STANDARD') {
|
||||||
return !annotation.isChangeLogRemoved;
|
return !annotation.isChangeLogRemoved;
|
||||||
} else if (viewMode === 'DELTA') {
|
} else if (viewMode === 'DELTA') {
|
||||||
@ -39,14 +39,33 @@ export class FileDataModel {
|
|||||||
return annotation.isRedacted;
|
return annotation.isRedacted;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
|
||||||
visibleAnnotations: visibleAnnotations,
|
|
||||||
allAnnotations: allAnnotations,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _convertData(dictionaryData: { [p: string]: Dictionary }): RedactionLogEntryWrapper[] {
|
private _buildAllAnnotations() {
|
||||||
|
const entries: RedactionLogEntryWrapper[] = this._convertData();
|
||||||
|
|
||||||
|
const previousAnnotations = this.allAnnotations || [];
|
||||||
|
this.allAnnotations = entries
|
||||||
|
.map(entry => AnnotationWrapper.fromData(entry))
|
||||||
|
.filter(ann => ann.manual || !this.file.excludedPages.includes(ann.pageNumber));
|
||||||
|
|
||||||
|
if (!this._areDevFeaturesEnabled) {
|
||||||
|
this.allAnnotations = this.allAnnotations.filter(annotation => !annotation.isFalsePositive);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setHiddenPropertyToNewAnnotations(this.allAnnotations, previousAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _setHiddenPropertyToNewAnnotations(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) {
|
||||||
|
newAnnotations.forEach(newAnnotation => {
|
||||||
|
const oldAnnotation = oldAnnotations.find(a => a.annotationId === newAnnotation.annotationId);
|
||||||
|
if (oldAnnotation) {
|
||||||
|
newAnnotation.hidden = oldAnnotation.hidden;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _convertData(): RedactionLogEntryWrapper[] {
|
||||||
let result: RedactionLogEntryWrapper[] = [];
|
let result: RedactionLogEntryWrapper[] = [];
|
||||||
|
|
||||||
const reasonAnnotationIds: { [key: string]: RedactionLogEntryWrapper[] } = {};
|
const reasonAnnotationIds: { [key: string]: RedactionLogEntryWrapper[] } = {};
|
||||||
@ -55,7 +74,7 @@ export class FileDataModel {
|
|||||||
const redactionLogEntryWrapper: RedactionLogEntryWrapper = {};
|
const redactionLogEntryWrapper: RedactionLogEntryWrapper = {};
|
||||||
Object.assign(redactionLogEntryWrapper, redactionLogEntry);
|
Object.assign(redactionLogEntryWrapper, redactionLogEntry);
|
||||||
redactionLogEntryWrapper.type = redactionLogEntry.type;
|
redactionLogEntryWrapper.type = redactionLogEntry.type;
|
||||||
redactionLogEntryWrapper.hintDictionary = dictionaryData[redactionLogEntry.type].hint;
|
redactionLogEntryWrapper.hintDictionary = this._dictionaryData[redactionLogEntry.type].hint;
|
||||||
|
|
||||||
this._isChangeLogEntry(redactionLogEntry, redactionLogEntryWrapper);
|
this._isChangeLogEntry(redactionLogEntry, redactionLogEntryWrapper);
|
||||||
|
|
||||||
|
|||||||
@ -124,7 +124,7 @@
|
|||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
|
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="suggestRemoveAnnotations($event, true)"
|
(action)="removeOrSuggestRemoveAnnotation($event, true)"
|
||||||
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveFromDictionary"
|
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveFromDictionary"
|
||||||
[tooltipPosition]="tooltipPosition"
|
[tooltipPosition]="tooltipPosition"
|
||||||
[tooltip]="'annotation-actions.remove-annotation.remove-from-dict' | translate"
|
[tooltip]="'annotation-actions.remove-annotation.remove-from-dict' | translate"
|
||||||
@ -144,7 +144,7 @@
|
|||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
|
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="suggestRemoveAnnotations($event, false)"
|
(action)="removeOrSuggestRemoveAnnotation($event, false)"
|
||||||
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere"
|
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere"
|
||||||
[tooltipPosition]="tooltipPosition"
|
[tooltipPosition]="tooltipPosition"
|
||||||
[tooltip]="'annotation-actions.remove-annotation.only-here' | translate"
|
[tooltip]="'annotation-actions.remove-annotation.only-here' | translate"
|
||||||
|
|||||||
@ -77,9 +77,15 @@ export class AnnotationActionsComponent implements OnChanges {
|
|||||||
this._setPermissions();
|
this._setPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
suggestRemoveAnnotations($event, removeFromDict: boolean) {
|
removeOrSuggestRemoveAnnotation($event, removeFromDict: boolean) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.annotationActionsService.suggestRemoveAnnotation($event, this.annotations, this.file, removeFromDict, this.annotationsChanged);
|
this.annotationActionsService.removeOrSuggestRemoveAnnotation(
|
||||||
|
$event,
|
||||||
|
this.annotations,
|
||||||
|
this.file,
|
||||||
|
removeFromDict,
|
||||||
|
this.annotationsChanged,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
markAsFalsePositive($event) {
|
markAsFalsePositive($event) {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnDestroy, Output } from '@angular/core';
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output } from '@angular/core';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { ConfigService } from '@services/config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||||
@ -31,6 +31,7 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy
|
|||||||
private readonly _filesMapService: FilesMapService,
|
private readonly _filesMapService: FilesMapService,
|
||||||
private readonly _dossiersService: DossiersService,
|
private readonly _dossiersService: DossiersService,
|
||||||
private readonly _configService: ConfigService,
|
private readonly _configService: ConfigService,
|
||||||
|
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||||
private readonly _permissionService: PermissionsService,
|
private readonly _permissionService: PermissionsService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
@ -41,12 +42,16 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _setReadState() {
|
private _setReadState() {
|
||||||
|
const readBefore = this.read;
|
||||||
const activePage = this.activePage;
|
const activePage = this.activePage;
|
||||||
if (!activePage) {
|
if (!activePage) {
|
||||||
this.read = false;
|
this.read = false;
|
||||||
} else {
|
} else {
|
||||||
|
// console.log('setting read to',activePage.showAsUnseen, !activePage.showAsUnseen);
|
||||||
this.read = !activePage.showAsUnseen;
|
this.read = !activePage.showAsUnseen;
|
||||||
}
|
}
|
||||||
|
// console.log(this.number, readBefore, activePage, this.read);
|
||||||
|
this._changeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
|
|||||||
@ -583,7 +583,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
try {
|
try {
|
||||||
this.instance.UI.enableTools(['AnnotationCreateRectangle']);
|
this.instance.UI.enableTools(['AnnotationCreateRectangle']);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
// happens
|
||||||
}
|
}
|
||||||
this.instance.UI.enableElements(elements);
|
this.instance.UI.enableElements(elements);
|
||||||
|
|
||||||
|
|||||||
@ -26,12 +26,7 @@
|
|||||||
|
|
||||||
<div class="vertical-line"></div>
|
<div class="vertical-line"></div>
|
||||||
|
|
||||||
<redaction-file-actions
|
<redaction-file-actions [file]="file" type="file-preview"></redaction-file-actions>
|
||||||
#fileActions
|
|
||||||
(ocredFile)="ocredFile()"
|
|
||||||
[file]="file"
|
|
||||||
type="file-preview"
|
|
||||||
></redaction-file-actions>
|
|
||||||
|
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="toggleFullScreen()"
|
(action)="toggleFullScreen()"
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
|
||||||
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import { PdfViewerComponent } from './components/pdf-viewer/pdf-viewer.component';
|
import { PdfViewerComponent } from './components/pdf-viewer/pdf-viewer.component';
|
||||||
import {
|
import {
|
||||||
@ -19,14 +18,13 @@ import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
|||||||
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { ManualAnnotationResponse } from '@models/file/manual-annotation-response';
|
import { ManualAnnotationResponse } from '@models/file/manual-annotation-response';
|
||||||
import { AnnotationData, FileDataModel } from '@models/file/file-data.model';
|
import { FileDataModel } from '@models/file/file-data.model';
|
||||||
import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
||||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||||
import { Dossier, File, ViewMode } from '@red/domain';
|
import { Dossier, File, ViewMode } from '@red/domain';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { combineLatest, Observable, timer } from 'rxjs';
|
import { combineLatest, Observable, timer } from 'rxjs';
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
import { UserService } from '@services/user.service';
|
|
||||||
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
|
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
|
||||||
import { download } from '@utils/file-download-utils';
|
import { download } from '@utils/file-download-utils';
|
||||||
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
|
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
|
||||||
@ -70,7 +68,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
fullScreen = false;
|
fullScreen = false;
|
||||||
shouldDeselectAnnotationsOnPageChange = true;
|
shouldDeselectAnnotationsOnPageChange = true;
|
||||||
fileData: FileDataModel;
|
fileData: FileDataModel;
|
||||||
annotationData: AnnotationData;
|
|
||||||
selectedAnnotations: AnnotationWrapper[] = [];
|
selectedAnnotations: AnnotationWrapper[] = [];
|
||||||
hideSkipped = false;
|
hideSkipped = false;
|
||||||
displayPdfViewer = false;
|
displayPdfViewer = false;
|
||||||
@ -84,7 +81,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
ready = false;
|
ready = false;
|
||||||
private _instance: WebViewerInstance;
|
private _instance: WebViewerInstance;
|
||||||
private _lastPage: string;
|
private _lastPage: string;
|
||||||
private _reloadFileOnReanalysis = false;
|
|
||||||
@ViewChild('fileWorkloadComponent') private readonly _workloadComponent: FileWorkloadComponent;
|
@ViewChild('fileWorkloadComponent') private readonly _workloadComponent: FileWorkloadComponent;
|
||||||
@ViewChild('annotationFilterTemplate', {
|
@ViewChild('annotationFilterTemplate', {
|
||||||
read: TemplateRef,
|
read: TemplateRef,
|
||||||
@ -95,8 +91,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
constructor(
|
constructor(
|
||||||
readonly permissionsService: PermissionsService,
|
readonly permissionsService: PermissionsService,
|
||||||
readonly userPreferenceService: UserPreferenceService,
|
readonly userPreferenceService: UserPreferenceService,
|
||||||
private readonly _appStateService: AppStateService,
|
|
||||||
private readonly _userService: UserService,
|
|
||||||
private readonly _watermarkService: WatermarkService,
|
private readonly _watermarkService: WatermarkService,
|
||||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||||
private readonly _activatedRoute: ActivatedRoute,
|
private readonly _activatedRoute: ActivatedRoute,
|
||||||
@ -139,15 +133,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
get annotations(): AnnotationWrapper[] {
|
get annotations(): AnnotationWrapper[] {
|
||||||
return this.annotationData ? this.annotationData.visibleAnnotations : [];
|
return this.fileData ? this.fileData.getVisibleAnnotations(this.viewModeService.viewMode) : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get activeViewer(): WebViewerInstance {
|
get activeViewer(): WebViewerInstance {
|
||||||
return this._instance;
|
return this._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private _setActiveViewerPage() {
|
private _setActiveViewerPage() {
|
||||||
const currentPage = this._instance?.Core.documentViewer?.getCurrentPage();
|
const currentPage = this._instance?.Core.documentViewer?.getCurrentPage();
|
||||||
if (!currentPage) {
|
if (!currentPage) {
|
||||||
@ -169,7 +161,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateViewMode(): Promise<void> {
|
async updateViewMode(): Promise<void> {
|
||||||
const ocrAnnotationIds = this.annotationData.allAnnotations.filter(a => a.isOCR).map(a => a.id);
|
const ocrAnnotationIds = this.fileData.allAnnotations.filter(a => a.isOCR).map(a => a.id);
|
||||||
const annotations = this._getAnnotations(a => a.getCustomData('redact-manager'));
|
const annotations = this._getAnnotations(a => a.getCustomData('redact-manager'));
|
||||||
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
||||||
|
|
||||||
@ -251,18 +243,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
console.log(`[REDACTION] Delete previous annotations time: ${new Date().getTime() - startTime} ms`);
|
console.log(`[REDACTION] Delete previous annotations time: ${new Date().getTime() - startTime} ms`);
|
||||||
}
|
}
|
||||||
const processStartTime = new Date().getTime();
|
const processStartTime = new Date().getTime();
|
||||||
const dossier = this._dossiersService.find(this.dossierId);
|
|
||||||
const newAnnotationsData = this.fileData.getAnnotations(
|
|
||||||
this._appStateService.dictionaryData[dossier.dossierTemplateId],
|
|
||||||
this._userService.currentUser,
|
|
||||||
this.viewModeService.viewMode,
|
|
||||||
this.userPreferenceService.areDevFeaturesEnabled,
|
|
||||||
);
|
|
||||||
if (this.annotationData) {
|
|
||||||
this._setHiddenPropertyToNewAnnotations(newAnnotationsData.visibleAnnotations, this.annotationData.visibleAnnotations);
|
|
||||||
this._setHiddenPropertyToNewAnnotations(newAnnotationsData.allAnnotations, this.annotationData.allAnnotations);
|
|
||||||
}
|
|
||||||
this.annotationData = newAnnotationsData;
|
|
||||||
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
|
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
|
||||||
const primaryFilters = this._filterService.getGroup('primaryFilters')?.filters;
|
const primaryFilters = this._filterService.getGroup('primaryFilters')?.filters;
|
||||||
this._filterService.addFilterGroup({
|
this._filterService.addFilterGroup({
|
||||||
@ -324,7 +305,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
response.manualRedactionEntryWrapper.rectId,
|
response.manualRedactionEntryWrapper.rectId,
|
||||||
);
|
);
|
||||||
this._instance.Core.annotationManager.deleteAnnotation(annotation);
|
this._instance.Core.annotationManager.deleteAnnotation(annotation);
|
||||||
// await this._filesService.reload(this.dossierId, this.fileId).toPromise();
|
// await this._filesService.reload(this.dossierId, this.fileId).toPromise();
|
||||||
const distinctPages = manualRedactionEntryWrapper.manualRedactionEntry.positions
|
const distinctPages = manualRedactionEntryWrapper.manualRedactionEntry.positions
|
||||||
.map(p => p.page)
|
.map(p => p.page)
|
||||||
.filter((item, pos, self) => self.indexOf(item) === pos);
|
.filter((item, pos, self) => self.indexOf(item) === pos);
|
||||||
@ -431,10 +412,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
await this._reloadAnnotationsForPage(annotation?.pageNumber || this.activeViewerPage);
|
await this._reloadAnnotationsForPage(annotation?.pageNumber || this.activeViewerPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
ocredFile(): void {
|
|
||||||
this._reloadFileOnReanalysis = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
closeFullScreen() {
|
closeFullScreen() {
|
||||||
if (!!document.fullscreenElement && document.exitFullscreen) {
|
if (!!document.fullscreenElement && document.exitFullscreen) {
|
||||||
document.exitFullscreen().then();
|
document.exitFullscreen().then();
|
||||||
@ -480,19 +457,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _reloadFile(file: File): Promise<void> {
|
private async _reloadFile(file: File): Promise<void> {
|
||||||
await this._loadFileData(file, true);
|
await this._loadFileData(file);
|
||||||
await this._stampPDF();
|
await this._stampPDF();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setHiddenPropertyToNewAnnotations(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) {
|
|
||||||
newAnnotations.forEach(newAnnotation => {
|
|
||||||
const oldAnnotation = oldAnnotations.find(a => a.annotationId === newAnnotation.annotationId);
|
|
||||||
if (oldAnnotation) {
|
|
||||||
newAnnotation.hidden = oldAnnotation.hidden;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _stampPDF() {
|
private async _stampPDF() {
|
||||||
if (!this._instance) {
|
if (!this._instance) {
|
||||||
return;
|
return;
|
||||||
@ -554,36 +522,26 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
this.addSubscription = this._filesMapService.fileReanalysed$
|
this.addSubscription = this._filesMapService.fileReanalysed$
|
||||||
.pipe(filter(file => file.fileId === this.fileId))
|
.pipe(filter(file => file.fileId === this.fileId))
|
||||||
.subscribe(async file => {
|
.subscribe(async file => {
|
||||||
await this._loadFileData(file, !this._reloadFileOnReanalysis);
|
if (file.lastProcessed !== this.fileData?.file.lastProcessed) {
|
||||||
this._reloadFileOnReanalysis = false;
|
await this._loadFileData(file);
|
||||||
await this._reloadAnnotations();
|
await this._reloadAnnotations();
|
||||||
|
}
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _loadFileData(file: File, performUpdate = false): Promise<void | boolean> {
|
private async _loadFileData(file: File): Promise<void | boolean> {
|
||||||
if (!file || file.isError) {
|
if (!file || file.isError) {
|
||||||
return this._router.navigate([this._dossiersService.find(this.dossierId).routerLink]);
|
return this._router.navigate([this._dossiersService.find(this.dossierId).routerLink]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileData = await this._fileDownloadService.loadDataFor(file).toPromise();
|
const fileData = await this._fileDownloadService.loadDataFor(file, this.fileData).toPromise();
|
||||||
|
|
||||||
if (file.isPending) {
|
if (file.isPending) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (performUpdate && !!this.fileData) {
|
this.fileData = fileData;
|
||||||
this.fileData.redactionLog = fileData.redactionLog;
|
|
||||||
this.fileData.viewedPages = fileData.viewedPages;
|
|
||||||
const excludedOrIncludedPages = new Set(diff(this.fileData.file.excludedPages, file.excludedPages));
|
|
||||||
const currentPageAnnotations = this.annotations.filter(a => excludedOrIncludedPages.has(a.pageNumber));
|
|
||||||
this.fileData.file = file;
|
|
||||||
if (excludedOrIncludedPages?.size) {
|
|
||||||
await this._cleanupAndRedrawAnnotations(currentPageAnnotations, a => excludedOrIncludedPages.has(a.pageNumber));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.fileData = fileData;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Debounce(0)
|
@Debounce(0)
|
||||||
@ -600,6 +558,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
private async _reloadAnnotationsForPage(page: number) {
|
private async _reloadAnnotationsForPage(page: number) {
|
||||||
const currentPageAnnotations = this.annotations.filter(a => a.pageNumber === page);
|
const currentPageAnnotations = this.annotations.filter(a => a.pageNumber === page);
|
||||||
|
|
||||||
|
this.fileData.file = await this._filesService.reload(this.dossierId, this.fileId).toPromise();
|
||||||
this.fileData.redactionLog = await this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).toPromise();
|
this.fileData.redactionLog = await this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).toPromise();
|
||||||
|
|
||||||
await this._cleanupAndRedrawAnnotations(currentPageAnnotations, annotation => annotation.pageNumber === page);
|
await this._cleanupAndRedrawAnnotations(currentPageAnnotations, annotation => annotation.pageNumber === page);
|
||||||
@ -625,7 +584,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _redrawAnnotations(annotations = this.annotationData.allAnnotations) {
|
private _redrawAnnotations(annotations = this.fileData.allAnnotations) {
|
||||||
return this._annotationDrawService.drawAnnotations(
|
return this._annotationDrawService.drawAnnotations(
|
||||||
this._instance,
|
this._instance,
|
||||||
annotations,
|
annotations,
|
||||||
|
|||||||
@ -113,7 +113,7 @@ export class AnnotationActionsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
suggestRemoveAnnotation(
|
removeOrSuggestRemoveAnnotation(
|
||||||
$event: MouseEvent,
|
$event: MouseEvent,
|
||||||
annotations: AnnotationWrapper[],
|
annotations: AnnotationWrapper[],
|
||||||
file: File,
|
file: File,
|
||||||
@ -290,7 +290,7 @@ export class AnnotationActionsService {
|
|||||||
title: this._translateService.instant('annotation-actions.remove-annotation.remove-from-dict'),
|
title: this._translateService.instant('annotation-actions.remove-annotation.remove-from-dict'),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
this.suggestRemoveAnnotation(null, annotations, file, true, annotationsChanged);
|
this.removeOrSuggestRemoveAnnotation(null, annotations, file, true, annotationsChanged);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -405,7 +405,7 @@ export class AnnotationActionsService {
|
|||||||
title: this._translateService.instant('annotation-actions.remove-annotation.only-here'),
|
title: this._translateService.instant('annotation-actions.remove-annotation.only-here'),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
this.suggestRemoveAnnotation(null, annotations, file, false, annotationsChanged);
|
this.removeOrSuggestRemoveAnnotation(null, annotations, file, false, annotationsChanged);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -441,7 +441,7 @@ export class AnnotationActionsService {
|
|||||||
viewer: WebViewerInstance,
|
viewer: WebViewerInstance,
|
||||||
file: File,
|
file: File,
|
||||||
annotationWrapper: AnnotationWrapper,
|
annotationWrapper: AnnotationWrapper,
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged?: EventEmitter<AnnotationWrapper>,
|
||||||
) {
|
) {
|
||||||
const data = { dossier: this._dossier(file) };
|
const data = { dossier: this._dossier(file) };
|
||||||
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
|
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
|
||||||
|
|||||||
@ -7,14 +7,20 @@ import { File } from '@red/domain';
|
|||||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||||
import { RedactionLogService } from './redaction-log.service';
|
import { RedactionLogService } from './redaction-log.service';
|
||||||
import { ViewedPagesService } from '@services/entity-services/viewed-pages.service';
|
import { ViewedPagesService } from '@services/entity-services/viewed-pages.service';
|
||||||
|
import { AppStateService } from '../../../state/app-state.service';
|
||||||
|
import { DossiersService } from '../../../services/entity-services/dossiers.service';
|
||||||
|
import { UserPreferenceService } from '../../../services/user-preference.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PdfViewerDataService {
|
export class PdfViewerDataService {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly _dossiersService: DossiersService,
|
||||||
private readonly _permissionsService: PermissionsService,
|
private readonly _permissionsService: PermissionsService,
|
||||||
private readonly _fileManagementService: FileManagementService,
|
private readonly _fileManagementService: FileManagementService,
|
||||||
private readonly _redactionLogService: RedactionLogService,
|
private readonly _redactionLogService: RedactionLogService,
|
||||||
private readonly _viewedPagesService: ViewedPagesService,
|
private readonly _viewedPagesService: ViewedPagesService,
|
||||||
|
private readonly _appStateService: AppStateService,
|
||||||
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
loadRedactionLogFor(dossierId: string, fileId: string) {
|
loadRedactionLogFor(dossierId: string, fileId: string) {
|
||||||
@ -24,12 +30,24 @@ export class PdfViewerDataService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDataFor(file: File): Observable<FileDataModel> {
|
loadDataFor(file: File, fileData?: FileDataModel): Observable<FileDataModel> {
|
||||||
const file$ = this.downloadOriginalFile(file);
|
const file$ = fileData?.file.cacheIdentifier === file.cacheIdentifier ? of(fileData.fileData) : this.downloadOriginalFile(file);
|
||||||
const reactionLog$ = this.loadRedactionLogFor(file.dossierId, file.fileId);
|
const reactionLog$ = this.loadRedactionLogFor(file.dossierId, file.fileId);
|
||||||
const viewedPages$ = this.getViewedPagesFor(file);
|
const viewedPages$ = this.getViewedPagesFor(file);
|
||||||
|
|
||||||
return forkJoin([file$, reactionLog$, viewedPages$]).pipe(map(data => new FileDataModel(file, ...data)));
|
const dossier = this._dossiersService.find(file.dossierId);
|
||||||
|
|
||||||
|
return forkJoin([file$, reactionLog$, viewedPages$]).pipe(
|
||||||
|
map(
|
||||||
|
data =>
|
||||||
|
new FileDataModel(
|
||||||
|
file,
|
||||||
|
...data,
|
||||||
|
this._appStateService.dictionaryData[dossier.dossierTemplateId],
|
||||||
|
this._userPreferenceService.areDevFeaturesEnabled,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewedPagesFor(file: File) {
|
getViewedPagesFor(file: File) {
|
||||||
|
|||||||
@ -51,7 +51,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
|||||||
@Input() file: File;
|
@Input() file: File;
|
||||||
@Input() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
|
@Input() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
|
||||||
@Input() maxWidth: number;
|
@Input() maxWidth: number;
|
||||||
@Output() readonly ocredFile = new EventEmitter<void>();
|
|
||||||
|
|
||||||
toggleTooltip?: string;
|
toggleTooltip?: string;
|
||||||
assignTooltip?: string;
|
assignTooltip?: string;
|
||||||
@ -308,7 +307,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
|||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
await this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId).toPromise();
|
await this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId).toPromise();
|
||||||
this.ocredFile.emit();
|
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
|
|||||||
private readonly _dossiersService: DossiersService,
|
private readonly _dossiersService: DossiersService,
|
||||||
private readonly _filesMapService: FilesMapService,
|
private readonly _filesMapService: FilesMapService,
|
||||||
) {
|
) {
|
||||||
super(_injector, 'search');
|
super(_injector, 'search-v2');
|
||||||
}
|
}
|
||||||
|
|
||||||
search({ dossierIds, query }: ISearchInput): Observable<ISearchResponse> {
|
search({ dossierIds, query }: ISearchInput): Observable<ISearchResponse> {
|
||||||
@ -29,7 +29,7 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
|
|||||||
const body: ISearchRequest = {
|
const body: ISearchRequest = {
|
||||||
dossierIds,
|
dossierIds,
|
||||||
queryString: query ?? '',
|
queryString: query ?? '',
|
||||||
page: 1,
|
page: 0,
|
||||||
returnSections: false,
|
returnSections: false,
|
||||||
pageSize: 300,
|
pageSize: 300,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 6527ccd3077bfcb4bedf729bf09edc5bd1449502
|
Subproject commit 3f1c419e0acdc92514b615611bdaa29e000a0b32
|
||||||
@ -2,6 +2,8 @@ import { IFileAttributeConfig } from './file-attribute-config';
|
|||||||
|
|
||||||
export interface IFileAttributesConfig {
|
export interface IFileAttributesConfig {
|
||||||
delimiter?: string;
|
delimiter?: string;
|
||||||
fileAttributeConfigs?: IFileAttributeConfig[];
|
encoding?: string;
|
||||||
filenameMappingColumnHeaderName?: string;
|
filenameMappingColumnHeaderName?: string;
|
||||||
|
|
||||||
|
fileAttributeConfigs?: IFileAttributeConfig[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,9 +93,7 @@ export class File extends Entity<IFile> implements IFile {
|
|||||||
this.hasSuggestions = !!file.hasSuggestions;
|
this.hasSuggestions = !!file.hasSuggestions;
|
||||||
|
|
||||||
this.statusSort = StatusSorter[this.workflowStatus];
|
this.statusSort = StatusSorter[this.workflowStatus];
|
||||||
if (this.lastUpdated && this.lastOCRTime) {
|
this.cacheIdentifier = btoa((this.lastUploaded ?? '') + (this.lastOCRTime ?? ''));
|
||||||
this.cacheIdentifier = btoa((this.lastUploaded ?? '') + this.lastOCRTime);
|
|
||||||
}
|
|
||||||
this.hintsOnly = this.hasHints && !this.hasRedactions;
|
this.hintsOnly = this.hasHints && !this.hasRedactions;
|
||||||
this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
|
this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
|
||||||
this.isPending = this.processingStatus === ProcessingFileStatuses.UNPROCESSED;
|
this.isPending = this.processingStatus === ProcessingFileStatuses.UNPROCESSED;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user