Merge branch 'master' of ssh://git.iqser.com:2222/red/ui

This commit is contained in:
Timo Bejan 2021-11-09 15:41:53 +02:00
commit d8f8c62316
5 changed files with 54 additions and 48 deletions

View File

@ -7,16 +7,16 @@
<div class="dialog-content">
<div class="iqser-input-group mb-14">
<label translate="add-edit-dictionary.form.technical-name"></label>
<div class="technical-name">{{ dictionary?.type || technicalName || '-' }}</div>
<div class="technical-name">{{ dictionary?.type || (technicalName$ | async) || '-' }}</div>
</div>
<div *ngIf="!!dictionary" class="iqser-input-group mb-14">
<div *ngIf="(canEditLabel$ | async) === false" class="iqser-input-group mb-14">
<label translate="add-edit-dictionary.form.name"></label>
{{ dictionary.label }}
</div>
<div class="first-row">
<div *ngIf="!dictionary" class="iqser-input-group required">
<div *ngIf="canEditLabel$ | async" class="iqser-input-group required">
<label translate="add-edit-dictionary.form.name"></label>
<input
[placeholder]="'add-edit-dictionary.form.name-placeholder' | translate"
@ -53,7 +53,7 @@
[style.background]="form.get('hexColor').value"
class="input-icon"
>
<mat-icon *ngIf="hasColor" svgIcon="red:color-picker"></mat-icon>
<mat-icon *ngIf="hasColor$ | async" svgIcon="red:color-picker"></mat-icon>
</div>
</div>
</div>

View File

@ -1,39 +1,47 @@
import { Component, Inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Observable } from 'rxjs';
import { BaseDialogComponent, Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, shareDistinctLast, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { AppStateService } from '@state/app-state.service';
import { toKebabCase } from '@utils/functions';
import { DictionaryService } from '@shared/services/dictionary.service';
import { Dictionary, IDictionary } from '@red/domain';
import { UserService } from '@services/user.service';
import { map } from 'rxjs/operators';
@Component({
selector: 'redaction-add-edit-dictionary-dialog',
templateUrl: './add-edit-dictionary-dialog.component.html',
styleUrls: ['./add-edit-dictionary-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
form: FormGroup;
readonly dictionary: Dictionary;
technicalName = '';
private readonly _dossierTemplateId: string;
readonly form: FormGroup;
readonly dictionary = this._data.dictionary;
readonly canEditLabel$ = this._canEditLabel$;
readonly technicalName$: Observable<string>;
readonly dialogHeader = this._translateService.instant('add-edit-dictionary.title', {
type: this._data.dictionary ? 'edit' : 'create',
name: this._data.dictionary?.label,
});
readonly hasColor$: Observable<boolean>;
private readonly _dossierTemplateId = this._data.dossierTemplateId;
constructor(
private readonly _dictionaryService: DictionaryService,
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
readonly userService: UserService,
private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
private readonly _appStateService: AppStateService,
private readonly _translateService: TranslateService,
private readonly _dictionaryService: DictionaryService,
private readonly _dialogRef: MatDialogRef<AddEditDictionaryDialogComponent>,
@Inject(MAT_DIALOG_DATA)
private readonly _data: { dictionary: Dictionary; dossierTemplateId: string },
private readonly _data: { readonly dictionary: Dictionary; readonly dossierTemplateId: string },
) {
super();
this.dictionary = _data.dictionary;
this._dossierTemplateId = _data.dossierTemplateId;
this.form = _formBuilder.group({
label: [this.dictionary?.label, [Validators.required, Validators.minLength(3)]],
description: [this.dictionary?.description],
@ -43,21 +51,8 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
addToDictionaryAction: [!!this.dictionary?.addToDictionaryAction],
caseSensitive: [this.dictCaseSensitive],
});
this.form.get('label').valueChanges.subscribe(() => {
this._updateTechnicalName();
});
}
get dialogHeader(): string {
return this._translateService.instant('add-edit-dictionary.title', {
type: this.dictionary ? 'edit' : 'create',
name: this.dictionary?.label,
});
}
get hasColor(): boolean {
const hexColorValue = this.form.get('hexColor').value;
return !hexColorValue || hexColorValue?.length === 0;
this.hasColor$ = this._colorEmpty$;
this.technicalName$ = this.form.get('label').valueChanges.pipe(map(value => this._toTechnicalName(value)));
}
get dictCaseSensitive(): boolean {
@ -82,21 +77,34 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
return false;
}
save(): void {
private get _canEditLabel$() {
return this.userService.currentUser$.pipe(
map(user => user.isAdmin || !this._data.dictionary),
shareDistinctLast(),
);
}
private get _colorEmpty$() {
return this.form.get('hexColor').valueChanges.pipe(map((value: string) => !value || value?.length === 0));
}
async save(): Promise<void> {
const dictionary = this._formToObject();
let observable: Observable<unknown>;
const dossierTemplateId = this._data.dossierTemplateId;
if (this.dictionary) {
// edit mode
observable = this._dictionaryService.updateDictionary(dictionary, this._dossierTemplateId, dictionary.type);
observable = this._dictionaryService.updateDictionary(dictionary, dossierTemplateId, dictionary.type);
} else {
// create mode
observable = this._dictionaryService.addDictionary({ ...dictionary, dossierTemplateId: this._dossierTemplateId });
observable = this._dictionaryService.addDictionary({ ...dictionary, dossierTemplateId });
}
observable.subscribe(
() => this._dialogRef.close(true),
error => {
return observable
.toPromise()
.then(() => this._dialogRef.close(true))
.catch(error => {
if (error.status === 409) {
this._toaster.error(_('add-edit-dictionary.error.dictionary-already-exists'));
} else if (error.status === 400) {
@ -104,25 +112,23 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
} else {
this._toaster.error(_('add-edit-dictionary.error.generic'));
}
},
);
});
}
private _updateTechnicalName() {
const displayName = this.form.get('label').value.trim();
private _toTechnicalName(value: string) {
const existingTechnicalNames = Object.keys(this._appStateService.dictionaryData[this._dossierTemplateId]);
const baseTechnicalName: string = toKebabCase(displayName);
const baseTechnicalName = toKebabCase(value.trim());
let technicalName = baseTechnicalName;
let suffix = 1;
while (existingTechnicalNames.includes(technicalName)) {
technicalName = [baseTechnicalName, suffix++].join('-');
}
this.technicalName = technicalName;
return technicalName;
}
private _formToObject(): IDictionary {
return {
type: this.dictionary?.type || this.technicalName,
type: this.dictionary?.type || this._toTechnicalName(this.form.get('label').value),
label: this.form.get('label').value,
caseInsensitive: !this.form.get('caseSensitive').value,
description: this.form.get('description').value,
@ -130,7 +136,7 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
hint: this.form.get('hint').value,
rank: this.form.get('rank').value,
addToDictionaryAction: this.form.get('addToDictionaryAction').value,
dossierTemplateId: this._dossierTemplateId,
dossierTemplateId: this._data.dossierTemplateId,
};
}
}

View File

@ -4,7 +4,7 @@ import { IDictionary } from './dictionary';
export class Dictionary implements IDictionary, IListable {
readonly addToDictionaryAction: boolean;
readonly caseInsensitive: boolean;
readonly description?: string;
readonly description: string;
readonly dossierTemplateId?: string;
entries: List;
readonly hexColor?: string;
@ -17,7 +17,7 @@ export class Dictionary implements IDictionary, IListable {
constructor(dictionary: IDictionary, readonly virtual = false) {
this.addToDictionaryAction = !!dictionary.addToDictionaryAction;
this.caseInsensitive = !!dictionary.caseInsensitive;
this.description = dictionary.description;
this.description = dictionary.description ?? '';
this.dossierTemplateId = dictionary.dossierTemplateId;
this.entries = dictionary.entries ?? [];
this.hexColor = dictionary.hexColor;

View File

@ -1,6 +1,6 @@
{
"name": "redaction",
"version": "2.339.0",
"version": "2.340.0",
"private": true,
"license": "MIT",
"scripts": {

Binary file not shown.