RED-4151: download dictionary / false positives / false recommendations

This commit is contained in:
Adina Țeudan 2022-06-03 18:28:52 +03:00
parent d41644eecb
commit 699df081e0
8 changed files with 59 additions and 40 deletions

View File

@ -1,7 +1,9 @@
<redaction-dictionary-manager
#dictionaryManager
(saveDictionary)="save()"
[canDownload]="permissionsService.canDownloadEntityDictionary()"
[canEdit]="currentUser.isAdmin"
[entityType]="entityType"
[filterByDossierTemplate]="true"
[initialEntries]="initialEntries$ | async"
[isLeavingPage]="isLeavingPage"

View File

@ -1,4 +1,4 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionaryService } from '@services/entity-services/dictionary.service';
@ -6,30 +6,33 @@ import { List, LoadingService } from '@iqser/common-ui';
import { UserService } from '@services/user.service';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { DICTIONARY_TO_ENTRY_TYPE_MAP, DICTIONARY_TYPE_KEY_MAP, DictionaryType, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
@Component({
templateUrl: './dictionary-screen.component.html',
styleUrls: ['./dictionary-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DictionaryScreenComponent implements OnInit {
readonly currentUser: User;
readonly initialEntries$ = new BehaviorSubject<string[]>([]);
isLeavingPage = false;
readonly type: DictionaryType;
readonly entityType: string;
readonly #dossierTemplateId: string;
readonly #entityType: string;
@ViewChild('dictionaryManager', { static: false })
private readonly _dictionaryManager: DictionaryManagerComponent;
constructor(
route: ActivatedRoute,
userService: UserService,
readonly route: ActivatedRoute,
readonly userService: UserService,
readonly permissionsService: PermissionsService,
private readonly _loadingService: LoadingService,
private readonly _dictionaryService: DictionaryService,
) {
this.currentUser = userService.currentUser;
this.#dossierTemplateId = route.parent.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
this.#entityType = route.parent.snapshot.paramMap.get(ENTITY_TYPE);
this.entityType = route.parent.snapshot.paramMap.get(ENTITY_TYPE);
this.type = route.snapshot.routeConfig.path as DictionaryType;
}
@ -51,7 +54,7 @@ export class DictionaryScreenComponent implements OnInit {
entries,
this.initialEntries$.value,
this.#dossierTemplateId,
this.#entityType,
this.entityType,
null,
true,
DICTIONARY_TO_ENTRY_TYPE_MAP[this.type],
@ -66,7 +69,7 @@ export class DictionaryScreenComponent implements OnInit {
private async _loadEntries() {
this._loadingService.start();
try {
const data = await firstValueFrom(this._dictionaryService.getForType(this.#dossierTemplateId, this.#entityType));
const data = await firstValueFrom(this._dictionaryService.getForType(this.#dossierTemplateId, this.entityType));
const entries: List = data[DICTIONARY_TYPE_KEY_MAP[this.type]];
this.initialEntries$.next([...entries].sort((str1, str2) => str1.localeCompare(str2, undefined, { sensitivity: 'accent' })));
this._loadingService.stop();

View File

@ -1,28 +1,38 @@
<div class="content-container">
<div class="actions-bar">
<div class="iqser-input-group w-250 mr-32">
<input
#inputElement
(keyup)="searchChanged(searchText)"
[(ngModel)]="searchText"
[class.with-matches]="searchText.length > 0"
[placeholder]="'dictionary-overview.search' | translate"
type="text"
/>
<div class="flex-align-items-center mr-32">
<div class="iqser-input-group w-250">
<input
#inputElement
(keyup)="searchChanged(searchText)"
[(ngModel)]="searchText"
[class.with-matches]="searchText.length > 0"
[placeholder]="'dictionary-overview.search' | translate"
type="text"
/>
<div class="input-icons">
<div *ngIf="searchText.length === 0" class="no-input">
<mat-icon svgIcon="iqser:search"></mat-icon>
</div>
<div *ngIf="searchText.length > 0" class="with-input">
<div class="search-match-text">
{{ currentMatch + '/' + findMatches.length }}
<div class="input-icons">
<div *ngIf="searchText.length === 0" class="no-input">
<mat-icon svgIcon="iqser:search"></mat-icon>
</div>
<div *ngIf="searchText.length > 0" class="with-input">
<div class="search-match-text">
{{ currentMatch + '/' + findMatches.length }}
</div>
<mat-icon (click)="previousSearchMatch()" class="pointer" svgIcon="red:arrow-up"></mat-icon>
<mat-icon (click)="nextSearchMatch()" class="pointer" svgIcon="iqser:arrow-down"></mat-icon>
<mat-icon (click)="searchChanged(''); inputElement.focus()" class="pointer" svgIcon="iqser:close"></mat-icon>
</div>
<mat-icon (click)="previousSearchMatch()" class="pointer" svgIcon="red:arrow-up"></mat-icon>
<mat-icon (click)="nextSearchMatch()" class="pointer" svgIcon="iqser:arrow-down"></mat-icon>
<mat-icon (click)="searchChanged(''); inputElement.focus()" class="pointer" svgIcon="iqser:close"></mat-icon>
</div>
</div>
<iqser-circle-button
(action)="download()"
*ngIf="canDownload"
[matTooltip]="'dictionary-overview.download' | translate"
class="ml-8"
icon="iqser:download"
></iqser-circle-button>
</div>
<div class="compare">
<div class="iqser-input-group mr-16">

View File

@ -9,6 +9,7 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { EditorComponent } from '@shared/components/editor/editor.component';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { saveAs } from 'file-saver';
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import FindMatch = monaco.editor.FindMatch;
@ -23,14 +24,15 @@ export class DictionaryManagerComponent implements OnChanges {
readonly iconButtonTypes = IconButtonTypes;
@Input() type: DictionaryType = 'dictionary';
@Input() entityType?: string;
@Input() withFloatingActions = true;
@Input() filterByDossierTemplate = false;
@Input() initialEntries: List;
@Input() canEdit = false;
@Input() canDownload = false;
@Input() isLeavingPage = false;
@Output() readonly saveDictionary = new EventEmitter<string[]>();
@ViewChild(EditorComponent) readonly editor: EditorComponent;
currentMatch = 0;
findMatches: FindMatch[] = [];
diffEditorText = '';
@ -151,6 +153,14 @@ export class DictionaryManagerComponent implements OnChanges {
return this.dossier.dossierName === this.selectDossier.dossierName;
}
download(): void {
const content = this.editor.currentEntries.join('\n');
const blob = new Blob([content], {
type: 'text/plain;charset=utf-8',
});
saveAs(blob, `${this.entityType}-${this.type}.txt`);
}
revert() {
this.editor?.revert();
this.searchChanged('');

View File

@ -16,6 +16,10 @@ export class PermissionsService {
return this._userService.currentUser.id;
}
canDownloadEntityDictionary(): boolean {
return this.isAdmin() || this.isManager();
}
canEditEntities(): boolean {
return this.isAdmin();
}

View File

@ -564,12 +564,6 @@
"title": "{count, plural, one{{justificationName}} other{ausgewählte Begründungen}} löschen"
},
"input-label": "Bitte geben Sie unten Folgendes ein, um fortzufahren",
"keep-manual-redactions": {
"confirmation-text": "",
"deny-text": "",
"question": "",
"title": ""
},
"report-template-same-name": {
"confirmation-text": "Ja. Hochladen fortsetzen",
"deny-text": "Nein. Hochladen abbrechen",
@ -635,6 +629,7 @@
"select-dossier": "Dossier auswählen",
"select-dossier-template": "Dossiervorlage auswählen"
},
"download": "",
"error": {
"entries-too-short": "Einige Einträge im Wörterbuch unterschreiten die Mindestlänge von 2 Zeichen. Diese sind rot markiert.",
"generic": "Es ist ein Fehler aufgetreten ... Das Wörterbuch konnte nicht aktualisiert werden!"

View File

@ -564,12 +564,6 @@
"title": "Delete {count, plural, one{{justificationName}} other{Selected Justifications}}"
},
"input-label": "To proceed please type below",
"keep-manual-redactions": {
"confirmation-text": "Keep",
"deny-text": "Clear",
"question": "At least one of the files you're overwriting has manual changes, do you wish to keep them?",
"title": "Keep Manual Redactions?"
},
"report-template-same-name": {
"confirmation-text": "Yes. Continue upload",
"deny-text": "No. Cancel Upload",
@ -635,6 +629,7 @@
"select-dossier": "Select Dossier",
"select-dossier-template": "Select Dossier Template"
},
"download": "Download current entries",
"error": {
"entries-too-short": "Some entries of the dictionary are below the minimum length of 2. These are highlighted with red!",
"generic": "Something went wrong... Dictionary update failed!"

@ -1 +1 @@
Subproject commit a814fc8aa7a16c9acdaa9b7dd749e4493a54e1c2
Subproject commit 43a9067bf3c712316c78223a243ae98868e46932