RED-6774 - added redact dialog
This commit is contained in:
parent
532ee9fa06
commit
0350eb4124
@ -2,6 +2,8 @@ import { IManualRedactionEntry } from '@red/domain';
|
||||
|
||||
export const ManualRedactionEntryTypes = {
|
||||
DICTIONARY: 'DICTIONARY',
|
||||
REDACT: 'REDACT',
|
||||
HINT: 'HINT',
|
||||
REDACTION: 'REDACTION',
|
||||
FALSE_POSITIVE: 'FALSE_POSITIVE',
|
||||
} as const;
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div [translate]="'redact-text.dialog.title'" class="dialog-header heading-l"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="iqser-input-group w-450">
|
||||
<label [translate]="'redact-text.dialog.content.selected-text'"></label>
|
||||
{{ form.get('selectedText').value }}
|
||||
</div>
|
||||
|
||||
<iqser-details-radio [options]="options" formControlName="option"></iqser-details-radio>
|
||||
|
||||
<ng-container *deny="roles.getRss; if: !dictionaryRequest">
|
||||
<div class="iqser-input-group required w-450">
|
||||
<label [translate]="'redact-text.dialog.content.reason'"></label>
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
[placeholder]="'redact-text.dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
<mat-option
|
||||
*ngFor="let option of legalOptions"
|
||||
[matTooltip]="option.description"
|
||||
[value]="option"
|
||||
matTooltipPosition="after"
|
||||
>
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-450">
|
||||
<label [translate]="'redact-text.dialog.content.legal-basis'"></label>
|
||||
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *deny="roles.getRss; if: dictionaryRequest">
|
||||
<div class="iqser-input-group required w-450">
|
||||
<label [translate]="'redact-text.dialog.content.type'"></label>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="dictionary" [placeholder]="'redact-text.dialog.content.type-placeholder' | translate">
|
||||
<mat-select-trigger>{{ displayedDictionaryLabel }}</mat-select-trigger>
|
||||
<mat-option
|
||||
*ngFor="let dictionary of dictionaries"
|
||||
[matTooltip]="dictionary.description"
|
||||
[value]="dictionary.type"
|
||||
matTooltipPosition="after"
|
||||
>
|
||||
<span> {{ dictionary.label }} </span>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="iqser-input-group w-450">
|
||||
<label [translate]="'redact-text.dialog.content.comment'"></label>
|
||||
<textarea
|
||||
formControlName="comment"
|
||||
iqserHasScrollbar
|
||||
name="comment"
|
||||
rows="4"
|
||||
type="text"
|
||||
[placeholder]="'redact-text.dialog.content.comment-placeholder' | translate"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
[disabled]="disabled"
|
||||
[label]="'redact-text.dialog.actions.save' | translate"
|
||||
[submit]="true"
|
||||
[type]="iconButtonTypes.primary"
|
||||
>
|
||||
</iqser-icon-button>
|
||||
|
||||
<div class="all-caps-label cancel" mat-dialog-close [translate]="'redact-text.dialog.actions.cancel'"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||
</section>
|
||||
@ -0,0 +1,4 @@
|
||||
label {
|
||||
font-weight: bold;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { BaseDialogComponent, DetailsRadioOption, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Dictionary, Dossier, File, IAddRedactionRequest } from '@red/domain';
|
||||
import { UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { Roles } from '@users/roles';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ManualRedactionEntryType, ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { redactTextTranslations } from '@translations/redact-text-translations';
|
||||
import { RedactTextOption, RedactTextOptions } from './redact-text-options';
|
||||
|
||||
const PIN_ICON = 'red:push-pin';
|
||||
const FOLDER_ICON = 'red:folder';
|
||||
|
||||
@Component({
|
||||
templateUrl: './redact-text-dialog.component.html',
|
||||
styleUrls: ['./redact-text-dialog.component.scss'],
|
||||
})
|
||||
export class RedactTextDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
readonly roles = Roles;
|
||||
readonly options: DetailsRadioOption<RedactTextOption>[];
|
||||
dictionaryRequest = false;
|
||||
legalOptions: LegalBasisOption[] = [];
|
||||
dictionaries: Dictionary[] = [];
|
||||
|
||||
readonly #translations = redactTextTranslations;
|
||||
readonly #dossier: Dossier;
|
||||
readonly #type: ManualRedactionEntryType;
|
||||
|
||||
constructor(
|
||||
private _justificationsService: JustificationsService,
|
||||
private _activeDossiersService: ActiveDossiersService,
|
||||
private _dictionaryService: DictionaryService,
|
||||
private _iqserPermissionsService: IqserPermissionsService,
|
||||
protected readonly _dialogRef: MatDialogRef<RedactTextDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string; file: File },
|
||||
) {
|
||||
super(_dialogRef);
|
||||
|
||||
this.#dossier = _activeDossiersService.find(this.data.dossierId);
|
||||
this.#type = this.data.manualRedactionEntryWrapper.type;
|
||||
this.options = this.#options();
|
||||
|
||||
this.form = this.#getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.dictionaries = await this._dictionaryService.getDictionariesOptions(this.#dossier.dossierTemplateId, this.#dossier.id);
|
||||
|
||||
const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId));
|
||||
this.legalOptions = data.map(lbm => ({
|
||||
legalBasis: lbm.reason,
|
||||
description: lbm.description,
|
||||
label: lbm.name,
|
||||
}));
|
||||
|
||||
this.#selectReason();
|
||||
this.#formatSelectedTextValue();
|
||||
}
|
||||
|
||||
get displayedDictionaryLabel() {
|
||||
const dictType = this.form.get('dictionary').value;
|
||||
if (dictType) {
|
||||
return this.dictionaries.find(d => d.type === dictType).label;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
|
||||
try {
|
||||
const annotation = this.data.manualRedactionEntryWrapper.manualRedactionEntry;
|
||||
this._dialogRef.close({
|
||||
annotation,
|
||||
dictionary: this.dictionaries.find(d => d.type === this.form.get('dictionary').value),
|
||||
});
|
||||
} catch (e) {
|
||||
this._toaster.error(_('manual-annotation.dialog.error'));
|
||||
}
|
||||
}
|
||||
|
||||
// toggleType() {
|
||||
// console.log('test');
|
||||
// this.dictionaryRequest = this.form.get('option').value === RedactTextOptions.IN_DOSSIER;
|
||||
// }
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
return this._formBuilder.group({
|
||||
selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
|
||||
reason: [null],
|
||||
comment: [null],
|
||||
dictionary: [null, Validators.required],
|
||||
classification: '',
|
||||
multiplePages: '',
|
||||
option: [this.options[0], Validators.required],
|
||||
});
|
||||
}
|
||||
|
||||
#formatSelectedTextValue(): void {
|
||||
this.data.manualRedactionEntryWrapper.manualRedactionEntry.value =
|
||||
this.data.manualRedactionEntryWrapper.manualRedactionEntry.value.replace(
|
||||
// eslint-disable-next-line no-control-regex,max-len
|
||||
/([^\s\d-]{2,})[-\u00AD]\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]/gi,
|
||||
'$1',
|
||||
);
|
||||
}
|
||||
|
||||
#selectReason() {
|
||||
if (this.legalOptions.length === 1) {
|
||||
this.form.get('reason').setValue(this.legalOptions[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
|
||||
const legalOption: LegalBasisOption = this.form.get('reason').value;
|
||||
addRedactionRequest.type = this.form.get('dictionary').value;
|
||||
if (legalOption) {
|
||||
addRedactionRequest.reason = legalOption.description;
|
||||
addRedactionRequest.legalBasis = legalOption.legalBasis;
|
||||
}
|
||||
|
||||
if (this._iqserPermissionsService.has(Roles.getRss)) {
|
||||
const selectedType = this.dictionaries.find(d => d.type === addRedactionRequest.type);
|
||||
addRedactionRequest.addToDictionary = selectedType.hasDictionary;
|
||||
} else {
|
||||
addRedactionRequest.addToDictionary = this.dictionaryRequest && addRedactionRequest.type !== 'dossier_redaction';
|
||||
addRedactionRequest.addToDossierDictionary = this.dictionaryRequest && addRedactionRequest.type === 'dossier_redaction';
|
||||
}
|
||||
|
||||
if (!addRedactionRequest.reason) {
|
||||
addRedactionRequest.reason = 'Dictionary Request';
|
||||
}
|
||||
const commentValue = this.form.get('comment').value;
|
||||
addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
|
||||
addRedactionRequest.section = this.form.get('section').value;
|
||||
addRedactionRequest.value = addRedactionRequest.rectangle
|
||||
? this.form.get('classification').value
|
||||
: this.form.get('selectedText').value;
|
||||
}
|
||||
|
||||
#options() {
|
||||
return [
|
||||
{
|
||||
label: this.#translations[this.#type].onlyHere.label,
|
||||
description: this.#translations[this.#type].onlyHere.description,
|
||||
icon: PIN_ICON,
|
||||
value: RedactTextOptions.ONLY_HERE,
|
||||
},
|
||||
{
|
||||
label: this.#translations[this.#type].inDossier.label,
|
||||
description: this.#translations[this.#type].inDossier.description,
|
||||
icon: FOLDER_ICON,
|
||||
value: RedactTextOptions.IN_DOSSIER,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
export const RedactTextOptions = {
|
||||
ONLY_HERE: 'ONLY_HERE',
|
||||
IN_DOSSIER: 'IN_DOSSIER',
|
||||
} as const;
|
||||
|
||||
export type RedactTextOption = keyof typeof RedactTextOptions;
|
||||
@ -40,7 +40,7 @@ import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationDrawService } from '../pdf-viewer/services/annotation-draw.service';
|
||||
import { AnnotationProcessingService } from './services/annotation-processing.service';
|
||||
import { Dictionary, File, ViewModes } from '@red/domain';
|
||||
import { Dictionary, File, IManualRedactionEntry, ViewModes } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { combineLatest, firstValueFrom, of, pairwise } from 'rxjs';
|
||||
import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.service';
|
||||
@ -165,15 +165,15 @@ export class FilePreviewScreenComponent
|
||||
});
|
||||
|
||||
effect(() => {
|
||||
const selectedText = this._documentViewer.selectedText();
|
||||
const canPerformActions = this.pdfProxyService.canPerformActions();
|
||||
const isCurrentPageExcluded = this.state.file().isPageExcluded(this.pdf.currentPage());
|
||||
|
||||
if ((selectedText.length > 2 || this._isJapaneseString(selectedText)) && canPerformActions && !isCurrentPageExcluded) {
|
||||
this.pdf.enable(textActions);
|
||||
} else {
|
||||
this.pdf.disable(textActions);
|
||||
}
|
||||
// const selectedText = this._documentViewer.selectedText();
|
||||
// const canPerformActions = this.pdfProxyService.canPerformActions();
|
||||
// const isCurrentPageExcluded = this.state.file().isPageExcluded(this.pdf.currentPage());
|
||||
//
|
||||
// if ((selectedText.length > 2 || this._isJapaneseString(selectedText)) && canPerformActions && !isCurrentPageExcluded) {
|
||||
// this.pdf.enable(textActions);
|
||||
// } else {
|
||||
// this.pdf.disable(textActions);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
@ -364,6 +364,34 @@ export class FilePreviewScreenComponent
|
||||
});
|
||||
}
|
||||
|
||||
openRedactTextDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) {
|
||||
return this._ngZone.run(() => {
|
||||
const file = this.state.file();
|
||||
|
||||
manualRedactionEntryWrapper.manualRedactionEntry.value = 'This is selected text';
|
||||
this._dialogService.openDialog(
|
||||
'redactText',
|
||||
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
|
||||
(result: { annotation: IManualRedactionEntry; dictionary?: Dictionary }) => {
|
||||
const selectedAnnotations = this._annotationManager.selected;
|
||||
if (selectedAnnotations.length > 0) {
|
||||
this._annotationManager.delete([selectedAnnotations[0].Id]);
|
||||
}
|
||||
|
||||
const add$ = this._manualRedactionService.addAnnotation(
|
||||
[result.annotation],
|
||||
this.dossierId,
|
||||
this.fileId,
|
||||
result.dictionary?.label,
|
||||
);
|
||||
|
||||
const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file)));
|
||||
return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined))));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
toggleFullScreen() {
|
||||
this.fullScreen = !this.fullScreen;
|
||||
if (this.fullScreen) {
|
||||
@ -623,6 +651,10 @@ export class FilePreviewScreenComponent
|
||||
this.openManualAnnotationDialog($event);
|
||||
});
|
||||
|
||||
this.addActiveScreenSubscription = this.pdfProxyService.redactTextRequested$.subscribe($event => {
|
||||
this.openRedactTextDialog($event);
|
||||
});
|
||||
|
||||
this.addActiveScreenSubscription = this.pdfProxyService.pageChanged$.subscribe(page =>
|
||||
this._ngZone.run(() => this.#updateQueryParamsPage(page)),
|
||||
);
|
||||
|
||||
@ -65,6 +65,7 @@ import { PagesComponent } from './components/pages/pages.component';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { SharedDossiersModule } from '../shared-dossiers/shared-dossiers.module';
|
||||
import { FalsePositiveDialogComponent } from './dialogs/false-positive-dialog/false-positive-dialog.component';
|
||||
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{
|
||||
@ -89,6 +90,7 @@ const dialogs = [
|
||||
ImportRedactionsDialogComponent,
|
||||
RssDialogComponent,
|
||||
FalsePositiveDialogComponent,
|
||||
RedactTextDialogComponent,
|
||||
];
|
||||
|
||||
const components = [
|
||||
|
||||
@ -11,6 +11,7 @@ import { ResizeAnnotationDialogComponent } from '../dialogs/resize-annotation-di
|
||||
import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
import { RssDialogComponent } from '../dialogs/rss-dialog/rss-dialog.component';
|
||||
import { FalsePositiveDialogComponent } from '../dialogs/false-positive-dialog/false-positive-dialog.component';
|
||||
import { RedactTextDialogComponent } from '../dialogs/redact-text-dialog/redact-text-dialog.component';
|
||||
|
||||
type DialogType =
|
||||
| 'confirm'
|
||||
@ -23,7 +24,8 @@ type DialogType =
|
||||
| 'forceAnnotation'
|
||||
| 'manualAnnotation'
|
||||
| 'highlightAction'
|
||||
| 'falsePositive';
|
||||
| 'falsePositive'
|
||||
| 'redactText';
|
||||
|
||||
@Injectable()
|
||||
export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
@ -65,6 +67,9 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
falsePositive: {
|
||||
component: FalsePositiveDialogComponent,
|
||||
},
|
||||
redactText: {
|
||||
component: RedactTextDialogComponent,
|
||||
},
|
||||
};
|
||||
|
||||
constructor(protected readonly _dialog: MatDialog) {
|
||||
|
||||
@ -42,6 +42,7 @@ import Quad = Core.Math.Quad;
|
||||
export class PdfProxyService {
|
||||
readonly annotationSelected$ = this.#annotationSelected$;
|
||||
readonly manualAnnotationRequested$ = new Subject<ManualRedactionEntryWrapper>();
|
||||
readonly redactTextRequested$ = new Subject<ManualRedactionEntryWrapper>();
|
||||
readonly pageChanged$ = this._pdf.pageChanged$.pipe(
|
||||
tap(() => this._handleCustomActions()),
|
||||
tap(() => this._pdf.resetAnnotationActions()),
|
||||
@ -60,6 +61,7 @@ export class PdfProxyService {
|
||||
? this._convertPath('/assets/icons/general/pdftron-action-add-component.svg')
|
||||
: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
|
||||
readonly #addDictIcon = this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg');
|
||||
readonly #addHintIcon = this._convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
|
||||
|
||||
constructor(
|
||||
private readonly _translateService: TranslateService,
|
||||
@ -157,6 +159,19 @@ export class PdfProxyService {
|
||||
}
|
||||
|
||||
if (this._iqserPermissionsService.has(Roles.redactions.write) || this._iqserPermissionsService.has(Roles.redactions.request)) {
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.REDACT_TEXT,
|
||||
img: this.#addRedactionIcon,
|
||||
onClick: () => this._ngZone.run(() => this._redactText(ManualRedactionEntryTypes.REDACT)),
|
||||
});
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_HINT,
|
||||
img: this.#addHintIcon,
|
||||
onClick: () => this._ngZone.run(() => this._redactText(ManualRedactionEntryTypes.HINT)),
|
||||
});
|
||||
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_REDACTION,
|
||||
@ -189,6 +204,13 @@ export class PdfProxyService {
|
||||
this.manualAnnotationRequested$.next({ manualRedactionEntry, type });
|
||||
}
|
||||
|
||||
private _redactText(type: ManualRedactionEntryType) {
|
||||
const selectedQuads: Record<string, Quad[]> = this._pdf.documentViewer.getSelectedTextQuads();
|
||||
const text = this._documentViewer.selectedText();
|
||||
const manualRedactionEntry = this._getManualRedaction(selectedQuads, text, true);
|
||||
this.redactTextRequested$.next({ manualRedactionEntry, type });
|
||||
}
|
||||
|
||||
private _handleCustomActions() {
|
||||
const isCurrentPageExcluded = this._state.file().isPageExcluded(this._pdf.currentPage());
|
||||
|
||||
@ -208,7 +230,7 @@ export class PdfProxyService {
|
||||
this._pdf.enable(TEXT_POPUPS_TO_TOGGLE);
|
||||
this._viewerHeaderService.enable(HEADER_ITEMS_TO_TOGGLE);
|
||||
|
||||
if (this._documentViewer.selectedText().length > 2) {
|
||||
if (this._documentViewer.selectedText()?.length > 2) {
|
||||
this._pdf.enable([TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE]);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -29,6 +29,8 @@ export const HeaderElements = {
|
||||
export type HeaderElementType = ValuesOf<typeof HeaderElements>;
|
||||
|
||||
export const TextPopups = {
|
||||
REDACT_TEXT: 'redact-text',
|
||||
ADD_HINT: 'add-hint',
|
||||
ADD_REDACTION: 'add-redaction',
|
||||
ADD_DICTIONARY: 'add-dictionary',
|
||||
ADD_RECTANGLE: 'add-rectangle',
|
||||
|
||||
@ -63,6 +63,7 @@ export class IconsModule {
|
||||
'padding-top-bottom',
|
||||
'page',
|
||||
'preview',
|
||||
'push-pin',
|
||||
'put-back',
|
||||
'read-only',
|
||||
'ready-for-approval',
|
||||
|
||||
@ -144,12 +144,12 @@ export class REDDocumentViewer {
|
||||
}
|
||||
|
||||
#listenForDocEvents() {
|
||||
this.#document.addEventListener('textSelected', ([, selectedText, pageNumber]: [Quad, string, number]) => {
|
||||
this.#ngZone.run(() => {
|
||||
this.#disableTextPopupIfCompareMode(pageNumber);
|
||||
this.#selectedText.set(selectedText);
|
||||
});
|
||||
});
|
||||
// this.#document.addEventListener('textSelected', ([, selectedText, pageNumber]: [Quad, string, number]) => {
|
||||
// this.#ngZone.run(() => {
|
||||
// this.#disableTextPopupIfCompareMode(pageNumber);
|
||||
// this.#selectedText.set(selectedText);
|
||||
// });
|
||||
// });
|
||||
|
||||
this.#document.addEventListener('pageComplete', event => {
|
||||
this.#ngZone.run(() => {
|
||||
|
||||
29
apps/red-ui/src/app/translations/redact-text-translations.ts
Normal file
29
apps/red-ui/src/app/translations/redact-text-translations.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
interface Option {
|
||||
label: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const redactTextTranslations: Record<'REDACT' | 'HINT', Record<'onlyHere' | 'inDossier', Option>> = {
|
||||
REDACT: {
|
||||
onlyHere: {
|
||||
label: _('redact-text.dialog.content.options.redact.only-here.label'),
|
||||
description: _('redact-text.dialog.content.options.redact.only-here.description'),
|
||||
},
|
||||
inDossier: {
|
||||
label: _('redact-text.dialog.content.options.redact.in-dossier.label'),
|
||||
description: _('redact-text.dialog.content.options.redact.in-dossier.description'),
|
||||
},
|
||||
},
|
||||
HINT: {
|
||||
onlyHere: {
|
||||
label: _('redact-text.dialog.content.options.hint.only-here.label'),
|
||||
description: _('redact-text.dialog.content.options.hint.only-here.description'),
|
||||
},
|
||||
inDossier: {
|
||||
label: _('redact-text.dialog.content.options.hint.in-dossier.label'),
|
||||
description: _('redact-text.dialog.content.options.hint.in-dossier.description'),
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
@ -1900,6 +1900,47 @@
|
||||
},
|
||||
"header": "Bildtypen bearbeiten"
|
||||
},
|
||||
"redact-text": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
"cancel": "",
|
||||
"save": ""
|
||||
},
|
||||
"content": {
|
||||
"comment": "",
|
||||
"comment-placeholder": "",
|
||||
"legal-basis": "",
|
||||
"options": {
|
||||
"hint": {
|
||||
"in-dossier": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"only-here": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"redact": {
|
||||
"in-dossier": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"only-here": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"reason": "",
|
||||
"reason-placeholder": "",
|
||||
"selected-text": "",
|
||||
"type": "",
|
||||
"type-placeholder": ""
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
},
|
||||
"redaction-abbreviation": "R",
|
||||
"references": "",
|
||||
"remove-annotations-dialog": {
|
||||
|
||||
@ -1900,6 +1900,47 @@
|
||||
},
|
||||
"header": "Edit Image Type"
|
||||
},
|
||||
"redact-text": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
"cancel": "Cancel",
|
||||
"save": "Save"
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions ...",
|
||||
"legal-basis": "Legal Basis",
|
||||
"options": {
|
||||
"hint": {
|
||||
"in-dossier": {
|
||||
"description": "Add hint in every document in Dossier Alpha.",
|
||||
"label": "Add hint in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Add hint only at this position in this document.",
|
||||
"label": "Add hint only here"
|
||||
}
|
||||
},
|
||||
"redact": {
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in Dossier Alpha.",
|
||||
"label": "Redact in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Add redaction only at this position in this document.",
|
||||
"label": "Redact only here"
|
||||
}
|
||||
}
|
||||
},
|
||||
"reason": "Reason",
|
||||
"reason-placeholder": "Select a reason ...",
|
||||
"selected-text": "Selected text:",
|
||||
"type": "Type",
|
||||
"type-placeholder": "Select type ..."
|
||||
},
|
||||
"title": "Redact text"
|
||||
}
|
||||
},
|
||||
"redaction-abbreviation": "R",
|
||||
"references": "{count} {count, plural, one{reference} other{references}}",
|
||||
"remove-annotations-dialog": {
|
||||
|
||||
@ -1900,6 +1900,47 @@
|
||||
},
|
||||
"header": "Bildtypen bearbeiten"
|
||||
},
|
||||
"redact-text": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
"cancel": "",
|
||||
"save": ""
|
||||
},
|
||||
"content": {
|
||||
"comment": "",
|
||||
"comment-placeholder": "",
|
||||
"legal-basis": "",
|
||||
"options": {
|
||||
"hint": {
|
||||
"in-dossier": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"only-here": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"redact": {
|
||||
"in-dossier": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"only-here": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"reason": "",
|
||||
"reason-placeholder": "",
|
||||
"selected-text": "",
|
||||
"type": "",
|
||||
"type-placeholder": ""
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
},
|
||||
"redaction-abbreviation": "C",
|
||||
"references": "",
|
||||
"remove-annotations-dialog": {
|
||||
|
||||
@ -1900,6 +1900,47 @@
|
||||
},
|
||||
"header": "Edit Image Type"
|
||||
},
|
||||
"redact-text": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
"cancel": "Cancel",
|
||||
"save": "Save"
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions ...",
|
||||
"legal-basis": "Legal Basis",
|
||||
"options": {
|
||||
"hint": {
|
||||
"in-dossier": {
|
||||
"description": "Add hint in every document in Dossier Alpha.",
|
||||
"label": "Add hint in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Add hint only at this position in this document.",
|
||||
"label": "Add hint only here"
|
||||
}
|
||||
},
|
||||
"redact": {
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in Dossier Alpha.",
|
||||
"label": "Redact in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Add redaction only at this position in this document.",
|
||||
"label": "Redact only here"
|
||||
}
|
||||
}
|
||||
},
|
||||
"reason": "Reason",
|
||||
"reason-placeholder": "Select a reason ...",
|
||||
"selected-text": "Selected text:",
|
||||
"type": "Type",
|
||||
"type-placeholder": "Select type ..."
|
||||
},
|
||||
"title": "Redact text"
|
||||
}
|
||||
},
|
||||
"redaction-abbreviation": "C",
|
||||
"references": "{count} {count, plural, one{reference} other{references}}",
|
||||
"remove-annotations-dialog": {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" version="1.1" viewBox="0 0 16 16" width="16px"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Redacted" stroke="none" stroke-width="1">
|
||||
<circle fill="#94989f" cx="8" cy="8" r="8" />
|
||||
<text fill="#FFFFFF" font-family="Arial, Helvetica, sans-serif" font-size="11" font-weight="500"
|
||||
id="H">
|
||||
<tspan x="4" y="12">H</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
@ -3,7 +3,7 @@
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Redacted" stroke="none" stroke-width="1">
|
||||
<rect fill="#283241" height="16" id="Rectangle" width="16" x="0" y="0"></rect>
|
||||
<text fill="#FFFFFF" font-family="Inter-SemiBold, Inter" font-size="11" font-weight="500"
|
||||
<text fill="#FFFFFF" font-family="Arial, Helvetica, sans-serif" font-size="11" font-weight="500"
|
||||
id="H">
|
||||
<tspan x="4.421875" y="12">R</tspan>
|
||||
</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 519 B After Width: | Height: | Size: 526 B |
3
apps/red-ui/src/assets/icons/general/push-pin.svg
Normal file
3
apps/red-ui/src/assets/icons/general/push-pin.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M75.5002 10L79.4998 55H85V65H55V100H45V65H15V55H20.5002L24.4998 10H20V0H80V10H75.5002ZM34.4995 10L30.4998 55H69.4991L65.4995 10H34.4995Z" fill="#283241"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 311 B |
Loading…
x
Reference in New Issue
Block a user