Dictionary technical name
This commit is contained in:
parent
69620b0b7e
commit
2f45fe631e
@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
<form (submit)="saveDictionary()" [formGroup]="dictionaryForm">
|
<form (submit)="saveDictionary()" [formGroup]="dictionaryForm">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
|
<div class="red-input-group mb-14">
|
||||||
|
<label translate="add-edit-dictionary.form.technical-name"></label>
|
||||||
|
<div class="technical-name">{{ dictionary?.type || technicalName || '-' }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div *ngIf="!!dictionary" class="red-input-group mb-14">
|
<div *ngIf="!!dictionary" class="red-input-group mb-14">
|
||||||
<label translate="add-edit-dictionary.form.name"></label>
|
<label translate="add-edit-dictionary.form.name"></label>
|
||||||
{{ dictionary.label }}
|
{{ dictionary.label }}
|
||||||
@ -15,8 +20,8 @@
|
|||||||
<label translate="add-edit-dictionary.form.name"></label>
|
<label translate="add-edit-dictionary.form.name"></label>
|
||||||
<input
|
<input
|
||||||
[placeholder]="'add-edit-dictionary.form.name-placeholder' | translate"
|
[placeholder]="'add-edit-dictionary.form.name-placeholder' | translate"
|
||||||
formControlName="type"
|
formControlName="label"
|
||||||
name="type"
|
name="label"
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<span class="hint" translate="add-edit-dictionary.form.name-hint"></span>
|
<span class="hint" translate="add-edit-dictionary.form.name-hint"></span>
|
||||||
|
|||||||
@ -15,3 +15,7 @@
|
|||||||
.mb-14 {
|
.mb-14 {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.technical-name {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import { Toaster } from '@services/toaster.service';
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { humanize } from '@iqser/common-ui';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
|
import { toKebabCase } from '@utils/functions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-add-edit-dictionary-dialog',
|
selector: 'redaction-add-edit-dictionary-dialog',
|
||||||
@ -17,10 +18,12 @@ import { humanize } from '@iqser/common-ui';
|
|||||||
export class AddEditDictionaryDialogComponent {
|
export class AddEditDictionaryDialogComponent {
|
||||||
dictionaryForm: FormGroup;
|
dictionaryForm: FormGroup;
|
||||||
readonly dictionary: TypeValueWrapper;
|
readonly dictionary: TypeValueWrapper;
|
||||||
|
technicalName = '';
|
||||||
private readonly _dossierTemplateId: string;
|
private readonly _dossierTemplateId: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _dictionaryControllerService: DictionaryControllerService,
|
private readonly _dictionaryControllerService: DictionaryControllerService,
|
||||||
|
private readonly _appStateService: AppStateService,
|
||||||
private readonly _formBuilder: FormBuilder,
|
private readonly _formBuilder: FormBuilder,
|
||||||
private readonly _toaster: Toaster,
|
private readonly _toaster: Toaster,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
@ -31,7 +34,7 @@ export class AddEditDictionaryDialogComponent {
|
|||||||
this.dictionary = _data.dictionary;
|
this.dictionary = _data.dictionary;
|
||||||
this._dossierTemplateId = _data.dossierTemplateId;
|
this._dossierTemplateId = _data.dossierTemplateId;
|
||||||
this.dictionaryForm = _formBuilder.group({
|
this.dictionaryForm = _formBuilder.group({
|
||||||
type: [this.dictionary?.type, [Validators.required, Validators.minLength(3)]],
|
label: [this.dictionary?.label, [Validators.required, Validators.minLength(3)]],
|
||||||
description: [this.dictionary?.description],
|
description: [this.dictionary?.description],
|
||||||
rank: [this.dictionary?.rank, Validators.required],
|
rank: [this.dictionary?.rank, Validators.required],
|
||||||
hexColor: [this.dictionary?.hexColor, [Validators.required, Validators.minLength(7)]],
|
hexColor: [this.dictionary?.hexColor, [Validators.required, Validators.minLength(7)]],
|
||||||
@ -39,12 +42,15 @@ export class AddEditDictionaryDialogComponent {
|
|||||||
addToDictionaryAction: [!!this.dictionary?.addToDictionaryAction],
|
addToDictionaryAction: [!!this.dictionary?.addToDictionaryAction],
|
||||||
caseSensitive: [this.dictCaseSensitive]
|
caseSensitive: [this.dictCaseSensitive]
|
||||||
});
|
});
|
||||||
|
this.dictionaryForm.get('label').valueChanges.subscribe(() => {
|
||||||
|
this._updateTechnicalName();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get dialogHeader(): string {
|
get dialogHeader(): string {
|
||||||
return this._translateService.instant('add-edit-dictionary.title', {
|
return this._translateService.instant('add-edit-dictionary.title', {
|
||||||
type: this.dictionary ? 'edit' : 'create',
|
type: this.dictionary ? 'edit' : 'create',
|
||||||
name: humanize(this.dictionary?.type)
|
name: this.dictionary?.label
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,13 +106,26 @@ export class AddEditDictionaryDialogComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _updateTechnicalName() {
|
||||||
|
const displayName = this.dictionaryForm.get('label').value.trim();
|
||||||
|
const existingTechnicalNames = Object.keys(this._appStateService.dictionaryData[this._dossierTemplateId]);
|
||||||
|
const baseTechnicalName: string = toKebabCase(displayName);
|
||||||
|
let technicalName = baseTechnicalName;
|
||||||
|
let suffix = 1;
|
||||||
|
while (existingTechnicalNames.includes(technicalName)) {
|
||||||
|
technicalName = [baseTechnicalName, suffix++].join('-');
|
||||||
|
}
|
||||||
|
this.technicalName = technicalName;
|
||||||
|
}
|
||||||
|
|
||||||
private _formToObject(): TypeValue {
|
private _formToObject(): TypeValue {
|
||||||
return {
|
return {
|
||||||
|
type: this.dictionary?.type || this.technicalName,
|
||||||
|
label: this.dictionaryForm.get('label').value,
|
||||||
caseInsensitive: !this.dictionaryForm.get('caseSensitive').value,
|
caseInsensitive: !this.dictionaryForm.get('caseSensitive').value,
|
||||||
description: this.dictionaryForm.get('description').value,
|
description: this.dictionaryForm.get('description').value,
|
||||||
hexColor: this.dictionaryForm.get('hexColor').value,
|
hexColor: this.dictionaryForm.get('hexColor').value,
|
||||||
hint: this.dictionaryForm.get('hint').value,
|
hint: this.dictionaryForm.get('hint').value,
|
||||||
type: this.dictionaryForm.get('type').value,
|
|
||||||
rank: this.dictionaryForm.get('rank').value,
|
rank: this.dictionaryForm.get('rank').value,
|
||||||
addToDictionaryAction: this.dictionaryForm.get('addToDictionaryAction').value,
|
addToDictionaryAction: this.dictionaryForm.get('addToDictionaryAction').value,
|
||||||
dossierTemplateId: this._dossierTemplateId
|
dossierTemplateId: this._dossierTemplateId
|
||||||
|
|||||||
@ -26,7 +26,6 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
|||||||
providers: [...DefaultListingServices]
|
providers: [...DefaultListingServices]
|
||||||
})
|
})
|
||||||
export class DictionaryListingScreenComponent extends ListingComponent<TypeValueWrapper> implements OnInit {
|
export class DictionaryListingScreenComponent extends ListingComponent<TypeValueWrapper> implements OnInit {
|
||||||
protected readonly _primaryKey = 'label';
|
|
||||||
readonly iconButtonTypes = IconButtonTypes;
|
readonly iconButtonTypes = IconButtonTypes;
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly currentUser = this._userService.currentUser;
|
readonly currentUser = this._userService.currentUser;
|
||||||
@ -46,8 +45,8 @@ export class DictionaryListingScreenComponent extends ListingComponent<TypeValue
|
|||||||
class: 'flex-center'
|
class: 'flex-center'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
chartData: DoughnutChartConfig[] = [];
|
chartData: DoughnutChartConfig[] = [];
|
||||||
|
protected readonly _primaryKey = 'type';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly _injector: Injector,
|
protected readonly _injector: Injector,
|
||||||
|
|||||||
@ -7,18 +7,18 @@
|
|||||||
(action)="openDeleteDictionaryDialog($event)"
|
(action)="openDeleteDictionaryDialog($event)"
|
||||||
*ngIf="currentUser.isAdmin"
|
*ngIf="currentUser.isAdmin"
|
||||||
[tooltip]="'dictionary-overview.action.delete' | translate"
|
[tooltip]="'dictionary-overview.action.delete' | translate"
|
||||||
|
[type]="circleButtonTypes.dark"
|
||||||
icon="red:trash"
|
icon="red:trash"
|
||||||
tooltipPosition="below"
|
tooltipPosition="below"
|
||||||
[type]="circleButtonTypes.dark"
|
|
||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
|
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="openEditDictionaryDialog($event)"
|
(action)="openEditDictionaryDialog($event)"
|
||||||
*ngIf="currentUser.isAdmin"
|
*ngIf="currentUser.isAdmin"
|
||||||
[tooltip]="'dictionary-overview.action.edit' | translate"
|
[tooltip]="'dictionary-overview.action.edit' | translate"
|
||||||
|
[type]="circleButtonTypes.dark"
|
||||||
icon="red:edit"
|
icon="red:edit"
|
||||||
tooltipPosition="below"
|
tooltipPosition="below"
|
||||||
[type]="circleButtonTypes.dark"
|
|
||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
|
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
@ -60,11 +60,11 @@
|
|||||||
[initialEntries]="entries"
|
[initialEntries]="entries"
|
||||||
></redaction-dictionary-manager>
|
></redaction-dictionary-manager>
|
||||||
|
|
||||||
<div class="right-container">
|
<div *ngIf="!!dictionary" class="right-container">
|
||||||
<div class="dictionary-header">
|
<div class="dictionary-header">
|
||||||
<div [style.backgroundColor]="dictionary.hexColor" class="color-box"></div>
|
<div [style.backgroundColor]="dictionary.hexColor" class="color-box"></div>
|
||||||
<div class="heading-xl">
|
<div class="heading-xl">
|
||||||
{{ dictionary.type | humanize }}
|
{{ dictionary.label }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="small-label stats-subtitle">
|
<div class="small-label stats-subtitle">
|
||||||
|
|||||||
@ -40,18 +40,18 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
|||||||
private readonly _dictionaryControllerService: DictionaryControllerService
|
private readonly _dictionaryControllerService: DictionaryControllerService
|
||||||
) {
|
) {
|
||||||
super(_translateService);
|
super(_translateService);
|
||||||
this._appStateService.activateDictionary(
|
|
||||||
this._activatedRoute.snapshot.params.type,
|
|
||||||
this._activatedRoute.snapshot.params.dossierTemplateId
|
|
||||||
);
|
|
||||||
this.dictionary = this._appStateService.activeDictionary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasChanges() {
|
get hasChanges() {
|
||||||
return this._dictionaryManager.hasChanges;
|
return this._dictionaryManager.hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
async ngOnInit() {
|
||||||
|
await this._appStateService.activateDictionary(
|
||||||
|
this._activatedRoute.snapshot.params.type,
|
||||||
|
this._activatedRoute.snapshot.params.dossierTemplateId
|
||||||
|
);
|
||||||
|
this.dictionary = this._appStateService.activeDictionary;
|
||||||
this._loadEntries();
|
this._loadEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
|||||||
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
|
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
|
||||||
import { DossiersService } from '../modules/dossier/services/dossiers.service';
|
import { DossiersService } from '../modules/dossier/services/dossiers.service';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { humanize } from '@iqser/common-ui';
|
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
@ -193,7 +192,7 @@ export class AppStateService {
|
|||||||
return this.dossierTemplates.find(rs => rs.dossierTemplateId === id);
|
return this.dossierTemplates.find(rs => rs.dossierTemplateId === id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDictionaryTypeValue(key: string, dossierTemplateId?: string) {
|
getDictionaryTypeValue(key: string, dossierTemplateId?: string): TypeValueWrapper {
|
||||||
if (!dossierTemplateId && this.activeDossier) {
|
if (!dossierTemplateId && this.activeDossier) {
|
||||||
dossierTemplateId = this.activeDossier.dossierTemplateId;
|
dossierTemplateId = this.activeDossier.dossierTemplateId;
|
||||||
}
|
}
|
||||||
@ -401,12 +400,32 @@ export class AppStateService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getDictionaryDataForDossierTemplateObservables(dossierTemplateId: string, dictionaryData: { [key: string]: any }): Observable<any>[] {
|
async loadDictionaryData(): Promise<void> {
|
||||||
|
const obj = {};
|
||||||
|
const observables = [];
|
||||||
|
|
||||||
|
for (const dossierTemplate of this.dossierTemplates) {
|
||||||
|
obj[dossierTemplate.dossierTemplateId] = {};
|
||||||
|
observables.push(
|
||||||
|
...this._getDictionaryDataForDossierTemplateObservables(
|
||||||
|
dossierTemplate.dossierTemplateId,
|
||||||
|
obj[dossierTemplate.dossierTemplateId]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await forkJoin(observables).toPromise();
|
||||||
|
this._dictionaryData = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getDictionaryDataForDossierTemplateObservables(
|
||||||
|
dossierTemplateId: string,
|
||||||
|
dictionaryData: { [key: string]: any }
|
||||||
|
): Observable<any>[] {
|
||||||
const typeObs = this._dictionaryControllerService.getAllTypes(dossierTemplateId).pipe(
|
const typeObs = this._dictionaryControllerService.getAllTypes(dossierTemplateId).pipe(
|
||||||
tap(typesResponse => {
|
tap(typesResponse => {
|
||||||
for (const type of typesResponse.types) {
|
for (const type of typesResponse.types) {
|
||||||
dictionaryData[type.type] = type;
|
dictionaryData[type.type] = type;
|
||||||
dictionaryData[type.type].label = humanize(type.type, false);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -634,24 +653,6 @@ export class AppStateService {
|
|||||||
return [typeObs, colorsObs];
|
return [typeObs, colorsObs];
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadDictionaryData(): Promise<void> {
|
|
||||||
const obj = {};
|
|
||||||
const observables = [];
|
|
||||||
|
|
||||||
for (const dossierTemplate of this.dossierTemplates) {
|
|
||||||
obj[dossierTemplate.dossierTemplateId] = {};
|
|
||||||
observables.push(
|
|
||||||
...this.getDictionaryDataForDossierTemplateObservables(
|
|
||||||
dossierTemplate.dossierTemplateId,
|
|
||||||
obj[dossierTemplate.dossierTemplateId]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await forkJoin(observables).toPromise();
|
|
||||||
this._dictionaryData = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _updateLastActiveFileForDossier(dossierId: string, fileId: string) {
|
private async _updateLastActiveFileForDossier(dossierId: string, fileId: string) {
|
||||||
this.activeDossier.files.forEach(f => {
|
this.activeDossier.files.forEach(f => {
|
||||||
f.lastOpened = f.fileId === fileId;
|
f.lastOpened = f.fileId === fileId;
|
||||||
|
|||||||
@ -89,3 +89,10 @@ export function getLeftDateTime(ISOString: string) {
|
|||||||
export function removeBraces(str: any): string {
|
export function removeBraces(str: any): string {
|
||||||
return str.replace(/[{}]/g, '');
|
return str.replace(/[{}]/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toKebabCase(str: string): string {
|
||||||
|
return str
|
||||||
|
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
||||||
|
.replace(/[\s_]+/g, '-')
|
||||||
|
.toLowerCase();
|
||||||
|
}
|
||||||
|
|||||||
@ -42,12 +42,13 @@
|
|||||||
"description": "Description",
|
"description": "Description",
|
||||||
"description-placeholder": "Enter Description",
|
"description-placeholder": "Enter Description",
|
||||||
"hint": "Hint",
|
"hint": "Hint",
|
||||||
"name": "Dictionary Name",
|
"name": "Display Name",
|
||||||
"name-hint": "Cannot be edited after saving.",
|
"name-hint": "Cannot be edited after saving.",
|
||||||
"name-placeholder": "Enter Name",
|
"name-placeholder": "Enter Name",
|
||||||
"rank": "Rank",
|
"rank": "Rank",
|
||||||
"rank-placeholder": "1000",
|
"rank-placeholder": "1000",
|
||||||
"redaction": "Redaction"
|
"redaction": "Redaction",
|
||||||
|
"technical-name": "Technical Name"
|
||||||
},
|
},
|
||||||
"save": "Save Dictionary",
|
"save": "Save Dictionary",
|
||||||
"title": "{type, select, edit{Edit {name}} create{Create} other{}} Dictionary"
|
"title": "{type, select, edit{Edit {name}} create{Create} other{}} Dictionary"
|
||||||
|
|||||||
@ -23,8 +23,8 @@ form .red-input-group:not(first-of-type) {
|
|||||||
right: 1px;
|
right: 1px;
|
||||||
bottom: 1px;
|
bottom: 1px;
|
||||||
background: $grey-5;
|
background: $grey-5;
|
||||||
height: 32px;
|
height: 34px;
|
||||||
width: 32px;
|
width: 34px;
|
||||||
border-left: 1px solid $grey-5;
|
border-left: 1px solid $grey-5;
|
||||||
border-top-right-radius: 7px;
|
border-top-right-radius: 7px;
|
||||||
border-bottom-right-radius: 7px;
|
border-bottom-right-radius: 7px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user