diff --git a/apps/red-ui/src/app/models/file/annotation.wrapper.ts b/apps/red-ui/src/app/models/file/annotation.wrapper.ts index daf99d2d5..c2bb7923d 100644 --- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts +++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts @@ -64,6 +64,7 @@ export class AnnotationWrapper implements IListable { hasBeenRemovedByManualOverride: boolean; isRemoved = false; isRemovedLocally = false; + hiddenInWorkload = false; lastManualChange: ManualRedactionType; get isRuleBased() { @@ -222,7 +223,8 @@ export class AnnotationWrapper implements IListable { ) { const annotationWrapper = new AnnotationWrapper(); - annotationWrapper.id = logEntry.id; + annotationWrapper.pending = logEntry.state === EntryStates.PENDING; + annotationWrapper.id = logEntry.id + (annotationWrapper.pending ? '-pending' : ''); annotationWrapper.isChangeLogEntry = logEntry.state === EntryStates.REMOVED || !!changeLogType; annotationWrapper.type = logEntry.type; annotationWrapper.value = logEntry.value; @@ -273,7 +275,6 @@ export class AnnotationWrapper implements IListable { const lastRelevantManualChange = logEntry.manualChanges?.at(-1); annotationWrapper.lastManualChange = lastRelevantManualChange?.manualRedactionType; - annotationWrapper.pending = logEntry.state === EntryStates.PENDING; if (annotationWrapper.pending) { const removedEntry = allLogEntries.find((e: IEntityLogEntry) => e.id === annotationWrapper.id); logEntry.oldState = removedEntry?.state; @@ -286,14 +287,14 @@ export class AnnotationWrapper implements IListable { annotationWrapper.typeLabel = dictionary?.virtual ? undefined : dictionary?.label; - let colorKey = annotationEntityColorConfig[annotationWrapper.superType]; - if (annotationWrapper.pending && lastRelevantManualChange.manualRedactionType === ManualRedactionTypes.REMOVE_FROM_DICTIONARY) { - colorKey = annotationWrapper.isHint - ? annotationEntityColorConfig[SuperTypes.IgnoredHint] - : annotationEntityColorConfig[SuperTypes.Skipped]; + if (annotationWrapper.pending) { + annotationWrapper.color = defaultColors[annotationDefaultColorConfig.analysis] as string; + } else { + const colorKey = annotationEntityColorConfig[annotationWrapper.superType]; + const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType]; + annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string); } - const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType]; - annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string); + annotationWrapper['entry'] = logEntry; return annotationWrapper; diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts index 4ab551813..014cee3d9 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts @@ -171,6 +171,10 @@ export class AnnotationActionsComponent implements OnChanges { } get #annotationChangesAllowed() { - return !this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis; + return (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.#somePending; + } + + get #somePending() { + return this.#annotations.some(a => a.pending); } } diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html index 962c48416..887105917 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html @@ -10,6 +10,7 @@
a.id.localeCompare(b.id)); + filter.children.sort((a, b) => a.id?.localeCompare(b.id)); handleCheckedValue(filter); if (filter.checked || filter.indeterminate) { filter.expanded = true; diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts index 6c11e64e6..6f4db12a1 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts @@ -227,6 +227,7 @@ export class FileDataService extends EntitiesService a.id === annotation.id && !a.pending); - annotations[oldAnnotationIndex] = annotation; - continue; - } - annotations.push(annotation); + + if (annotation.pending) { + this.#createPendingAnnotations(annotation, annotations); + } } return annotations; @@ -292,4 +291,16 @@ export class FileDataService extends EntitiesService a.pending); actions = - this._multiSelectService.inactive() && !this._documentViewer.selectedText.length + this._multiSelectService.inactive() && !this._documentViewer.selectedText.length && !somePending ? [...actions, ...this._pdfAnnotationActionsService.get(annotationWrappers, annotationChangesAllowed)] : []; this._pdf.instance.UI.annotationPopup.update(actions); diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts index ccafe0af3..e167d6a94 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts @@ -128,6 +128,29 @@ export class AnnotationDrawService { return; } + if (annotationWrapper.positions.length === 0) { + return; + } + + if (annotationWrapper.pending) { + const polylineAnnot = this._pdf.polyline(); + polylineAnnot.ReadOnly = true; + polylineAnnot.StrokeColor = this.convertColor(annotationWrapper.color); + polylineAnnot.StrokeThickness = 2; + polylineAnnot.Id = annotationWrapper.id; + polylineAnnot.PageNumber = pageNumber; + polylineAnnot.Opacity = polylineAnnot.Id.endsWith('pending') ? 0 : 0.5; + console.log(polylineAnnot.Id); + console.log(polylineAnnot.Id.split('-')); + + const points = this.#computePolylinePoints(annotationWrapper.positions, annotationWrapper.pageNumber); + for (let i = 0; i < points.length; i++) { + polylineAnnot.addPathPoint(points[i].x, points[i].y); + } + + return polylineAnnot; + } + if (annotationWrapper.superType === SuperTypes.TextHighlight) { const rectangleAnnot = this._pdf.rectangle(); const pageHeight = this._documentViewer.getHeight(pageNumber); @@ -178,6 +201,24 @@ export class AnnotationDrawService { return annotation; } + #computePolylinePoints(positions: IRectangle[], pageNumber: number): IPoint[] { + const pageHeight = this._documentViewer.getHeight(pageNumber); + const points = [this.#topLeft(positions[0], pageHeight)]; + + for (let i = 0; i < positions.length; i++) { + points.push(this.#topRight(positions[i], pageHeight)); + points.push(this.#bottomRight(positions[i], pageHeight)); + } + + for (let i = positions.length - 1; i >= 0; i--) { + points.push(this.#bottomLeft(positions[i], pageHeight)); + points.push(this.#topLeft(positions[i], pageHeight)); + } + + points.push(this.#topRight(positions[0], pageHeight)); + return points; + } + #rectanglesToQuads(positions: IRectangle[], pageNumber: number): Quad[] { const pageHeight = this._documentViewer.getHeight(pageNumber); return positions.map(p => this.#rectangleToQuad(p, pageHeight)); diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts index 90da413ac..09fc4f9a7 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts @@ -243,6 +243,10 @@ export class PdfViewer { return new this.#instance.Core.Annotations.TextHighlightAnnotation(); } + polyline() { + return new this.#instance.Core.Annotations.PolylineAnnotation(); + } + isTextHighlight(annotation: Annotation): annotation is TextHighlightAnnotation { return annotation instanceof this.#instance.Core.Annotations.TextHighlightAnnotation; }