RED-7069, prepopulate relevent info, load reasons, and types. WORK IN PROGRESS.

This commit is contained in:
George 2023-07-26 17:06:24 +03:00
parent 41bf95d3a6
commit 7cc0f4e551
11 changed files with 428 additions and 17 deletions

View File

@ -0,0 +1,89 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div [translate]="'edit-redaction.dialog.title'" class="dialog-header heading-l"></div>
<div class="dialog-content redaction">
<div *ngIf="singleEntry" class="iqser-input-group w-450">
<label [translate]="'edit-redaction.dialog.content.redacted-text'" class="selected-text"></label>
{{ redactedText }}
</div>
<div class="iqser-input-group required w-450">
<label [translate]="'edit-redaction.dialog.content.type'"></label>
<mat-form-field>
<mat-select formControlName="dictionary">
<mat-select-trigger>{{ displayedDictionaryLabel }}</mat-select-trigger>
<mat-option
(click)="typeChanged()"
*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>
<iqser-details-radio
(extraOptionChanged)="extraOptionChanged($event)"
[options]="options"
formControlName="option"
></iqser-details-radio>
<div class="iqser-input-group required w-450">
<label [translate]="'edit-redaction.dialog.content.reason'"></label>
<mat-form-field>
<mat-select 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]="'edit-redaction.dialog.content.legal-basis'"></label>
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div class="iqser-input-group w-400">
<label [translate]="'edit-redaction.dialog.content.section'"></label>
<input formControlName="section" name="section" type="text" />
</div>
<div class="iqser-input-group w-450">
<label [translate]="'edit-redaction.dialog.content.comment'"></label>
<textarea
[placeholder]="'edit-redaction.dialog.content.comment-placeholder' | translate"
formControlName="comment"
iqserHasScrollbar
name="comment"
rows="4"
type="text"
></textarea>
</div>
</div>
<div class="dialog-actions">
<iqser-icon-button
[disabled]="disabled"
[label]="'edit-redaction.dialog.actions.save' | translate"
[submit]="true"
[type]="iconButtonTypes.primary"
>
</iqser-icon-button>
<div [translate]="'edit-redaction.dialog.actions.cancel'" class="all-caps-label cancel" mat-dialog-close></div>
</div>
</form>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
</section>

View File

@ -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<EditRedactionDialogComponent, EditRedactionData, RedactTextResult>
implements OnInit
{
readonly roles = Roles;
readonly iconButtonTypes = IconButtonTypes;
readonly options: DetailsRadioOption<RedactOrHintOption>[];
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<void> {
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<RedactOrHintOption>): 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;
}
}

View File

@ -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,

View File

@ -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) {

View File

@ -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<RedactOrHintOption>[] => [
{
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,

View File

@ -12,6 +12,11 @@ export interface RedactTextData {
isApprover?: boolean;
}
export interface EditRedactionData {
annotations: AnnotationWrapper[];
dossierId: string;
}
export type AddAnnotationData = RedactTextData;
export type AddHintData = RedactTextData;

View File

@ -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;

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",