diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index d1658240f..403a7e829 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -37,7 +37,7 @@ import { import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; import { validatePageRange } from '../../utils/form-validators'; -import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; +import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils'; interface TypeSelectOptions { type: string; @@ -103,6 +103,14 @@ export class EditRedactionDialogComponent private readonly _dictionaryService: DictionaryService, ) { super(); + + if (this.allRectangles) { + prefillPageRange( + this.data.annotations[0], + this.data.allFileAnnotations, + this.options as DetailsRadioOption[], + ); + } } get displayedDictionaryLabel() { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index b7c80d8ed..b27c5dbbf 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -36,7 +36,7 @@ import { } from '../../utils/dialog-types'; import { isJustOne } from '@common-ui/utils'; import { validatePageRange } from '../../utils/form-validators'; -import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; +import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils'; @Component({ templateUrl: './remove-redaction-dialog.component.html', @@ -140,6 +140,14 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< private readonly _userPreferences: UserPreferenceService, ) { super(); + + if (this.#allRectangles) { + prefillPageRange( + this.data.redactions[0], + this.data.allFileRedactions, + this.options as DetailsRadioOption[], + ); + } } get hasFalsePositiveOption() { diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 04bae147e..c513b2089 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -95,7 +95,7 @@ export class AnnotationActionsService { ); } else { const addAnnotationRequest = annotations.map(a => ({ - comment: { text: request.comment }, + comment: request.comment, legalBasis: request.legalBasis, reason: request.reason, positions: a.positions, @@ -113,9 +113,11 @@ export class AnnotationActionsService { async editRedaction(annotations: AnnotationWrapper[]) { const { dossierId, file } = this._state; + const allFileAnnotations = this._fileDataService.annotations(); const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true)); const data = { annotations, + allFileAnnotations, dossierId, file: file(), }; @@ -184,9 +186,11 @@ export class AnnotationActionsService { const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId); const isApprover = this._permissionsService.isApprover(this._state.dossier()); const { file } = this._state; + const allFileRedactions = this._fileDataService.annotations(); const data = { redactions, + allFileRedactions, file: file(), dossier: this._state.dossier(), falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)), diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 00131bcda..e0f84cba2 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -64,6 +64,7 @@ export interface RedactTextData { export interface EditRedactionData { annotations: AnnotationWrapper[]; + allFileAnnotations?: AnnotationWrapper[]; dossierId: string; file: File; isApprover?: boolean; @@ -135,6 +136,7 @@ export interface RemoveRedactionPermissions { export interface RemoveRedactionData { redactions: AnnotationWrapper[]; + allFileRedactions?: AnnotationWrapper[]; dossier: Dossier; file?: File; falsePositiveContext: string[]; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index 3a28bf209..17e16a046 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -1,7 +1,8 @@ import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { LegalBasisOption } from './dialog-types'; +import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions } from './dialog-types'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; +import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; export interface EnhanceRequestData { readonly type: SuperType | null; @@ -79,3 +80,60 @@ export const parseRectanglePosition = (annotation: AnnotationWrapper) => { pageNumber: position.page, } as IEntityLogEntryPosition; }; + +export const prefillPageRange = ( + annotation: AnnotationWrapper, + allFileAnnotations: AnnotationWrapper[], + options: DetailsRadioOption[], +) => { + const option = options.find(o => o.value === RectangleRedactOptions.MULTIPLE_PAGES); + const pages = extractPages(annotation, allFileAnnotations); + option.additionalInput.value = toRangeString(pages); +}; + +const extractPages = (annotation: AnnotationWrapper, allFileAnnotations: AnnotationWrapper[]): number[] => { + return allFileAnnotations.reduce((pages, a) => { + const position = a.positions[0]; + const annotationPosition = annotation.positions[0]; + if ( + position.height === annotationPosition.height && + position.width === annotationPosition.width && + position.topLeft.x === annotationPosition.topLeft.x && + position.topLeft.y === annotationPosition.topLeft.y + ) { + pages.push(position.page); + } + return pages; + }, []); +}; + +const toRangeString = (pages: number[]): string => { + if (pages.length === 0) { + return ''; + } + + let ranges = []; + let start = pages[0]; + let end = pages[0]; + + for (let i = 1; i < pages.length; i++) { + if (pages[i] === end + 1) { + end = pages[i]; + } else { + if (start === end) { + ranges.push(`${start}`); + } else { + ranges.push(`${start}-${end}`); + } + start = end = pages[i]; + } + } + + if (start === end) { + ranges.push(`${start}`); + } else { + ranges.push(`${start}-${end}`); + } + + return ranges.join(','); +};