RED-7340 - removed dictionary & false positive logic from rectangle annotation dialog

This commit is contained in:
Valentin Mihai 2024-10-05 22:55:28 +03:00
parent af17c026ff
commit 2377fbff55
4 changed files with 21 additions and 94 deletions

View File

@ -1,6 +1,6 @@
<section class="dialog"> <section class="dialog">
<form (submit)="save()" [formGroup]="form"> <form (submit)="save()" [formGroup]="form">
<div [translate]="title" class="dialog-header heading-l"></div> <div [translate]="'manual-annotation.dialog.header.redaction'" class="dialog-header heading-l"></div>
<div class="dialog-content"> <div class="dialog-content">
<iqser-details-radio <iqser-details-radio
@ -9,29 +9,7 @@
formControlName="option" formControlName="option"
></iqser-details-radio> ></iqser-details-radio>
<div <div *deny="roles.getRss" class="iqser-input-group required w-450">
*ngIf="!isFalsePositiveRequest && (isDictionaryRequest || !manualRedactionTypeExists)"
class="iqser-input-group required w-450"
>
<label *ngIf="isDictionaryRequest" [translate]="'manual-annotation.dialog.content.dictionary'"></label>
<label *ngIf="!isDictionaryRequest" [translate]="'manual-annotation.dialog.content.type'"></label>
<mat-form-field>
<mat-select formControlName="dictionary">
<mat-select-trigger>{{ displayedDictionaryLabel }}</mat-select-trigger>
<mat-option
*ngFor="let dictionary of possibleDictionaries"
[matTooltip]="dictionary.description"
[value]="dictionary.type"
matTooltipPosition="after"
>
<span> {{ dictionary.label }} </span>
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *deny="roles.getRss; if: !isDictionaryRequest" class="iqser-input-group required w-450">
<label [translate]="'manual-annotation.dialog.content.reason'"></label> <label [translate]="'manual-annotation.dialog.content.reason'"></label>
<mat-form-field> <mat-form-field>
<mat-select <mat-select
@ -39,19 +17,16 @@
class="full-width" class="full-width"
formControlName="reason" formControlName="reason"
> >
<mat-option @for (option of legalOptions; track option) {
*ngFor="let option of legalOptions" <mat-option [matTooltip]="option.description" [value]="option" matTooltipPosition="after">
[matTooltip]="option.description" {{ option.label }}
[value]="option" </mat-option>
matTooltipPosition="after" }
>
{{ option.label }}
</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div *deny="roles.getRss; if: !isDictionaryRequest" class="iqser-input-group w-450"> <div *deny="roles.getRss" class="iqser-input-group w-450">
<label [translate]="'manual-annotation.dialog.content.legalBasis'"></label> <label [translate]="'manual-annotation.dialog.content.legalBasis'"></label>
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" /> <input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div> </div>

View File

@ -7,13 +7,11 @@ import {
IconButtonComponent, IconButtonComponent,
IqserDenyDirective, IqserDenyDirective,
IqserDialogComponent, IqserDialogComponent,
IqserPermissionsService,
Toaster, Toaster,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; import { Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { JustificationsService } from '@services/entity-services/justifications.service'; import { JustificationsService } from '@services/entity-services/justifications.service';
import { Roles } from '@users/roles'; import { Roles } from '@users/roles';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
@ -39,7 +37,6 @@ interface RectangleDialogData {
} }
export interface RectangleDialogResult { export interface RectangleDialogResult {
annotation: IManualRedactionEntry; annotation: IManualRedactionEntry;
dictionary: Dictionary;
} }
export const NON_READABLE_CONTENT = 'non-readable content'; export const NON_READABLE_CONTENT = 'non-readable content';
@ -74,30 +71,19 @@ export class RectangleAnnotationDialog
readonly #dossier: Dossier; readonly #dossier: Dossier;
protected readonly roles = Roles; protected readonly roles = Roles;
protected readonly options: DetailsRadioOption<RectangleRedactOption>[]; protected readonly options: DetailsRadioOption<RectangleRedactOption>[];
protected isDictionaryRequest: boolean;
protected isFalsePositiveRequest: boolean;
protected manualRedactionTypeExists = true;
protected possibleDictionaries: Dictionary[] = [];
protected legalOptions: LegalBasisOption[] = []; protected legalOptions: LegalBasisOption[] = [];
readonly form: UntypedFormGroup; readonly form: UntypedFormGroup;
constructor( constructor(
private readonly iqserPermissionsService: IqserPermissionsService,
private readonly _justificationsService: JustificationsService,
private readonly _manualRedactionService: ManualRedactionService,
private readonly activeDossiersService: ActiveDossiersService, private readonly activeDossiersService: ActiveDossiersService,
private readonly _dictionaryService: DictionaryService, private readonly _justificationsService: JustificationsService,
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _toaster: Toaster, private readonly _toaster: Toaster,
) { ) {
super(); super();
this.#dossier = activeDossiersService.find(this.data.dossierId); this.#dossier = activeDossiersService.find(this.data.dossierId);
this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE';
this.isDictionaryRequest = this.data.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
this.manualRedactionTypeExists = this._dictionaryService.hasManualType(this.#dossier.dossierTemplateId);
this.options = getRectangleRedactOptions(); this.options = getRectangleRedactOptions();
this.form = this.#getForm(); this.form = this.#getForm();
@ -112,27 +98,7 @@ export class RectangleAnnotationDialog
} }
} }
get title() {
return this._manualRedactionService.getTitle(this.data.manualRedactionEntryWrapper.type);
}
get displayedDictionaryLabel() {
const dictType = this.form.get('dictionary').value;
if (dictType) {
return this.possibleDictionaries.find(d => d.type === dictType).label;
}
return null;
}
get disabled() {
return this.form.invalid;
}
async ngOnInit() { async ngOnInit() {
this.possibleDictionaries = this.isDictionaryRequest
? this._dictionaryService.getDictionariesOptions(this.#dossier.dossierTemplateId)
: this._dictionaryService.getRedactionTypes(this.#dossier.dossierTemplateId);
const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId)); const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId));
this.legalOptions = data.map(lbm => ({ this.legalOptions = data.map(lbm => ({
legalBasis: lbm.reason, legalBasis: lbm.reason,
@ -148,13 +114,13 @@ export class RectangleAnnotationDialog
save() { save() {
this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
try { try {
const annotation = const annotation = (
this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES
? getMultiplePagesRectangle(this.#multiplePagesRectangleData).manualRedactionEntry ? getMultiplePagesRectangle(this.#multiplePagesRectangleData)
: this.data.manualRedactionEntryWrapper; : this.data.manualRedactionEntryWrapper
).manualRedactionEntry;
super.close({ super.close({
annotation, annotation,
dictionary: this.possibleDictionaries.find(d => d.type === this.form.get('dictionary').value),
}); });
} catch (e) { } catch (e) {
this._toaster.error(_('manual-annotation.dialog.error')); this._toaster.error(_('manual-annotation.dialog.error'));
@ -173,10 +139,7 @@ export class RectangleAnnotationDialog
return this._formBuilder.group({ return this._formBuilder.group({
selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value, selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
section: [null], section: [null],
reason: this.isDictionaryRequest ? [null] : [null, Validators.required], reason: [null, Validators.required],
dictionary: this.isDictionaryRequest
? [this.isFalsePositiveRequest ? 'false_positive' : null, Validators.required]
: [this.manualRedactionTypeExists ? SuperTypes.ManualRedaction : null, Validators.required],
comment: [null], comment: [null],
classification: [NON_READABLE_CONTENT], classification: [NON_READABLE_CONTENT],
option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()],
@ -185,22 +148,13 @@ export class RectangleAnnotationDialog
#enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
const legalOption: LegalBasisOption = this.form.get('reason').value; const legalOption: LegalBasisOption = this.form.get('reason').value;
addRedactionRequest.type = this.form.get('dictionary').value; addRedactionRequest.type = SuperTypes.ManualRedaction;
if (legalOption) { if (legalOption) {
addRedactionRequest.reason = legalOption.description; addRedactionRequest.reason = legalOption.description;
addRedactionRequest.legalBasis = legalOption.legalBasis; addRedactionRequest.legalBasis = legalOption.legalBasis;
} }
if (this.iqserPermissionsService.has(Roles.getRss)) { addRedactionRequest.addToDictionary = false;
const selectedType = this.possibleDictionaries.find(d => d.type === addRedactionRequest.type);
addRedactionRequest.addToDictionary = selectedType.hasDictionary;
} else {
addRedactionRequest.addToDictionary = this.isDictionaryRequest && addRedactionRequest.type !== 'dossier_redaction';
}
if (!addRedactionRequest.reason) {
addRedactionRequest.reason = 'Dictionary Request';
}
const commentValue = this.form.get('comment').value; const commentValue = this.form.get('comment').value;
addRedactionRequest.comment = commentValue ? { text: commentValue } : null; addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
addRedactionRequest.section = this.form.get('section').value; addRedactionRequest.section = this.form.get('section').value;

View File

@ -324,9 +324,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._annotationManager.delete([selectedAnnotations[0].Id]); this._annotationManager.delete([selectedAnnotations[0].Id]);
} }
const add$ = this._manualRedactionService.addAnnotation([result.annotation], this.dossierId, this.fileId, { const add$ = this._manualRedactionService.addAnnotation([result.annotation], this.dossierId, this.fileId);
dictionaryLabel: result.dictionary?.label,
});
const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file))); const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file)));
return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined)))); return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined))));

View File

@ -97,7 +97,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
: this.#showToast(options?.hint ? 'force-hint' : 'add'); : this.#showToast(options?.hint ? 'force-hint' : 'add');
const canAddRedaction = this._iqserPermissionsService.has(Roles.redactions.write); const canAddRedaction = this._iqserPermissionsService.has(Roles.redactions.write);
if (canAddRedaction) { if (canAddRedaction) {
return this.add(requests, dossierId, fileId, options.bulkLocal).pipe(toast); return this.add(requests, dossierId, fileId, options?.bulkLocal).pipe(toast);
} }
return of(undefined); return of(undefined);
@ -139,7 +139,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
} }
add(body: List<IAddRedactionRequest>, dossierId: string, fileId: string, bulkLocal = false) { add(body: List<IAddRedactionRequest>, dossierId: string, fileId: string, bulkLocal = false) {
bulkLocal = bulkLocal || !!body[0].pageNumbers.length; bulkLocal = bulkLocal || !!body[0].pageNumbers?.length;
const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction;
return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body));