Dictionary technical name

This commit is contained in:
Adina Țeudan 2021-08-16 10:48:25 +03:00
parent 69620b0b7e
commit 2f45fe631e
10 changed files with 80 additions and 44 deletions

View File

@ -5,6 +5,11 @@
<form (submit)="saveDictionary()" [formGroup]="dictionaryForm">
<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">
<label translate="add-edit-dictionary.form.name"></label>
{{ dictionary.label }}
@ -15,8 +20,8 @@
<label translate="add-edit-dictionary.form.name"></label>
<input
[placeholder]="'add-edit-dictionary.form.name-placeholder' | translate"
formControlName="type"
name="type"
formControlName="label"
name="label"
type="text"
/>
<span class="hint" translate="add-edit-dictionary.form.name-hint"></span>

View File

@ -15,3 +15,7 @@
.mb-14 {
margin-bottom: 14px;
}
.technical-name {
font-weight: 600;
}

View File

@ -7,7 +7,8 @@ import { Toaster } from '@services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
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({
selector: 'redaction-add-edit-dictionary-dialog',
@ -17,10 +18,12 @@ import { humanize } from '@iqser/common-ui';
export class AddEditDictionaryDialogComponent {
dictionaryForm: FormGroup;
readonly dictionary: TypeValueWrapper;
technicalName = '';
private readonly _dossierTemplateId: string;
constructor(
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _toaster: Toaster,
private readonly _translateService: TranslateService,
@ -31,7 +34,7 @@ export class AddEditDictionaryDialogComponent {
this.dictionary = _data.dictionary;
this._dossierTemplateId = _data.dossierTemplateId;
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],
rank: [this.dictionary?.rank, Validators.required],
hexColor: [this.dictionary?.hexColor, [Validators.required, Validators.minLength(7)]],
@ -39,12 +42,15 @@ export class AddEditDictionaryDialogComponent {
addToDictionaryAction: [!!this.dictionary?.addToDictionaryAction],
caseSensitive: [this.dictCaseSensitive]
});
this.dictionaryForm.get('label').valueChanges.subscribe(() => {
this._updateTechnicalName();
});
}
get dialogHeader(): string {
return this._translateService.instant('add-edit-dictionary.title', {
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 {
return {
type: this.dictionary?.type || this.technicalName,
label: this.dictionaryForm.get('label').value,
caseInsensitive: !this.dictionaryForm.get('caseSensitive').value,
description: this.dictionaryForm.get('description').value,
hexColor: this.dictionaryForm.get('hexColor').value,
hint: this.dictionaryForm.get('hint').value,
type: this.dictionaryForm.get('type').value,
rank: this.dictionaryForm.get('rank').value,
addToDictionaryAction: this.dictionaryForm.get('addToDictionaryAction').value,
dossierTemplateId: this._dossierTemplateId

View File

@ -26,7 +26,6 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
providers: [...DefaultListingServices]
})
export class DictionaryListingScreenComponent extends ListingComponent<TypeValueWrapper> implements OnInit {
protected readonly _primaryKey = 'label';
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = this._userService.currentUser;
@ -46,8 +45,8 @@ export class DictionaryListingScreenComponent extends ListingComponent<TypeValue
class: 'flex-center'
}
];
chartData: DoughnutChartConfig[] = [];
protected readonly _primaryKey = 'type';
constructor(
protected readonly _injector: Injector,

View File

@ -7,18 +7,18 @@
(action)="openDeleteDictionaryDialog($event)"
*ngIf="currentUser.isAdmin"
[tooltip]="'dictionary-overview.action.delete' | translate"
[type]="circleButtonTypes.dark"
icon="red:trash"
tooltipPosition="below"
[type]="circleButtonTypes.dark"
></iqser-circle-button>
<iqser-circle-button
(action)="openEditDictionaryDialog($event)"
*ngIf="currentUser.isAdmin"
[tooltip]="'dictionary-overview.action.edit' | translate"
[type]="circleButtonTypes.dark"
icon="red:edit"
tooltipPosition="below"
[type]="circleButtonTypes.dark"
></iqser-circle-button>
<iqser-circle-button
@ -60,11 +60,11 @@
[initialEntries]="entries"
></redaction-dictionary-manager>
<div class="right-container">
<div *ngIf="!!dictionary" class="right-container">
<div class="dictionary-header">
<div [style.backgroundColor]="dictionary.hexColor" class="color-box"></div>
<div class="heading-xl">
{{ dictionary.type | humanize }}
{{ dictionary.label }}
</div>
</div>
<div class="small-label stats-subtitle">

View File

@ -40,18 +40,18 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
private readonly _dictionaryControllerService: DictionaryControllerService
) {
super(_translateService);
this._appStateService.activateDictionary(
this._activatedRoute.snapshot.params.type,
this._activatedRoute.snapshot.params.dossierTemplateId
);
this.dictionary = this._appStateService.activeDictionary;
}
get 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();
}

View File

@ -22,7 +22,6 @@ import { TypeValueWrapper } from '@models/file/type-value.wrapper';
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
import { DossiersService } from '../modules/dossier/services/dossiers.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { humanize } from '@iqser/common-ui';
import { UserPreferenceService } from '@services/user-preference.service';
export interface AppState {
@ -193,7 +192,7 @@ export class AppStateService {
return this.dossierTemplates.find(rs => rs.dossierTemplateId === id);
}
getDictionaryTypeValue(key: string, dossierTemplateId?: string) {
getDictionaryTypeValue(key: string, dossierTemplateId?: string): TypeValueWrapper {
if (!dossierTemplateId && this.activeDossier) {
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(
tap(typesResponse => {
for (const type of typesResponse.types) {
dictionaryData[type.type] = type;
dictionaryData[type.type].label = humanize(type.type, false);
}
})
);
@ -634,24 +653,6 @@ export class AppStateService {
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) {
this.activeDossier.files.forEach(f => {
f.lastOpened = f.fileId === fileId;

View File

@ -89,3 +89,10 @@ export function getLeftDateTime(ISOString: string) {
export function removeBraces(str: any): string {
return str.replace(/[{}]/g, '');
}
export function toKebabCase(str: string): string {
return str
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/[\s_]+/g, '-')
.toLowerCase();
}

View File

@ -42,12 +42,13 @@
"description": "Description",
"description-placeholder": "Enter Description",
"hint": "Hint",
"name": "Dictionary Name",
"name": "Display Name",
"name-hint": "Cannot be edited after saving.",
"name-placeholder": "Enter Name",
"rank": "Rank",
"rank-placeholder": "1000",
"redaction": "Redaction"
"redaction": "Redaction",
"technical-name": "Technical Name"
},
"save": "Save Dictionary",
"title": "{type, select, edit{Edit {name}} create{Create} other{}} Dictionary"

View File

@ -23,8 +23,8 @@ form .red-input-group:not(first-of-type) {
right: 1px;
bottom: 1px;
background: $grey-5;
height: 32px;
width: 32px;
height: 34px;
width: 34px;
border-left: 1px solid $grey-5;
border-top-right-radius: 7px;
border-bottom-right-radius: 7px;