diff --git a/apps/red-ui/src/app/modules/admin/screens/entities/screens/dictionary/dictionary-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/entities/screens/dictionary/dictionary-screen.component.ts
index 98035a664..5ed382572 100644
--- a/apps/red-ui/src/app/modules/admin/screens/entities/screens/dictionary/dictionary-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/entities/screens/dictionary/dictionary-screen.component.ts
@@ -47,16 +47,14 @@ export class DictionaryScreenComponent implements OnInit {
this._loadingService.start();
try {
- await lastValueFrom(
- this._dictionaryService.saveEntries(
- entries,
- this.initialEntries$.value,
- this.#dossierTemplateId,
- this.entityType,
- null,
- true,
- DICTIONARY_TO_ENTRY_TYPE_MAP[this.type],
- ),
+ await this._dictionaryService.saveEntries(
+ entries,
+ this.initialEntries$.value,
+ this.#dossierTemplateId,
+ this.entityType,
+ null,
+ true,
+ DICTIONARY_TO_ENTRY_TYPE_MAP[this.type],
);
await this._loadEntries();
} catch (e) {
diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
index af47cfbd7..30d1e781f 100644
--- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
+++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
@@ -50,15 +50,13 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
async save(): EditDossierSaveResult {
try {
- await firstValueFrom(
- this._dictionaryService.saveEntries(
- this._dictionaryManager.editor.currentEntries,
- this._dictionaryManager.initialEntries,
- this.dossier.dossierTemplateId,
- this.dossierDictionary.type,
- this.dossier.id,
- false,
- ),
+ await this._dictionaryService.saveEntries(
+ this._dictionaryManager.editor.currentEntries,
+ this._dictionaryManager.initialEntries,
+ this.dossier.dossierTemplateId,
+ this.dossierDictionary.type,
+ this.dossier.id,
+ false,
);
await this.#updateDossierDictionary();
diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
index f35b02351..33b8651e9 100644
--- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
+++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
@@ -97,6 +97,7 @@
[label]="'dictionary-overview.save-changes' | translate"
[type]="iconButtonTypes.primary"
icon="iqser:check"
+ [disabled]="!!(_loadingService.isLoading$ | async)"
>
diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
index 7f97a508e..90e22c1a4 100644
--- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
@@ -57,7 +57,7 @@ export class DictionaryManagerComponent implements OnChanges {
constructor(
private readonly _dictionaryService: DictionaryService,
private readonly _dictionariesMapService: DictionariesMapService,
- private readonly _loadingService: LoadingService,
+ protected readonly _loadingService: LoadingService,
private readonly _changeRef: ChangeDetectorRef,
readonly activeDossiersService: ActiveDossiersService,
readonly dossierTemplatesService: DossierTemplatesService,
diff --git a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.html b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.html
index 0a113be28..441062e92 100644
--- a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.html
+++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.html
@@ -1,6 +1,6 @@
+
+
diff --git a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts
index b59f54434..2b34ec87f 100644
--- a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts
@@ -1,5 +1,5 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
-import { Debounce, List, LoadingService, OnChange } from '@iqser/common-ui';
+import { List, LoadingService, OnChange } from '@iqser/common-ui';
import { EditorThemeService } from '@services/editor-theme.service';
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
import ICodeEditor = monaco.editor.ICodeEditor;
@@ -7,6 +7,8 @@ import IDiffEditor = monaco.editor.IDiffEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import ILineChange = monaco.editor.ILineChange;
import IEditorMouseEvent = monaco.editor.IEditorMouseEvent;
+import { BehaviorSubject } from 'rxjs';
+import { debounceTime, filter, tap } from 'rxjs/operators';
const MIN_WORD_LENGTH = 2;
const lineChangeToDecoration = ({ originalEndLineNumber, originalStartLineNumber }: ILineChange) =>
@@ -41,6 +43,17 @@ export class EditorComponent implements OnInit, OnChanges {
value: string;
private _diffEditor: IDiffEditor;
private _decorations: string[] = [];
+ private readonly _codeEditorTextChanged$ = new BehaviorSubject('');
+ protected readonly _codeEditorTextChangedHandler$ = this._codeEditorTextChanged$.asObservable().pipe(
+ filter(Boolean),
+ debounceTime(0), // prevent race condition with onPaste event
+ tap(newText => {
+ const newDecorations = this.#getDecorations(newText);
+ this._decorations = this.codeEditor.deltaDecorations(this._decorations, newDecorations);
+ this.diffValue = this.value;
+ this._loadingService.stop();
+ }),
+ );
constructor(private readonly _loadingService: LoadingService, private readonly _editorThemeService: EditorThemeService) {}
@@ -56,12 +69,12 @@ export class EditorComponent implements OnInit, OnChanges {
return this.currentEntries.length;
}
- @Debounce()
- codeEditorTextChanged() {
- const newDecorations = this.#getDecorations();
- this._decorations = this.codeEditor.deltaDecorations(this._decorations, newDecorations);
- this.diffValue = this.value;
- this._loadingService.stop();
+ onPaste() {
+ this._loadingService.start();
+ }
+
+ codeEditorTextChanged(event) {
+ this._codeEditorTextChanged$.next(event);
}
ngOnChanges(changes: SimpleChanges) {
@@ -105,12 +118,8 @@ export class EditorComponent implements OnInit, OnChanges {
this._diffEditor?.getModifiedEditor().setValue(this.diffValue);
}
- onPaste() {
- this._loadingService.start();
- }
-
- #getDecorations() {
- const currentEntries = this.currentEntries;
+ #getDecorations(newText: string) {
+ const currentEntries = newText.split('/n');
const newDecorations: IModelDeltaDecoration[] = [];
for (let index = 0; index < currentEntries.length; ++index) {
diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts
index 158a4b176..ea65f2479 100644
--- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts
+++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts
@@ -86,7 +86,7 @@ export class DictionaryService extends EntitiesService
);
}
- saveEntries(
+ async saveEntries(
entries: List,
initialEntries: List,
dossierTemplateId: string,
@@ -94,42 +94,50 @@ export class DictionaryService extends EntitiesService
dossierId: string,
showToast = true,
dictionaryEntryType = DictionaryEntryTypes.ENTRY,
- ): Observable {
- const entriesToAdd = entries.map(e => e.trim()).filter(e => !!e);
- const deletedEntries = initialEntries.filter(e => !entries.includes(e));
- console.log({ entriesToAdd, deletedEntries });
+ ): Promise {
+ const entriesToAdd: Array = [];
+ const deletedEntries: Array = [];
+ for (let i = 0; i < entries.length; i++) {
+ if (!entries.at(i).trim()) {
+ continue;
+ }
+ entriesToAdd.push(entries.at(i));
+ }
+ for (let i = 0; i < initialEntries.length; i++) {
+ if (entries.includes(initialEntries.at(i))) {
+ continue;
+ }
+ deletedEntries.push(initialEntries.at(i));
+ }
// remove empty lines
const invalidRowsExist = entriesToAdd.filter(e => e.length < MIN_WORD_LENGTH);
if (invalidRowsExist.length === 0) {
// can add at least 1 - block UI
- const obs: Observable[] = [];
+ const promises: Promise[] = [];
if (deletedEntries.length) {
- obs.push(this._deleteEntries(deletedEntries, dossierTemplateId, type, dictionaryEntryType, dossierId));
+ promises.push(firstValueFrom(this._deleteEntries(deletedEntries, dossierTemplateId, type, dictionaryEntryType, dossierId)));
}
if (entriesToAdd.filter(e => !initialEntries.includes(e)).length) {
- obs.push(this._addEntries(entriesToAdd, dossierTemplateId, type, dictionaryEntryType, dossierId));
+ promises.push(firstValueFrom(this._addEntries(entriesToAdd, dossierTemplateId, type, dictionaryEntryType, dossierId)));
+ }
+ try {
+ await Promise.all(promises);
+ if (showToast) {
+ this._toaster.success(_('dictionary-overview.success.generic'));
+ }
+ return;
+ } catch (error) {
+ if ((error as HttpErrorResponse).status === 400) {
+ this._toaster.error(_('dictionary-overview.error.400'));
+ } else {
+ this._toaster.error(_('dictionary-overview.error.generic'));
+ }
+ return;
}
- return zip(obs).pipe(
- switchMap(dictionary => this._dossierTemplateStatsService.getFor([dossierTemplateId]).pipe(map(() => dictionary))),
- tap({
- next: () => {
- if (showToast) {
- this._toaster.success(_('dictionary-overview.success.generic'));
- }
- },
- error: (error: unknown) => {
- if ((error as HttpErrorResponse).status === 400) {
- this._toaster.error(_('dictionary-overview.error.400'));
- } else {
- this._toaster.error(_('dictionary-overview.error.generic'));
- }
- },
- }),
- );
}
this._toaster.error(_('dictionary-overview.error.entries-too-short'));
- return throwError(() => 'Entries too short');
+ throw new Error('Entries too short');
}
hasManualType(dossierTemplateId: string): boolean {