Merge branch 'VM/RED-7588' into 'master'
RED-7588 - Improve the behavior of the add-to-dict text edit in new dialog Closes RED-7588 See merge request redactmanager/red-ui!76
This commit is contained in:
commit
114f52dd71
@ -12,22 +12,24 @@
|
|||||||
"
|
"
|
||||||
class="selected-text"
|
class="selected-text"
|
||||||
></label>
|
></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>
|
<span *ngIf="!isEditingSelectedText">{{ form.get('selectedText').value }}</span>
|
||||||
<textarea
|
<textarea
|
||||||
*ngIf="isEditingSelectedText"
|
*ngIf="isEditingSelectedText"
|
||||||
|
[rows]="selectedTextRows"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
formControlName="selectedText"
|
formControlName="selectedText"
|
||||||
iqserHasScrollbar
|
iqserHasScrollbar
|
||||||
name="comment"
|
name="comment"
|
||||||
rows="4"
|
|
||||||
type="text"
|
type="text"
|
||||||
></textarea>
|
></textarea>
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="isEditingSelectedText = !isEditingSelectedText"
|
(action)="toggleEditingSelectedText()"
|
||||||
*ngIf="dictionaryRequest"
|
*ngIf="dictionaryRequest"
|
||||||
[class.absolute]="isEditingSelectedText"
|
[class.absolute]="isEditingSelectedText"
|
||||||
|
[showDot]="initialText !== form.get('selectedText').value && !isEditingSelectedText"
|
||||||
[tooltip]="'redact-text.dialog.content.edit-text' | translate"
|
[tooltip]="'redact-text.dialog.content.edit-text' | translate"
|
||||||
|
[type]="isEditingSelectedText ? 'dark' : 'default'"
|
||||||
class="edit-button"
|
class="edit-button"
|
||||||
icon="iqser:edit"
|
icon="iqser:edit"
|
||||||
tooltipPosition="below"
|
tooltipPosition="below"
|
||||||
|
|||||||
@ -5,11 +5,18 @@
|
|||||||
|
|
||||||
.selected-text-group > div {
|
.selected-text-group > div {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-button {
|
.edit-button {
|
||||||
top: 0;
|
top: 0;
|
||||||
right: calc((0.5rem + 34px) * -1);
|
right: calc((0.5rem + 34px) * -1);
|
||||||
|
position: sticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
.undo-button {
|
.undo-button {
|
||||||
@ -28,3 +35,11 @@
|
|||||||
.relative {
|
.relative {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fixed-height {
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Component, inject, OnInit } from '@angular/core';
|
import { Component, inject, OnInit } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
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 { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
|
||||||
import { Dictionary, IAddRedactionRequest, SuperTypes } from '@red/domain';
|
import { Dictionary, IAddRedactionRequest, SuperTypes } from '@red/domain';
|
||||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
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 { getRedactOrHintOptions, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-options';
|
||||||
import { RedactTextData, RedactTextResult } from '../../utils/dialog-types';
|
import { RedactTextData, RedactTextResult } from '../../utils/dialog-types';
|
||||||
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';
|
||||||
|
import { calcTextWidthInPixels } from '@utils/functions';
|
||||||
|
|
||||||
|
const MAXIMUM_SELECTED_TEXT_WIDTH = 421;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './redact-text-dialog.component.html',
|
templateUrl: './redact-text-dialog.component.html',
|
||||||
@ -21,19 +24,20 @@ export class RedactTextDialogComponent
|
|||||||
extends IqserDialogComponent<RedactTextDialogComponent, RedactTextData, RedactTextResult>
|
extends IqserDialogComponent<RedactTextDialogComponent, RedactTextData, RedactTextResult>
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
readonly #manualRedactionTypeExists: boolean;
|
||||||
|
readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
|
||||||
|
#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
|
||||||
readonly roles = Roles;
|
readonly roles = Roles;
|
||||||
readonly iconButtonTypes = IconButtonTypes;
|
readonly iconButtonTypes = IconButtonTypes;
|
||||||
readonly options: DetailsRadioOption<RedactOrHintOption>[];
|
readonly options: DetailsRadioOption<RedactOrHintOption>[];
|
||||||
|
readonly form: UntypedFormGroup;
|
||||||
|
readonly initialText: string;
|
||||||
dictionaryRequest = false;
|
dictionaryRequest = false;
|
||||||
legalOptions: LegalBasisOption[] = [];
|
legalOptions: LegalBasisOption[] = [];
|
||||||
dictionaries: Dictionary[] = [];
|
dictionaries: Dictionary[] = [];
|
||||||
readonly form;
|
|
||||||
isEditingSelectedText = false;
|
isEditingSelectedText = false;
|
||||||
readonly initialText: string;
|
|
||||||
modifiedText: string;
|
modifiedText: string;
|
||||||
readonly #manualRedactionTypeExists: boolean;
|
selectedTextRows = 1;
|
||||||
#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
|
|
||||||
readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _justificationsService: JustificationsService,
|
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() {
|
#setDictionaries() {
|
||||||
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierTemplateId, !this.#applyToAllDossiers);
|
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierTemplateId, !this.#applyToAllDossiers);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,3 +115,21 @@ export function moveElementInArray<T>(array: T[], element: T, index: number) {
|
|||||||
result.splice(index, 0, element);
|
result.splice(index, 0, element);
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -2052,11 +2052,11 @@
|
|||||||
},
|
},
|
||||||
"only-here": {
|
"only-here": {
|
||||||
"description": "Do not annotate \"{value}\" at this position in the current document.",
|
"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"
|
"label": "Remove here"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redacted-text": ""
|
"redacted-text": "Selected redactions"
|
||||||
},
|
},
|
||||||
"title": "Remove {count, plural, one{annotation} other {annotations}}"
|
"title": "Remove {count, plural, one{annotation} other {annotations}}"
|
||||||
}
|
}
|
||||||
@ -2070,30 +2070,38 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"comment": "Comment",
|
"comment": "Comment",
|
||||||
"comment-placeholder": "Add remarks or mentions ...",
|
"comment-placeholder": "Add remarks or mentions ...",
|
||||||
|
"list-item": "{text}",
|
||||||
|
"list-item-false-positive": "\"{text}\" in the context: \"{context}\"",
|
||||||
"options": {
|
"options": {
|
||||||
"do-not-recommend": {
|
"do-not-recommend": {
|
||||||
"description": "Do not recommend \"{value}\" as {type} in any document of the current dossier.",
|
"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",
|
"extraOptionLabel": "Apply to all dossiers",
|
||||||
"label": "Remove from dossier"
|
"label": "Remove from dossier"
|
||||||
},
|
},
|
||||||
"false-positive": {
|
"false-positive": {
|
||||||
"description": "\"{value}\" is not a {type} in this context: \"{context}\".",
|
"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",
|
"extraOptionLabel": "Apply to all dossiers",
|
||||||
"label": "False positive"
|
"label": "False positive"
|
||||||
},
|
},
|
||||||
"in-dossier": {
|
"in-dossier": {
|
||||||
"description": "Do not {type} \"{value}\" in any document of the current 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",
|
"extraOptionLabel": "Apply to all dossiers",
|
||||||
"label": "Remove from dossier"
|
"label": "Remove from dossier",
|
||||||
|
"label-bulk": "No longer redact in any dossier"
|
||||||
},
|
},
|
||||||
"only-here": {
|
"only-here": {
|
||||||
"description": "Do not {type, select, undefined{redact} other{type}} \"{value}\" at this position in the current document.",
|
"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"
|
"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": {
|
"report-type": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user