DM-412: Documine bulk delete

This commit is contained in:
Adina Țeudan 2023-09-11 23:48:48 +03:00
parent 1c5d8a340c
commit 149a900a4d
19 changed files with 208 additions and 94 deletions

View File

@ -25,9 +25,8 @@ export const canRemoveFromDictionary = (annotation: AnnotationWrapper) =>
!annotation.pending &&
!annotation.hasBeenResized;
export const canRemoveRedaction = (annotations: AnnotationWrapper[], permissions: AnnotationPermissions) =>
annotations.length === 1 &&
(permissions.canRemoveOnlyHere || permissions.canRemoveFromDictionary || permissions.canMarkAsFalsePositive);
export const canRemoveRedaction = (permissions: AnnotationPermissions) =>
permissions.canRemoveOnlyHere || permissions.canRemoveFromDictionary || permissions.canMarkAsFalsePositive;
export const canChangeLegalBasis = (annotation: AnnotationWrapper, canAddRedaction: boolean) =>
canAddRedaction && annotation.isRedacted && !annotation.pending;

View File

@ -47,7 +47,6 @@ export class AnnotationPermissions {
for (const annotation of annotations) {
const permissions: AnnotationPermissions = new AnnotationPermissions();
const annotationEntity = entities.find(entity => entity.type === annotation.type);
permissions.canUndo = canUndo(annotation, isApprover);
permissions.canForceHint = canForceHint(annotation, canAddRedaction);
permissions.canForceRedaction = canForceRedaction(annotation, canAddRedaction);
@ -55,7 +54,7 @@ export class AnnotationPermissions {
permissions.canMarkAsFalsePositive = canMarkAsFalsePositive(annotation, annotationEntity);
permissions.canRemoveOnlyHere = canRemoveOnlyHere(annotation, canAddRedaction);
permissions.canRemoveFromDictionary = canRemoveFromDictionary(annotation);
permissions.canRemoveRedaction = canRemoveRedaction(annotations, permissions);
permissions.canRemoveRedaction = canRemoveRedaction(permissions);
permissions.canChangeLegalBasis = canChangeLegalBasis(annotation, canAddRedaction);
permissions.canRecategorizeAnnotation = canRecategorizeAnnotation(annotation, canAddRedaction);
permissions.canResizeAnnotation = canResizeAnnotation(annotation, canAddRedaction);

View File

@ -136,7 +136,7 @@
<iqser-circle-button
(action)="removeOrSuggestRemoveRedaction()"
*ngIf="annotationPermissions.canRemoveRedaction"
*ngIf="canRemoveRedaction"
[tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.remove-annotation.remove-redaction' | translate"
[type]="buttonType"

View File

@ -24,8 +24,6 @@ export type AnnotationButtonType = keyof typeof AnnotationButtonTypes;
styleUrls: ['./annotation-actions.component.scss'],
})
export class AnnotationActionsComponent implements OnChanges {
#annotations: AnnotationWrapper[] = [];
protected _annotationId = '';
@Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.default;
@Input() tooltipPosition: 'before' | 'above' = 'before';
@Input() canPerformAnnotationActions: boolean;
@ -33,12 +31,46 @@ export class AnnotationActionsComponent implements OnChanges {
readonly roles = Roles;
annotationPermissions: AnnotationPermissions;
isImage = true;
protected _annotationId = '';
#annotations: AnnotationWrapper[] = [];
readonly isVisible = computed(() => {
const hidden = this._annotationManager.hidden();
return this.#annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true);
});
readonly #isDocumine = getConfig().IS_DOCUMINE;
get annotations(): AnnotationWrapper[] {
return this.#annotations;
}
@Input()
set annotations(annotations: AnnotationWrapper[]) {
this.#annotations = annotations.filter(a => a !== undefined);
this.isImage = this.#annotations?.reduce((accumulator, annotation) => annotation.isImage && accumulator, true);
this._annotationId = this.#annotations[0]?.id;
}
get canEdit(): boolean {
const documineCanEditRedactions =
this.annotationPermissions.canChangeLegalBasis ||
this.annotationPermissions.canRecategorizeAnnotation ||
this.annotationPermissions.canForceHint ||
this.annotationPermissions.canForceRedaction;
return this.#isDocumine && this.annotations.length > 1 ? this.annotationPermissions.canEditAnnotations : documineCanEditRedactions;
}
get canRemoveRedaction(): boolean {
return (this.#isDocumine || this.annotations.length === 1) && this.annotationPermissions.canRemoveRedaction;
}
get viewerAnnotations() {
return this._annotationManager.get(this.#annotations);
}
get resizing() {
return this.#annotations?.length === 1 && this.#annotations?.[0].id === this._annotationManager.resizingAnnotationId;
}
constructor(
readonly viewModeService: ViewModeService,
readonly helpModeService: HelpModeService,
@ -51,40 +83,12 @@ export class AnnotationActionsComponent implements OnChanges {
readonly annotationReferencesService: AnnotationReferencesService,
) {}
get annotations(): AnnotationWrapper[] {
return this.#annotations;
}
get canEdit() {
const canEditRedactions =
this.annotationPermissions.canChangeLegalBasis ||
this.annotationPermissions.canRecategorizeAnnotation ||
this.annotationPermissions.canForceHint ||
this.annotationPermissions.canForceRedaction;
return this.#isDocumine && this.annotations.length > 1 ? this.annotationPermissions.canEditAnnotations : canEditRedactions;
}
@Input()
set annotations(annotations: AnnotationWrapper[]) {
this.#annotations = annotations.filter(a => a !== undefined);
this.isImage = this.#annotations?.reduce((accumulator, annotation) => annotation.isImage && accumulator, true);
this._annotationId = this.#annotations[0]?.id;
}
get viewerAnnotations() {
return this._annotationManager.get(this.#annotations);
}
get resizing() {
return this.#annotations?.length === 1 && this.#annotations?.[0].id === this._annotationManager.resizingAnnotationId;
}
ngOnChanges(): void {
this.#setPermissions();
}
removeOrSuggestRemoveRedaction() {
this.annotationActionsService.removeRedaction(this.annotations[0], this.annotationPermissions);
this.annotationActionsService.removeRedaction(this.annotations, this.annotationPermissions);
}
acceptRecommendation() {

View File

@ -1,8 +1,41 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div [innerHTML]="'remove-annotation.dialog.title' | translate" class="dialog-header heading-l"></div>
<div
[innerHTML]="'remove-annotation.dialog.title' | translate: { count: data.redactions.length }"
class="dialog-header heading-l"
></div>
<div class="dialog-content redaction">
<div *ngIf="data.redactions.length > 1">
<label
[translateParams]="{ length: redactedTexts.length }"
[translate]="'remove-annotation.dialog.content.redacted-text'"
class="selected-text"
></label>
<cdk-virtual-scroll-viewport
[itemSize]="16"
[ngStyle]="{ height: redactedTexts.length <= 5 ? 16 * redactedTexts.length + 'px' : 80 + 'px' }"
>
<ul *cdkVirtualFor="let text of redactedTexts; let idx = index">
<li>
{{
(isFalsePositive
? 'remove-annotation.dialog.content.list-item-false-positive'
: 'remove-annotation.dialog.content.list-item'
)
| translate
: {
text: text,
context: data.falsePositiveContext[idx]
}
| replaceNbsp
}}
</li>
</ul>
</cdk-virtual-scroll-viewport>
</div>
<div class="dialog-content">
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
<div class="iqser-input-group w-450">

View File

@ -0,0 +1,14 @@
cdk-virtual-scroll-viewport {
margin-top: 8px;
}
:host ::ng-deep .cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper {
max-width: 100% !important;
}
li {
white-space: nowrap;
text-overflow: ellipsis;
list-style-position: inside;
overflow: hidden;
}

View File

@ -1,13 +1,12 @@
import { Component } from '@angular/core';
import { DetailsRadioOption, IconButtonTypes } from '@iqser/common-ui';
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
import { IqserDialogComponent } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import { RemoveAnnotationData, RemoveAnnotationResult } from '../../../utils/dialog-types';
import { getRemoveRedactionOptions, RemoveAnnotationOption, RemoveAnnotationOptions } from '../../../utils/dialog-options';
@Component({
templateUrl: './remove-annotation-dialog.component.html',
templateUrl: 'remove-annotation-dialog.component.html',
styleUrls: ['remove-annotation-dialog.component.scss'],
})
export class RemoveAnnotationDialogComponent extends IqserDialogComponent<
RemoveAnnotationDialogComponent,
@ -16,13 +15,12 @@ export class RemoveAnnotationDialogComponent extends IqserDialogComponent<
> {
readonly iconButtonTypes = IconButtonTypes;
readonly options: DetailsRadioOption<RemoveAnnotationOption>[];
readonly redactedTexts: string[];
form!: UntypedFormGroup;
constructor(private readonly _formBuilder: FormBuilder, private readonly _permissionsService: PermissionsService) {
super();
this.options = getRemoveRedactionOptions(this.data, true);
this.form = this.#getForm();
get isFalsePositive(): boolean {
return this.form.get('option').value.value === RemoveAnnotationOptions.FALSE_POSITIVE;
}
get #applyToAllDossiers(): boolean {
@ -30,6 +28,13 @@ export class RemoveAnnotationDialogComponent extends IqserDialogComponent<
return selectedOption === RemoveAnnotationOptions.IN_DOSSIER || selectedOption === RemoveAnnotationOptions.FALSE_POSITIVE;
}
constructor(private readonly _formBuilder: FormBuilder) {
super();
this.options = getRemoveRedactionOptions(this.data, true);
this.redactedTexts = this.data.redactions.map(annotation => annotation.value);
this.form = this.#getForm();
}
save(): void {
this.dialogRef.close({ ...this.form.getRawValue(), applyToAllDossiers: this.#applyToAllDossiers });
}

View File

@ -15,16 +15,17 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
RemoveRedactionData,
RemoveRedactionResult
> {
#applyToAllDossiers: boolean;
readonly iconButtonTypes = IconButtonTypes;
readonly options: DetailsRadioOption<RemoveRedactionOption>[];
readonly recommendation = this.data.redaction.isRecommendation;
readonly recommendation;
readonly hint: boolean;
form!: UntypedFormGroup;
hint: boolean;
#applyToAllDossiers: boolean;
constructor(private readonly _formBuilder: FormBuilder) {
super();
this.hint = this.data.redaction.hint;
this.recommendation = this.data.redactions.every(r => r.isRecommendation);
this.hint = this.data.redactions.every(r => r.hint);
this.options = getRemoveRedactionOptions(this.data);
this.form = this.#getForm();
this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;

View File

@ -71,6 +71,7 @@ import { DocumentUnloadedGuard } from './services/document-unloaded.guard';
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
import { ManualRedactionService } from './services/manual-redaction.service';
import { TablesService } from './services/tables.service';
import { ReplaceNbspPipe } from '@common-ui/pipes/replace-nbsp.pipe';
const routes: IqserRoutes = [
{
@ -154,6 +155,7 @@ const components = [
IqserDenyDirective,
TenantPipe,
LogPipe,
ReplaceNbspPipe,
],
providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard, TablesService],
})

View File

@ -134,7 +134,7 @@ export class AnnotationActionsService {
await this.#processObsAndEmit(zip(requests).pipe(log()));
}
async removeRedaction(redaction: AnnotationWrapper, permissions: AnnotationPermissions) {
async removeRedaction(redactions: AnnotationWrapper[], permissions: AnnotationPermissions) {
const removePermissions: RemoveRedactionPermissions = {
canRemoveOnlyHere: permissions.canRemoveOnlyHere,
canRemoveFromDictionary: permissions.canRemoveFromDictionary,
@ -144,9 +144,9 @@ export class AnnotationActionsService {
const isApprover = this._permissionsService.isApprover(this._state.dossier());
const data = {
redaction,
redactions,
dossier: this._state.dossier(),
falsePositiveContext: this.#getFalsePositiveText(redaction),
falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)),
permissions: removePermissions,
applyToAllDossiers: isApprover ? dossierTemplate.applyDictionaryUpdatesToAllDossiersByDefault : false,
isApprover,
@ -162,9 +162,9 @@ export class AnnotationActionsService {
result.option.value === RemoveRedactionOptions.FALSE_POSITIVE ||
result.option.value === RemoveRedactionOptions.DO_NOT_RECOMMEND
) {
this.#setAsFalsePositive(redaction, result);
this.#setAsFalsePositive(redactions, result);
} else {
this.#removeRedaction(redaction, result);
this.#removeRedaction(redactions, result);
}
}
@ -393,8 +393,8 @@ export class AnnotationActionsService {
return words;
}
#setAsFalsePositive(redaction: AnnotationWrapper, dialogResult: RemoveRedactionResult) {
const request = {
#setAsFalsePositive(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
const requests = redactions.map(redaction => ({
sourceId: redaction.id,
value: this.#getFalsePositiveText(redaction),
type: redaction.type,
@ -406,24 +406,24 @@ export class AnnotationActionsService {
? DictionaryEntryTypes.FALSE_RECOMMENDATION
: DictionaryEntryTypes.FALSE_POSITIVE,
comment: dialogResult.comment ? { text: dialogResult.comment } : null,
};
}));
const { dossierId, fileId } = this._state;
this.#processObsAndEmit(this._manualRedactionService.addAnnotation([request], dossierId, fileId)).then();
this.#processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId)).then();
}
#removeRedaction(redaction: AnnotationWrapper, dialogResult: RemoveRedactionResult) {
#removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER;
const body = {
const body = redactions.map(redaction => ({
annotationId: redaction.id,
comment: dialogResult.comment,
removeFromDictionary,
removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers,
};
}));
// 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, redaction.isHint),
).then();
this.#processObsAndEmit(this._manualRedactionService.removeRedaction(body, dossierId, fileId, removeFromDictionary, isHint)).then();
}
#getRemoveRedactionDialog(data: RemoveRedactionData) {

View File

@ -22,6 +22,7 @@ export class PdfAnnotationActionsService {
readonly #iqserPermissionsService = inject(IqserPermissionsService);
readonly #annotationManager = inject(REDAnnotationManager);
readonly #isDocumine = getConfig().IS_DOCUMINE;
get(annotations: AnnotationWrapper[]): IHeaderElement[] {
const availableActions: IHeaderElement[] = [];
const permissions = this.#getAnnotationsPermissions(annotations);
@ -83,7 +84,7 @@ export class PdfAnnotationActionsService {
if (permissions.canRemoveRedaction) {
const removeRedactionButton = this.#getButton('trash', _('annotation-actions.remove-annotation.remove-redaction'), () =>
this.#annotationActionsService.removeRedaction(annotations[0], permissions),
this.#annotationActionsService.removeRedaction(annotations, permissions),
);
availableActions.push(removeRedactionButton);
}

View File

@ -149,15 +149,16 @@ export const getRemoveRedactionOptions = (
isDocumine: boolean = false,
): DetailsRadioOption<RemoveRedactionOption>[] => {
const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations;
const { permissions, redaction, applyToAllDossiers, isApprover, falsePositiveContext } = data;
const { permissions, redactions, applyToAllDossiers, isApprover, falsePositiveContext } = data;
const isBulk = redactions.length > 1;
const options: DetailsRadioOption<RemoveRedactionOption>[] = [];
if (permissions.canRemoveOnlyHere) {
options.push({
label: translations.ONLY_HERE.label,
description: translations.ONLY_HERE.description,
description: isBulk ? translations.ONLY_HERE.descriptionBulk : translations.ONLY_HERE.description,
descriptionParams: {
value: redaction.value,
value: redactions[0].value,
},
icon: PIN_ICON,
value: RemoveRedactionOptions.ONLY_HERE,
@ -165,9 +166,9 @@ export const getRemoveRedactionOptions = (
}
if (permissions.canRemoveFromDictionary) {
options.push({
label: translations.IN_DOSSIER.label,
description: translations.IN_DOSSIER.description,
descriptionParams: { value: redaction.value, type: redaction.type },
label: isBulk ? translations.IN_DOSSIER.labelBulk : translations.IN_DOSSIER.label,
description: isBulk ? translations.IN_DOSSIER.descriptionBulk : translations.IN_DOSSIER.description,
descriptionParams: { value: redactions[0].value, type: redactions[0].type },
icon: FOLDER_ICON,
value: RemoveRedactionOptions.IN_DOSSIER,
extraOption: !isDocumine
@ -180,11 +181,15 @@ export const getRemoveRedactionOptions = (
});
}
if (permissions.canMarkAsFalsePositive) {
if (data.redaction.isRecommendation) {
if (data.redactions[0].isRecommendation) {
options.push({
label: translations.DO_NOT_RECOMMEND.label,
description: translations.DO_NOT_RECOMMEND.description,
descriptionParams: { value: redaction.value, type: redaction.type, context: falsePositiveContext },
description: isBulk ? translations.DO_NOT_RECOMMEND.descriptionBulk : translations.DO_NOT_RECOMMEND.description,
descriptionParams: {
value: redactions[0].value,
type: redactions[0].type,
context: falsePositiveContext[0],
},
icon: FOLDER_ICON,
value: RemoveRedactionOptions.DO_NOT_RECOMMEND,
extraOption: !isDocumine
@ -198,8 +203,12 @@ export const getRemoveRedactionOptions = (
} else {
options.push({
label: translations.FALSE_POSITIVE.label,
description: translations.FALSE_POSITIVE.description,
descriptionParams: { value: redaction.value, type: redaction.type, context: falsePositiveContext },
description: isBulk ? translations.FALSE_POSITIVE.descriptionBulk : translations.FALSE_POSITIVE.description,
descriptionParams: {
value: redactions[0].value,
type: redactions[0].type,
context: falsePositiveContext[0],
},
icon: REMOVE_FROM_DICT_ICON,
value: RemoveRedactionOptions.FALSE_POSITIVE,
extraOption: !isDocumine

View File

@ -71,9 +71,9 @@ export interface RemoveRedactionPermissions {
}
export interface RemoveRedactionData {
redaction: AnnotationWrapper;
redactions: AnnotationWrapper[];
dossier: Dossier;
falsePositiveContext: string;
falsePositiveContext: string[];
permissions: RemoveRedactionPermissions;
applyToAllDossiers: boolean;
isApprover: boolean;

View File

@ -2,7 +2,9 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
export interface DialogOption {
label: string;
labelBulk?: string;
description: string;
descriptionBulk?: string;
extraOptionLabel?: string;
}

View File

@ -6,17 +6,22 @@ export const removeAnnotationTranslations: { [key in RemoveAnnotationOption]: Di
ONLY_HERE: {
label: _('remove-annotation.dialog.content.options.only-here.label'),
description: _('remove-annotation.dialog.content.options.only-here.description'),
descriptionBulk: _('remove-annotation.dialog.content.options.only-here.description-bulk'),
},
IN_DOSSIER: {
label: _('remove-annotation.dialog.content.options.in-dossier.label'),
labelBulk: _('remove-annotation.dialog.content.options.in-dossier.label-bulk'),
description: _('remove-annotation.dialog.content.options.in-dossier.description'),
descriptionBulk: _('remove-annotation.dialog.content.options.in-dossier.description-bulk'),
},
FALSE_POSITIVE: {
label: _('remove-annotation.dialog.content.options.false-positive.label'),
description: _('remove-annotation.dialog.content.options.false-positive.description'),
descriptionBulk: _('remove-annotation.dialog.content.options.false-positive.description-bulk'),
},
DO_NOT_RECOMMEND: {
label: _('remove-redaction.dialog.content.options.do-not-recommend.label'),
description: _('remove-redaction.dialog.content.options.do-not-recommend.description'),
descriptionBulk: _('remove-redaction.dialog.content.options.do-not-recommend.description-bulk'),
},
};

View File

@ -2036,20 +2036,27 @@
"content": {
"comment": "",
"comment-placeholder": "",
"list-item": "",
"list-item-false-positive": "",
"options": {
"false-positive": {
"description": "",
"description-bulk": "",
"label": ""
},
"in-dossier": {
"description": "",
"label": ""
"description-bulk": "",
"label": "",
"label-bulk": ""
},
"only-here": {
"description": "",
"description-bulk": "",
"label": ""
}
}
},
"redacted-text": ""
},
"title": ""
}
@ -2066,11 +2073,13 @@
"options": {
"do-not-recommend": {
"description": "",
"description-bulk": "",
"extraOptionLabel": "",
"label": ""
},
"false-positive": {
"description": "",
"descriptionBulk": "",
"extraOptionLabel": "",
"label": ""
},
@ -2081,6 +2090,7 @@
},
"only-here": {
"description": "",
"description-bulk": "",
"label": ""
}
}

View File

@ -1252,7 +1252,7 @@
"redacted-text": "Redacted text",
"section": "Paragraph / Location",
"type": "Type",
"unchanged": ""
"unchanged": "Unchanged"
},
"title": "Edit {type, select, image{Image} hint{Hint} other{Redaction}}"
}
@ -2036,22 +2036,29 @@
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"list-item": "",
"list-item-false-positive": "",
"options": {
"false-positive": {
"description": "\"{value}\" is not a \"{type}\" in this context: \"{context}\".",
"description-bulk": "",
"label": "False positive"
},
"in-dossier": {
"description": "Do not annotate \"{value}\" as \"{type}\" in any dossier.",
"label": "No longer annotate as \"{type}\""
"description-bulk": "",
"label": "No longer annotate as \"{type}\"",
"label-bulk": ""
},
"only-here": {
"description": "Do not annotate \"{value}\" at this position in the current document.",
"description-bulk": "",
"label": "Remove here"
}
}
},
"redacted-text": ""
},
"title": "Remove annotation"
"title": "Remove {count, plural, one{annotation} other {annotations}}"
}
},
"remove-redaction": {
@ -2066,11 +2073,13 @@
"options": {
"do-not-recommend": {
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
"description-bulk": "",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier"
},
"false-positive": {
"description": "\"{value}\" is not a {type} in this context: \"{context}\".",
"descriptionBulk": "",
"extraOptionLabel": "Apply to all dossiers",
"label": "False positive"
},
@ -2081,6 +2090,7 @@
},
"only-here": {
"description": "Do not {type, select, undefined{redact} other{type}} \"{value}\" at this position in the current document.",
"description-bulk": "",
"label": "Remove here"
}
}

View File

@ -2036,20 +2036,27 @@
"content": {
"comment": "",
"comment-placeholder": "",
"list-item": "",
"list-item-false-positive": "",
"options": {
"false-positive": {
"description": "",
"description-bulk": "",
"label": ""
},
"in-dossier": {
"description": "",
"label": ""
"description-bulk": "",
"label": "",
"label-bulk": ""
},
"only-here": {
"description": "",
"description-bulk": "",
"label": ""
}
}
},
"redacted-text": ""
},
"title": ""
}
@ -2066,11 +2073,13 @@
"options": {
"do-not-recommend": {
"description": "",
"description-bulk": "",
"extraOptionLabel": "",
"label": ""
},
"false-positive": {
"description": "",
"descriptionBulk": "",
"extraOptionLabel": "",
"label": ""
},
@ -2081,6 +2090,7 @@
},
"only-here": {
"description": "",
"description-bulk": "",
"label": ""
}
}

View File

@ -2036,22 +2036,29 @@
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"list-item": "{text}",
"list-item-false-positive": "\"{text}\" in the context: \"{context}\"",
"options": {
"false-positive": {
"description": "\"{value}\" is not a \"{type}\" in this context: \"{context}\".",
"description-bulk": "The selected items should not be annotated in their respective contexts.",
"label": "False positive"
},
"in-dossier": {
"description": "Do not annotate \"{value}\" as \"{type}\" in any dossier.",
"label": "No longer annotate as \"{type}\""
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
"label": "No longer annotate as \"{type}\"",
"label-bulk": "No longer annotate in any dossier"
},
"only-here": {
"description": "Do not annotate \"{value}\" at this position in the current document.",
"description-bulk": "Do not annotate the selected terms at this position in the current document.",
"label": "Remove here"
}
}
},
"redacted-text": "Selected annotations"
},
"title": "Remove annotation"
"title": "Remove {count, plural, one{annotation} other {annotations}}"
}
},
"remove-redaction": {
@ -2065,12 +2072,14 @@
"comment-placeholder": "Add remarks or mentions ...",
"options": {
"do-not-recommend": {
"description": "",
"extraOptionLabel": "",
"label": ""
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
"description-bulk": "Do not recommend the selected values as their respective types in any document of the current dossier.",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier"
},
"false-positive": {
"description": "\"{value}\" is not a {type} in this context: \"{context}\".",
"descriptionBulk": "The selected values should not be redacted in their respective contexts.",
"extraOptionLabel": "Apply to all dossiers",
"label": "False positive"
},
@ -2081,6 +2090,7 @@
},
"only-here": {
"description": "Do not {type} \"{value}\" at this position in the current document.",
"description-bulk": "",
"label": "Remove here"
}
}