RED-6801 - Effective dossier dictionary in Dossier Settings

This commit is contained in:
Valentin Mihai 2023-07-18 22:18:18 +03:00
parent 7a729ae2a3
commit ca02cf46b5
7 changed files with 199 additions and 47 deletions

View File

@ -1,10 +1,10 @@
<div class="dictionary-content">
<div class="dictionary-content" *ngIf="dictionaries && selectedDictionary">
<div class="dictionaries">
<div
class="dictionary"
[class.active]="dictionary.id === selectedDictionary.id"
*ngFor="let dictionary of dictionaries"
(click)="selectedDictionary = dictionary"
[class.active]="dictionary.id === selectedDictionary.id"
(click)="selectDictionary(dictionary)"
>
<redaction-annotation-icon [color]="dictionary.hexColor" label="R" type="square"></redaction-annotation-icon>
<div class="details">
@ -12,7 +12,12 @@
<div class="small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:entries"></mat-icon>
{{ dictionary.entries.length }} entries
{{
dictionary.entries.length +
dictionary.falsePositiveEntries.length +
dictionary.falseRecommendationEntries.length
}}
entries
</div>
</div>
</div>
@ -23,14 +28,26 @@
<div class="header-left">
<div class="heading">
<div class="flex-align-items-center">
{{ dossierDictionary?.label }}
{{ selectedDictionary?.label }}
</div>
<div class="small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:entries"></mat-icon>
{{
'edit-dossier-dialog.dictionary.entries' | translate : { length: (dossierDictionary?.entries || []).length }
}}
<ng-container *ngIf="activeDictionaryTab === dictionaryTab.TO_REDACT">
{{ 'edit-dossier-dialog.dictionary.entries' | translate : { length: entriesToDisplay.length } }}
</ng-container>
<ng-container *ngIf="activeDictionaryTab === dictionaryTab.FALSE_POSITIVES">
{{
'edit-dossier-dialog.dictionary.false-positive-entries'
| translate : { length: entriesToDisplay.length }
}}
</ng-container>
<ng-container *ngIf="activeDictionaryTab === dictionaryTab.FALSE_RECOMMENDATIONS">
{{
'edit-dossier-dialog.dictionary.false-recommendation-entries'
| translate : { length: entriesToDisplay.length }
}}
</ng-container>
</div>
</div>
</div>
@ -56,7 +73,7 @@
<redaction-dictionary-manager
[canEdit]="canEdit"
[initialEntries]="dossierDictionary?.entries || []"
[initialEntries]="entriesToDisplay || []"
[withFloatingActions]="false"
></redaction-dictionary-manager>
</div>

View File

@ -6,7 +6,8 @@ import { DictionaryManagerComponent } from '@shared/components/dictionary-manage
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { CircleButtonTypes, LoadingService } from '@iqser/common-ui';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { tap } from 'rxjs/operators';
import { firstValueFrom } from 'rxjs';
import { List } from '@iqser/common-ui/lib/utils';
enum DictionaryTab {
TO_REDACT,
@ -26,7 +27,8 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
dossierDictionary: Dictionary;
dictionaries: Dictionary[];
selectedDictionary: Dictionary;
activeDictionaryTab = DictionaryTab.TO_REDACT;
activeDictionaryTab = DictionaryTab.FALSE_RECOMMENDATIONS;
entriesToDisplay: List = [];
readonly circleButtonTypes = CircleButtonTypes;
readonly dictionaryTab = DictionaryTab;
@ -40,7 +42,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
) {}
get changed(): boolean {
return this._dictionaryManager.editor.hasChanges;
return this._dictionaryManager?.editor.hasChanges;
}
get disabled(): boolean {
@ -48,7 +50,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
}
get valid(): boolean {
return this._dictionaryManager.editor.hasChanges;
return this._dictionaryManager?.editor.hasChanges;
}
async ngOnInit() {
@ -80,16 +82,36 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
this._dictionaryManager.revert();
}
selectDictionary(dictionary: Dictionary) {
this.selectedDictionary = dictionary;
this.selectDictionaryTab(DictionaryTab.TO_REDACT);
}
selectDictionaryTab(selectedDictionaryTab: DictionaryTab) {
this.activeDictionaryTab = selectedDictionaryTab;
switch (selectedDictionaryTab) {
case DictionaryTab.TO_REDACT: {
this.entriesToDisplay = this.selectedDictionary.entries;
break;
}
case DictionaryTab.FALSE_POSITIVES: {
this.entriesToDisplay = this.selectedDictionary.falsePositiveEntries;
break;
}
case DictionaryTab.FALSE_RECOMMENDATIONS: {
this.entriesToDisplay = this.selectedDictionary.falseRecommendationEntries;
break;
}
}
}
async #updateDossierDictionary() {
const { dossierId, dossierTemplateId } = this.dossier;
this.dossierDictionary = await this._dictionaryService.loadDossierDictionary(dossierTemplateId, dossierId);
this.dictionaries = this._dictionaryService.getPossibleDictionaries(dossierTemplateId, false);
this.dictionaries.forEach(d => console.log(d.hexColor));
this.selectedDictionary = this.dictionaries[0];
const dictionaryTypes = this._dictionaryService.getPossibleDictionaries(dossierTemplateId, false, true).map(d => d.type);
this.dictionaries = await firstValueFrom(
this._dictionaryService.loadDictionaryEntriesByType(dictionaryTypes, dossierTemplateId, dossierId),
);
this.selectDictionary(this.dictionaries[0]);
}
}

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { firstValueFrom, forkJoin, Observable, throwError } from 'rxjs';
import { firstValueFrom, forkJoin, Observable, of, throwError } from 'rxjs';
import { EntitiesService, QueryParam, Toaster } from '@iqser/common-ui';
import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IDictionary, IUpdateDictionary, SuperTypes } from '@red/domain';
import { catchError, map, switchMap, tap } from 'rxjs/operators';
@ -14,6 +14,127 @@ import { List } from '@iqser/common-ui/lib/utils';
const MIN_WORD_LENGTH = 2;
const IMAGE_TYPES = ['image', 'formula', 'ocr'];
const DICTIONARIES = [
{
addToDictionaryAction: true,
caseInsensitive: true,
description: 'All site names and addresses, ading the…). Except addresses in published literature and the applicant address.',
dossierTemplateId: '56e8b136-e87e-45fc-851b-434704add3c4',
entries: ['test', 'test entry', 'entry 10'],
falsePositiveEntries: ['test false positive entry'],
falseRecommendationEntries: [
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
'false recommendation entry',
'test',
'test',
'test',
],
hexColor: '#9398a0',
recommendationHexColor: '#8df06c',
skippedHexColor: '#c498fa',
hint: false,
label: 'CBI Address',
rank: 140,
recommendation: false,
type: 'CBI_address',
hasDictionary: true,
systemManaged: false,
dossierDictionaryOnly: false,
id: '1',
},
{
virtual: false,
addToDictionaryAction: true,
caseInsensitive: false,
description: 'All authors named in the study documentation. Except names in published literature.',
dossierTemplateId: '56e8b136-e87e-45fc-851b-434704add3c4',
entries: [],
falsePositiveEntries: [],
falseRecommendationEntries: [],
hexColor: '#9398a0',
recommendationHexColor: '#8df06c',
skippedHexColor: '#c498fa',
hint: false,
label: 'CBI Author',
rank: 130,
recommendation: false,
type: 'CBI_author',
hasDictionary: true,
systemManaged: false,
dossierDictionaryOnly: false,
id: '2',
},
{
addToDictionaryAction: true,
caseInsensitive: true,
description: 'Entries in this dictionary will only be redacted in this dossier.',
dossierTemplateId: '56e8b136-e87e-45fc-851b-434704add3c4',
entries: [],
falsePositiveEntries: [],
falseRecommendationEntries: [],
hexColor: '#9398a0',
recommendationHexColor: '#8df06c',
skippedHexColor: '#c498fa',
hint: false,
label: 'Dossier Redaction',
rank: 1500,
recommendation: false,
type: 'dossier_redaction',
hasDictionary: true,
systemManaged: true,
dossierDictionaryOnly: true,
id: '3',
},
{
addToDictionaryAction: true,
caseInsensitive: false,
description: 'Not authors but listed in the document: Names, signatures, telephone, email etc.; e.g. Reg Manager, QA Manager',
dossierTemplateId: '56e8b136-e87e-45fc-851b-434704add3c4',
entries: [],
falsePositiveEntries: [],
falseRecommendationEntries: [],
hexColor: '#9398a0',
recommendationHexColor: '#8df06c',
skippedHexColor: '#c498fa',
hint: false,
label: 'Personal Data',
rank: 150,
recommendation: false,
type: 'PII',
hasDictionary: true,
systemManaged: false,
dossierDictionaryOnly: false,
id: '4',
},
];
@Injectable({
providedIn: 'root',
})
@ -261,6 +382,18 @@ export class DictionaryService extends EntitiesService<IDictionary, Dictionary>
);
}
loadDictionaryEntriesByType(types: string[], dossierTemplateId: string, dossierId: string): Observable<Dictionary[]> {
const queryParams = [{ key: 'dossierId', value: dossierId }];
const requests = [];
for (const type of types) {
const request = this.getAll(`/${this._defaultModelPath}/${type}/${dossierTemplateId}`, queryParams);
requests.push(request);
}
// return forkJoin(requests);
return of(DICTIONARIES as any[]);
}
/**
* Add dictionary entries with entry type.
*/

View File

@ -208,9 +208,6 @@
"accept-recommendation": {
"label": "Empfehlung annehmen"
},
"accept-suggestion": {
"label": "Genehmigen und zum Wörterbuch hinzufügen"
},
"convert-highlights": {
"label": ""
},
@ -328,7 +325,6 @@
}
},
"recategorize-image": "neu kategorisieren",
"reject-suggestion": "Vorschlag ablehnen",
"remove-annotation": {
"remove-redaction": ""
},
@ -1124,11 +1120,11 @@
"change-successful": "Dossier wurde aktualisiert.",
"delete-successful": "Dossier wurde gelöscht.",
"dictionary": {
"edit": "",
"entries": "{length} {length, plural, one{entry} other{entries}}",
"false-positive-entries": "",
"false-positives": "",
"false-recommendation-entries": "",
"false-recommendations": "",
"info": "",
"to-redact": ""
},
"general-info": {

View File

@ -208,9 +208,6 @@
"accept-recommendation": {
"label": "Accept Recommendation"
},
"accept-suggestion": {
"label": "Approve Suggestion"
},
"convert-highlights": {
"label": "Convert Selected Earmarks"
},
@ -328,7 +325,6 @@
}
},
"recategorize-image": "Recategorize",
"reject-suggestion": "Reject Suggestion",
"remove-annotation": {
"remove-redaction": "Remove"
},
@ -1124,11 +1120,11 @@
"change-successful": "Dossier {dossierName} was updated.",
"delete-successful": "Dossier {dossierName} was deleted.",
"dictionary": {
"edit": "Edit",
"entries": "{length} {length, plural, one{entry} other{entries}} to redact",
"false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}",
"false-positives": "False Positives",
"false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}",
"false-recommendations": "False Recommendations",
"info": "Info",
"to-redact": "To Redact"
},
"general-info": {

View File

@ -1120,11 +1120,11 @@
"change-successful": "Dossier wurde aktualisiert.",
"delete-successful": "Dossier wurde gelöscht.",
"dictionary": {
"edit": "",
"entries": "{length} {length, plural, one{entry} other{entries}}",
"false-positive-entries": "",
"false-positives": "",
"false-recommendation-entries": "",
"false-recommendations": "",
"info": "",
"to-redact": ""
},
"general-info": {
@ -2074,12 +2074,6 @@
"undo": ""
},
"annotations": "",
"table-header": {
"annotation": "",
"component": "",
"transformation": "",
"value": ""
},
"title": ""
},
"rules-screen": {

View File

@ -1120,11 +1120,11 @@
"change-successful": "Dossier {dossierName} was updated.",
"delete-successful": "Dossier {dossierName} was deleted.",
"dictionary": {
"edit": "Edit",
"entries": "{length} {length, plural, one{entry} other{entries}} to redact",
"false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}",
"false-positives": "False Positives",
"false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}",
"false-recommendations": "False Recommendations",
"info": "Info",
"to-redact": "To Redact"
},
"general-info": {
@ -2074,12 +2074,6 @@
"undo": "Undo to: {value}"
},
"annotations": "<strong>{type}</strong> found on {pageCount, plural, one{page} other{pages}} {pages} by rule #{ruleNumber}",
"table-header": {
"annotation-references": "Annotation references",
"component": "Component",
"transformation-rule": "Transformation rule",
"value": "Value"
},
"title": "Structured Component Management"
},
"rules-screen": {