RED-6506: Added confirmation dialog for false positive action.
This commit is contained in:
parent
a5b7b76d46
commit
cd2f51c30e
@ -0,0 +1,31 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div class="dialog-header heading-l" translate="false-positive-dialog.header"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<ul>
|
||||
<li
|
||||
*ngFor="let value of data"
|
||||
[innerHTML]="'false-positive-dialog.content.body-text' | translate : { value: value.text, context: value.context }"
|
||||
></li>
|
||||
</ul>
|
||||
<div class="iqser-input-group w-300">
|
||||
<label translate="false-positive-dialog.content.comment"></label>
|
||||
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
[disabled]="!form.valid"
|
||||
[label]="'false-positive-dialog.actions.save' | translate"
|
||||
[submit]="true"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
|
||||
<div class="all-caps-label cancel" mat-dialog-close translate="false-positive-dialog.actions.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||
</section>
|
||||
@ -0,0 +1,30 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { BaseDialogComponent } from '@iqser/common-ui';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
export interface FalsePositiveDialogInput {
|
||||
text: string;
|
||||
context: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './false-positive-dialog.component.html',
|
||||
})
|
||||
export class FalsePositiveDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
constructor(
|
||||
protected readonly _dialogRef: MatDialogRef<FalsePositiveDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: FalsePositiveDialogInput[],
|
||||
) {
|
||||
super(_dialogRef);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const controlsConfig = { comment: [null] };
|
||||
this.form = this._formBuilder.group(controlsConfig);
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this._dialogRef.close(this.form.getRawValue());
|
||||
}
|
||||
}
|
||||
@ -64,6 +64,7 @@ import { SuggestionsService } from './services/suggestions.service';
|
||||
import { PagesComponent } from './components/pages/pages.component';
|
||||
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';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{
|
||||
@ -87,6 +88,7 @@ const dialogs = [
|
||||
DocumentInfoDialogComponent,
|
||||
ImportRedactionsDialogComponent,
|
||||
RssDialogComponent,
|
||||
FalsePositiveDialogComponent,
|
||||
];
|
||||
|
||||
const components = [
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ManualRedactionService } from './manual-redaction.service';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Observable } from 'rxjs';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { getFirstRelevantTextPart } from '../../../utils';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import {
|
||||
@ -50,7 +50,7 @@ export class AnnotationActionsService {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const ids = annotations.map(a => a.id);
|
||||
const request = this._manualRedactionService.approve(ids, dossierId, fileId);
|
||||
this.#processObsAndEmit(request);
|
||||
this.#processObsAndEmit(request).then();
|
||||
}
|
||||
|
||||
removeHighlights(highlights: AnnotationWrapper[]): void {
|
||||
@ -72,7 +72,7 @@ export class AnnotationActionsService {
|
||||
fileId,
|
||||
annotations[0].isModifyDictionary,
|
||||
),
|
||||
);
|
||||
).then();
|
||||
}
|
||||
|
||||
forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) {
|
||||
@ -86,7 +86,7 @@ export class AnnotationActionsService {
|
||||
fileId,
|
||||
annotations[0].isIgnoredHint,
|
||||
),
|
||||
);
|
||||
).then();
|
||||
});
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ export class AnnotationActionsService {
|
||||
value: data.value,
|
||||
}));
|
||||
|
||||
this.#processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId));
|
||||
this.#processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId)).then();
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -125,7 +125,7 @@ export class AnnotationActionsService {
|
||||
}));
|
||||
this.#processObsAndEmit(
|
||||
this._manualRedactionService.removeOrSuggestRemove(body, dossierId, fileId, removeFromDictionary, annotations[0].isHint),
|
||||
);
|
||||
).then();
|
||||
});
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ export class AnnotationActionsService {
|
||||
type,
|
||||
comment,
|
||||
}));
|
||||
this.#processObsAndEmit(this._manualRedactionService.recategorizeImage(body, dossierId, fileId));
|
||||
this.#processObsAndEmit(this._manualRedactionService.recategorizeImage(body, dossierId, fileId)).then();
|
||||
});
|
||||
}
|
||||
|
||||
@ -152,10 +152,10 @@ export class AnnotationActionsService {
|
||||
fileId,
|
||||
modifyDictionary,
|
||||
),
|
||||
);
|
||||
).then();
|
||||
}
|
||||
|
||||
convertRecommendationToAnnotation(recommendations: AnnotationWrapper[]) {
|
||||
async convertRecommendationToAnnotation(recommendations: AnnotationWrapper[]) {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const dialogRef = this._dialog.open<AcceptRecommendationDialogComponent, AcceptRecommendationData, AcceptRecommendationReturnType>(
|
||||
AcceptRecommendationDialogComponent,
|
||||
@ -163,7 +163,7 @@ export class AnnotationActionsService {
|
||||
);
|
||||
// TODO: remove observables
|
||||
const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations));
|
||||
dialogClosed.subscribe(({ annotations, comment: commentText }) => {
|
||||
await firstValueFrom(dialogClosed).then(({ annotations, comment: commentText }) => {
|
||||
if (isJustOne(annotations) && this._annotationManager.resizingAnnotationId === annotations[0].id) {
|
||||
this.cancelResize(annotations[0]).then();
|
||||
}
|
||||
@ -231,20 +231,24 @@ export class AnnotationActionsService {
|
||||
}
|
||||
|
||||
markAsFalsePositive(annotations: AnnotationWrapper[]) {
|
||||
const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||
sourceId: annotation.id,
|
||||
value: this._getFalsePositiveText(annotation),
|
||||
type: annotation.type,
|
||||
positions: annotation.positions,
|
||||
addToDictionary: true,
|
||||
reason: 'False Positive',
|
||||
dictionaryEntryType: annotation.isRecommendation
|
||||
? DictionaryEntryTypes.FALSE_RECOMMENDATION
|
||||
: DictionaryEntryTypes.FALSE_POSITIVE,
|
||||
}));
|
||||
const { dossierId, fileId } = this._state;
|
||||
const data = annotations.map(annotation => ({ text: annotation.value, context: this._getFalsePositiveText(annotation) }));
|
||||
this._dialogService.openDialog('falsePositive', data, (result: { comment: string }) => {
|
||||
const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||
sourceId: annotation.id,
|
||||
value: this._getFalsePositiveText(annotation),
|
||||
type: annotation.type,
|
||||
positions: annotation.positions,
|
||||
addToDictionary: true,
|
||||
reason: 'False Positive',
|
||||
dictionaryEntryType: annotation.isRecommendation
|
||||
? DictionaryEntryTypes.FALSE_RECOMMENDATION
|
||||
: DictionaryEntryTypes.FALSE_POSITIVE,
|
||||
comment: result.comment ? { text: result.comment } : null,
|
||||
}));
|
||||
const { dossierId, fileId } = this._state;
|
||||
|
||||
this.#processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId));
|
||||
this.#processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId)).then();
|
||||
});
|
||||
}
|
||||
|
||||
#generateRectangle(annotationWrapper: AnnotationWrapper) {
|
||||
@ -279,12 +283,15 @@ export class AnnotationActionsService {
|
||||
};
|
||||
}
|
||||
|
||||
#processObsAndEmit(obs: Observable<unknown>) {
|
||||
async #processObsAndEmit(obs: Observable<unknown>) {
|
||||
// TODO: remove observables and use promises instead
|
||||
obs.subscribe({
|
||||
next: () => this._fileDataService.annotationsChanged(),
|
||||
error: () => this._fileDataService.annotationsChanged(),
|
||||
});
|
||||
await firstValueFrom(obs)
|
||||
.then(() => this._fileDataService.annotationsChanged())
|
||||
.catch(() => this._fileDataService.annotationsChanged());
|
||||
// obs.subscribe({
|
||||
// next: () => this._fileDataService.annotationsChanged(),
|
||||
// error: () => this._fileDataService.annotationsChanged(),
|
||||
// });
|
||||
}
|
||||
|
||||
private _getFalsePositiveText(annotation: AnnotationWrapper) {
|
||||
|
||||
@ -10,6 +10,7 @@ import { ConfirmationDialogComponent, DialogConfig, DialogService } from '@iqser
|
||||
import { ResizeAnnotationDialogComponent } from '../dialogs/resize-annotation-dialog/resize-annotation-dialog.component';
|
||||
import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
import { RssDialogComponent } from '../dialogs/rss-dialog/rss-dialog.component';
|
||||
import { FalsePositiveDialogComponent } from '../dialogs/false-positive-dialog/false-positive-dialog.component';
|
||||
|
||||
type DialogType =
|
||||
| 'confirm'
|
||||
@ -21,7 +22,8 @@ type DialogType =
|
||||
| 'resizeAnnotation'
|
||||
| 'forceAnnotation'
|
||||
| 'manualAnnotation'
|
||||
| 'highlightAction';
|
||||
| 'highlightAction'
|
||||
| 'falsePositive';
|
||||
|
||||
@Injectable()
|
||||
export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
@ -60,6 +62,9 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
component: RssDialogComponent,
|
||||
dialogConfig: { width: '90vw' },
|
||||
},
|
||||
falsePositive: {
|
||||
component: FalsePositiveDialogComponent,
|
||||
},
|
||||
};
|
||||
|
||||
constructor(protected readonly _dialog: MatDialog) {
|
||||
|
||||
@ -1994,6 +1994,17 @@
|
||||
"annotations": "",
|
||||
"title": ""
|
||||
},
|
||||
"false-positive-dialog": {
|
||||
"actions": {
|
||||
"cancel": "",
|
||||
"save": ""
|
||||
},
|
||||
"content": {
|
||||
"comment": "",
|
||||
"body-text": ""
|
||||
},
|
||||
"header": ""
|
||||
},
|
||||
"rules-screen": {
|
||||
"error": {
|
||||
"generic": "Es ist ein Fehler aufgetreten ... Die Regeln konnten nicht aktualisiert werden!"
|
||||
|
||||
@ -1994,6 +1994,17 @@
|
||||
"annotations": "",
|
||||
"title": "Structured Component Management"
|
||||
},
|
||||
"false-positive-dialog": {
|
||||
"actions": {
|
||||
"cancel": "Cancel",
|
||||
"save": "Yes, proceed"
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"body-text": "''{value}'' is a false positive in this context: {context}"
|
||||
},
|
||||
"header": "False Positive"
|
||||
},
|
||||
"rules-screen": {
|
||||
"error": {
|
||||
"generic": "Something went wrong... Rules update failed!"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user