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

View File

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

Binary file not shown.