From 7cc0f4e551c1912f7c54034980931485b9f3a911 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 26 Jul 2023 17:06:24 +0300 Subject: [PATCH] RED-7069, prepopulate relevent info, load reasons, and types. WORK IN PROGRESS. --- .../edit-redaction-dialog.component.html | 89 ++++++++++ .../edit-redaction-dialog.component.ts | 157 ++++++++++++++++++ .../file-preview/file-preview.module.ts | 2 + .../services/annotation-actions.service.ts | 37 +++-- .../file-preview/utils/dialog-options.ts | 27 ++- .../file-preview/utils/dialog-types.ts | 5 + .../translations/redact-text-translations.ts | 12 ++ apps/red-ui/src/assets/i18n/redact/de.json | 29 ++++ apps/red-ui/src/assets/i18n/redact/en.json | 29 ++++ apps/red-ui/src/assets/i18n/scm/de.json | 29 ++++ apps/red-ui/src/assets/i18n/scm/en.json | 29 ++++ 11 files changed, 428 insertions(+), 17 deletions(-) create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html new file mode 100644 index 000000000..6b520c722 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html @@ -0,0 +1,89 @@ +
+
+
+ +
+
+ + {{ redactedText }} +
+ +
+ + + + + {{ displayedDictionaryLabel }} + + {{ dictionary.label }} + + + +
+ + + +
+ + + + + {{ option.label }} + + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + +
+
+
+ + +
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts new file mode 100644 index 000000000..6503a9f3f --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -0,0 +1,157 @@ +import { Component, OnInit } from '@angular/core'; +import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent, IqserPermissionsService } from '@iqser/common-ui'; +import { Dictionary, Dossier, IAddRedactionRequest } from '@red/domain'; +import { FormBuilder, UntypedFormGroup } 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 { getEditRedactionOptions, RedactOrHintOption } from '../../utils/dialog-options'; +import { EditRedactionData, RedactTextResult } from '../../utils/dialog-types'; + +@Component({ + templateUrl: './edit-redaction-dialog.component.html', +}) +export class EditRedactionDialogComponent + extends IqserDialogComponent + implements OnInit +{ + readonly roles = Roles; + readonly iconButtonTypes = IconButtonTypes; + readonly options: DetailsRadioOption[]; + readonly singleEntry: boolean; + readonly redactedText: string; + legalOptions: LegalBasisOption[] = []; + dictionaries: Dictionary[] = []; + form!: UntypedFormGroup; + + #manualRedactionTypeExists = true; + #applyToAllDossiers: boolean; + + readonly #dossier: Dossier; + + constructor( + private readonly _justificationsService: JustificationsService, + private readonly _activeDossiersService: ActiveDossiersService, + private readonly _dictionaryService: DictionaryService, + private readonly _iqserPermissionsService: IqserPermissionsService, + private readonly _formBuilder: FormBuilder, + ) { + super(); + console.log(this.data.annotations); + this.#dossier = _activeDossiersService.find(this.data.dossierId); + this.#applyToAllDossiers = true; + this.#manualRedactionTypeExists = this._dictionaryService.hasManualType(this.#dossier.dossierTemplateId); + this.options = getEditRedactionOptions(this.#dossier, this.#applyToAllDossiers, true); + this.form = this.#getForm(); + this.singleEntry = this.data.annotations.length === 1; + this.redactedText = this.data?.annotations[0].value; + console.log(this.form.value); + } + + get displayedDictionaryLabel() { + const dictType = this.form.get('dictionary').value; + if (dictType) { + return this.dictionaries.find(d => d.type === dictType)?.label ?? null; + } + return null; + } + + get disabled() { + return !this.form.get('reason').value; + } + + async ngOnInit(): Promise { + this.#setDictionaries(); + 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.form.patchValue({ + reason: this.legalOptions.find(o => o.legalBasis === this.data.annotations[0].legalBasis), + }); + + this.legalOptions.sort((a, b) => a.label.localeCompare(b.label)); + } + + extraOptionChanged(option: DetailsRadioOption): void { + this.#applyToAllDossiers = option.extraOption.checked; + + this.#setDictionaries(); + if (this.#applyToAllDossiers && this.form.get('dictionary').value) { + const selectedDictionaryLabel = this.form.get('dictionary').value; + const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryLabel); + if (!selectedDictionary) { + this.form.get('dictionary').setValue(null); + } + } + } + + typeChanged() { + console.log(this.form.value); + if (!this.#applyToAllDossiers) { + const selectedDictionaryType = this.form.get('dictionary').value; + const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType); + this.options[1].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; + } + } + + save(): void { + this.#enhanceManualRedaction(this.data.annotations[0].manualRedactionEntry); + const redaction = this.data.annotations[0].manualRedactionEntry; + this.dialogRef.close({ + redaction, + dictionary: this.dictionaries.find(d => d.type === this.form.get('dictionary').value), + }); + } + + #setDictionaries() { + this.dictionaries = this._dictionaryService.getRedactTextDictionaries( + this.#dossier.dossierTemplateId, + !this.#applyToAllDossiers, + null, + ); + } + + #getForm(): UntypedFormGroup { + return this._formBuilder.group({ + reason: [null], + comment: [null], + dictionary: [this.data.annotations[0].type], + section: [this.data.annotations[0].section], + option: [this.options[0]], + }); + } + + #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { + addRedactionRequest.type = this.form.get('dictionary').value; + addRedactionRequest.section = null; + addRedactionRequest.value = this.form.get('selectedText').value; + + const legalOption: LegalBasisOption = this.form.get('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 = 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.addToAllDossiers = this.#applyToAllDossiers; + } +} diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts b/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts index c0c29f152..e8b48638e 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts @@ -70,6 +70,7 @@ import { AddHintDialogComponent } from './dialogs/add-hint-dialog/add-hint-dialo import { AddAnnotationDialogComponent } from './dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component'; import { RemoveAnnotationDialogComponent } from './dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component'; import { ResizeAnnotationDialogComponent } from './dialogs/docu-mine/resize-annotation-dialog/resize-annotation-dialog.component'; +import { EditRedactionDialogComponent } from './dialogs/edit-redaction-dialog/edit-redaction-dialog.component'; const routes: IqserRoutes = [ { @@ -92,6 +93,7 @@ const dialogs = [ ImportRedactionsDialogComponent, RssDialogComponent, RedactTextDialogComponent, + EditRedactionDialogComponent, AddHintDialogComponent, RemoveRedactionDialogComponent, AddAnnotationDialogComponent, diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 7f0cf09fd..a797f0b0f 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ManualRedactionService } from './manual-redaction.service'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { firstValueFrom, Observable } from 'rxjs'; @@ -45,10 +45,13 @@ import { RemoveRedactionOptions } from '../utils/dialog-options'; import { RemoveAnnotationDialogComponent } from '../dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component'; import { ResizeRedactionDialogComponent } from '../dialogs/resize-redaction-dialog/resize-redaction-dialog.component'; import { ResizeAnnotationDialogComponent } from '../dialogs/docu-mine/resize-annotation-dialog/resize-annotation-dialog.component'; +import { EditRedactionDialogComponent } from '../dialogs/edit-redaction-dialog/edit-redaction-dialog.component'; @Injectable() export class AnnotationActionsService { readonly #isDocumine; + readonly #iqserDialog = inject(IqserDialog); + constructor( private readonly _manualRedactionService: ManualRedactionService, private readonly _dialogService: FilePreviewDialogService, @@ -106,21 +109,23 @@ export class AnnotationActionsService { changeLegalBasis(annotations: AnnotationWrapper[]) { const { dossierId, fileId } = this._state; - this._dialogService.openDialog( - 'changeLegalBasis', - { annotations, dossier: this._state.dossier() }, - (data: { comment: string; legalBasis: string; section: string; value: string }) => { - const body = annotations.map(annotation => ({ - annotationId: annotation.id, - comment: data.comment, - legalBasis: data.legalBasis, - section: data.section, - value: data.value, - })); - - this.#processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId)).then(); - }, - ); + console.log('we here ', annotations); + this._iqserDialog.openDefault(EditRedactionDialogComponent, { data: { annotations, dossierId } }); + // this._dialogService.openDialog( + // 'changeLegalBasis', + // { annotations, dossier: this._state.dossier() }, + // (data: { comment: string; legalBasis: string; section: string; value: string }) => { + // const body = annotations.map(annotation => ({ + // annotationId: annotation.id, + // comment: data.comment, + // legalBasis: data.legalBasis, + // section: data.section, + // value: data.value, + // })); + // + // this.#processObsAndEmit(this._manualRedactionService.changeLegalBasis(body, dossierId, fileId)).then(); + // }, + // ); } async removeRedaction(redaction: AnnotationWrapper, permissions) { diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 257e3f9b5..fde090997 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -1,6 +1,6 @@ import { DetailsRadioOption } from '@iqser/common-ui'; import { addHintTranslations } from '@translations/add-hint-translations'; -import { redactTextTranslations } from '@translations/redact-text-translations'; +import { editRedactionTranslations, redactTextTranslations } from '@translations/redact-text-translations'; import { Dossier } from '@red/domain'; import { removeRedactionTranslations } from '@translations/remove-redaction-translations'; import { RemoveRedactionData } from './dialog-types'; @@ -32,6 +32,31 @@ export const RemoveAnnotationOptions = RemoveRedactionOptions; export type RemoveRedactionOption = keyof typeof RemoveRedactionOptions; export type RemoveAnnotationOption = RemoveRedactionOption; +export const getEditRedactionOptions = ( + dossier: Dossier, + applyToAllDossiers: boolean, + isApprover: boolean, +): DetailsRadioOption[] => [ + { + label: editRedactionTranslations.onlyHere.label, + description: editRedactionTranslations.onlyHere.description, + icon: PIN_ICON, + value: ResizeOptions.ONLY_HERE, + }, + { + label: editRedactionTranslations.inDossier.label, + description: editRedactionTranslations.inDossier.description, + descriptionParams: { dossierName: dossier.dossierName }, + icon: FOLDER_ICON, + value: ResizeOptions.IN_DOSSIER, + extraOption: { + label: editRedactionTranslations.inDossier.extraOptionLabel, + checked: applyToAllDossiers, + hidden: !isApprover, + }, + }, +]; + export const getRedactOrHintOptions = ( dossier: Dossier, isRss: boolean, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 9caddce07..40499fb5e 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -12,6 +12,11 @@ export interface RedactTextData { isApprover?: boolean; } +export interface EditRedactionData { + annotations: AnnotationWrapper[]; + dossierId: string; +} + export type AddAnnotationData = RedactTextData; export type AddHintData = RedactTextData; diff --git a/apps/red-ui/src/app/translations/redact-text-translations.ts b/apps/red-ui/src/app/translations/redact-text-translations.ts index ae4b9cc61..5c149848b 100644 --- a/apps/red-ui/src/app/translations/redact-text-translations.ts +++ b/apps/red-ui/src/app/translations/redact-text-translations.ts @@ -17,3 +17,15 @@ export const redactTextTranslations: Record<'onlyHere' | 'inDossier', DialogOpti extraOptionLabel: _('redact-text.dialog.content.options.in-dossier.extraOptionLabel'), }, } as const; + +export const editRedactionTranslations: Record<'onlyHere' | 'inDossier', DialogOption> = { + onlyHere: { + label: _('edit-redaction.dialog.content.options.only-here.label'), + description: _('edit-redaction.dialog.content.options.only-here.description'), + }, + inDossier: { + label: _('edit-redaction.dialog.content.options.in-dossier.label'), + description: _('edit-redaction.dialog.content.options.in-dossier.description'), + extraOptionLabel: _('edit-redaction.dialog.content.options.in-dossier.extraOptionLabel'), + }, +} as const; diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index b9c5ca2e8..0335ff00e 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1204,6 +1204,35 @@ }, "side-nav-title": "Konfiguration" }, + "edit-redaction": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "legal-basis": "", + "options": { + "in-dossier": { + "description": "", + "extraOptionLabel": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + }, + "reason": "", + "redacted-text": "", + "section": "", + "type": "" + }, + "title": "" + } + }, "entities-listing": { "action": { "delete": "Wörterbuch löschen", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 46a41292f..1f686d949 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1204,6 +1204,35 @@ }, "side-nav-title": "Configurations" }, + "edit-redaction": { + "dialog": { + "actions": { + "cancel": "Cancel", + "save": "Save changes" + }, + "content": { + "comment": "Comment", + "comment-placeholder": "Add remarks or mentions ...", + "legal-basis": "Legal basis", + "options": { + "in-dossier": { + "description": "Edit redaction in every document in {dossierName}.", + "extraOptionLabel": "Apply to all dossiers", + "label": "Change type in dossier" + }, + "only-here": { + "description": "Edit redaction only at this position in this document.", + "label": "Change type only here" + } + }, + "reason": "Reason", + "redacted-text": "Redacted text", + "section": "Paragraph / Location", + "type": "Type" + }, + "title": "Edit Redaction" + } + }, "entities-listing": { "action": { "delete": "Delete Entity", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 4ede6a01c..1a99a7c11 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1204,6 +1204,35 @@ }, "side-nav-title": "Konfiguration" }, + "edit-redaction": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "legal-basis": "", + "options": { + "in-dossier": { + "description": "", + "extraOptionLabel": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + }, + "reason": "", + "redacted-text": "", + "section": "", + "type": "" + }, + "title": "" + } + }, "entities-listing": { "action": { "delete": "Wörterbuch löschen", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index ca50a4eab..773748ad3 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1204,6 +1204,35 @@ }, "side-nav-title": "Configurations" }, + "edit-redaction": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "legal-basis": "", + "options": { + "in-dossier": { + "description": "", + "extraOptionLabel": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + }, + "reason": "", + "redacted-text": "", + "section": "", + "type": "" + }, + "title": "" + } + }, "entities-listing": { "action": { "delete": "Delete Entity",