RED-8045 - Dossier template selection/filter at dossier dictionary comparison
This commit is contained in:
parent
645285bfe6
commit
4953ed2e68
@ -4,8 +4,9 @@
|
||||
[canDownload]="permissionsService.canDownloadEntityDictionary()"
|
||||
[canEdit]="currentUser.isAdmin && (iqserPermissionsService.has$(roles.dictionaryEntries.write) | async)"
|
||||
[entityType]="entityType"
|
||||
[filterByDossierTemplate]="true"
|
||||
[initialEntries]="initialEntries$ | async"
|
||||
[isLeavingPage]="isLeavingPage"
|
||||
[currentDossierTemplateId]="dossierTemplateId"
|
||||
[selectedDictionaryType]="entityType"
|
||||
[type]="type"
|
||||
></redaction-dictionary-manager>
|
||||
|
||||
@ -20,10 +20,10 @@ export class DictionaryScreenComponent implements OnInit {
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = Roles;
|
||||
readonly initialEntries$ = new BehaviorSubject<List>([]);
|
||||
isLeavingPage = false;
|
||||
readonly type: DictionaryType;
|
||||
readonly entityType = getParam(ENTITY_TYPE);
|
||||
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
isLeavingPage = false;
|
||||
dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
@ViewChild('dictionaryManager', { static: false })
|
||||
private readonly _dictionaryManager: DictionaryManagerComponent;
|
||||
|
||||
@ -55,7 +55,7 @@ export class DictionaryScreenComponent implements OnInit {
|
||||
await this._dictionaryService.saveEntries(
|
||||
entries,
|
||||
this.initialEntries$.value,
|
||||
this.#dossierTemplateId,
|
||||
this.dossierTemplateId,
|
||||
this.entityType,
|
||||
null,
|
||||
true,
|
||||
@ -70,7 +70,7 @@ export class DictionaryScreenComponent implements OnInit {
|
||||
async #loadEntries() {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
const data = await this._dictionaryService.getForType(this.#dossierTemplateId, this.entityType);
|
||||
const data = await this._dictionaryService.getForType(this.dossierTemplateId, this.entityType);
|
||||
const entries: List = data[DICTIONARY_TYPE_KEY_MAP[this.type]];
|
||||
this.initialEntries$.next(entries);
|
||||
} catch (e) {
|
||||
|
||||
@ -41,55 +41,45 @@
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="filterByDossierTemplate">
|
||||
<div *ngIf="dossierTemplatesService.all$ | async as templates" class="iqser-input-group w-200 mt-0 mr-8">
|
||||
<ng-container>
|
||||
<div *ngIf="dossierTemplates" class="iqser-input-group w-200 mt-0 mr-8">
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="dossierTemplate" [disabled]="!compare">
|
||||
<mat-option [value]="selectDossierTemplate">{{ selectDossierTemplate.name | translate }}</mat-option>
|
||||
<mat-option *ngFor="let dossierTemplate of templates" [value]="dossierTemplate">
|
||||
{{ dossierTemplate.name }}
|
||||
</mat-option>
|
||||
<mat-select
|
||||
[(ngModel)]="selectedDossierTemplate"
|
||||
[disabled]="!compare"
|
||||
[placeholder]="compare ? selectedDossierTemplate.name : (selectDossierTemplate.name | translate)"
|
||||
>
|
||||
<ng-container *ngFor="let dossierTemplate of dossierTemplates">
|
||||
<mat-option [value]="dossierTemplate" *ngIf="dossierTemplate?.id !== selectedDossierTemplate.id">
|
||||
{{ dossierTemplate.name }}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-200 mt-0">
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="compareDictionary" [disabled]="!compare || dossierTemplateIsNotSelected">
|
||||
<mat-option [value]="selectDictionary">{{ selectDictionary.label | translate }}</mat-option>
|
||||
<mat-option *ngFor="let dictionary of dictionaries" [value]="dictionary">
|
||||
{{ dictionary.label }}
|
||||
</mat-option>
|
||||
<mat-select
|
||||
[(ngModel)]="selectedDossier"
|
||||
[disabled]="!compare"
|
||||
[placeholder]="selectedDossier.dossierId ? selectedDossier.dossierName : (selectDictionary.label | translate)"
|
||||
>
|
||||
<ng-container *ngFor="let dossier of dossiers; let index = index">
|
||||
<mat-option
|
||||
*ngIf="dossier.dossierId !== selectedDossier.dossierId && dossier.dossierId !== currentDossierId"
|
||||
[value]="dossier"
|
||||
>
|
||||
{{ dossier.dossierName }}
|
||||
</mat-option>
|
||||
<mat-divider
|
||||
*ngIf="index === dossiers.length - 2 && !selectedDossier.dossierId?.includes('template')"
|
||||
></mat-divider>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div
|
||||
*ngIf="!filterByDossierTemplate && !!dossiers.length"
|
||||
class="iqser-input-group w-200 mt-0"
|
||||
[class.not-clickable]="dossiers.length === 2 && !!selectedDossier.id"
|
||||
>
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
[(ngModel)]="selectedDossier"
|
||||
[disabled]="!compare"
|
||||
[placeholder]="selectedDossier.dossierId ? selectedDossier.dossierName : (selectDictionary.label | translate)"
|
||||
>
|
||||
<ng-container *ngFor="let dossier of dossiers; let index = index">
|
||||
<mat-option
|
||||
*ngIf="dossier.dossierId !== selectedDossier.dossierId && dossier.dossierId !== currentDossierId"
|
||||
[value]="dossier"
|
||||
>
|
||||
{{ dossier.dossierName }}
|
||||
</mat-option>
|
||||
<mat-divider
|
||||
*ngIf="index === dossiers.length - 2 && !selectedDossier.dossierId?.includes('template')"
|
||||
></mat-divider>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import {
|
||||
Dictionary,
|
||||
DICTIONARY_TYPE_KEY_MAP,
|
||||
DictionaryEntryType,
|
||||
DictionaryEntryTypes,
|
||||
DictionaryType,
|
||||
Dossier,
|
||||
DossierTemplate,
|
||||
IDictionary,
|
||||
} from '@red/domain';
|
||||
import { IconButtonTypes, LoadingService } from '@iqser/common-ui';
|
||||
import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, DictionaryType, Dossier, DossierTemplate, IDictionary } from '@red/domain';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
@ -22,6 +13,7 @@ import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
|
||||
import FindMatch = monaco.editor.FindMatch;
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
const COMPARE_ENTRIES_ERROR = 'compare-entries-error';
|
||||
const SMOOTH_SCROLL = 0;
|
||||
const HELP_MODE_KEYS = {
|
||||
dictionary: 'dictionary_entity',
|
||||
@ -40,9 +32,8 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
@Input() type: DictionaryType = 'dictionary';
|
||||
@Input() entityType?: string;
|
||||
@Input() currentDossierId: string;
|
||||
@Input() currentDossierTemplateId: string;
|
||||
@Input() currentDossierTemplateId!: string;
|
||||
@Input() withFloatingActions = true;
|
||||
@Input() filterByDossierTemplate = false;
|
||||
@Input() initialEntries: List;
|
||||
@Input() canEdit = false;
|
||||
@Input() canDownload = false;
|
||||
@ -54,7 +45,8 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
@Output() readonly saveDictionary = new EventEmitter<string[]>();
|
||||
@ViewChild(EditorComponent) readonly editor: EditorComponent;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly dossiers: Dossier[];
|
||||
dossiers: Dossier[];
|
||||
dossierTemplates: DossierTemplate[];
|
||||
currentMatch = 0;
|
||||
findMatches: FindMatch[] = [];
|
||||
diffEditorText = '';
|
||||
@ -64,110 +56,64 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
selectDictionary = {
|
||||
label: _('dictionary-overview.compare.select-dictionary'),
|
||||
} as Dictionary;
|
||||
#compareDictionary = this.selectDictionary;
|
||||
selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') } as DossierTemplate;
|
||||
compare = false;
|
||||
dictionaries: List<Dictionary> = this.#dictionaries;
|
||||
#dossierTemplate = this.dossierTemplatesService.all[0];
|
||||
#dossier = this.selectDossier;
|
||||
#initialDossierTemplateId: string;
|
||||
|
||||
constructor(
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
private readonly _dictionariesMapService: DictionariesMapService,
|
||||
protected readonly _loadingService: LoadingService,
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _toaster: Toaster,
|
||||
readonly dossierTemplatesService: DossierTemplatesService,
|
||||
) {
|
||||
this.dossiers = _activeDossiersService.all;
|
||||
}
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const templateDictionary = {
|
||||
id: 'template',
|
||||
dossierId: 'template',
|
||||
dossierName: 'Template Dictionary',
|
||||
dossierTemplateId: this.currentDossierTemplateId,
|
||||
} as Dossier;
|
||||
this.dossiers.push(templateDictionary);
|
||||
this.#initialDossierTemplateId = this.currentDossierTemplateId;
|
||||
this.#updateDropdownsOptions();
|
||||
}
|
||||
|
||||
private _dossierTemplate = this.selectDossierTemplate;
|
||||
|
||||
get dossierTemplate() {
|
||||
return this._dossierTemplate;
|
||||
get selectedDossierTemplate() {
|
||||
return this.#dossierTemplate;
|
||||
}
|
||||
|
||||
set dossierTemplate(value: DossierTemplate) {
|
||||
this._dossierTemplate = value;
|
||||
set selectedDossierTemplate(value: DossierTemplate) {
|
||||
if (!value) {
|
||||
value = this.dossierTemplates.find(t => t.id === this.#initialDossierTemplateId);
|
||||
}
|
||||
this.#dossierTemplate = value;
|
||||
this.currentDossierTemplateId = value.dossierTemplateId;
|
||||
this.#dossier = this.selectDossier;
|
||||
this.dictionaries = this.#dictionaries;
|
||||
this.#compareDictionary = this.selectDictionary;
|
||||
this.showDiffEditor = false;
|
||||
}
|
||||
this.#disableDiffEditor();
|
||||
|
||||
private _dossier = this.selectDossier;
|
||||
this.#updateDropdownsOptions(false);
|
||||
}
|
||||
|
||||
get selectedDossier() {
|
||||
return this._dossier;
|
||||
return this.#dossier;
|
||||
}
|
||||
|
||||
set selectedDossier(dossier: Dossier) {
|
||||
this._dossier = dossier;
|
||||
this.#dossier = dossier;
|
||||
|
||||
if (dossier.dossierName === this.selectDossier.dossierName) {
|
||||
this.showDiffEditor = false;
|
||||
this.diffEditorText = '';
|
||||
this.#disableDiffEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
this.#onDossierChanged(dossier.dossierTemplateId, dossier.id).then(entries => {
|
||||
this.diffEditorText = entries;
|
||||
this.showDiffEditor = true;
|
||||
if (!entries.startsWith(COMPARE_ENTRIES_ERROR)) {
|
||||
this.diffEditorText = entries;
|
||||
this.showDiffEditor = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get compareDictionary() {
|
||||
return this.#compareDictionary;
|
||||
}
|
||||
|
||||
set compareDictionary(dictionary: Dictionary) {
|
||||
this._loadingService.start();
|
||||
this.#compareDictionary = dictionary;
|
||||
|
||||
if (dictionary.label === this.selectDictionary.label) {
|
||||
this.showDiffEditor = false;
|
||||
this.diffEditorText = '';
|
||||
return;
|
||||
}
|
||||
const entries: List =
|
||||
this.#compareDictionary.getEntries(this.type) ??
|
||||
this._dictionariesMapService.get(this.#compareDictionary.dossierTemplateId, this.#compareDictionary.type).getEntries(this.type);
|
||||
|
||||
if (entries.length) {
|
||||
this.diffEditorText = entries.join('\n');
|
||||
this.showDiffEditor = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this._dictionaryService
|
||||
.getForType(this.#compareDictionary.dossierTemplateId, this.#compareDictionary.type)
|
||||
.then(values => {
|
||||
this.#compareDictionary.setEntries([...values[DICTIONARY_TYPE_KEY_MAP[this.type]]] ?? [], this.type);
|
||||
this.diffEditorText = [...(this.#compareDictionary.getEntries(this.type) as string[])].join('\n');
|
||||
this.showDiffEditor = true;
|
||||
this._changeRef.markForCheck();
|
||||
this._loadingService.stop();
|
||||
})
|
||||
.catch(() => this.#compareDictionary.setEntries([], this.type));
|
||||
}
|
||||
|
||||
get dossierTemplateIsNotSelected() {
|
||||
return this.filterByDossierTemplate && this._dossierTemplate.name === this.selectDossierTemplate.name;
|
||||
}
|
||||
|
||||
get optionNotSelected() {
|
||||
if (this.filterByDossierTemplate) {
|
||||
return this.selectDictionary.label === this.#compareDictionary.label;
|
||||
}
|
||||
return this.selectedDossier.dossierName === this.selectDossier.dossierName;
|
||||
}
|
||||
|
||||
@ -176,10 +122,16 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
get #dictionaries(): Dictionary[] {
|
||||
if (!this._dossierTemplate || this._dossierTemplate.name === this.selectDossierTemplate.name) {
|
||||
if (!this.#dossierTemplate || this.#dossierTemplate.name === this.selectDossierTemplate.name) {
|
||||
return;
|
||||
}
|
||||
return this._dictionariesMapService.get(this.dossierTemplate?.dossierTemplateId).filter(dict => !dict.virtual);
|
||||
return this._dictionariesMapService.get(this.selectedDossierTemplate?.dossierTemplateId).filter(dict => !dict.virtual);
|
||||
}
|
||||
|
||||
get #templatesWithCurrentEntityType() {
|
||||
return this.dossierTemplatesService.all.filter(t =>
|
||||
this._dictionaryService.hasType(t.dossierTemplateId, this.selectedDictionaryType),
|
||||
);
|
||||
}
|
||||
|
||||
download(): void {
|
||||
@ -198,8 +150,8 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
|
||||
@Debounce()
|
||||
searchChanged(text: string) {
|
||||
this.findMatches = this._getMatches(text.toLowerCase());
|
||||
this._applySearchDecorations();
|
||||
this.findMatches = this.#getMatches(text.toLowerCase());
|
||||
this.#applySearchDecorations();
|
||||
|
||||
this.currentMatch = 0;
|
||||
this.nextSearchMatch();
|
||||
@ -211,7 +163,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
this.currentMatch = this.currentMatch < this.findMatches.length ? this.currentMatch + 1 : 1;
|
||||
this._scrollToCurrentMatch();
|
||||
this.#scrollToCurrentMatch();
|
||||
}
|
||||
|
||||
previousSearchMatch(): void {
|
||||
@ -220,7 +172,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
this.currentMatch = this.currentMatch > 1 ? this.currentMatch - 1 : this.findMatches.length;
|
||||
this._scrollToCurrentMatch();
|
||||
this.#scrollToCurrentMatch();
|
||||
}
|
||||
|
||||
toggleCompareMode() {
|
||||
@ -231,39 +183,39 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (
|
||||
(changes.selectedDictionaryType || changes.activeEntryType) &&
|
||||
this._dossier?.dossierTemplateId &&
|
||||
this.selectedDossier?.dossierId
|
||||
) {
|
||||
this.#onDossierChanged(this._dossier.dossierTemplateId, this._dossier.dossierId).then(entries => {
|
||||
this.diffEditorText = entries;
|
||||
this.showDiffEditor = true;
|
||||
if (changes.activeEntryType && this.#dossier?.dossierTemplateId && this.selectedDossier?.dossierId) {
|
||||
this.#onDossierChanged(this.#dossier.dossierTemplateId, this.#dossier.dossierId).then(entries => {
|
||||
if (!entries.startsWith(COMPARE_ENTRIES_ERROR)) {
|
||||
this.diffEditorText = entries;
|
||||
this.showDiffEditor = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (changes.selectedDictionaryType) {
|
||||
this.searchText = '';
|
||||
this.#disableDiffEditor();
|
||||
this.#updateDropdownsOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private _applySearchDecorations() {
|
||||
#applySearchDecorations() {
|
||||
this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, []) || [];
|
||||
|
||||
const decorations = this.findMatches.map(match => this._getSearchDecoration(match));
|
||||
const decorations = this.findMatches.map(match => this.#getSearchDecoration(match));
|
||||
|
||||
this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, decorations) || [];
|
||||
}
|
||||
|
||||
private _getMatches(text: string): FindMatch[] {
|
||||
#getMatches(text: string): FindMatch[] {
|
||||
const model = this.editor.codeEditor?.getModel();
|
||||
return model?.findMatches(text, false, false, false, null, false) || [];
|
||||
}
|
||||
|
||||
private _getSearchDecoration(match: FindMatch): IModelDeltaDecoration {
|
||||
#getSearchDecoration(match: FindMatch): IModelDeltaDecoration {
|
||||
return { range: match.range, options: { inlineClassName: 'search-marker' } };
|
||||
}
|
||||
|
||||
private _scrollToCurrentMatch(): void {
|
||||
#scrollToCurrentMatch(): void {
|
||||
const range = this.findMatches[this.currentMatch - 1].range;
|
||||
|
||||
this.editor.codeEditor.setSelection(range);
|
||||
@ -279,14 +231,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
await firstValueFrom(
|
||||
this._dictionaryService.loadDictionaryEntriesByType([this.selectedDictionaryType], dossierTemplateId, dossierId),
|
||||
).catch(() => {
|
||||
const selectedDossierTemplate = this.dossierTemplatesService.find(dossierTemplateId);
|
||||
this._toaster.error(_('dictionary-overview.compare-error'), {
|
||||
params: {
|
||||
type: this.selectedDictionaryTypeLabel,
|
||||
template: selectedDossierTemplate.name,
|
||||
},
|
||||
});
|
||||
return [{ entries: [], type: '' }];
|
||||
return [{ entries: [COMPARE_ENTRIES_ERROR], type: '' }];
|
||||
})
|
||||
)[0];
|
||||
}
|
||||
@ -294,8 +239,28 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
this.activeEntryType === DictionaryEntryTypes.ENTRY || this.hint
|
||||
? [...dictionary.entries]
|
||||
: this.activeEntryType === DictionaryEntryTypes.FALSE_POSITIVE
|
||||
? [...dictionary.falsePositiveEntries]
|
||||
: [...dictionary.falseRecommendationEntries];
|
||||
? [...dictionary.falsePositiveEntries]
|
||||
: [...dictionary.falseRecommendationEntries];
|
||||
return activeEntries.join('\n');
|
||||
}
|
||||
|
||||
#updateDropdownsOptions(updateSelectedDossierTemplate = true) {
|
||||
if (updateSelectedDossierTemplate) {
|
||||
this.dossierTemplates = this.#templatesWithCurrentEntityType;
|
||||
this.selectedDossierTemplate = this.dossierTemplates.find(t => t.id === this.currentDossierTemplateId);
|
||||
}
|
||||
this.dossiers = this._activeDossiersService.all.filter(d => d.dossierTemplateId === this.currentDossierTemplateId);
|
||||
const templateDictionary = {
|
||||
id: 'template',
|
||||
dossierId: 'template',
|
||||
dossierName: 'Template Dictionary',
|
||||
dossierTemplateId: this.currentDossierTemplateId,
|
||||
} as Dossier;
|
||||
this.dossiers.push(templateDictionary);
|
||||
}
|
||||
|
||||
#disableDiffEditor() {
|
||||
this.showDiffEditor = false;
|
||||
this.diffEditorText = '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,6 +133,10 @@ export class DictionaryService extends EntitiesService<IDictionary, Dictionary>
|
||||
return !!this._dictionariesMapService.get(dossierTemplateId).find(e => e.type === SuperTypes.ManualRedaction && !e.virtual);
|
||||
}
|
||||
|
||||
hasType(dossierTemplateId: string, type: string): boolean {
|
||||
return !!this._dictionariesMapService.get(dossierTemplateId).find(e => e.type === type && !e.virtual);
|
||||
}
|
||||
|
||||
getRedactTextDictionaries(dossierTemplateId: string, dossierDictionaryOnly: boolean): Dictionary[] {
|
||||
return this._dictionariesMapService
|
||||
.get(dossierTemplateId)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user