Merge branch 'master' into RED-7550

# Conflicts:
#	apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts
#	apps/red-ui/src/assets/i18n/redact/en.json
This commit is contained in:
Nicoleta Panaghiu 2023-09-14 18:05:16 +03:00
commit f3177c0f65
22 changed files with 249 additions and 76 deletions

View File

@ -4,12 +4,7 @@
</div>
<div class="dialog-content">
<redaction-add-edit-entity
#redactionAddEditEntity
[dossierTemplateId]="data.dossierTemplateId"
[entity]="null"
[readOnly]="false"
></redaction-add-edit-entity>
<redaction-add-edit-entity [dossierTemplateId]="data.dossierTemplateId" [entity]="null"></redaction-add-edit-entity>
</div>
<div class="dialog-actions">

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, inject, ViewChild } from '@angular/core';
import { Component, inject, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
import { BaseDialogComponent, getConfig, IconButtonTypes } from '@iqser/common-ui';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
interface DialogData {
readonly dossierTemplateId: string;
@ -10,7 +10,6 @@ interface DialogData {
@Component({
templateUrl: './add-entity-dialog.component.html',
styleUrls: ['./add-entity-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEntityDialogComponent extends BaseDialogComponent {
@ViewChild(AddEditEntityComponent, { static: true }) private readonly _addEditEntityComponent: AddEditEntityComponent;
@ -30,6 +29,10 @@ export class AddEntityDialogComponent extends BaseDialogComponent {
return this._addEditEntityComponent.changed;
}
get disabled(): boolean {
return this._addEditEntityComponent.disabled;
}
async save(): Promise<void> {
try {
await this._addEditEntityComponent.save();

View File

@ -24,7 +24,7 @@
<div class="separator">·</div>
<form [formGroup]="form">
<form [formGroup]="form" [attr.help-mode-key]="'audit_filter_audit_entries'">
<div class="iqser-input-group w-150 mr-20">
<mat-form-field>
<mat-select (selectionChange)="filterChange()" formControlName="category" id="select-category">
@ -103,7 +103,7 @@
</div>
<div class="cell">
<span class="small-label">{{ log.recordDate | date : 'd MMM yyyy, hh:mm a' }}</span>
<span class="small-label">{{ log.recordDate | date: 'd MMM yyyy, hh:mm a' }}</span>
</div>
<div class="user-column cell">
@ -116,6 +116,7 @@
<div class="action-buttons">
<iqser-circle-button
(action)="openAuditDetails(log)"
[attr.help-mode-key]="'audit_detailed_audit_info'"
*ngIf="log.hasDetails"
[tooltip]="'audit-screen.action.info' | translate"
icon="red:info"

View File

@ -51,7 +51,7 @@
<iqser-circle-button
(action)="openConfigurationsDialog()"
*allow="roles.fileAttributes.writeConfig; if: currentUser.isAdmin"
[attr.help-mode-key]="'upload_file_attribute'"
[attr.help-mode-key]="'configure_csv_mapping'"
[tooltip]="'file-attributes-listing.configurations' | translate"
icon="iqser:settings"
tooltipPosition="above"

View File

@ -10,7 +10,7 @@
<ng-container *ngFor="let placeholder of placeholders">
<div class="placeholder">{{ placeholder.placeholder }}</div>
<div
[innerHTML]="placeholder.descriptionTranslation | translate : { attribute: placeholder.attributeName }"
[innerHTML]="placeholder.descriptionTranslation | translate: { attribute: placeholder.attributeName }"
class="description"
></div>
</ng-container>
@ -25,7 +25,7 @@
(action)="fileInput.click()"
*allow="roles.reportTemplates.upload; if: currentUser.isAdmin"
[tooltip]="'reports-screen.upload-document' | translate"
[attr.help-mode-key]="'reports'"
[attr.help-mode-key]="'upload_report'"
icon="iqser:upload"
></iqser-circle-button>
</div>

View File

@ -60,7 +60,14 @@ export class AnnotationActionsComponent implements OnChanges {
}
get canRemoveRedaction(): boolean {
return (this.#isDocumine || this.annotations.length === 1) && this.annotationPermissions.canRemoveRedaction;
if (this.annotationPermissions.canRemoveRedaction) {
if (this.annotations.length > 1) {
const foundIgnoredHint = this.annotations.find(a => a.isIgnoredHint);
return !foundIgnoredHint && this.#sameType;
}
return true;
}
return false;
}
get viewerAnnotations() {
@ -131,4 +138,9 @@ export class AnnotationActionsComponent implements OnChanges {
helpModeKey(action: string) {
return this.#isDocumine ? `${action}_annotation` : '';
}
get #sameType() {
const type = this.annotations[0].superType;
return this.annotations.every(a => a.superType === type);
}
}

View File

@ -9,10 +9,14 @@ cdk-virtual-scroll-viewport {
max-width: 100% !important;
}
ul {
padding-left: 16px;
}
li {
white-space: nowrap;
text-overflow: ellipsis;
list-style-position: inside;
overflow: hidden;
padding-right: 4px;
padding-right: 10px;
}

View File

@ -12,22 +12,24 @@
"
class="selected-text"
></label>
<div [ngClass]="isEditingSelectedText ? 'flex relative' : 'flex-align-items-center'">
<div [ngClass]="isEditingSelectedText ? 'flex relative' : 'flex-align-items-center'" class="fixed-height">
<span *ngIf="!isEditingSelectedText">{{ form.get('selectedText').value }}</span>
<textarea
*ngIf="isEditingSelectedText"
[rows]="selectedTextRows"
class="w-full"
formControlName="selectedText"
iqserHasScrollbar
name="comment"
rows="4"
type="text"
></textarea>
<iqser-circle-button
(action)="isEditingSelectedText = !isEditingSelectedText"
(action)="toggleEditingSelectedText()"
*ngIf="dictionaryRequest"
[class.absolute]="isEditingSelectedText"
[showDot]="initialText !== form.get('selectedText').value && !isEditingSelectedText"
[tooltip]="'redact-text.dialog.content.edit-text' | translate"
[type]="isEditingSelectedText ? 'dark' : 'default'"
class="edit-button"
icon="iqser:edit"
tooltipPosition="below"

View File

@ -5,11 +5,18 @@
.selected-text-group > div {
gap: 0.5rem;
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.edit-button {
top: 0;
right: calc((0.5rem + 34px) * -1);
position: sticky;
}
.undo-button {
@ -28,3 +35,11 @@
.relative {
position: relative;
}
.fixed-height {
min-height: 40px;
}
textarea {
margin-top: 0;
}

View File

@ -1,6 +1,6 @@
import { Component, inject, OnInit } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormBuilder } from '@angular/forms';
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { Dictionary, IAddRedactionRequest, SuperTypes } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
@ -12,6 +12,9 @@ import { tap } from 'rxjs/operators';
import { getRedactOrHintOptions, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-options';
import { RedactTextData, RedactTextResult } from '../../utils/dialog-types';
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
import { calcTextWidthInPixels } from '@utils/functions';
const MAXIMUM_SELECTED_TEXT_WIDTH = 421;
@Component({
templateUrl: './redact-text-dialog.component.html',
@ -21,19 +24,20 @@ export class RedactTextDialogComponent
extends IqserDialogComponent<RedactTextDialogComponent, RedactTextData, RedactTextResult>
implements OnInit
{
readonly #manualRedactionTypeExists: boolean;
readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
readonly roles = Roles;
readonly iconButtonTypes = IconButtonTypes;
readonly options: DetailsRadioOption<RedactOrHintOption>[];
readonly form: UntypedFormGroup;
readonly initialText: string;
dictionaryRequest = false;
legalOptions: LegalBasisOption[] = [];
dictionaries: Dictionary[] = [];
readonly form;
isEditingSelectedText = false;
readonly initialText: string;
modifiedText: string;
readonly #manualRedactionTypeExists: boolean;
#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
selectedTextRows = 1;
constructor(
private readonly _justificationsService: JustificationsService,
@ -130,6 +134,14 @@ export class RedactTextDialogComponent
});
}
toggleEditingSelectedText() {
this.isEditingSelectedText = !this.isEditingSelectedText;
if (this.isEditingSelectedText) {
const width = calcTextWidthInPixels(this.form.get('selectedText').value);
this.selectedTextRows = Math.ceil(width / MAXIMUM_SELECTED_TEXT_WIDTH);
}
}
#setDictionaries() {
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierTemplateId, !this.#applyToAllDossiers);
}

View File

@ -1,13 +1,51 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div
*ngIf="data.redactions.length === 1"
[innerHTML]="
'remove-redaction.dialog.title' | translate : { type: hint ? 'hint' : recommendation ? 'recommendation' : 'redaction' }
'remove-redaction.dialog.title' | translate: { type: hint ? 'hint' : recommendation ? 'recommendation' : 'redaction' }
"
class="dialog-header heading-l"
></div>
<div
*ngIf="data.redactions.length > 1"
[innerHTML]="
'remove-redaction.dialog.title-bulk' | translate: { type: hint ? 'hint' : recommendation ? 'recommendation' : 'redaction' }
"
class="dialog-header heading-l"
></div>
<div class="dialog-content">
<div class="dialog-content redaction">
<div *ngIf="data.redactions.length > 1">
<label
[translateParams]="{ type: hint ? 'hints' : recommendation ? 'recommendations' : 'redactions' }"
[translate]="'remove-redaction.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-redaction.dialog.content.list-item-false-positive'
: 'remove-redaction.dialog.content.list-item'
)
| translate
: {
text: text,
context: data.falsePositiveContext[idx]
}
| replaceNbsp
}}
</li>
</ul>
</cdk-virtual-scroll-viewport>
</div>
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
<div class="iqser-input-group w-450">

View File

@ -1,3 +1,18 @@
.dialog-content {
height: 408px;
}
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

@ -3,7 +3,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
import { getRemoveRedactionOptions, RemoveRedactionOption } from '../../utils/dialog-options';
import { getRemoveRedactionOptions, RemoveAnnotationOptions, RemoveRedactionOption } from '../../utils/dialog-options';
import { RemoveRedactionData, RemoveRedactionResult } from '../../utils/dialog-types';
@Component({
@ -19,14 +19,16 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
readonly options: DetailsRadioOption<RemoveRedactionOption>[];
readonly recommendation;
readonly hint: boolean;
readonly redactedTexts: string[];
form!: UntypedFormGroup;
#applyToAllDossiers: boolean;
constructor(private readonly _formBuilder: FormBuilder) {
super();
this.recommendation = this.data.redactions.every(r => r.isRecommendation);
this.hint = this.data.redactions.every(r => r.hint);
this.recommendation = this.data.redactions[0].isRecommendation;
this.hint = this.data.redactions[0].hint;
this.options = getRemoveRedactionOptions(this.data);
this.redactedTexts = this.data.redactions.map(annotation => annotation.value);
this.form = this.#getForm();
this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
@ -45,6 +47,10 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
.subscribe();
}
get isFalsePositive(): boolean {
return this.form.get('option').value.value === RemoveAnnotationOptions.FALSE_POSITIVE;
}
save(): void {
this.close(this.form.getRawValue());
}

View File

@ -15,7 +15,7 @@ import {
} from '@red/domain';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { PermissionsService } from '@services/permissions.service';
import { firstValueFrom, from, Observable, zip } from 'rxjs';
import { firstValueFrom, Observable, zip } from 'rxjs';
import { getFirstRelevantTextPart } from '../../../utils';
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
@ -97,7 +97,6 @@ export class AnnotationActionsService {
};
const result = await this.#getEditRedactionDialog(data).result();
console.log(result);
const requests: Observable<unknown>[] = [];
@ -114,22 +113,23 @@ export class AnnotationActionsService {
}));
requests.push(this._manualRedactionService.changeLegalBasis(changeLegalBasisBody, dossierId, fileId));
}
const recategorizeBody: List<IRecategorizationRequest> = annotations.map(annotation => ({
annotationId: annotation.id,
type: result.type ?? annotation.type,
}));
requests.push(this._manualRedactionService.recategorizeRedactions(recategorizeBody, dossierId, fileId));
if (result.type && !annotations.every(annotation => annotation.type === result.type)) {
const recategorizeBody: List<IRecategorizationRequest> = annotations.map(annotation => ({
annotationId: annotation.id,
type: result.type ?? annotation.type,
}));
requests.push(this._manualRedactionService.recategorizeRedactions(recategorizeBody, dossierId, fileId));
}
if (result.comment) {
for (const a of annotations) {
await this._manualRedactionService.addComment(result.comment, a.id, dossierId, fileId);
}
}
if (!requests.length) {
return;
}
if (result.comment) {
requests.push(
from(Promise.all(annotations.map(a => this._manualRedactionService.addComment(result.comment, a.id, dossierId, fileId)))),
);
}
await this.#processObsAndEmit(zip(requests).pipe(log()));
}

View File

@ -1,13 +1,13 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
import { Dictionary, IDictionary } from '@red/domain';
import { booleanAttribute, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
import { FormGroup, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { map, startWith } from 'rxjs/operators';
import { firstValueFrom, Observable } from 'rxjs';
import { toSnakeCase } from '@utils/functions';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { BaseFormComponent, getConfig, LoadingService, Toaster } from '@iqser/common-ui';
import { Dictionary, IDictionary } from '@red/domain';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { toSnakeCase } from '@utils/functions';
import { firstValueFrom, Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
const REDACTION_FIELDS = ['defaultReason'];
@ -20,15 +20,14 @@ interface Color {
}
@Component({
selector: 'redaction-add-edit-entity [entity] [dossierTemplateId] [readOnly]',
selector: 'redaction-add-edit-entity [entity] [dossierTemplateId]',
templateUrl: './add-edit-entity.component.html',
styleUrls: ['./add-edit-entity.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEditEntityComponent extends BaseFormComponent implements OnInit {
@Input() dossierTemplateId: string;
@Input() entity: Dictionary;
@Input() readOnly: boolean;
@Input({ required: true }) dossierTemplateId: string;
@Input({ required: true }) entity: Dictionary;
@Input({ transform: booleanAttribute }) readOnly = false;
@Input() dossierId?: string;
technicalName$: Observable<string>;

View File

@ -6,20 +6,25 @@ export const removeRedactionTranslations: { [key in RemoveRedactionOption]: Dial
ONLY_HERE: {
label: _('remove-redaction.dialog.content.options.only-here.label'),
description: _('remove-redaction.dialog.content.options.only-here.description'),
descriptionBulk: _('remove-redaction.dialog.content.options.only-here.description-bulk'),
},
IN_DOSSIER: {
label: _('remove-redaction.dialog.content.options.in-dossier.label'),
labelBulk: _('remove-redaction.dialog.content.options.in-dossier.label-bulk'),
description: _('remove-redaction.dialog.content.options.in-dossier.description'),
descriptionBulk: _('remove-redaction.dialog.content.options.in-dossier.description-bulk'),
extraOptionLabel: _('remove-redaction.dialog.content.options.in-dossier.extraOptionLabel'),
},
FALSE_POSITIVE: {
label: _('remove-redaction.dialog.content.options.false-positive.label'),
description: _('remove-redaction.dialog.content.options.false-positive.description'),
descriptionBulk: _('remove-redaction.dialog.content.options.false-positive.description-bulk'),
extraOptionLabel: _('remove-redaction.dialog.content.options.false-positive.extraOptionLabel'),
},
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'),
extraOptionLabel: _('remove-redaction.dialog.content.options.do-not-recommend.extraOptionLabel'),
},
};

View File

@ -115,3 +115,21 @@ export function moveElementInArray<T>(array: T[], element: T, index: number) {
result.splice(index, 0, element);
return result;
}
export function calcTextWidthInPixels(text: string): number {
const temporaryElement = document.createElement('span');
document.body.appendChild(temporaryElement);
temporaryElement.style.font = 'times new roman';
temporaryElement.style.fontSize = 13 + 'px';
temporaryElement.style.height = 'auto';
temporaryElement.style.width = 'auto';
temporaryElement.style.position = 'absolute';
temporaryElement.style.whiteSpace = 'no-wrap';
temporaryElement.innerHTML = text;
const width = Math.ceil(temporaryElement.clientWidth);
document.body.removeChild(temporaryElement);
return width;
}

View File

@ -596,5 +596,21 @@
"elementKey": "workload_bulk_selection",
"documentKey": "workload_bulk_selection",
"overlappingElements": ["USER_MENU", "DOCUMENT_INFO"]
},
{
"elementKey": "audit_detailed_audit_info",
"documentKey": "audit_detailed_audit_info"
},
{
"elementKey": "audit_filter_audit_entries",
"documentKey": "audit_filter_audit_entries"
},
{
"elementKey": "configure_csv_mapping",
"documentKey": "configure_csv_mapping"
},
{
"elementKey": "upload_report",
"documentKey": "upload_report"
}
]

View File

@ -2052,11 +2052,11 @@
},
"only-here": {
"description": "Do not annotate \"{value}\" at this position in the current document.",
"description-bulk": "",
"description-bulk": "Do not annotate the selected terms at this position in the current document.",
"label": "Remove here"
}
},
"redacted-text": ""
"redacted-text": "Selected redactions"
},
"title": "Remove {count, plural, one{annotation} other {annotations}}"
}
@ -2070,30 +2070,38 @@
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"list-item": "{text}",
"list-item-false-positive": "\"{text}\" in the context: \"{context}\"",
"options": {
"do-not-recommend": {
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
"description-bulk": "",
"description-bulk": "Do not recommend the selected terms 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}\".",
"description-bulk": "Do not redact the selected terms in their respective context.",
"extraOptionLabel": "Apply to all dossiers",
"label": "False positive"
},
"in-dossier": {
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
"description-bulk": "Do not redact the selected terms as their respective types in any dossier.",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier"
"label": "Remove from dossier",
"label-bulk": "No longer redact in any dossier"
},
"only-here": {
"description": "Do not {type, select, undefined{redact} other{type}} \"{value}\" at this position in the current document.",
"description-bulk": "Do not redact the selected terms at this position in the current document.",
"label": "Remove here"
}
}
},
"redacted-text": "Selected {type}"
},
"title": "Remove {type}"
"title": "Remove {type, select, redaction{redaction} recommendation{recommendation} other{hint}}",
"title-bulk": "Remove {type, select, redaction{redactions} recommendation{recommendations} other{hints}}"
}
},
"report-type": {
@ -2533,4 +2541,4 @@
}
},
"yesterday": "Gestern"
}
}

View File

@ -2052,11 +2052,11 @@
},
"only-here": {
"description": "Do not annotate \"{value}\" at this position in the current document.",
"description-bulk": "",
"description-bulk": "Do not annotate the selected terms at this position in the current document.",
"label": "Remove here"
}
},
"redacted-text": "Redacted {length, plural, one{text} other {texts}}"
"redacted-text": "Selected {length, plural, one{redaction} other {redactions}}"
},
"title": "Remove {count, plural, one{annotation} other {annotations}}"
}
@ -2070,30 +2070,38 @@
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"list-item": "{text}",
"list-item-false-positive": "\"{text}\" in the context: \"{context}\"",
"options": {
"do-not-recommend": {
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
"description-bulk": "",
"description-bulk": "Do not recommend the selected terms 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}\".",
"description-bulk": "Do not redact the selected terms in their respective context.",
"extraOptionLabel": "Apply to all dossiers",
"label": "False positive"
},
"in-dossier": {
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
"description-bulk": "Do not redact the selected terms as their respective types in any dossier.",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier"
"label": "Remove from dossier",
"label-bulk": "No longer redact in any dossier"
},
"only-here": {
"description": "Do not {type, select, undefined{redact} other{type}} \"{value}\" at this position in the current document.",
"description-bulk": "Do not redact the selected terms at this position in the current document.",
"label": "Remove here"
}
}
},
"redacted-text": "Selected {type}"
},
"title": "Remove {type}"
"title": "Remove {type, select, redaction{redaction} recommendation{recommendation} other{hint}}",
"title-bulk": "Remove {type, select, redaction{redactions} recommendation{recommendations} other{hints}}"
}
},
"report-type": {
@ -2533,4 +2541,4 @@
}
},
"yesterday": "Yesterday"
}
}

View File

@ -2070,6 +2070,8 @@
"content": {
"comment": "",
"comment-placeholder": "",
"list-item": "",
"list-item-false-positive": "",
"options": {
"do-not-recommend": {
"description": "",
@ -2079,21 +2081,27 @@
},
"false-positive": {
"description": "",
"description-bulk": "",
"extraOptionLabel": "",
"label": ""
},
"in-dossier": {
"description": "",
"description-bulk": "",
"extraOptionLabel": "",
"label": ""
"label": "",
"label-bulk": ""
},
"only-here": {
"description": "",
"description-bulk": "",
"label": ""
}
}
},
"redacted-text": ""
},
"title": ""
"title": "",
"title-bulk": ""
}
},
"report-type": {

View File

@ -2070,6 +2070,8 @@
"content": {
"comment": "Comment",
"comment-placeholder": "Add remarks or mentions ...",
"list-item": "",
"list-item-false-positive": "",
"options": {
"do-not-recommend": {
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
@ -2079,21 +2081,27 @@
},
"false-positive": {
"description": "\"{value}\" is not a {type} in this context: \"{context}\".",
"description-bulk": "",
"extraOptionLabel": "Apply to all dossiers",
"label": "False positive"
},
"in-dossier": {
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
"description-bulk": "",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier"
"label": "Remove from dossier",
"label-bulk": ""
},
"only-here": {
"description": "Do not {type} \"{value}\" at this position in the current document.",
"description-bulk": "",
"label": "Remove here"
}
}
},
"redacted-text": ""
},
"title": "Remove {type}"
"title": "Remove {type}",
"title-bulk": ""
}
},
"report-type": {