-
+
+
-
-
-
- {{ translations[option] | translate }}
-
-
-
+
+
+
+ {{ translations[option] | translate }}
+
+
+
+
+
+
+
+
+ {{ translations[data.operation].confirmation | translate: { count: data.highlights.length } }}
+
+
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts
index 6fcf33d99..ec26760b3 100644
--- a/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts
@@ -39,11 +39,14 @@ export class HighlightActionDialogComponent extends BaseDialogComponent {
async save(): Promise
{
this._loadingService.start();
- const { dossierId, fileId, operation, highlights, pageNumber } = this.data;
+ const { dossierId, fileId, operation, highlights, pageNumber, color } = this.data;
+
+ // !color means we are in bulk select mode, so we don't need to apply additional page filters
const filteredHighlights =
- this.form.get('option').value === TextHighlightOperationPages.ALL_PAGES
+ !color || this.form.get('option').value === TextHighlightOperationPages.ALL_PAGES
? highlights
: highlights.filter(h => h.pageNumber === pageNumber);
+
const ids = filteredHighlights.map(h => h.id);
await firstValueFrom(this._textHighlightService.performHighlightsAction(ids, dossierId, fileId, operation));
this._loadingService.stop();
@@ -51,9 +54,15 @@ export class HighlightActionDialogComponent extends BaseDialogComponent {
}
private _getForm(): FormGroup {
- return this._formBuilder.group({
- color: [{ value: this.data.color, disabled: true }, Validators.required],
- option: [null, Validators.required],
- });
+ if (this.data.color) {
+ return this._formBuilder.group({
+ color: [{ value: this.data.color, disabled: true }, Validators.required],
+ option: [null, Validators.required],
+ });
+ } else {
+ return this._formBuilder.group({
+ confirmation: [false, Validators.requiredTrue],
+ });
+ }
}
}
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 61c219508..5b39e9bb9 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
@@ -17,6 +17,7 @@ import {
IRecategorizationRequest,
IRectangle,
IResizeRequest,
+ TextHighlightOperation,
} from '@red/domain';
import { toPosition } from '../../dossier/utils/pdf-calculation.utils';
import { AnnotationDrawService } from './annotation-draw.service';
@@ -71,6 +72,16 @@ export class AnnotationActionsService {
);
}
+ removeHighlights(highlights: AnnotationWrapper[]): void {
+ const data = this._getHighlightOperationData(TextHighlightOperation.REMOVE, highlights);
+ this._dialogService.openDialog('highlightAction', null, data);
+ }
+
+ convertHighlights(highlights: AnnotationWrapper[]): void {
+ const data = this._getHighlightOperationData(TextHighlightOperation.CONVERT, highlights);
+ this._dialogService.openDialog('highlightAction', null, data);
+ }
+
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state;
@@ -485,6 +496,15 @@ export class AnnotationActionsService {
this._processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId), annotations, annotationsChanged);
}
+ private _getHighlightOperationData(operation: TextHighlightOperation, highlights: AnnotationWrapper[]) {
+ return {
+ dossierId: this._state.dossierId,
+ fileId: this._state.fileId,
+ operation,
+ highlights,
+ };
+ }
+
private _processObsAndEmit(
obs: Observable,
annotations: AnnotationWrapper[],
diff --git a/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts b/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts
index 59db5bc89..f918f5b59 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts
@@ -4,6 +4,9 @@ import { boolFactory } from '@iqser/common-ui';
import { ViewModeService } from './view-mode.service';
import { map, tap } from 'rxjs/operators';
import { FilePreviewStateService } from './file-preview-state.service';
+import { ViewMode, ViewModes } from '@red/domain';
+
+const ENABLED_MULTISELECT: ViewMode[] = [ViewModes.STANDARD, ViewModes.TEXT_HIGHLIGHTS];
@Injectable()
export class MultiSelectService {
@@ -15,8 +18,8 @@ export class MultiSelectService {
constructor(private readonly _viewModeService: ViewModeService, private readonly _state: FilePreviewStateService) {
[this.active$, this.inactive$] = boolFactory(this.#active$.asObservable());
- this.enabled$ = combineLatest([this._viewModeService.isStandard$, _state.isWritable$]).pipe(
- map((result: boolean[]) => !result.some(res => !res)),
+ this.enabled$ = combineLatest([this._viewModeService.viewMode$, _state.isWritable$]).pipe(
+ map(([viewMode, isWritable]) => isWritable && ENABLED_MULTISELECT.includes(viewMode)),
tap(enabled => this.#enabled$.next(enabled)),
);
}
diff --git a/apps/red-ui/src/app/translations/highlights-translations.ts b/apps/red-ui/src/app/translations/highlights-translations.ts
index e3077dace..4b52df343 100644
--- a/apps/red-ui/src/app/translations/highlights-translations.ts
+++ b/apps/red-ui/src/app/translations/highlights-translations.ts
@@ -6,11 +6,13 @@ export const highlightsTranslations = {
title: _('highlight-action-dialog.convert.title'),
details: _('highlight-action-dialog.convert.details'),
save: _('highlight-action-dialog.convert.save'),
+ confirmation: _('highlight-action-dialog.convert.confirmation'),
},
[TextHighlightOperation.REMOVE]: {
title: _('highlight-action-dialog.remove.title'),
details: _('highlight-action-dialog.remove.details'),
save: _('highlight-action-dialog.remove.save'),
+ confirmation: _('highlight-action-dialog.remove.confirmation'),
},
[TextHighlightOperationPages.ALL_PAGES]: _('highlight-action-dialog.all-pages'),
[TextHighlightOperationPages.THIS_PAGE]: _('highlight-action-dialog.this-page'),
diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json
index 36c4dbaa9..cf9aac978 100644
--- a/apps/red-ui/src/assets/i18n/de.json
+++ b/apps/red-ui/src/assets/i18n/de.json
@@ -195,6 +195,9 @@
"accept-suggestion": {
"label": "Genehmigen und zum Wörterbuch hinzufügen"
},
+ "convert-highlights": {
+ "label": ""
+ },
"edit-reason": {
"label": "Begründung bearbeiten"
},
@@ -299,6 +302,9 @@
"only-here": "nur hier entfernen",
"remove-from-dict": "Aus dem Wörterbuch entfernen"
},
+ "remove-highlights": {
+ "label": ""
+ },
"resize-accept": {
"label": "Größe speichern"
},
@@ -1421,6 +1427,7 @@
},
"all-pages": "",
"convert": {
+ "confirmation": "",
"details": "",
"save": "",
"title": ""
@@ -1431,6 +1438,7 @@
}
},
"remove": {
+ "confirmation": "",
"details": "",
"save": "",
"title": ""
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index f31c3f0c1..b9a940b85 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -195,6 +195,9 @@
"accept-suggestion": {
"label": "Approve Suggestion"
},
+ "convert-highlights": {
+ "label": "Convert Selected Highlights"
+ },
"edit-reason": {
"label": "Edit Reason"
},
@@ -299,6 +302,9 @@
"only-here": "Remove only here",
"remove-from-dict": "Remove from dictionary"
},
+ "remove-highlights": {
+ "label": "Remove Selected Highlights"
+ },
"resize-accept": {
"label": "Save Resize"
},
@@ -1421,6 +1427,7 @@
},
"all-pages": "For all pages in this document",
"convert": {
+ "confirmation": "The {count} selected {count, plural, one{highlight} other{highlights}} will be converted",
"details": "All highlights from the document will be converted to Imported Redactions, using the color set up in the Default Colors section of the app.",
"save": "Convert Highlights",
"title": "Convert highlights to imported redactions"
@@ -1431,6 +1438,7 @@
}
},
"remove": {
+ "confirmation": "The {count} selected {count, plural, one{highlight} other{highlights}} will be removed from the document",
"details": "Removing highlights from the document will delete all the rectangles and leave a white background behind the highlighted text.",
"save": "Remove Highlights",
"title": "Remove highlights"