RED-6774 - added remove dialog

This commit is contained in:
Valentin Mihai 2023-06-18 22:36:51 +03:00
parent 8d468bf2bc
commit 9a967c0c0d
19 changed files with 317 additions and 20 deletions

View File

@ -176,5 +176,14 @@
[type]="buttonType"
icon="iqser:trash"
></iqser-circle-button>
<iqser-circle-button
(action)="removeOrSuggestRemoveRedaction()"
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere"
[tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.remove-annotation.remove-redaction' | translate"
[type]="buttonType"
icon="iqser:trash"
></iqser-circle-button>
</ng-container>
</div>

View File

@ -78,6 +78,10 @@ export class AnnotationActionsComponent implements OnChanges {
this.annotationActionsService.removeOrSuggestRemoveAnnotation(this.annotations, removeFromDict);
}
removeOrSuggestRemoveRedaction() {
this.annotationActionsService.removeOrSuggestRemoveRedaction(this.annotations);
}
markAsFalsePositive() {
this.annotationActionsService.markAsFalsePositive(this.annotations);
}

View File

@ -10,7 +10,7 @@
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
<ng-container *deny="roles.getRss; if: !dictionaryRequest">
<ng-container *deny="roles.getRss; if: !dictionaryRequest && type !== 'HINT'">
<div class="iqser-input-group required w-450">
<label [translate]="'redact-text.dialog.content.reason'"></label>
<mat-form-field>
@ -37,7 +37,7 @@
</div>
</ng-container>
<ng-container *deny="roles.getRss; if: dictionaryRequest">
<ng-container *deny="roles.getRss; if: dictionaryRequest || type === 'HINT'">
<div class="iqser-input-group required w-450">
<label [translate]="'redact-text.dialog.content.type'"></label>

View File

@ -2,3 +2,7 @@ label {
font-weight: bold;
padding-bottom: 8px;
}
iqser-details-radio {
padding-top: 20px;
}

View File

@ -13,6 +13,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ManualRedactionEntryType, ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
import { redactTextTranslations } from '@translations/redact-text-translations';
import { RedactTextOption, RedactTextOptions } from './redact-text-options';
import { tap } from 'rxjs/operators';
const PIN_ICON = 'red:push-pin';
const FOLDER_ICON = 'red:folder';
@ -24,13 +25,13 @@ const FOLDER_ICON = 'red:folder';
export class RedactTextDialogComponent extends BaseDialogComponent implements OnInit {
readonly roles = Roles;
readonly options: DetailsRadioOption<RedactTextOption>[];
readonly type: ManualRedactionEntryType;
dictionaryRequest = false;
legalOptions: LegalBasisOption[] = [];
dictionaries: Dictionary[] = [];
readonly #translations = redactTextTranslations;
readonly #dossier: Dossier;
readonly #type: ManualRedactionEntryType;
constructor(
private _justificationsService: JustificationsService,
@ -43,7 +44,7 @@ export class RedactTextDialogComponent extends BaseDialogComponent implements On
super(_dialogRef);
this.#dossier = _activeDossiersService.find(this.data.dossierId);
this.#type = this.data.manualRedactionEntryWrapper.type;
this.type = this.data.manualRedactionEntryWrapper.type;
this.options = this.#options();
this.form = this.#getForm();
@ -62,6 +63,17 @@ export class RedactTextDialogComponent extends BaseDialogComponent implements On
this.#selectReason();
this.#formatSelectedTextValue();
this._subscriptions.add(
this.form
.get('option')
.valueChanges.pipe(
tap((option: DetailsRadioOption<RedactTextOption>) => {
this.dictionaryRequest = option.value === RedactTextOptions.IN_DOSSIER;
}),
)
.subscribe(),
);
}
get displayedDictionaryLabel() {
@ -85,11 +97,6 @@ export class RedactTextDialogComponent extends BaseDialogComponent implements On
}
}
// toggleType() {
// console.log('test');
// this.dictionaryRequest = this.form.get('option').value === RedactTextOptions.IN_DOSSIER;
// }
#getForm(): UntypedFormGroup {
return this._formBuilder.group({
selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
@ -98,7 +105,7 @@ export class RedactTextDialogComponent extends BaseDialogComponent implements On
dictionary: [null, Validators.required],
classification: '',
multiplePages: '',
option: [this.options[0], Validators.required],
option: [this.options[0]],
});
}
@ -147,14 +154,14 @@ export class RedactTextDialogComponent extends BaseDialogComponent implements On
#options() {
return [
{
label: this.#translations[this.#type].onlyHere.label,
description: this.#translations[this.#type].onlyHere.description,
label: this.#translations[this.type].onlyHere.label,
description: this.#translations[this.type].onlyHere.description,
icon: PIN_ICON,
value: RedactTextOptions.ONLY_HERE,
},
{
label: this.#translations[this.#type].inDossier.label,
description: this.#translations[this.#type].inDossier.description,
label: this.#translations[this.type].inDossier.label,
description: this.#translations[this.type].inDossier.description,
icon: FOLDER_ICON,
value: RedactTextOptions.IN_DOSSIER,
},

View File

@ -0,0 +1,65 @@
import { Component, Inject } from '@angular/core';
import { BaseDialogComponent, DetailsRadioOption } from '@iqser/common-ui';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { RemoveRedactionOption, RemoveRedactionOptions } from './remove-redaction-options';
import { UntypedFormGroup } from '@angular/forms';
import { removeRedactionTranslations } from '@translations/remove-redaction-translations';
const PIN_ICON = 'red:push-pin';
const FOLDER_ICON = 'red:folder';
const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict';
@Component({
templateUrl: './remove-redaction-dialog.html',
styleUrls: ['./remove-redaction-dialog.component.scss'],
})
export class RemoveRedactionDialogComponent extends BaseDialogComponent {
readonly options: DetailsRadioOption<RemoveRedactionOption>[];
readonly #translations = removeRedactionTranslations;
constructor(
protected readonly _dialogRef: MatDialogRef<RemoveRedactionDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly data: NonNullable<unknown>,
) {
super(_dialogRef);
this.options = this.#options();
this.form = this.#getForm();
this.initialFormValue = this.form.getRawValue();
}
save(): void {
console.log('test');
}
#getForm(): UntypedFormGroup {
return this._formBuilder.group({
comment: [null],
option: [this.options[0]],
});
}
#options() {
return [
{
label: this.#translations.ONLY_HERE.label,
description: this.#translations.ONLY_HERE.description,
icon: PIN_ICON,
value: RemoveRedactionOptions.ONLY_HERE,
},
{
label: this.#translations.IN_DOSSIER.label,
description: this.#translations.IN_DOSSIER.description,
icon: FOLDER_ICON,
value: RemoveRedactionOptions.IN_DOSSIER,
},
{
label: this.#translations.FALSE_POSITIVE.label,
description: this.#translations.FALSE_POSITIVE.description,
icon: REMOVE_FROM_DICT_ICON,
value: RemoveRedactionOptions.FALSE_POSITIVE,
},
];
}
}

View File

@ -0,0 +1,35 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div [translate]="'remove-redaction.dialog.title'" class="dialog-header heading-l"></div>
<div class="dialog-content">
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
<div class="iqser-input-group w-450">
<label [translate]="'remove-redaction.dialog.content.comment'"></label>
<textarea
formControlName="comment"
iqserHasScrollbar
name="comment"
rows="4"
type="text"
[placeholder]="'remove-redaction.dialog.content.comment-placeholder' | translate"
></textarea>
</div>
</div>
<div class="dialog-actions">
<iqser-icon-button
[disabled]="disabled"
[label]="'remove-redaction.dialog.actions.save' | translate"
[submit]="true"
[type]="iconButtonTypes.primary"
>
</iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'remove-redaction.dialog.actions.cancel'"></div>
</div>
</form>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
</section>

View File

@ -0,0 +1,7 @@
export const RemoveRedactionOptions = {
ONLY_HERE: 'ONLY_HERE',
IN_DOSSIER: 'IN_DOSSIER',
FALSE_POSITIVE: 'FALSE_POSITIVE',
} as const;
export type RemoveRedactionOption = keyof typeof RemoveRedactionOptions;

View File

@ -66,6 +66,7 @@ import { SharedModule } from '@shared/shared.module';
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
import { FalsePositiveDialogComponent } from './dialogs/false-positive-dialog/false-positive-dialog.component';
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
import { RemoveRedactionDialogComponent } from './dialogs/remove-redaction-dialog/remove-redaction-dialog.component';
const routes: IqserRoutes = [
{
@ -91,6 +92,7 @@ const dialogs = [
RssDialogComponent,
FalsePositiveDialogComponent,
RedactTextDialogComponent,
RemoveRedactionDialogComponent,
];
const components = [

View File

@ -129,6 +129,24 @@ export class AnnotationActionsService {
});
}
removeOrSuggestRemoveRedaction(annotations: AnnotationWrapper[]) {
const data = {
annotationsToRemove: annotations,
dossier: this._state.dossier(),
hint: annotations[0].hintDictionary,
};
const { dossierId, fileId } = this._state;
this._dialogService.openDialog('removeRedaction', data, (result: { comment: string }) => {
const body = annotations.map(annotation => ({
annotationId: annotation.id,
comment: result.comment,
}));
this.#processObsAndEmit(
this._manualRedactionService.removeOrSuggestRemove(body, dossierId, fileId, true, annotations[0].isHint),
).then();
});
}
recategorizeImages(annotations: AnnotationWrapper[]) {
const data = { annotations, dossier: this._state.dossier() };
const { dossierId, fileId } = this._state;

View File

@ -12,6 +12,7 @@ import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dial
import { RssDialogComponent } from '../dialogs/rss-dialog/rss-dialog.component';
import { FalsePositiveDialogComponent } from '../dialogs/false-positive-dialog/false-positive-dialog.component';
import { RedactTextDialogComponent } from '../dialogs/redact-text-dialog/redact-text-dialog.component';
import { RemoveRedactionDialogComponent } from '../dialogs/remove-redaction-dialog/remove-redaction-dialog.component';
type DialogType =
| 'confirm'
@ -25,7 +26,8 @@ type DialogType =
| 'manualAnnotation'
| 'highlightAction'
| 'falsePositive'
| 'redactText';
| 'redactText'
| 'removeRedaction';
@Injectable()
export class FilePreviewDialogService extends DialogService<DialogType> {
@ -70,6 +72,9 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
redactText: {
component: RedactTextDialogComponent,
},
removeRedaction: {
component: RemoveRedactionDialogComponent,
},
};
constructor(protected readonly _dialog: MatDialog) {

View File

@ -129,6 +129,13 @@ export class PdfAnnotationActionsService {
availableActions.push(removeOrSuggestToRemoveOnlyHereButton);
}
if (permissions.canRemoveOrSuggestToRemoveOnlyHere) {
const removeOrSuggestToRemoveButton = this.#getButton('trash', _('annotation-actions.remove-annotation.remove-redaction'), () =>
this.#annotationActionsService.removeOrSuggestRemoveRedaction(annotations),
);
availableActions.push(removeOrSuggestToRemoveButton);
}
return availableActions;
}

View File

@ -0,0 +1,22 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RemoveRedactionOption } from '../modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-options';
interface Option {
label: string;
description: string;
}
export const removeRedactionTranslations: { [key in RemoveRedactionOption]: Option } = {
ONLY_HERE: {
label: _('remove-redaction.dialog.content.options.only-here.label'),
description: _('remove-redaction.dialog.content.options.only-here.description'),
},
IN_DOSSIER: {
label: _('remove-redaction.dialog.content.options.in-dossier.label'),
description: _('remove-redaction.dialog.content.options.in-dossier.description'),
},
FALSE_POSITIVE: {
label: _('remove-redaction.dialog.content.options.false-positive.label'),
description: _('remove-redaction.dialog.content.options.false-positive.description'),
},
};

View File

@ -328,7 +328,8 @@
"remove-annotation": {
"false-positive": "Falsch positiv",
"only-here": "nur hier entfernen",
"remove-from-dict": "Aus dem Wörterbuch entfernen"
"remove-from-dict": "Aus dem Wörterbuch entfernen",
"remove-redaction": ""
},
"remove-highlights": {
"label": ""
@ -1958,6 +1959,33 @@
},
"value": "Wert"
},
"remove-redaction": {
"dialog": {
"actions": {
"cancel": "",
"save": ""
},
"content": {
"comment": "",
"comment-placeholder": "",
"options": {
"false-positive": {
"description": "",
"label": ""
},
"in-dossier": {
"description": "",
"label": ""
},
"only-here": {
"description": "",
"label": ""
}
}
},
"title": ""
}
},
"report-type": {
"label": "{length} {length, plural, one{Berichtstyp} other{Berichtstypen}}"
},

View File

@ -328,7 +328,8 @@
"remove-annotation": {
"false-positive": "False Positive",
"only-here": "Remove only here",
"remove-from-dict": "Remove from dictionary"
"remove-from-dict": "Remove from dictionary",
"remove-redaction": "Remove"
},
"remove-highlights": {
"label": "Remove Selected Earmarks"
@ -1958,6 +1959,33 @@
},
"value": "Value"
},
"remove-redaction": {
"dialog": {
"actions": {
"cancel": "Cancel",
"save": "Save"
},
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"options": {
"false-positive": {
"description": "\"White\" is not a CBI Author in this context: \"White rabbits are\".",
"label": "False positive"
},
"in-dossier": {
"description": "Do not redact \"White\" in any document of the current dossier.",
"label": "Remove in dossier"
},
"only-here": {
"description": "Do not redact \"White\" at this position in the current document.",
"label": "Remove here"
}
}
},
"title": "Remove redaction"
}
},
"report-type": {
"label": "{length} report {length, plural, one{type} other{types}}"
},

View File

@ -328,7 +328,8 @@
"remove-annotation": {
"false-positive": "Falsch positiv",
"only-here": "nur hier entfernen",
"remove-from-dict": "Aus dem Wörterbuch entfernen"
"remove-from-dict": "Aus dem Wörterbuch entfernen",
"remove-redaction": ""
},
"remove-highlights": {
"label": ""
@ -1958,6 +1959,33 @@
},
"value": "Wert"
},
"remove-redaction": {
"dialog": {
"actions": {
"cancel": "",
"save": ""
},
"content": {
"comment": "",
"comment-placeholder": "",
"options": {
"false-positive": {
"description": "",
"label": ""
},
"in-dossier": {
"description": "",
"label": ""
},
"only-here": {
"description": "",
"label": ""
}
}
},
"title": ""
}
},
"report-type": {
"label": "{length} {length, plural, one{Berichtstyp} other{Berichtstypen}}"
},

View File

@ -328,7 +328,8 @@
"remove-annotation": {
"false-positive": "False Positive",
"only-here": "Remove only here",
"remove-from-dict": "Remove from dictionary"
"remove-from-dict": "Remove from dictionary",
"remove-redaction": "Remove"
},
"remove-highlights": {
"label": "Remove Selected Earmarks"
@ -1958,6 +1959,33 @@
},
"value": "Value"
},
"remove-redaction": {
"dialog": {
"actions": {
"cancel": "Cancel",
"save": "Save"
},
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"options": {
"false-positive": {
"description": "\"White\" is not a CBI Author in this context: \"White rabbits are\".",
"label": "False positive"
},
"in-dossier": {
"description": "Do not redact \"White\" in any document of the current dossier.",
"label": "Remove in dossier"
},
"only-here": {
"description": "Do not redact \"White\" at this position in the current document.",
"label": "Remove here"
}
}
},
"title": "Remove redaction"
}
},
"report-type": {
"label": "{length} report {length, plural, one{type} other{types}}"
},

@ -1 +1 @@
Subproject commit e23f355aefa0d723783eff1860fa549e56d7cf71
Subproject commit 5a027f7e1cb7aa1b093fc2f664bf6c1d3b919a8f