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 441062e92..10abee1e3 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,10 +1,10 @@
-
-
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 2b34ec87f..914e4931a 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,14 +1,15 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { List, LoadingService, OnChange } from '@iqser/common-ui';
import { EditorThemeService } from '@services/editor-theme.service';
+import { Subject } from 'rxjs';
+import { debounceTime, filter, tap } from 'rxjs/operators';
+import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
import ICodeEditor = monaco.editor.ICodeEditor;
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,28 +42,35 @@ export class EditorComponent implements OnInit, OnChanges {
editorOptions: IStandaloneEditorConstructionOptions = {};
codeEditor: ICodeEditor;
value: string;
+ protected _initialEntriesMap = new Set();
+
+ protected readonly _editorTextChanged$ = new Subject();
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) {}
+ constructor(private readonly _loadingService: LoadingService, private readonly _editorThemeService: EditorThemeService) {
+ const textChanged$ = this._editorTextChanged$.pipe(
+ debounceTime(300), // prevent race condition with onPaste event
+ takeUntilDestroyed(),
+ filter(text => text.length > 0),
+ tap(newText => {
+ const newDecorations = this.#getDecorations(newText);
+ this._decorations = this.codeEditor.deltaDecorations(this._decorations, newDecorations);
+ this.diffValue = this.value;
+ this._loadingService.stop();
+ }),
+ );
+ // eslint-disable-next-line rxjs/no-ignored-subscription
+ textChanged$.subscribe();
+ }
get currentEntries(): string[] {
return this.value.split('\n');
}
+ // TODO: this is called way too often, we need a better option
get hasChanges(): boolean {
- return this.currentEntries.toString() !== this.initialEntries.toString();
+ return this.value.trim() !== this.initialEntries.join('\n');
}
get #currentEntriesCount(): number {
@@ -73,10 +81,6 @@ export class EditorComponent implements OnInit, OnChanges {
this._loadingService.start();
}
- codeEditorTextChanged(event) {
- this._codeEditorTextChanged$.next(event);
- }
-
ngOnChanges(changes: SimpleChanges) {
if (changes.diffEditorText) {
this._diffEditor?.getOriginalEditor().setValue(this.diffEditorText);
@@ -114,17 +118,23 @@ export class EditorComponent implements OnInit, OnChanges {
revert() {
this.value = this.initialEntries.join('\n');
+ this._initialEntriesMap = new Set(this.initialEntries);
this.diffValue = this.value;
this._diffEditor?.getModifiedEditor().setValue(this.diffValue);
+ this._editorTextChanged$.next(this.value);
}
#getDecorations(newText: string) {
- const currentEntries = newText.split('/n');
+ const currentEntries = newText.split('\n');
const newDecorations: IModelDeltaDecoration[] = [];
- for (let index = 0; index < currentEntries.length; ++index) {
- const entry = currentEntries.at(index);
- if (!this.#isNew(entry)) {
+ for (let index = 0; index < currentEntries.length; index++) {
+ const entry = currentEntries.at(index)?.trim();
+ if (!entry || entry.length === 0) {
+ continue;
+ }
+
+ if (this._initialEntriesMap.has(entry)) {
continue;
}
@@ -187,10 +197,6 @@ export class EditorComponent implements OnInit, OnChanges {
});
}
- #isNew(entry: string): boolean {
- return this.initialEntries.indexOf(entry) < 0 && entry?.trim().length > 0;
- }
-
#getDecoration(entry: string, line: number): IModelDeltaDecoration {
const cssClass = entry.length < MIN_WORD_LENGTH ? 'too-short-marker' : 'changed-row-marker';
const range = new monaco.Range(line, 1, line, 1);