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 8a3d50aa3..8c5f7e34b 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
@@ -3,34 +3,34 @@ import { AnnotationWrapper } from './annotation.wrapper';
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
import * as moment from 'moment';
-export class AnnotationData {
- visibleAnnotations: AnnotationWrapper[];
- allAnnotations: AnnotationWrapper[];
-}
-
export class FileDataModel {
static readonly DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes;
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(
- dictionaryData: { [p: string]: Dictionary },
- currentUser: User,
- 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));
+ set redactionLog(redactionLog: IRedactionLog) {
+ this._redactionLog = redactionLog;
+ this._buildAllAnnotations();
+ }
- if (!areDevFeaturesEnabled) {
- allAnnotations = allAnnotations.filter(annotation => !annotation.isFalsePositive);
- }
+ get redactionLog() {
+ return this._redactionLog;
+ }
- const visibleAnnotations = allAnnotations.filter(annotation => {
+ getVisibleAnnotations(viewMode: ViewMode) {
+ return this.allAnnotations.filter(annotation => {
if (viewMode === 'STANDARD') {
return !annotation.isChangeLogRemoved;
} else if (viewMode === 'DELTA') {
@@ -39,14 +39,33 @@ export class FileDataModel {
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[] = [];
const reasonAnnotationIds: { [key: string]: RedactionLogEntryWrapper[] } = {};
@@ -55,7 +74,7 @@ export class FileDataModel {
const redactionLogEntryWrapper: RedactionLogEntryWrapper = {};
Object.assign(redactionLogEntryWrapper, redactionLogEntry);
redactionLogEntryWrapper.type = redactionLogEntry.type;
- redactionLogEntryWrapper.hintDictionary = dictionaryData[redactionLogEntry.type].hint;
+ redactionLogEntryWrapper.hintDictionary = this._dictionaryData[redactionLogEntry.type].hint;
this._isChangeLogEntry(redactionLogEntry, redactionLogEntryWrapper);
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.html
index 1dc525fb2..c3d7d4599 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-actions/annotation-actions.component.html
@@ -124,7 +124,7 @@
>
-
+
{
- 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 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`);
}
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 primaryFilters = this._filterService.getGroup('primaryFilters')?.filters;
this._filterService.addFilterGroup({
@@ -324,7 +305,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
response.manualRedactionEntryWrapper.rectId,
);
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
.map(p => p.page)
.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);
}
- ocredFile(): void {
- this._reloadFileOnReanalysis = true;
- }
-
closeFullScreen() {
if (!!document.fullscreenElement && document.exitFullscreen) {
document.exitFullscreen().then();
@@ -480,19 +457,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private async _reloadFile(file: File): Promise {
- await this._loadFileData(file, true);
+ await this._loadFileData(file);
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() {
if (!this._instance) {
return;
@@ -554,36 +522,26 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this.addSubscription = this._filesMapService.fileReanalysed$
.pipe(filter(file => file.fileId === this.fileId))
.subscribe(async file => {
- await this._loadFileData(file, !this._reloadFileOnReanalysis);
- this._reloadFileOnReanalysis = false;
- await this._reloadAnnotations();
+ if (file.lastProcessed !== this.fileData?.file.lastProcessed) {
+ await this._loadFileData(file);
+ await this._reloadAnnotations();
+ }
this._loadingService.stop();
});
}
- private async _loadFileData(file: File, performUpdate = false): Promise {
+ private async _loadFileData(file: File): Promise {
if (!file || file.isError) {
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) {
return;
}
- if (performUpdate && !!this.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;
- }
+ this.fileData = fileData;
}
@Debounce(0)
@@ -600,6 +558,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private async _reloadAnnotationsForPage(page: number) {
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();
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(
this._instance,
annotations,
diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts
index 170566f58..003b14a86 100644
--- a/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts
@@ -113,7 +113,7 @@ export class AnnotationActionsService {
);
}
- suggestRemoveAnnotation(
+ removeOrSuggestRemoveAnnotation(
$event: MouseEvent,
annotations: AnnotationWrapper[],
file: File,
@@ -290,7 +290,7 @@ export class AnnotationActionsService {
title: this._translateService.instant('annotation-actions.remove-annotation.remove-from-dict'),
onClick: () => {
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'),
onClick: () => {
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,
file: File,
annotationWrapper: AnnotationWrapper,
- annotationsChanged: EventEmitter,
+ annotationsChanged?: EventEmitter,
) {
const data = { dossier: this._dossier(file) };
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
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 fb20bd16c..6625f138f 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
@@ -7,14 +7,20 @@ import { File } from '@red/domain';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { RedactionLogService } from './redaction-log.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()
export class PdfViewerDataService {
constructor(
+ private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _fileManagementService: FileManagementService,
private readonly _redactionLogService: RedactionLogService,
private readonly _viewedPagesService: ViewedPagesService,
+ private readonly _appStateService: AppStateService,
+ private readonly _userPreferenceService: UserPreferenceService,
) {}
loadRedactionLogFor(dossierId: string, fileId: string) {
@@ -24,12 +30,24 @@ export class PdfViewerDataService {
);
}
- loadDataFor(file: File): Observable {
- const file$ = this.downloadOriginalFile(file);
+ loadDataFor(file: File, fileData?: FileDataModel): Observable {
+ const file$ = fileData?.file.cacheIdentifier === file.cacheIdentifier ? of(fileData.fileData) : this.downloadOriginalFile(file);
const reactionLog$ = this.loadRedactionLogFor(file.dossierId, file.fileId);
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) {
diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts
index 964825091..150f44c55 100644
--- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts
@@ -51,7 +51,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
@Input() file: File;
@Input() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
@Input() maxWidth: number;
- @Output() readonly ocredFile = new EventEmitter();
toggleTooltip?: string;
assignTooltip?: string;
@@ -308,7 +307,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
$event.stopPropagation();
this._loadingService.start();
await this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId).toPromise();
- this.ocredFile.emit();
this._loadingService.stop();
}
diff --git a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts
index 752b6f07d..000d563c1 100644
--- a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts
+++ b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts
@@ -15,7 +15,7 @@ export class PlatformSearchService extends GenericService {
private readonly _dossiersService: DossiersService,
private readonly _filesMapService: FilesMapService,
) {
- super(_injector, 'search');
+ super(_injector, 'search-v2');
}
search({ dossierIds, query }: ISearchInput): Observable {
@@ -29,7 +29,7 @@ export class PlatformSearchService extends GenericService {
const body: ISearchRequest = {
dossierIds,
queryString: query ?? '',
- page: 1,
+ page: 0,
returnSections: false,
pageSize: 300,
};
diff --git a/libs/common-ui b/libs/common-ui
index 6527ccd30..3f1c419e0 160000
--- a/libs/common-ui
+++ b/libs/common-ui
@@ -1 +1 @@
-Subproject commit 6527ccd3077bfcb4bedf729bf09edc5bd1449502
+Subproject commit 3f1c419e0acdc92514b615611bdaa29e000a0b32
diff --git a/libs/red-domain/src/lib/file-attributes/file-attributes-config.ts b/libs/red-domain/src/lib/file-attributes/file-attributes-config.ts
index e3363aebe..7aa96c500 100644
--- a/libs/red-domain/src/lib/file-attributes/file-attributes-config.ts
+++ b/libs/red-domain/src/lib/file-attributes/file-attributes-config.ts
@@ -2,6 +2,8 @@ import { IFileAttributeConfig } from './file-attribute-config';
export interface IFileAttributesConfig {
delimiter?: string;
- fileAttributeConfigs?: IFileAttributeConfig[];
+ encoding?: string;
filenameMappingColumnHeaderName?: string;
+
+ fileAttributeConfigs?: IFileAttributeConfig[];
}
diff --git a/libs/red-domain/src/lib/files/file.model.ts b/libs/red-domain/src/lib/files/file.model.ts
index 81148059e..aa3f705da 100644
--- a/libs/red-domain/src/lib/files/file.model.ts
+++ b/libs/red-domain/src/lib/files/file.model.ts
@@ -93,9 +93,7 @@ export class File extends Entity implements IFile {
this.hasSuggestions = !!file.hasSuggestions;
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.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
this.isPending = this.processingStatus === ProcessingFileStatuses.UNPROCESSED;