Merge branch 'VM/RED-7345' into 'master'
VM/RED-7345 - Add/Remove bulk-local text redaction option in dialogs Closes RED-7345 See merge request redactmanager/red-ui!582
This commit is contained in:
commit
e39e2522aa
@ -2,11 +2,12 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { addHintTranslations } from '@translations/add-hint-translations';
|
||||
import { redactTextTranslations } from '@translations/redact-text-translations';
|
||||
import { removeRedactionTranslations } from '@translations/remove-redaction-translations';
|
||||
import { RedactOrHintOptions, RemoveRedactionOptions } from '../../file-preview/utils/dialog-types';
|
||||
import { ForceAnnotationOptions, RedactOrHintOptions, RemoveRedactionOptions } from '../../file-preview/utils/dialog-types';
|
||||
|
||||
export const SystemDefaults = {
|
||||
ADD_REDACTION_DEFAULT: RedactOrHintOptions.IN_DOSSIER,
|
||||
ADD_HINT_DEFAULT: RedactOrHintOptions.IN_DOSSIER,
|
||||
FORCE_REDACTION_DEFAULT: ForceAnnotationOptions.ONLY_HERE,
|
||||
REMOVE_REDACTION_DEFAULT: RemoveRedactionOptions.ONLY_HERE,
|
||||
REMOVE_HINT_DEFAULT: RemoveRedactionOptions.ONLY_HERE,
|
||||
REMOVE_RECOMMENDATION_DEFAULT: RemoveRedactionOptions.DO_NOT_RECOMMEND,
|
||||
@ -28,6 +29,10 @@ export const redactionAddOptions = [
|
||||
label: redactTextTranslations.onlyHere.label,
|
||||
value: RedactOrHintOptions.ONLY_HERE,
|
||||
},
|
||||
{
|
||||
label: redactTextTranslations.inDocument.label,
|
||||
value: RedactOrHintOptions.IN_DOCUMENT,
|
||||
},
|
||||
{
|
||||
label: redactTextTranslations.inDossier.label,
|
||||
value: RedactOrHintOptions.IN_DOSSIER,
|
||||
|
||||
@ -2,32 +2,40 @@
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div class="dialog-header heading-l" [translate]="dialogTitle"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<redaction-selected-annotations-table
|
||||
[columns]="tableColumns"
|
||||
[data]="tableData"
|
||||
[staticColumns]="true"
|
||||
*ngIf="!isImageHint"
|
||||
></redaction-selected-annotations-table>
|
||||
<div *ngIf="!isHintDialog && !isDocumine" class="iqser-input-group required w-400">
|
||||
<label [translate]="'manual-annotation.dialog.content.reason'"></label>
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
<mat-option *ngFor="let option of legalOptions" [matTooltip]="option.description" [value]="option">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="dialog-content force-annotation">
|
||||
@if (!isImageHint) {
|
||||
<redaction-selected-annotations-table
|
||||
[columns]="tableColumns"
|
||||
[data]="tableData"
|
||||
[staticColumns]="true"
|
||||
></redaction-selected-annotations-table>
|
||||
}
|
||||
|
||||
<div *ngIf="!isHintDialog && !isDocumine" class="iqser-input-group w-400">
|
||||
<label [translate]="'manual-annotation.dialog.content.legalBasis'"></label>
|
||||
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
@if (!isHintDialog && !isDocumine) {
|
||||
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
|
||||
|
||||
<div class="iqser-input-group required w-400">
|
||||
<label [translate]="'manual-annotation.dialog.content.reason'"></label>
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
@for (option of legalOptions; track option) {
|
||||
<mat-option [matTooltip]="option.description" [value]="option">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-400">
|
||||
<label [translate]="'manual-annotation.dialog.content.legalBasis'"></label>
|
||||
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="iqser-input-group w-300">
|
||||
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
|
||||
|
||||
@ -25,6 +25,11 @@ import { MatFormField } from '@angular/material/form-field';
|
||||
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
|
||||
import { ForceAnnotationOption, RedactOrHintOption } from '../../utils/dialog-types';
|
||||
import { getForceAnnotationOptions, getRedactOrHintOptions } from '../../utils/dialog-options';
|
||||
import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component';
|
||||
import { SystemDefaults } from '../../../account/utils/dialog-defaults';
|
||||
|
||||
export interface LegalBasisOption {
|
||||
label?: string;
|
||||
@ -55,10 +60,12 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.';
|
||||
CircleButtonComponent,
|
||||
NgForOf,
|
||||
HelpButtonComponent,
|
||||
DetailsRadioComponent,
|
||||
],
|
||||
})
|
||||
export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly options: DetailsRadioOption<ForceAnnotationOption>[];
|
||||
|
||||
readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }];
|
||||
readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [
|
||||
@ -76,6 +83,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] },
|
||||
) {
|
||||
super(_dialogRef);
|
||||
this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog);
|
||||
this.form = this.#getForm();
|
||||
}
|
||||
|
||||
@ -128,6 +136,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
return this._formBuilder.group({
|
||||
reason: this._data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null],
|
||||
comment: [null],
|
||||
option: this.options.find(o => o.value === SystemDefaults.FORCE_REDACTION_DEFAULT),
|
||||
});
|
||||
}
|
||||
|
||||
@ -136,6 +145,8 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
|
||||
request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS;
|
||||
request.comment = this.form.get('comment').value;
|
||||
request.reason = this.form.get('reason').value.description;
|
||||
request.option = this.form.get('option').value.value;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@ -32,6 +32,8 @@ export interface LegalBasisOption {
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const NON_READABLE_CONTENT = 'non-readable content';
|
||||
|
||||
@Component({
|
||||
templateUrl: './manual-annotation-dialog.component.html',
|
||||
styleUrls: ['./manual-annotation-dialog.component.scss'],
|
||||
@ -196,7 +198,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme
|
||||
? [this.isFalsePositiveRequest ? 'false_positive' : null, Validators.required]
|
||||
: [this.manualRedactionTypeExists ? SuperTypes.ManualRedaction : null, Validators.required],
|
||||
comment: [null],
|
||||
classification: ['non-readable content'],
|
||||
classification: [NON_READABLE_CONTENT],
|
||||
multiplePages: '',
|
||||
});
|
||||
}
|
||||
|
||||
@ -22,7 +22,13 @@ import {
|
||||
ValueColumn,
|
||||
} from '../../components/selected-annotations-table/selected-annotations-table.component';
|
||||
import { getRedactOrHintOptions } from '../../utils/dialog-options';
|
||||
import { RedactOrHintOption, RedactOrHintOptions, RedactRecommendationData, RedactRecommendationResult } from '../../utils/dialog-types';
|
||||
import {
|
||||
RedactOrHintOption,
|
||||
RedactOrHintOptions,
|
||||
RedactRecommendationData,
|
||||
RedactRecommendationResult,
|
||||
ResizeOptions,
|
||||
} from '../../utils/dialog-types';
|
||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
|
||||
@Component({
|
||||
@ -147,6 +153,7 @@ export class RedactRecommendationDialogComponent
|
||||
this.close({
|
||||
redaction,
|
||||
isMulti: this.isMulti,
|
||||
bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.dialog-content {
|
||||
height: 493px;
|
||||
height: 530px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
@ -21,8 +21,9 @@ import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults';
|
||||
import { getRedactOrHintOptions } from '../../utils/dialog-options';
|
||||
import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult } from '../../utils/dialog-types';
|
||||
import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult, ResizeOptions } from '../../utils/dialog-types';
|
||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { enhanceManualRedactionRequest, EnhanceRequestData } from '../../utils/enhance-manual-redaction-request.utils';
|
||||
|
||||
const MAXIMUM_TEXT_AREA_WIDTH = 421;
|
||||
|
||||
@ -165,16 +166,17 @@ export class RedactTextDialogComponent
|
||||
if (!this.#applyToAllDossiers) {
|
||||
const selectedDictionaryType = this.form.controls.dictionary.value;
|
||||
const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType);
|
||||
this.options[1].extraOption.disabled = selectedDictionary.dossierDictionaryOnly;
|
||||
this.options[2].extraOption.disabled = selectedDictionary.dossierDictionaryOnly;
|
||||
}
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
|
||||
const redaction = this.data.manualRedactionEntryWrapper.manualRedactionEntry;
|
||||
enhanceManualRedactionRequest(redaction, this.#enhanceRequestData);
|
||||
this.close({
|
||||
redaction,
|
||||
dictionary: this.dictionaries.find(d => d.type === this.form.controls.dictionary.value),
|
||||
bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
|
||||
@ -188,14 +190,18 @@ export class RedactTextDialogComponent
|
||||
|
||||
#setupValidators(option: RedactOrHintOption) {
|
||||
switch (option) {
|
||||
case RedactOrHintOptions.IN_DOSSIER:
|
||||
this.form.controls.reason.clearValidators();
|
||||
this.form.controls.dictionary.addValidators(Validators.required);
|
||||
break;
|
||||
case RedactOrHintOptions.ONLY_HERE:
|
||||
this.form.controls.dictionary.clearValidators();
|
||||
this.form.controls.reason.addValidators(Validators.required);
|
||||
break;
|
||||
case RedactOrHintOptions.IN_DOCUMENT:
|
||||
this.form.controls.dictionary.clearValidators();
|
||||
this.form.controls.reason.addValidators(Validators.required);
|
||||
break;
|
||||
case RedactOrHintOptions.IN_DOSSIER:
|
||||
this.form.controls.reason.clearValidators();
|
||||
this.form.controls.dictionary.addValidators(Validators.required);
|
||||
break;
|
||||
}
|
||||
|
||||
this.form.controls.reason.updateValueAndValidity();
|
||||
@ -222,36 +228,9 @@ export class RedactTextDialogComponent
|
||||
}
|
||||
}
|
||||
|
||||
#enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
|
||||
addRedactionRequest.type = this.form.controls.dictionary.value;
|
||||
addRedactionRequest.section = null;
|
||||
addRedactionRequest.value = this.form.controls.selectedText.value;
|
||||
|
||||
const legalOption: LegalBasisOption = this.form.controls.reason.value;
|
||||
if (legalOption) {
|
||||
addRedactionRequest.reason = legalOption.description;
|
||||
addRedactionRequest.legalBasis = legalOption.legalBasis;
|
||||
}
|
||||
|
||||
const selectedType = this.dictionaries.find(d => d.type === addRedactionRequest.type);
|
||||
|
||||
if (selectedType) {
|
||||
addRedactionRequest.addToDictionary = selectedType.hasDictionary;
|
||||
} else {
|
||||
addRedactionRequest.addToDictionary = this.dictionaryRequest && addRedactionRequest.type !== 'dossier_redaction';
|
||||
}
|
||||
|
||||
if (!addRedactionRequest.reason) {
|
||||
addRedactionRequest.reason = 'Dictionary Request';
|
||||
}
|
||||
const commentValue = this.form.controls.comment.value;
|
||||
addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
|
||||
addRedactionRequest.addToAllDossiers = this.data.isApprover && this.dictionaryRequest && this.#applyToAllDossiers;
|
||||
}
|
||||
|
||||
#resetValues() {
|
||||
this.#applyToAllDossiers = this.applyToAll;
|
||||
this.options[1].extraOption.checked = this.#applyToAllDossiers;
|
||||
this.options[2].extraOption.checked = this.#applyToAllDossiers;
|
||||
if (this.dictionaryRequest) {
|
||||
this.form.controls.reason.setValue(null);
|
||||
this.form.controls.dictionary.setValue(null);
|
||||
@ -263,4 +242,17 @@ export class RedactTextDialogComponent
|
||||
#getOption(option: RedactOrHintOption): DetailsRadioOption<RedactOrHintOption> {
|
||||
return this.options.find(o => o.value === option);
|
||||
}
|
||||
|
||||
get #enhanceRequestData(): EnhanceRequestData {
|
||||
return {
|
||||
type: this.form.controls.dictionary.value,
|
||||
selectedText: this.form.controls.selectedText.value,
|
||||
reason: this.form.controls.reason.value,
|
||||
dictionaries: this.dictionaries,
|
||||
dictionaryRequest: this.dictionaryRequest,
|
||||
comment: this.form.controls.comment.value,
|
||||
isApprover: this.data.isApprover,
|
||||
applyToAllDossiers: this.#applyToAllDossiers,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,13 @@ import {
|
||||
} from '../../components/selected-annotations-table/selected-annotations-table.component';
|
||||
import { DialogHelpModeKeys } from '../../utils/constants';
|
||||
import { getRemoveRedactionOptions } from '../../utils/dialog-options';
|
||||
import { RemoveRedactionData, RemoveRedactionOption, RemoveRedactionOptions, RemoveRedactionResult } from '../../utils/dialog-types';
|
||||
import {
|
||||
RemoveRedactionData,
|
||||
RemoveRedactionOption,
|
||||
RemoveRedactionOptions,
|
||||
RemoveRedactionResult,
|
||||
ResizeOptions,
|
||||
} from '../../utils/dialog-types';
|
||||
|
||||
@Component({
|
||||
templateUrl: './remove-redaction-dialog.component.html',
|
||||
@ -128,19 +134,6 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
|
||||
super();
|
||||
}
|
||||
|
||||
get helpButtonKey() {
|
||||
if (this.hint) {
|
||||
return DialogHelpModeKeys.HINT_REMOVE;
|
||||
}
|
||||
if (this.recommendation) {
|
||||
return DialogHelpModeKeys.RECOMMENDATION_REMOVE;
|
||||
}
|
||||
if (this.skipped) {
|
||||
return DialogHelpModeKeys.SKIPPED_REMOVE;
|
||||
}
|
||||
return DialogHelpModeKeys.REDACTION_REMOVE;
|
||||
}
|
||||
|
||||
get hasFalsePositiveOption() {
|
||||
return !!this.options.find(option => option.value === RemoveRedactionOptions.FALSE_POSITIVE);
|
||||
}
|
||||
@ -168,7 +161,10 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this.close(this.form.getRawValue());
|
||||
this.close({
|
||||
...this.form.getRawValue(),
|
||||
bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
|
||||
#getOption(option: RemoveRedactionOption): DetailsRadioOption<RemoveRedactionOption> {
|
||||
|
||||
@ -468,6 +468,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const add$ = this._manualRedactionService.addAnnotation([result.redaction], this.dossierId, this.fileId, {
|
||||
hint,
|
||||
dictionaryLabel: result.dictionary?.label,
|
||||
bulkLocal: result.bulkLocal,
|
||||
});
|
||||
|
||||
const addAndReload$ = add$.pipe(
|
||||
|
||||
@ -8,9 +8,11 @@ import { Core } from '@pdftron/webviewer';
|
||||
import {
|
||||
DictionaryEntryTypes,
|
||||
EarmarkOperation,
|
||||
type IBulkLocalRemoveRequest,
|
||||
ILegalBasisChangeRequest,
|
||||
IRecategorizationRequest,
|
||||
IRectangle,
|
||||
type IRemoveRedactionRequest,
|
||||
IResizeRequest,
|
||||
} from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
@ -31,6 +33,7 @@ import { ResizeRedactionDialogComponent } from '../dialogs/resize-redaction-dial
|
||||
import {
|
||||
EditRedactionData,
|
||||
EditRedactResult,
|
||||
ForceAnnotationOptions,
|
||||
RemoveRedactionData,
|
||||
RemoveRedactionOptions,
|
||||
RemoveRedactionPermissions,
|
||||
@ -43,6 +46,7 @@ import { FilePreviewDialogService } from './file-preview-dialog.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { ManualRedactionService } from './manual-redaction.service';
|
||||
import { SkippedService } from './skipped.service';
|
||||
import { NON_READABLE_CONTENT } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationActionsService {
|
||||
@ -77,14 +81,29 @@ export class AnnotationActionsService {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const data = { dossier: this._state.dossier(), annotations, hint };
|
||||
this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => {
|
||||
this.#processObsAndEmit(
|
||||
this._manualRedactionService.bulkForce(
|
||||
let obs$;
|
||||
if (request.option === ForceAnnotationOptions.ONLY_HERE) {
|
||||
obs$ = this._manualRedactionService.bulkForce(
|
||||
annotations.map(a => ({ ...request, annotationId: a.id })),
|
||||
dossierId,
|
||||
fileId,
|
||||
annotations[0].isIgnoredHint,
|
||||
),
|
||||
).then();
|
||||
);
|
||||
} else {
|
||||
const addAnnotationRequest = annotations.map(a => ({
|
||||
comment: { text: request.comment },
|
||||
legalBasis: request.legalBasis,
|
||||
reason: request.reason,
|
||||
positions: a.positions,
|
||||
type: a.type,
|
||||
value: a.value,
|
||||
}));
|
||||
obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, {
|
||||
hint,
|
||||
bulkLocal: true,
|
||||
});
|
||||
}
|
||||
this.#processObsAndEmit(obs$).then();
|
||||
});
|
||||
}
|
||||
|
||||
@ -192,7 +211,13 @@ export class AnnotationActionsService {
|
||||
this.cancelResize(recommendations[0]).then();
|
||||
}
|
||||
|
||||
const request$ = this._manualRedactionService.addRecommendation(recommendations, result.redaction, dossierId, fileId);
|
||||
const request$ = this._manualRedactionService.addRecommendation(
|
||||
recommendations,
|
||||
result.redaction,
|
||||
dossierId,
|
||||
fileId,
|
||||
result.bulkLocal,
|
||||
);
|
||||
return this.#processObsAndEmit(request$);
|
||||
}
|
||||
|
||||
@ -425,17 +450,20 @@ export class AnnotationActionsService {
|
||||
#removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
|
||||
const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER;
|
||||
const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true));
|
||||
const body = redactions.map(redaction => ({
|
||||
annotationId: redaction.id,
|
||||
comment: dialogResult.comment,
|
||||
removeFromDictionary,
|
||||
removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers,
|
||||
}));
|
||||
const body = this.#getRemoveRedactionBody(redactions, dialogResult);
|
||||
// todo: might not be correct, probably shouldn't get to this point if they are not all the same
|
||||
const isHint = redactions.every(r => r.isHint);
|
||||
const { dossierId, fileId } = this._state;
|
||||
this.#processObsAndEmit(
|
||||
this._manualRedactionService.removeRedaction(body, dossierId, fileId, removeFromDictionary, isHint, includeUnprocessed),
|
||||
this._manualRedactionService.removeRedaction(
|
||||
body,
|
||||
dossierId,
|
||||
fileId,
|
||||
removeFromDictionary,
|
||||
isHint,
|
||||
includeUnprocessed,
|
||||
dialogResult.bulkLocal,
|
||||
),
|
||||
).then();
|
||||
}
|
||||
|
||||
@ -505,4 +533,35 @@ export class AnnotationActionsService {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#getRemoveRedactionBody(
|
||||
redactions: AnnotationWrapper[],
|
||||
dialogResult: RemoveRedactionResult,
|
||||
): List<IRemoveRedactionRequest> | IBulkLocalRemoveRequest {
|
||||
if (dialogResult.bulkLocal) {
|
||||
const redaction = redactions[0];
|
||||
if (redaction.value === NON_READABLE_CONTENT) {
|
||||
return {
|
||||
value: redaction.value,
|
||||
rectangle: true,
|
||||
position: redaction.entry.positions[0],
|
||||
originTypes: [redaction.entry.type],
|
||||
pageNumbers: [redaction.pageNumber],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
value: redaction.value,
|
||||
rectangle: false,
|
||||
};
|
||||
}
|
||||
|
||||
return redactions.map(redaction => ({
|
||||
annotationId: redaction.id,
|
||||
value: redaction.value,
|
||||
comment: dialogResult.comment,
|
||||
removeFromDictionary: dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER,
|
||||
removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import { type ManualRedactionEntryType } from '@models/file/manual-redaction-ent
|
||||
import type {
|
||||
DictionaryActions,
|
||||
IAddRedactionRequest,
|
||||
IBulkLocalRemoveRequest,
|
||||
ILegalBasisChangeRequest,
|
||||
IManualAddResponse,
|
||||
IRecategorizationRequest,
|
||||
@ -39,6 +40,7 @@ function getMessage(action: ManualRedactionActions, isDictionary = false, error
|
||||
export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
protected readonly _defaultModelPath = 'manualRedaction';
|
||||
readonly #bulkRedaction = `${this._defaultModelPath}/bulk/redaction`;
|
||||
readonly #bulkLocal = `${this._defaultModelPath}/bulk-local`;
|
||||
|
||||
constructor(
|
||||
private readonly _toaster: Toaster,
|
||||
@ -48,7 +50,13 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
super();
|
||||
}
|
||||
|
||||
addRecommendation(annotations: AnnotationWrapper[], redaction: IAddRedactionRequest, dossierId: string, fileId: string) {
|
||||
addRecommendation(
|
||||
annotations: AnnotationWrapper[],
|
||||
redaction: IAddRedactionRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
bulkLocal: boolean = false,
|
||||
) {
|
||||
const recommendations: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||
addToDictionary: redaction.addToDictionary,
|
||||
addToAllDossiers: redaction.addToAllDossiers,
|
||||
@ -59,7 +67,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
type: redaction.type ?? annotation.type,
|
||||
comment: redaction.comment,
|
||||
}));
|
||||
return this.addAnnotation(recommendations, dossierId, fileId);
|
||||
return this.addAnnotation(recommendations, dossierId, fileId, { bulkLocal });
|
||||
}
|
||||
|
||||
recategorizeRedactions(
|
||||
@ -80,14 +88,14 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
requests: List<IAddRedactionRequest>,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
options?: { hint?: boolean; dictionaryLabel?: string },
|
||||
options?: { hint?: boolean; dictionaryLabel?: string; bulkLocal?: boolean },
|
||||
) {
|
||||
const toast = requests[0].addToDictionary
|
||||
? this.#showAddToDictionaryToast(requests, options?.dictionaryLabel)
|
||||
: this.#showToast(options?.hint ? 'force-hint' : 'add');
|
||||
const canAddRedaction = this._iqserPermissionsService.has(Roles.redactions.write);
|
||||
if (canAddRedaction) {
|
||||
return this.add(requests, dossierId, fileId).pipe(toast);
|
||||
return this.add(requests, dossierId, fileId, options.bulkLocal).pipe(toast);
|
||||
}
|
||||
|
||||
return of(undefined);
|
||||
@ -102,14 +110,15 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
}
|
||||
|
||||
removeRedaction(
|
||||
body: List<IRemoveRedactionRequest>,
|
||||
body: List<IRemoveRedactionRequest> | IBulkLocalRemoveRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
removeFromDictionary = false,
|
||||
isHint = false,
|
||||
includeUnprocessed = false,
|
||||
bulkLocal = false,
|
||||
) {
|
||||
return this.remove(body, dossierId, fileId, includeUnprocessed).pipe(
|
||||
return this.remove(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe(
|
||||
this.#showToast(!isHint ? 'remove' : 'remove-hint', removeFromDictionary),
|
||||
);
|
||||
}
|
||||
@ -127,8 +136,9 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
}
|
||||
}
|
||||
|
||||
add(body: List<IAddRedactionRequest>, dossierId: string, fileId: string) {
|
||||
return this._post(body, `${this.#bulkRedaction}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body));
|
||||
add(body: List<IAddRedactionRequest>, dossierId: string, fileId: string, bulkLocal = false) {
|
||||
const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction;
|
||||
return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body));
|
||||
}
|
||||
|
||||
recategorize(body: List<IRecategorizationRequest>, dossierId: string, fileId: string, includeUnprocessed = false) {
|
||||
@ -142,8 +152,15 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
return super.delete(annotationIds, url).pipe(this.#log('Undo', annotationIds));
|
||||
}
|
||||
|
||||
remove(body: List<IRemoveRedactionRequest>, dossierId: string, fileId: string, includeUnprocessed = false) {
|
||||
return this._post(body, `${this.#bulkRedaction}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe(
|
||||
remove(
|
||||
body: List<IRemoveRedactionRequest> | IBulkLocalRemoveRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
includeUnprocessed = false,
|
||||
bulkLocal = false,
|
||||
) {
|
||||
const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction;
|
||||
return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe(
|
||||
this.#log('Remove', body),
|
||||
);
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import { removeAnnotationTranslations } from '@translations/remove-annotation-tr
|
||||
import { removeRedactionTranslations } from '@translations/remove-redaction-translations';
|
||||
import { resizeRedactionTranslations } from '@translations/resize-redaction-translations';
|
||||
import {
|
||||
ForceAnnotationOption,
|
||||
RedactOrHintOption,
|
||||
RedactOrHintOptions,
|
||||
RemoveRedactionData,
|
||||
@ -17,6 +18,7 @@ import {
|
||||
} from './dialog-types';
|
||||
|
||||
const PIN_ICON = 'red:push-pin';
|
||||
const DOCUMENT_ICON = 'iqser:document';
|
||||
const FOLDER_ICON = 'red:folder';
|
||||
const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict';
|
||||
|
||||
@ -77,6 +79,15 @@ export const getRedactOrHintOptions = (
|
||||
return options;
|
||||
}
|
||||
|
||||
if (!isHint) {
|
||||
options.push({
|
||||
label: redactTextTranslations.inDocument.label,
|
||||
description: redactTextTranslations.inDocument.description,
|
||||
icon: DOCUMENT_ICON,
|
||||
value: ResizeOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
|
||||
options.push({
|
||||
label: translations.inDossier.label,
|
||||
description: translations.inDossier.description,
|
||||
@ -156,6 +167,13 @@ export const getRemoveRedactionOptions = (
|
||||
icon: PIN_ICON,
|
||||
value: RemoveRedactionOptions.ONLY_HERE,
|
||||
});
|
||||
|
||||
options.push({
|
||||
label: removeRedactionTranslations.IN_DOCUMENT.label,
|
||||
description: removeRedactionTranslations.IN_DOCUMENT.description,
|
||||
icon: DOCUMENT_ICON,
|
||||
value: RemoveRedactionOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
if (permissions.canRemoveFromDictionary) {
|
||||
options.push({
|
||||
@ -217,3 +235,24 @@ export const getRemoveRedactionOptions = (
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
export const getForceAnnotationOptions = (isDocumine: boolean, isHint: boolean): DetailsRadioOption<ForceAnnotationOption>[] => {
|
||||
if (isDocumine || isHint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: redactTextTranslations.onlyHere.label,
|
||||
description: redactTextTranslations.onlyHere.description,
|
||||
icon: PIN_ICON,
|
||||
value: ResizeOptions.ONLY_HERE,
|
||||
},
|
||||
{
|
||||
label: redactTextTranslations.inDocument.label,
|
||||
description: redactTextTranslations.inDocument.description,
|
||||
icon: DOCUMENT_ICON,
|
||||
value: ResizeOptions.IN_DOCUMENT,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
@ -5,16 +5,25 @@ import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry
|
||||
|
||||
export const RedactOrHintOptions = {
|
||||
ONLY_HERE: 'ONLY_HERE',
|
||||
IN_DOCUMENT: 'IN_DOCUMENT',
|
||||
IN_DOSSIER: 'IN_DOSSIER',
|
||||
} as const;
|
||||
|
||||
export type RedactOrHintOption = keyof typeof RedactOrHintOptions;
|
||||
|
||||
export const ForceAnnotationOptions = {
|
||||
ONLY_HERE: 'ONLY_HERE',
|
||||
IN_DOCUMENT: 'IN_DOCUMENT',
|
||||
} as const;
|
||||
|
||||
export type ForceAnnotationOption = keyof typeof ForceAnnotationOptions;
|
||||
|
||||
export const ResizeOptions = RedactOrHintOptions;
|
||||
export type ResizeRedactionOption = RedactOrHintOption;
|
||||
|
||||
export const RemoveRedactionOptions = {
|
||||
ONLY_HERE: 'ONLY_HERE',
|
||||
IN_DOCUMENT: 'IN_DOCUMENT',
|
||||
IN_DOSSIER: 'IN_DOSSIER',
|
||||
FALSE_POSITIVE: 'FALSE_POSITIVE',
|
||||
DO_NOT_RECOMMEND: 'DO_NOT_RECOMMEND',
|
||||
@ -46,6 +55,7 @@ export type AddHintData = RedactTextData;
|
||||
export interface RedactTextResult {
|
||||
redaction: IManualRedactionEntry;
|
||||
dictionary: Dictionary;
|
||||
bulkLocal?: boolean;
|
||||
}
|
||||
|
||||
export type RedactRecommendationData = EditRedactionData;
|
||||
@ -53,6 +63,7 @@ export type RedactRecommendationData = EditRedactionData;
|
||||
export interface RedactRecommendationResult {
|
||||
redaction: IAddRedactionRequest;
|
||||
isMulti: boolean;
|
||||
bulkLocal: boolean;
|
||||
}
|
||||
|
||||
export interface EditRedactResult {
|
||||
@ -112,6 +123,7 @@ export interface RemoveRedactionResult {
|
||||
comment: string;
|
||||
option: DetailsRadioOption<RemoveRedactionOption>;
|
||||
applyToAllDossiers?: boolean;
|
||||
bulkLocal?: boolean;
|
||||
}
|
||||
|
||||
export type RemoveAnnotationResult = RemoveRedactionResult;
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
import { Dictionary, IAddRedactionRequest, SuperType } from '@red/domain';
|
||||
import { LegalBasisOption } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
|
||||
export interface EnhanceRequestData {
|
||||
readonly type: SuperType | null;
|
||||
readonly selectedText: string;
|
||||
readonly reason: LegalBasisOption;
|
||||
readonly dictionaries: Dictionary[];
|
||||
readonly dictionaryRequest: boolean;
|
||||
readonly comment: string;
|
||||
readonly isApprover: boolean;
|
||||
readonly applyToAllDossiers: boolean;
|
||||
}
|
||||
|
||||
export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedactionRequest, data: EnhanceRequestData) => {
|
||||
addRedactionRequest.type = data.type;
|
||||
addRedactionRequest.section = null;
|
||||
addRedactionRequest.value = data.selectedText;
|
||||
|
||||
const legalOption: LegalBasisOption = data.reason;
|
||||
if (legalOption) {
|
||||
addRedactionRequest.reason = legalOption.description;
|
||||
addRedactionRequest.legalBasis = legalOption.legalBasis;
|
||||
}
|
||||
|
||||
const selectedType = data.dictionaries.find(d => d.type === addRedactionRequest.type);
|
||||
|
||||
if (selectedType) {
|
||||
addRedactionRequest.addToDictionary = selectedType.hasDictionary;
|
||||
} else {
|
||||
addRedactionRequest.addToDictionary = data.dictionaryRequest && addRedactionRequest.type !== 'dossier_redaction';
|
||||
}
|
||||
|
||||
if (!addRedactionRequest.reason) {
|
||||
addRedactionRequest.reason = 'Dictionary Request';
|
||||
}
|
||||
const commentValue = data.comment;
|
||||
addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
|
||||
addRedactionRequest.addToAllDossiers = data.isApprover && data.dictionaryRequest && data.applyToAllDossiers;
|
||||
};
|
||||
@ -9,11 +9,15 @@ export interface DialogOption {
|
||||
extraOptionDescription?: string;
|
||||
}
|
||||
|
||||
export const redactTextTranslations: Record<'onlyHere' | 'inDossier', DialogOption> = {
|
||||
export const redactTextTranslations: Record<'onlyHere' | 'inDocument' | 'inDossier', DialogOption> = {
|
||||
onlyHere: {
|
||||
label: _('redact-text.dialog.content.options.only-here.label'),
|
||||
description: _('redact-text.dialog.content.options.only-here.description'),
|
||||
},
|
||||
inDocument: {
|
||||
label: _('redact-text.dialog.content.options.in-document.label'),
|
||||
description: _('redact-text.dialog.content.options.in-document.description'),
|
||||
},
|
||||
inDossier: {
|
||||
label: _('redact-text.dialog.content.options.in-dossier.label'),
|
||||
description: _('redact-text.dialog.content.options.in-dossier.description'),
|
||||
|
||||
@ -8,6 +8,10 @@ export const removeAnnotationTranslations: { [key in RemoveAnnotationOption]: Di
|
||||
description: _('remove-annotation.dialog.content.options.only-here.description'),
|
||||
descriptionBulk: _('remove-annotation.dialog.content.options.only-here.description-bulk'),
|
||||
},
|
||||
IN_DOCUMENT: {
|
||||
label: _('remove-annotation.dialog.content.options.in-document.label'),
|
||||
description: _('remove-annotation.dialog.content.options.in-document.description'),
|
||||
},
|
||||
IN_DOSSIER: {
|
||||
label: _('remove-annotation.dialog.content.options.in-dossier.label'),
|
||||
labelBulk: _('remove-annotation.dialog.content.options.in-dossier.label-bulk'),
|
||||
|
||||
@ -8,6 +8,10 @@ export const removeRedactionTranslations: { [key in RemoveRedactionOption]: Dial
|
||||
description: _('remove-redaction.dialog.content.options.only-here.description'),
|
||||
descriptionBulk: _('remove-redaction.dialog.content.options.only-here.description-bulk'),
|
||||
},
|
||||
IN_DOCUMENT: {
|
||||
label: _('remove-redaction.dialog.content.options.in-document.label'),
|
||||
description: _('remove-redaction.dialog.content.options.in-document.description'),
|
||||
},
|
||||
IN_DOSSIER: {
|
||||
label: _('remove-redaction.dialog.content.options.in-dossier.label'),
|
||||
labelBulk: _('remove-redaction.dialog.content.options.in-dossier.label-bulk'),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dan2.iqser.cloud",
|
||||
"API_URL": "https://dan1.iqser.cloud",
|
||||
"APP_NAME": "RedactManager",
|
||||
"IS_DOCUMINE": false,
|
||||
"RULE_EDITOR_DEV_ONLY": false,
|
||||
@ -13,7 +13,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dan2.iqser.cloud/auth",
|
||||
"OAUTH_URL": "https://dan1.iqser.cloud/auth",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
||||
|
||||
@ -2074,6 +2074,10 @@
|
||||
"edit-text": "Text bearbeiten",
|
||||
"legal-basis": "Rechtsgrundlage",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.",
|
||||
"extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen",
|
||||
@ -2113,6 +2117,10 @@
|
||||
"description-bulk": "",
|
||||
"label": "In diesem Kontext aus dem Dossier entfernen"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Annotieren Sie den Begriff in diesem Dossier nicht.",
|
||||
"description-bulk": "",
|
||||
@ -2153,6 +2161,10 @@
|
||||
"extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen",
|
||||
"label": "In diesem Kontext aus Dossier entfernen"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.",
|
||||
"description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.",
|
||||
|
||||
@ -2074,6 +2074,10 @@
|
||||
"edit-text": "Edit text",
|
||||
"legal-basis": "Legal basis",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "Add redaction for each occurrence of the term in this document.",
|
||||
"label": "Redact in document"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
@ -2113,6 +2117,10 @@
|
||||
"description-bulk": "",
|
||||
"label": "Remove from dossier in this context"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not annotate the term in this dossier.",
|
||||
"description-bulk": "",
|
||||
@ -2153,6 +2161,10 @@
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier in this context"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "Do not auto-redact the selected term in any pages of this document.",
|
||||
"label": "Remove from document"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.",
|
||||
"description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.",
|
||||
|
||||
@ -2074,6 +2074,10 @@
|
||||
"edit-text": "",
|
||||
"legal-basis": "Legal basis",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
@ -2113,6 +2117,10 @@
|
||||
"description-bulk": "The selected items should not be annotated in their respective contexts.",
|
||||
"label": "False positive"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.",
|
||||
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
|
||||
@ -2153,6 +2161,10 @@
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"label": "False positive"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
|
||||
"description-bulk": "",
|
||||
|
||||
@ -2074,6 +2074,10 @@
|
||||
"edit-text": "",
|
||||
"legal-basis": "Legal basis",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "Add redaction for each occurrence of the term in this document.",
|
||||
"label": "Redact in document"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
@ -2113,6 +2117,10 @@
|
||||
"description-bulk": "The selected items should not be annotated in their respective contexts.",
|
||||
"label": "False positive"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.",
|
||||
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
|
||||
@ -2153,6 +2161,10 @@
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"label": "False positive"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
|
||||
"description-bulk": "",
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import { ForceAnnotationOption } from '../../../../../apps/red-ui/src/app/modules/file-preview/utils/dialog-types';
|
||||
|
||||
export interface ILegalBasisChangeRequest {
|
||||
annotationId?: string;
|
||||
comment?: string;
|
||||
legalBasis?: string;
|
||||
reason?: string;
|
||||
option?: ForceAnnotationOption;
|
||||
}
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
import { IEntityLogEntryPosition } from './entity-log-entry';
|
||||
|
||||
export interface IRemoveRedactionRequest {
|
||||
annotationId?: string;
|
||||
comment?: string;
|
||||
removeFromDictionary?: boolean;
|
||||
removeFromAllDossiers?: boolean;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export interface IBulkLocalRemoveRequest {
|
||||
rectangle: boolean;
|
||||
value: string;
|
||||
caseSensitive?: boolean;
|
||||
position?: IEntityLogEntryPosition;
|
||||
originTypes?: string[];
|
||||
originLegalBases?: string[];
|
||||
pageNumbers?: number[];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user