move to bulk endpoints, add works
This commit is contained in:
parent
7b9d5ac405
commit
7fdfa5d308
@ -29,7 +29,7 @@ export class AnnotationActionsComponent implements OnChanges {
|
|||||||
@Input() tooltipPosition: 'before' | 'above' = 'before';
|
@Input() tooltipPosition: 'before' | 'above' = 'before';
|
||||||
@Input() canPerformAnnotationActions: boolean;
|
@Input() canPerformAnnotationActions: boolean;
|
||||||
@Input() alwaysVisible: boolean;
|
@Input() alwaysVisible: boolean;
|
||||||
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper[]>();
|
||||||
annotationPermissions: AnnotationPermissions;
|
annotationPermissions: AnnotationPermissions;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@ -58,7 +58,7 @@ export class FileWorkloadComponent {
|
|||||||
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||||
@Output() readonly selectAnnotations = new EventEmitter<AnnotationWrapper[]>();
|
@Output() readonly selectAnnotations = new EventEmitter<AnnotationWrapper[]>();
|
||||||
@Output() readonly selectPage = new EventEmitter<number>();
|
@Output() readonly selectPage = new EventEmitter<number>();
|
||||||
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper[]>();
|
||||||
displayedPages: number[] = [];
|
displayedPages: number[] = [];
|
||||||
pagesPanelActive = true;
|
pagesPanelActive = true;
|
||||||
readonly displayedAnnotations$: Observable<Map<number, AnnotationWrapper[]>>;
|
readonly displayedAnnotations$: Observable<Map<number, AnnotationWrapper[]>>;
|
||||||
|
|||||||
@ -60,7 +60,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
@Output() readonly manualAnnotationRequested = new EventEmitter<ManualRedactionEntryWrapper>();
|
@Output() readonly manualAnnotationRequested = new EventEmitter<ManualRedactionEntryWrapper>();
|
||||||
@Output() readonly pageChanged = new EventEmitter<number>();
|
@Output() readonly pageChanged = new EventEmitter<number>();
|
||||||
@Output() readonly keyUp = new EventEmitter<KeyboardEvent>();
|
@Output() readonly keyUp = new EventEmitter<KeyboardEvent>();
|
||||||
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper[]>();
|
||||||
@ViewChild('viewer', { static: true }) viewer: ElementRef;
|
@ViewChild('viewer', { static: true }) viewer: ElementRef;
|
||||||
@ViewChild('compareFileInput', { static: true }) compareFileInput: ElementRef;
|
@ViewChild('compareFileInput', { static: true }) compareFileInput: ElementRef;
|
||||||
instance: WebViewerInstance;
|
instance: WebViewerInstance;
|
||||||
|
|||||||
@ -9,7 +9,15 @@ import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
|||||||
import { BASE_HREF } from '../../../tokens';
|
import { BASE_HREF } from '../../../tokens';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { Core } from '@pdftron/webviewer';
|
import { Core } from '@pdftron/webviewer';
|
||||||
import { DictionaryEntryTypes, Dossier, IAddRedactionRequest, ILegalBasisChangeRequest, IRectangle, IResizeRequest } from '@red/domain';
|
import {
|
||||||
|
DictionaryEntryTypes,
|
||||||
|
Dossier,
|
||||||
|
IAddRedactionRequest,
|
||||||
|
ILegalBasisChangeRequest,
|
||||||
|
IRecategorizationRequest,
|
||||||
|
IRectangle,
|
||||||
|
IResizeRequest,
|
||||||
|
} from '@red/domain';
|
||||||
import { toPosition } from '../../dossier/utils/pdf-calculation.utils';
|
import { toPosition } from '../../dossier/utils/pdf-calculation.utils';
|
||||||
import { AnnotationDrawService } from './annotation-draw.service';
|
import { AnnotationDrawService } from './annotation-draw.service';
|
||||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||||
@ -18,7 +26,7 @@ import {
|
|||||||
AcceptRecommendationDialogComponent,
|
AcceptRecommendationDialogComponent,
|
||||||
AcceptRecommendationReturnType,
|
AcceptRecommendationReturnType,
|
||||||
} from '../dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component';
|
} from '../dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component';
|
||||||
import { defaultDialogConfig } from '@iqser/common-ui';
|
import { defaultDialogConfig, List } from '@iqser/common-ui';
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
@ -41,86 +49,85 @@ export class AnnotationActionsService {
|
|||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _annotationDrawService: AnnotationDrawService,
|
private readonly _annotationDrawService: AnnotationDrawService,
|
||||||
private readonly _activeDossiersService: ActiveDossiersService,
|
private readonly _activeDossiersService: ActiveDossiersService,
|
||||||
private readonly _screenStateService: FilePreviewStateService,
|
|
||||||
private readonly _dictionariesMapService: DictionariesMapService,
|
private readonly _dictionariesMapService: DictionariesMapService,
|
||||||
|
private readonly _state: FilePreviewStateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private get _dossier(): Dossier {
|
private get _dossier(): Dossier {
|
||||||
return this._activeDossiersService.find(this._screenStateService.dossierId);
|
return this._activeDossiersService.find(this._state.dossierId);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
$event?.stopPropagation();
|
$event?.stopPropagation();
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
annotations.forEach(annotation => {
|
this._processObsAndEmit(
|
||||||
this._processObsAndEmit(
|
this._manualRedactionService.approve(
|
||||||
this._manualRedactionService.approve(annotation.id, dossierId, fileId, annotation.isModifyDictionary),
|
annotations.map(a => a.id),
|
||||||
annotation,
|
dossierId,
|
||||||
annotationsChanged,
|
fileId,
|
||||||
);
|
),
|
||||||
});
|
annotations,
|
||||||
|
annotationsChanged,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
$event?.stopPropagation();
|
$event?.stopPropagation();
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
annotations.forEach(annotation => {
|
const modifyDictionary = annotations[0].isModifyDictionary;
|
||||||
this._processObsAndEmit(
|
this._processObsAndEmit(
|
||||||
this._manualRedactionService.declineOrRemoveRequest(annotation, dossierId, fileId),
|
this._manualRedactionService.declineOrRemoveRequest(
|
||||||
annotation,
|
annotations.map(a => a.id),
|
||||||
annotationsChanged,
|
dossierId,
|
||||||
);
|
fileId,
|
||||||
});
|
modifyDictionary,
|
||||||
|
),
|
||||||
|
annotations,
|
||||||
|
annotationsChanged,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceAnnotation(
|
forceAnnotation(
|
||||||
$event: MouseEvent,
|
$event: MouseEvent,
|
||||||
annotations: AnnotationWrapper[],
|
annotations: AnnotationWrapper[],
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged: EventEmitter<AnnotationWrapper[]>,
|
||||||
hint: boolean = false,
|
hint: boolean = false,
|
||||||
) {
|
) {
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
const data = { dossier: this._dossier, annotations, hint };
|
const data = { dossier: this._dossier, annotations, hint };
|
||||||
this._dialogService.openDialog('forceAnnotation', $event, data, (request: ILegalBasisChangeRequest) => {
|
this._dialogService.openDialog('forceAnnotation', $event, data, (request: ILegalBasisChangeRequest) => {
|
||||||
annotations.forEach(annotation => {
|
this._processObsAndEmit(
|
||||||
this._processObsAndEmit(
|
this._manualRedactionService.bulkForce(
|
||||||
this._manualRedactionService.force(
|
annotations.map(a => ({ ...request, annotationId: a.id })),
|
||||||
{
|
dossierId,
|
||||||
...request,
|
fileId,
|
||||||
annotationId: annotation.id,
|
),
|
||||||
},
|
annotations,
|
||||||
dossierId,
|
annotationsChanged,
|
||||||
fileId,
|
);
|
||||||
),
|
|
||||||
annotation,
|
|
||||||
annotationsChanged,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeLegalBasis($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
changeLegalBasis($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
this._dialogService.openDialog(
|
this._dialogService.openDialog(
|
||||||
'changeLegalBasis',
|
'changeLegalBasis',
|
||||||
$event,
|
$event,
|
||||||
{ annotations, dossier: this._dossier },
|
{ annotations, dossier: this._dossier },
|
||||||
(data: { comment: string; legalBasis: string; section: string; value: string }) => {
|
(data: { comment: string; legalBasis: string; section: string; value: string }) => {
|
||||||
annotations.forEach(annotation => {
|
const body = annotations.map(annotation => ({
|
||||||
this._processObsAndEmit(
|
annotationId: annotation.id,
|
||||||
this._manualRedactionService.changeLegalBasis(
|
comment: data.comment,
|
||||||
annotation.annotationId,
|
legalBasis: data.legalBasis,
|
||||||
dossierId,
|
section: data.section,
|
||||||
fileId,
|
value: data.value,
|
||||||
data.section,
|
}));
|
||||||
data.value,
|
|
||||||
data.legalBasis,
|
this._processObsAndEmit(
|
||||||
data.comment,
|
this._manualRedactionService.changeLegalBasis(body, dossierId, fileId),
|
||||||
),
|
annotations,
|
||||||
annotation,
|
annotationsChanged,
|
||||||
annotationsChanged,
|
);
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -129,7 +136,7 @@ export class AnnotationActionsService {
|
|||||||
$event: MouseEvent,
|
$event: MouseEvent,
|
||||||
annotations: AnnotationWrapper[],
|
annotations: AnnotationWrapper[],
|
||||||
removeFromDictionary: boolean,
|
removeFromDictionary: boolean,
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged: EventEmitter<AnnotationWrapper[]>,
|
||||||
) {
|
) {
|
||||||
const data = {
|
const data = {
|
||||||
annotationsToRemove: annotations,
|
annotationsToRemove: annotations,
|
||||||
@ -137,65 +144,63 @@ export class AnnotationActionsService {
|
|||||||
dossier: this._dossier,
|
dossier: this._dossier,
|
||||||
hint: annotations[0].hintDictionary,
|
hint: annotations[0].hintDictionary,
|
||||||
};
|
};
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
this._dialogService.openDialog('removeAnnotations', $event, data, (result: { comment: string }) => {
|
this._dialogService.openDialog('removeAnnotations', $event, data, (result: { comment: string }) => {
|
||||||
annotations.forEach(annotation => {
|
const body = annotations.map(annotation => ({
|
||||||
this._processObsAndEmit(
|
annotationId: annotation.id,
|
||||||
this._manualRedactionService.removeOrSuggestRemoveAnnotation(
|
removeFromDictionary,
|
||||||
annotation,
|
comment: result.comment,
|
||||||
dossierId,
|
}));
|
||||||
fileId,
|
|
||||||
result.comment,
|
|
||||||
removeFromDictionary,
|
|
||||||
),
|
|
||||||
annotation,
|
|
||||||
annotationsChanged,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
markAsFalsePositive($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
|
||||||
annotations.forEach(annotation => {
|
|
||||||
this._markAsFalsePositive($event, annotation, this._getFalsePositiveText(annotation), annotationsChanged);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
recategorizeImages($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
|
||||||
const data = { annotations, dossier: this._dossier };
|
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
|
||||||
this._dialogService.openDialog('recategorizeImage', $event, data, (res: { type: string; comment: string }) => {
|
|
||||||
annotations.forEach(annotation => {
|
|
||||||
this._processObsAndEmit(
|
|
||||||
this._manualRedactionService.recategorizeImg(annotation.annotationId, dossierId, fileId, res.type, res.comment),
|
|
||||||
annotation,
|
|
||||||
annotationsChanged,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
undoDirectAction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
|
||||||
$event?.stopPropagation();
|
|
||||||
|
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
|
||||||
annotations.forEach(annotation => {
|
|
||||||
this._processObsAndEmit(
|
this._processObsAndEmit(
|
||||||
this._manualRedactionService.undoRequest(annotation, dossierId, fileId),
|
this._manualRedactionService.removeOrSuggestRemoveAnnotation(body, dossierId, fileId, removeFromDictionary),
|
||||||
annotation,
|
annotations,
|
||||||
annotationsChanged,
|
annotationsChanged,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recategorizeImages($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
|
const data = { annotations, dossier: this._dossier };
|
||||||
|
const { dossierId, fileId } = this._state;
|
||||||
|
this._dialogService.openDialog('recategorizeImage', $event, data, ({ comment, type }: { type: string; comment: string }) => {
|
||||||
|
const body: List<IRecategorizationRequest> = annotations.map(({ annotationId }) => ({
|
||||||
|
annotationId,
|
||||||
|
type,
|
||||||
|
comment,
|
||||||
|
}));
|
||||||
|
this._processObsAndEmit(
|
||||||
|
this._manualRedactionService.recategorizeImage(body, dossierId, fileId),
|
||||||
|
annotations,
|
||||||
|
annotationsChanged,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
undoDirectAction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
|
$event?.stopPropagation();
|
||||||
|
|
||||||
|
const { dossierId, fileId } = this._state;
|
||||||
|
const modifyDictionary = annotations[0].isModifyDictionary;
|
||||||
|
this._processObsAndEmit(
|
||||||
|
this._manualRedactionService.undoRequest(
|
||||||
|
annotations.map(a => a.id),
|
||||||
|
dossierId,
|
||||||
|
fileId,
|
||||||
|
modifyDictionary,
|
||||||
|
),
|
||||||
|
annotations,
|
||||||
|
annotationsChanged,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
convertRecommendationToAnnotation(
|
convertRecommendationToAnnotation(
|
||||||
$event: any,
|
$event: any,
|
||||||
recommendations: AnnotationWrapper[],
|
recommendations: AnnotationWrapper[],
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged: EventEmitter<AnnotationWrapper[]>,
|
||||||
) {
|
) {
|
||||||
$event?.stopPropagation();
|
$event?.stopPropagation();
|
||||||
|
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
const { dossierId, fileId } = this._state;
|
||||||
const dialogRef = this._dialog.open<AcceptRecommendationDialogComponent, AcceptRecommendationData, AcceptRecommendationReturnType>(
|
const dialogRef = this._dialog.open<AcceptRecommendationDialogComponent, AcceptRecommendationData, AcceptRecommendationReturnType>(
|
||||||
AcceptRecommendationDialogComponent,
|
AcceptRecommendationDialogComponent,
|
||||||
{ ...defaultDialogConfig, autoFocus: true, data: { annotations: recommendations, dossierId } },
|
{ ...defaultDialogConfig, autoFocus: true, data: { annotations: recommendations, dossierId } },
|
||||||
@ -203,20 +208,18 @@ export class AnnotationActionsService {
|
|||||||
const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations));
|
const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations));
|
||||||
dialogClosed.subscribe(({ annotations, comment: commentText }) => {
|
dialogClosed.subscribe(({ annotations, comment: commentText }) => {
|
||||||
const comment = commentText ? { text: commentText } : undefined;
|
const comment = commentText ? { text: commentText } : undefined;
|
||||||
annotations.forEach(annotation => {
|
this._processObsAndEmit(
|
||||||
this._processObsAndEmit(
|
this._manualRedactionService.addRecommendation(annotations, dossierId, fileId, comment),
|
||||||
this._manualRedactionService.addRecommendation(annotation, dossierId, fileId, comment),
|
annotations,
|
||||||
annotation,
|
annotationsChanged,
|
||||||
annotationsChanged,
|
);
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewerAvailableActions(
|
getViewerAvailableActions(
|
||||||
dossier: Dossier,
|
dossier: Dossier,
|
||||||
annotations: AnnotationWrapper[],
|
annotations: AnnotationWrapper[],
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged: EventEmitter<AnnotationWrapper[]>,
|
||||||
): Record<string, unknown>[] {
|
): Record<string, unknown>[] {
|
||||||
const availableActions = [];
|
const availableActions = [];
|
||||||
const annotationPermissions = annotations.map(annotation => ({
|
const annotationPermissions = annotations.map(annotation => ({
|
||||||
@ -428,9 +431,9 @@ export class AnnotationActionsService {
|
|||||||
this._annotationDrawService.annotationToQuads(viewerAnnotation);
|
this._annotationDrawService.annotationToQuads(viewerAnnotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged?: EventEmitter<AnnotationWrapper>) {
|
acceptResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged?: EventEmitter<AnnotationWrapper[]>) {
|
||||||
const data = { dossier: this._dossier };
|
const data = { dossier: this._dossier };
|
||||||
const fileId = this._screenStateService.fileId;
|
const fileId = this._state.fileId;
|
||||||
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
|
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
|
||||||
const textAndPositions = await this._extractTextAndPositions(annotationWrapper.id);
|
const textAndPositions = await this._extractTextAndPositions(annotationWrapper.id);
|
||||||
const text =
|
const text =
|
||||||
@ -444,14 +447,14 @@ export class AnnotationActionsService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._processObsAndEmit(
|
this._processObsAndEmit(
|
||||||
this._manualRedactionService.resizeOrSuggestToResize(annotationWrapper, data.dossier.dossierId, fileId, resizeRequest),
|
this._manualRedactionService.resizeOrSuggestToResize([resizeRequest], data.dossier.dossierId, fileId),
|
||||||
annotationWrapper,
|
[annotationWrapper],
|
||||||
annotationsChanged,
|
annotationsChanged,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async cancelResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
async cancelResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
$event?.stopPropagation();
|
$event?.stopPropagation();
|
||||||
|
|
||||||
annotationWrapper.resizing = false;
|
annotationWrapper.resizing = false;
|
||||||
@ -461,17 +464,36 @@ export class AnnotationActionsService {
|
|||||||
this._pdf.deleteAnnotations([viewerAnnotation.Id]);
|
this._pdf.deleteAnnotations([viewerAnnotation.Id]);
|
||||||
await this._annotationDrawService.drawAnnotations([annotationWrapper]);
|
await this._annotationDrawService.drawAnnotations([annotationWrapper]);
|
||||||
this._pdf.annotationManager.deselectAllAnnotations();
|
this._pdf.annotationManager.deselectAllAnnotations();
|
||||||
annotationsChanged.emit(annotationWrapper);
|
annotationsChanged.emit([annotationWrapper]);
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsFalsePositive($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper[]>) {
|
||||||
|
$event?.stopPropagation();
|
||||||
|
|
||||||
|
const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||||
|
reason: annotation.id,
|
||||||
|
value: this._getFalsePositiveText(annotation),
|
||||||
|
type: annotation.type,
|
||||||
|
positions: annotation.positions,
|
||||||
|
addToDictionary: true,
|
||||||
|
comment: { text: 'False Positive' },
|
||||||
|
dictionaryEntryType: annotation.isRecommendation
|
||||||
|
? DictionaryEntryTypes.FALSE_RECOMMENDATION
|
||||||
|
: DictionaryEntryTypes.FALSE_POSITIVE,
|
||||||
|
}));
|
||||||
|
const { dossierId, fileId } = this._state;
|
||||||
|
|
||||||
|
this._processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId), annotations, annotationsChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processObsAndEmit(
|
private _processObsAndEmit(
|
||||||
obs: Observable<unknown>,
|
obs: Observable<unknown>,
|
||||||
annotation: AnnotationWrapper,
|
annotations: AnnotationWrapper[],
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
annotationsChanged: EventEmitter<AnnotationWrapper[]>,
|
||||||
) {
|
) {
|
||||||
obs.subscribe({
|
obs.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
annotationsChanged.emit(annotation);
|
annotationsChanged.emit(annotations);
|
||||||
},
|
},
|
||||||
error: () => {
|
error: () => {
|
||||||
annotationsChanged.emit();
|
annotationsChanged.emit();
|
||||||
@ -495,34 +517,6 @@ export class AnnotationActionsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _markAsFalsePositive(
|
|
||||||
$event: MouseEvent,
|
|
||||||
annotation: AnnotationWrapper,
|
|
||||||
text: string,
|
|
||||||
annotationsChanged: EventEmitter<AnnotationWrapper>,
|
|
||||||
) {
|
|
||||||
$event?.stopPropagation();
|
|
||||||
|
|
||||||
const falsePositiveRequest: IAddRedactionRequest = {
|
|
||||||
reason: annotation.id,
|
|
||||||
value: text,
|
|
||||||
type: annotation.type,
|
|
||||||
positions: annotation.positions,
|
|
||||||
addToDictionary: true,
|
|
||||||
comment: { text: 'False Positive' },
|
|
||||||
dictionaryEntryType: annotation.isRecommendation
|
|
||||||
? DictionaryEntryTypes.FALSE_RECOMMENDATION
|
|
||||||
: DictionaryEntryTypes.FALSE_POSITIVE,
|
|
||||||
};
|
|
||||||
const { dossierId, fileId } = this._screenStateService;
|
|
||||||
|
|
||||||
this._processObsAndEmit(
|
|
||||||
this._manualRedactionService.addAnnotation(falsePositiveRequest, dossierId, fileId),
|
|
||||||
annotation,
|
|
||||||
annotationsChanged,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _convertPath(path: string): string {
|
private _convertPath(path: string): string {
|
||||||
return this._baseHref + path;
|
return this._baseHref + path;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,44 +1,32 @@
|
|||||||
import { Injectable, Injector } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import type {
|
import type {
|
||||||
AnnotationActionMode,
|
|
||||||
DictionaryActions,
|
DictionaryActions,
|
||||||
Dossier,
|
Dossier,
|
||||||
IAddRedactionRequest,
|
IAddRedactionRequest,
|
||||||
IApproveRequest,
|
|
||||||
IImageRecategorizationRequest,
|
|
||||||
ILegalBasisChangeRequest,
|
ILegalBasisChangeRequest,
|
||||||
IManualAddResponse,
|
IManualAddResponse,
|
||||||
|
IRecategorizationRequest,
|
||||||
IRemoveRedactionRequest,
|
IRemoveRedactionRequest,
|
||||||
IResizeRequest,
|
IResizeRequest,
|
||||||
ManualRedactionActions,
|
ManualRedactionActions,
|
||||||
} from '@red/domain';
|
} from '@red/domain';
|
||||||
import { type AnnotationWrapper } from '../../../models/file/annotation.wrapper';
|
import { type AnnotationWrapper } from '../../../models/file/annotation.wrapper';
|
||||||
import { GenericService, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
import { GenericService, List, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||||
import { map, tap } from 'rxjs/operators';
|
import { map, tap } from 'rxjs/operators';
|
||||||
import { PermissionsService } from '../../../services/permissions.service';
|
import { PermissionsService } from '../../../services/permissions.service';
|
||||||
import {
|
import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '../../../translations/annotation-actions-translations';
|
||||||
annotationActionsTranslations,
|
|
||||||
dictionaryActionsTranslations,
|
|
||||||
manualRedactionActionsTranslations,
|
|
||||||
} from '../../../translations/annotation-actions-translations';
|
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
||||||
import { ActiveDossiersService } from '../../../services/dossiers/active-dossiers.service';
|
import { ActiveDossiersService } from '../../../services/dossiers/active-dossiers.service';
|
||||||
import { type Observable } from 'rxjs';
|
|
||||||
import { DictionariesMapService } from '../../../services/entity-services/dictionaries-map.service';
|
import { DictionariesMapService } from '../../../services/entity-services/dictionaries-map.service';
|
||||||
import { type ManualRedactionEntryType } from '../../../models/file/manual-redaction-entry.wrapper';
|
import { type ManualRedactionEntryType } from '../../../models/file/manual-redaction-entry.wrapper';
|
||||||
|
import { NGXLogger } from 'ngx-logger';
|
||||||
function getMessage(mode: AnnotationActionMode, modifyDictionary?: boolean, error = false, isConflict = false) {
|
|
||||||
const type = modifyDictionary ? 'dictionary' : 'manual-redaction';
|
|
||||||
const resultType = error ? (isConflict ? 'conflictError' : 'error') : 'success';
|
|
||||||
return annotationActionsTranslations[type][mode][resultType];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getResponseType(error: boolean, isConflict: boolean) {
|
function getResponseType(error: boolean, isConflict: boolean) {
|
||||||
return error ? (isConflict ? 'conflictError' : 'error') : 'success';
|
return error ? (isConflict ? 'conflictError' : 'error') : 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDictionaryMessage(action: DictionaryActions, error = false, isConflict = false) {
|
function getDictionaryMessage(action: DictionaryActions, error = false, isConflict = false): string {
|
||||||
return dictionaryActionsTranslations[action][getResponseType(error, isConflict)];
|
return dictionaryActionsTranslations[action][getResponseType(error, isConflict)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,70 +36,18 @@ function getManualRedactionMessage(action: ManualRedactionActions, error = false
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||||
readonly request = `${this._defaultModelPath}/request`;
|
readonly bulkRequest = `${this._defaultModelPath}/bulk/request`;
|
||||||
readonly redaction = `${this._defaultModelPath}/redaction`;
|
readonly bulkRedaction = `${this._defaultModelPath}/bulk/redaction`;
|
||||||
CONFIG: {
|
|
||||||
[key in AnnotationActionMode]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _dictionariesMapService: DictionariesMapService,
|
private readonly _dictionariesMapService: DictionariesMapService,
|
||||||
private readonly _toaster: Toaster,
|
private readonly _toaster: Toaster,
|
||||||
|
private readonly _logger: NGXLogger,
|
||||||
private readonly _permissionsService: PermissionsService,
|
private readonly _permissionsService: PermissionsService,
|
||||||
private readonly _activeDossiersService: ActiveDossiersService,
|
private readonly _activeDossiersService: ActiveDossiersService,
|
||||||
protected readonly _injector: Injector,
|
protected readonly _injector: Injector,
|
||||||
) {
|
) {
|
||||||
super(_injector, 'manualRedaction');
|
super(_injector, 'manualRedaction');
|
||||||
this.CONFIG = {
|
|
||||||
add: 'addRedaction',
|
|
||||||
'recategorize-image': 'recategorizeImage',
|
|
||||||
'request-image-recategorization': 'requestImageRecategorization',
|
|
||||||
'change-legal-basis': 'legalBasisChange',
|
|
||||||
'request-change-legal-basis': 'requestLegalBasisChange',
|
|
||||||
'request-remove': 'requestRemoveRedaction',
|
|
||||||
approve: 'approveRequest',
|
|
||||||
decline: 'declineRequest',
|
|
||||||
undo: 'undo',
|
|
||||||
remove: 'removeRedaction',
|
|
||||||
suggest: 'requestAddRedaction',
|
|
||||||
'force-redaction': 'forceRedaction',
|
|
||||||
'request-force-redaction': 'requestForceRedaction',
|
|
||||||
resize: 'resize',
|
|
||||||
'request-resize': 'requestResize',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_makeRequest(
|
|
||||||
mode: AnnotationActionMode,
|
|
||||||
dossierId: string,
|
|
||||||
fileId: string,
|
|
||||||
body: any,
|
|
||||||
secondParam: any = null,
|
|
||||||
modifyDictionary = false,
|
|
||||||
): Observable<unknown> {
|
|
||||||
const obs = !secondParam
|
|
||||||
? this[this.CONFIG[mode]](body, dossierId, fileId)
|
|
||||||
: this[this.CONFIG[mode]](body, secondParam, dossierId, fileId);
|
|
||||||
|
|
||||||
return obs.pipe(
|
|
||||||
tap({
|
|
||||||
next: () => this._toaster.success(getMessage(mode, modifyDictionary), { positionClass: 'toast-file-preview' }),
|
|
||||||
error: (error: HttpErrorResponse) => {
|
|
||||||
const isConflict = error.status === HttpStatusCode.Conflict;
|
|
||||||
this._toaster.error(getMessage(mode, modifyDictionary, true, isConflict), {
|
|
||||||
error,
|
|
||||||
params: {
|
|
||||||
dictionaryName: this._dictionariesMapService.getDictionary(
|
|
||||||
body.type as string,
|
|
||||||
this.#dossier(dossierId).dossierTemplateId,
|
|
||||||
).label,
|
|
||||||
content: body.value,
|
|
||||||
},
|
|
||||||
positionClass: 'toast-file-preview',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
@ -126,124 +62,93 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
|||||||
return super.delete({}, url);
|
return super.delete({}, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
addRecommendation(annotation: AnnotationWrapper, dossierId: string, fileId: string, comment = { text: 'Accepted Recommendation' }) {
|
addRecommendation(annotations: AnnotationWrapper[], dossierId: string, fileId: string, comment = { text: 'Accepted Recommendation' }) {
|
||||||
const manualRedactionEntry: IAddRedactionRequest = {
|
const recommendations = annotations.map(
|
||||||
addToDictionary: true,
|
annotation =>
|
||||||
// set the ID as reason, so we can hide the suggestion
|
({
|
||||||
reason: annotation.annotationId,
|
addToDictionary: true,
|
||||||
value: annotation.value,
|
// set the ID as reason, so we can hide the suggestion
|
||||||
positions: annotation.positions,
|
reason: annotation.annotationId,
|
||||||
type: annotation.recommendationType,
|
value: annotation.value,
|
||||||
comment: comment,
|
positions: annotation.positions,
|
||||||
};
|
type: annotation.recommendationType,
|
||||||
return this.addAnnotation(manualRedactionEntry, dossierId, fileId);
|
comment: comment,
|
||||||
}
|
} as IAddRedactionRequest),
|
||||||
|
|
||||||
changeLegalBasis(
|
|
||||||
annotationId: string,
|
|
||||||
dossierId: string,
|
|
||||||
fileId: string,
|
|
||||||
section: string,
|
|
||||||
value: string,
|
|
||||||
legalBasis: string,
|
|
||||||
comment?: string,
|
|
||||||
) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId))
|
|
||||||
? 'change-legal-basis'
|
|
||||||
: 'request-change-legal-basis';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, { annotationId, legalBasis, comment, section, value });
|
|
||||||
}
|
|
||||||
|
|
||||||
recategorizeImg(annotationId: string, dossierId: string, fileId: string, type: string, comment: string) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId))
|
|
||||||
? 'recategorize-image'
|
|
||||||
: 'request-image-recategorization';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, { annotationId, type, comment });
|
|
||||||
}
|
|
||||||
|
|
||||||
addAnnotation(manualRedactionEntry: IAddRedactionRequest, dossierId: string, fileId: string) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId)) ? 'add' : 'suggest';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, manualRedactionEntry, null, manualRedactionEntry.addToDictionary);
|
|
||||||
}
|
|
||||||
|
|
||||||
force(request: ILegalBasisChangeRequest, dossierId: string, fileId: string) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId))
|
|
||||||
? 'force-redaction'
|
|
||||||
: 'request-force-redaction';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
_force(request: ILegalBasisChangeRequest, dossierId: string, fileId: string) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId))
|
|
||||||
? 'force-redaction'
|
|
||||||
: 'request-force-redaction';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
_requestForce(request: ILegalBasisChangeRequest, dossierId: string, fileId: string) {
|
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId))
|
|
||||||
? 'force-redaction'
|
|
||||||
: 'request-force-redaction';
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
approve(annotationId: string, dossierId: string, fileId: string, addToDictionary: boolean = false) {
|
|
||||||
// for only here - approve the request
|
|
||||||
return this._makeRequest(
|
|
||||||
'approve',
|
|
||||||
dossierId,
|
|
||||||
fileId,
|
|
||||||
{ addOrRemoveFromDictionary: addToDictionary },
|
|
||||||
annotationId,
|
|
||||||
addToDictionary,
|
|
||||||
);
|
);
|
||||||
|
return this.addAnnotation(recommendations, dossierId, fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
undoRequest(annotationWrapper: AnnotationWrapper, dossierId: string, fileId: string) {
|
changeLegalBasis(body: List<ILegalBasisChangeRequest>, dossierId: string, fileId: string) {
|
||||||
return this._makeRequest('undo', dossierId, fileId, annotationWrapper.id, null, annotationWrapper.isModifyDictionary);
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
|
return this.bulkLegalBasisChange(body, dossierId, fileId).pipe(this.#showToast('change-legal-basis'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkRequestLegalBasisChange(body, dossierId, fileId).pipe(this.#showToast('request-change-legal-basis'));
|
||||||
}
|
}
|
||||||
|
|
||||||
declineOrRemoveRequest(annotationWrapper: AnnotationWrapper, dossierId: string, fileId: string) {
|
recategorizeImage(body: List<IRecategorizationRequest>, dossierId: string, fileId: string) {
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId)) ? 'decline' : 'undo';
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
return this._makeRequest(mode, dossierId, fileId, annotationWrapper.id, null, annotationWrapper.isModifyDictionary);
|
return this.recategorize(body, dossierId, fileId).pipe(this.#showToast('recategorize-image'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkRequestImageRecategorization(body, dossierId, fileId).pipe(this.#showToast('request-image-recategorization'));
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeOrSuggestToResize(annotationWrapper: AnnotationWrapper, dossierId: string, fileId: string, resizeRequest: IResizeRequest) {
|
addAnnotation(requests: List<IAddRedactionRequest>, dossierId: string, fileId: string) {
|
||||||
const mode: AnnotationActionMode = this._permissionsService.isApprover(this.#dossier(dossierId)) ? 'resize' : 'request-resize';
|
const toast = requests[0].addToDictionary ? this.#showAddToDictionaryToast(requests, dossierId) : this.#showToast('add');
|
||||||
return this._makeRequest(mode, dossierId, fileId, resizeRequest);
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
|
return this.add(requests, dossierId, fileId).pipe(toast);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkRequestAddRedaction(requests, dossierId, fileId).pipe(toast);
|
||||||
|
}
|
||||||
|
|
||||||
|
bulkForce(requests: List<ILegalBasisChangeRequest>, dossierId: string, fileId: string) {
|
||||||
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
|
return this.bulkForceRedaction(requests, dossierId, fileId).pipe(this.#showToast('force-redaction'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkForceRequest(requests, dossierId, fileId).pipe(this.#showToast('request-force-redaction'));
|
||||||
|
}
|
||||||
|
|
||||||
|
approve(annotationIds: List, dossierId: string, fileId: string) {
|
||||||
|
return this.bulkApprove(annotationIds, dossierId, fileId).pipe(this.#showToast('approve'));
|
||||||
|
}
|
||||||
|
|
||||||
|
undoRequest(annotationIds: List, dossierId: string, fileId: string, modifyDictionary = false) {
|
||||||
|
const toast = modifyDictionary ? this.#showDictionaryToast : this.#showToast;
|
||||||
|
return this.bulkUndo(annotationIds, dossierId, fileId).pipe(toast('undo'));
|
||||||
|
}
|
||||||
|
|
||||||
|
declineOrRemoveRequest(annotationIds: List, dossierId: string, fileId: string, modifyDictionary = false) {
|
||||||
|
const toast = modifyDictionary ? this.#showDictionaryToast : this.#showToast;
|
||||||
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
|
return this.bulkDecline(annotationIds, dossierId, fileId).pipe(toast('decline'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkUndo(annotationIds, dossierId, fileId).pipe(toast('undo'));
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeOrSuggestToResize(requests: List<IResizeRequest>, dossierId: string, fileId: string) {
|
||||||
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
|
return this.bulkResize(requests, dossierId, fileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bulkRequestResize(requests, dossierId, fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeOrSuggestRemoveAnnotation(
|
removeOrSuggestRemoveAnnotation(
|
||||||
annotationWrapper: AnnotationWrapper,
|
body: List<IRemoveRedactionRequest>,
|
||||||
dossierId: string,
|
dossierId: string,
|
||||||
fileId: string,
|
fileId: string,
|
||||||
comment: string,
|
|
||||||
removeFromDictionary: boolean = false,
|
removeFromDictionary: boolean = false,
|
||||||
) {
|
) {
|
||||||
let mode: AnnotationActionMode,
|
const toast = removeFromDictionary ? this.#showDictionaryToast : this.#showToast;
|
||||||
body: any,
|
|
||||||
removeDict = false;
|
|
||||||
|
|
||||||
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||||
// if it was something manual simply decline the existing request
|
return this.bulkRemoveRedaction(body, dossierId, fileId).pipe(toast('remove'));
|
||||||
mode = 'remove';
|
|
||||||
body = {
|
|
||||||
annotationId: annotationWrapper.id,
|
|
||||||
removeFromDictionary,
|
|
||||||
comment: comment,
|
|
||||||
};
|
|
||||||
removeDict = removeFromDictionary;
|
|
||||||
} else {
|
|
||||||
mode = 'request-remove';
|
|
||||||
body = {
|
|
||||||
annotationId: annotationWrapper.id,
|
|
||||||
removeFromDictionary,
|
|
||||||
comment: comment,
|
|
||||||
};
|
|
||||||
removeDict = removeFromDictionary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._makeRequest(mode, dossierId, fileId, body, null, removeDict);
|
return this.bulkRequestRemoveRedaction(body, dossierId, fileId).pipe(toast('request-remove'));
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle(type: ManualRedactionEntryType, dossier: Dossier) {
|
getTitle(type: ManualRedactionEntryType, dossier: Dossier) {
|
||||||
@ -269,127 +174,162 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
addRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
add(@RequiredParam() body: List<IAddRedactionRequest>, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
const url = `${this.redaction}/add/${dossierId}/${fileId}`;
|
return this._post(body, `${this.bulkRedaction}/add/${dossierId}/${fileId}`).pipe(
|
||||||
return this._post(body, url);
|
tap(response => {
|
||||||
|
this._logger.info('[MANUAL-REDACTIONS] Add ', body, response);
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
recategorizeImage(
|
recategorize(
|
||||||
@RequiredParam() body: IImageRecategorizationRequest,
|
@RequiredParam() body: List<IRecategorizationRequest>,
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
const url = `${this.redaction}/recategorize/${dossierId}/${fileId}`;
|
return this._post(body, `${this.bulkRedaction}/recategorize/${dossierId}/${fileId}`);
|
||||||
return this._post(body, url);
|
// .pipe(
|
||||||
|
// tap(response => {
|
||||||
|
// this._logger.info('[MANUAL-REDACTIONS] Recategorize', body, response);
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
requestImageRecategorization(
|
bulkRequestImageRecategorization(
|
||||||
@RequiredParam() body: IImageRecategorizationRequest,
|
@RequiredParam() body: List<IRecategorizationRequest>,
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
const url = `${this.request}/recategorize/${dossierId}/${fileId}`;
|
return this._post(body, `${this.bulkRequest}/recategorize/${dossierId}/${fileId}`);
|
||||||
return this._post(body, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
legalBasisChange(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkLegalBasisChange(
|
||||||
const url = `${this.redaction}/legalBasisChange/${dossierId}/${fileId}`;
|
@RequiredParam() body: List<ILegalBasisChangeRequest>,
|
||||||
return this._post(body, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Validate()
|
|
||||||
requestLegalBasisChange(
|
|
||||||
@RequiredParam() body: ILegalBasisChangeRequest,
|
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
const url = `${this.request}/legalBasis/${dossierId}/${fileId}`;
|
return this._post(body, `${this.bulkRedaction}/legalBasisChange/${dossierId}/${fileId}`);
|
||||||
return this._post(body, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
requestRemoveRedaction(
|
bulkRequestLegalBasisChange(
|
||||||
@RequiredParam() body: IRemoveRedactionRequest,
|
@RequiredParam() body: List<ILegalBasisChangeRequest>,
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
const url = `${this.request}/remove/${dossierId}/${fileId}`;
|
return this._post(body, `${this.bulkRequest}/legalBasis/${dossierId}/${fileId}`);
|
||||||
return this._post(body, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
approveRequest(
|
bulkRequestRemoveRedaction(
|
||||||
@RequiredParam() body: IApproveRequest,
|
@RequiredParam() body: List<IRemoveRedactionRequest>,
|
||||||
@RequiredParam() annotationId: string,
|
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
const url = `${this._defaultModelPath}/approve/${dossierId}/${fileId}/${annotationId}`;
|
return this._post(body, `${this.bulkRequest}/remove/${dossierId}/${fileId}`);
|
||||||
return this._post<unknown>(body, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
declineRequest(@RequiredParam() annotationId: string, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkApprove(@RequiredParam() annotationIds: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
const url = `${this._defaultModelPath}/decline/${dossierId}/${fileId}/${annotationId}`;
|
return this._post(annotationIds, `${this._defaultModelPath}/bulk/approve/${dossierId}/${fileId}`);
|
||||||
return this._post<unknown>({}, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
undo(@RequiredParam() annotationId: string, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkDecline(@RequiredParam() annotationIds: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
const url = `${this._defaultModelPath}/undo/${dossierId}/${fileId}/${annotationId}`;
|
return this._post(annotationIds, `${this._defaultModelPath}/bulk/decline/${dossierId}/${fileId}`);
|
||||||
return super.delete({}, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
removeRedaction(@RequiredParam() body: IRemoveRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkUndo(@RequiredParam() annotationIds: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
return this._post(body, `${this.redaction}/remove/${dossierId}/${fileId}`);
|
return super.delete(annotationIds, `${this._defaultModelPath}/bulk/undo/${dossierId}/${fileId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
requestAddRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkRemoveRedaction(
|
||||||
return this._post(body, `${this.request}/add/${dossierId}/${fileId}`);
|
@RequiredParam() body: List<IRemoveRedactionRequest>,
|
||||||
}
|
|
||||||
|
|
||||||
@Validate()
|
|
||||||
forceRedaction(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
|
||||||
return this._post(body, `${this.redaction}/force/${dossierId}/${fileId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Validate()
|
|
||||||
requestForceRedaction(
|
|
||||||
@RequiredParam() body: ILegalBasisChangeRequest,
|
|
||||||
@RequiredParam() dossierId: string,
|
@RequiredParam() dossierId: string,
|
||||||
@RequiredParam() fileId: string,
|
@RequiredParam() fileId: string,
|
||||||
) {
|
) {
|
||||||
return this._post(body, `${this.request}/force/${dossierId}/${fileId}`);
|
return this._post(body, `${this.bulkRedaction}/remove/${dossierId}/${fileId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
resize(@RequiredParam() body: IResizeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkRequestAddRedaction(
|
||||||
return this._post(body, `${this.redaction}/resize/${dossierId}/${fileId}`);
|
@RequiredParam() body: List<IAddRedactionRequest>,
|
||||||
|
@RequiredParam() dossierId: string,
|
||||||
|
@RequiredParam() fileId: string,
|
||||||
|
) {
|
||||||
|
return this._post(body, `${this.bulkRequest}/add/${dossierId}/${fileId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
requestResize(@RequiredParam() body: IResizeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
bulkForceRedaction(
|
||||||
return this._post(body, `${this.request}/resize/${dossierId}/${fileId}`);
|
@RequiredParam() body: List<ILegalBasisChangeRequest>,
|
||||||
|
@RequiredParam() dossierId: string,
|
||||||
|
@RequiredParam() fileId: string,
|
||||||
|
) {
|
||||||
|
return this._post(body, `${this.bulkRedaction}/force/${dossierId}/${fileId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
#showToast(mode: AnnotationActionMode, body, dossierId: string, modifyDictionary = false) {
|
@Validate()
|
||||||
|
bulkForceRequest(
|
||||||
|
@RequiredParam() body: List<ILegalBasisChangeRequest>,
|
||||||
|
@RequiredParam() dossierId: string,
|
||||||
|
@RequiredParam() fileId: string,
|
||||||
|
) {
|
||||||
|
return this._post(body, `${this.bulkRequest}/force/${dossierId}/${fileId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validate()
|
||||||
|
bulkResize(@RequiredParam() body: List<IResizeRequest>, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
|
return this._post(body, `${this.bulkRedaction}/resize/${dossierId}/${fileId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validate()
|
||||||
|
bulkRequestResize(@RequiredParam() body: List<IResizeRequest>, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||||
|
return this._post(body, `${this.bulkRequest}/resize/${dossierId}/${fileId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
#showToast(action: ManualRedactionActions) {
|
||||||
return tap({
|
return tap({
|
||||||
next: () => this._toaster.success(getMessage(mode, modifyDictionary), { positionClass: 'toast-file-preview' }),
|
next: () => this._toaster.success(getManualRedactionMessage(action), { positionClass: 'toast-file-preview' }),
|
||||||
error: (error: HttpErrorResponse) => {
|
error: (error: HttpErrorResponse) => {
|
||||||
const isConflict = error.status === HttpStatusCode.Conflict;
|
const isConflict = error.status === HttpStatusCode.Conflict;
|
||||||
this._toaster.error(getMessage(mode, modifyDictionary, true, isConflict), {
|
this._toaster.error(getManualRedactionMessage(action, true, isConflict), {
|
||||||
|
error,
|
||||||
|
positionClass: 'toast-file-preview',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#showDictionaryToast(action: DictionaryActions) {
|
||||||
|
return tap({
|
||||||
|
next: () => this._toaster.success(getDictionaryMessage(action), { positionClass: 'toast-file-preview' }),
|
||||||
|
error: (error: HttpErrorResponse) => {
|
||||||
|
const isConflict = error.status === HttpStatusCode.Conflict;
|
||||||
|
this._toaster.error(getDictionaryMessage(action, true, isConflict), {
|
||||||
|
error,
|
||||||
|
positionClass: 'toast-file-preview',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#showAddToDictionaryToast(body: List<IAddRedactionRequest>, dossierId: string) {
|
||||||
|
return tap({
|
||||||
|
next: () => this._toaster.success(getDictionaryMessage('add'), { positionClass: 'toast-file-preview' }),
|
||||||
|
error: (error: HttpErrorResponse) => {
|
||||||
|
const isConflict = error.status === HttpStatusCode.Conflict;
|
||||||
|
this._toaster.error(getDictionaryMessage('add', true, isConflict), {
|
||||||
error,
|
error,
|
||||||
params: {
|
params: {
|
||||||
dictionaryName: this._dictionariesMapService.getDictionary(
|
dictionaryName: this._dictionariesMapService.getDictionary(body[0].type, this.#dossier(dossierId).dossierTemplateId)
|
||||||
body.type as string,
|
.label,
|
||||||
this.#dossier(dossierId).dossierTemplateId,
|
content: body[0].value,
|
||||||
).label,
|
|
||||||
content: body.value,
|
|
||||||
},
|
},
|
||||||
positionClass: 'toast-file-preview',
|
positionClass: 'toast-file-preview',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { AnnotationActionMode, DictionaryActions, ManualRedactionActions } from '@red/domain';
|
import { DictionaryActions, ManualRedactionActions } from '@red/domain';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
|
|
||||||
interface AnnotationActionResponses {
|
interface AnnotationActionResponses {
|
||||||
@ -7,99 +7,6 @@ interface AnnotationActionResponses {
|
|||||||
conflictError?: string;
|
conflictError?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionType = { [key in AnnotationActionMode]?: AnnotationActionResponses };
|
|
||||||
|
|
||||||
export const annotationActionsTranslations: {
|
|
||||||
dictionary: ActionType;
|
|
||||||
'manual-redaction': ActionType;
|
|
||||||
} = {
|
|
||||||
dictionary: {
|
|
||||||
add: {
|
|
||||||
error: _('annotation-actions.message.dictionary.add.error'),
|
|
||||||
conflictError: _('annotation-actions.message.dictionary.add.conflict-error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.add.success'),
|
|
||||||
},
|
|
||||||
approve: {
|
|
||||||
error: _('annotation-actions.message.dictionary.approve.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.approve.success'),
|
|
||||||
},
|
|
||||||
decline: {
|
|
||||||
error: _('annotation-actions.message.dictionary.decline.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.decline.success'),
|
|
||||||
},
|
|
||||||
remove: {
|
|
||||||
error: _('annotation-actions.message.dictionary.remove.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.remove.success'),
|
|
||||||
},
|
|
||||||
'request-remove': {
|
|
||||||
error: _('annotation-actions.message.dictionary.request-remove.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.request-remove.success'),
|
|
||||||
},
|
|
||||||
suggest: {
|
|
||||||
error: _('annotation-actions.message.dictionary.suggest.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.suggest.success'),
|
|
||||||
},
|
|
||||||
undo: {
|
|
||||||
error: _('annotation-actions.message.dictionary.undo.error'),
|
|
||||||
success: _('annotation-actions.message.dictionary.undo.success'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'manual-redaction': {
|
|
||||||
add: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.add.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.add.success'),
|
|
||||||
},
|
|
||||||
approve: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.approve.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.approve.success'),
|
|
||||||
},
|
|
||||||
'change-legal-basis': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.change-legal-basis.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.change-legal-basis.success'),
|
|
||||||
},
|
|
||||||
decline: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.decline.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.decline.success'),
|
|
||||||
},
|
|
||||||
'force-redaction': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.force-redaction.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.force-redaction.success'),
|
|
||||||
},
|
|
||||||
'recategorize-image': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.recategorize-image.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.recategorize-image.success'),
|
|
||||||
},
|
|
||||||
'request-change-legal-basis': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.request-change-legal-basis.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.request-change-legal-basis.success'),
|
|
||||||
},
|
|
||||||
'request-force-redaction': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.request-force-redaction.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.request-force-redaction.success'),
|
|
||||||
},
|
|
||||||
'request-image-recategorization': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.request-image-recategorization.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.request-image-recategorization.success'),
|
|
||||||
},
|
|
||||||
suggest: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.suggest.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.suggest.success'),
|
|
||||||
},
|
|
||||||
undo: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.undo.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.undo.success'),
|
|
||||||
},
|
|
||||||
remove: {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.remove.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.remove.success'),
|
|
||||||
},
|
|
||||||
'request-remove': {
|
|
||||||
error: _('annotation-actions.message.manual-redaction.request-remove.error'),
|
|
||||||
success: _('annotation-actions.message.manual-redaction.request-remove.success'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const dictionaryActionsTranslations: Record<DictionaryActions, AnnotationActionResponses> = {
|
export const dictionaryActionsTranslations: Record<DictionaryActions, AnnotationActionResponses> = {
|
||||||
add: {
|
add: {
|
||||||
error: _('annotation-actions.message.dictionary.add.error'),
|
error: _('annotation-actions.message.dictionary.add.error'),
|
||||||
|
|||||||
@ -1,23 +1,7 @@
|
|||||||
export type ImageCategory = 'signature' | 'logo' | 'formula' | 'image';
|
export type ImageCategory = 'signature' | 'logo' | 'formula' | 'image';
|
||||||
|
|
||||||
export type AnnotationActionMode =
|
|
||||||
| 'add'
|
|
||||||
| 'approve'
|
|
||||||
| 'remove'
|
|
||||||
| 'change-legal-basis'
|
|
||||||
| 'decline'
|
|
||||||
| 'request-remove'
|
|
||||||
| 'request-change-legal-basis'
|
|
||||||
| 'recategorize-image'
|
|
||||||
| 'request-image-recategorization'
|
|
||||||
| 'suggest'
|
|
||||||
| 'undo'
|
|
||||||
| 'force-redaction'
|
|
||||||
| 'request-force-redaction'
|
|
||||||
| 'resize'
|
|
||||||
| 'request-resize';
|
|
||||||
|
|
||||||
export type DictionaryActions = 'add' | 'approve' | 'remove' | 'decline' | 'request-remove' | 'suggest' | 'undo';
|
export type DictionaryActions = 'add' | 'approve' | 'remove' | 'decline' | 'request-remove' | 'suggest' | 'undo';
|
||||||
|
|
||||||
export type ManualRedactionActions =
|
export type ManualRedactionActions =
|
||||||
| 'add'
|
| 'add'
|
||||||
| 'approve'
|
| 'approve'
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export * from './redaction-log';
|
|||||||
export * from './remove-redaction.request';
|
export * from './remove-redaction.request';
|
||||||
export * from './manual-add.response';
|
export * from './manual-add.response';
|
||||||
export * from './approve-request';
|
export * from './approve-request';
|
||||||
export * from './image-recategorization.request';
|
export * from './recategorization.request';
|
||||||
export * from './resize.request';
|
export * from './resize.request';
|
||||||
export * from './manual-change';
|
export * from './manual-change';
|
||||||
export * from './dictionary-entry-types';
|
export * from './dictionary-entry-types';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export interface IImageRecategorizationRequest {
|
export interface IRecategorizationRequest {
|
||||||
readonly annotationId?: string;
|
readonly annotationId?: string;
|
||||||
readonly comment?: string;
|
readonly comment?: string;
|
||||||
readonly type?: string;
|
readonly type?: string;
|
||||||
Loading…
x
Reference in New Issue
Block a user