+
();
+ @ViewChild(EditorComponent) readonly editor: EditorComponent;
currentMatch = 0;
findMatches: FindMatch[] = [];
- currentEntries: string[] = [];
- editorOptions: IStandaloneEditorConstructionOptions = {};
diffEditorText = '';
showDiffEditor = false;
searchText = '';
-
- selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') };
- selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') };
+ selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') } as Dossier;
+ selectDictionary = {
+ label: _('dictionary-overview.compare.select-dictionary')
+ } as TypeValue;
+ selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') } as DossierTemplate;
compare: false;
- dossiers: List = this._dossiers;
-
- private _codeEditor: ICodeEditor;
- private _diffEditor: IDiffEditor;
- private _decorations: string[] = [];
+ dictionaries: List = this._dictionaries;
private _searchDecorations: string[] = [];
constructor(
private readonly _dictionaryService: DictionaryService,
readonly dossiersService: DossiersService,
+ readonly appStateService: AppStateService,
readonly dossierTemplatesService: DossierTemplatesService
) {}
- private _dossierTemplate: DossierTemplate = this.selectDossierTemplate as DossierTemplate;
+ private _dossierTemplate = this.selectDossierTemplate;
get dossierTemplate() {
return this._dossierTemplate;
@@ -63,11 +60,12 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
set dossierTemplate(value) {
this._dossierTemplate = value;
- this.dossier = this.selectDossier as Dossier;
- this.dossiers = this._dossiers;
+ this.dictionaries = this._dictionaries;
+ this._dictionary = this.selectDictionary;
+ this.showDiffEditor = false;
}
- private _dossier: Dossier = this.selectDossier as Dossier;
+ private _dossier = this.selectDossier;
get dossier() {
return this._dossier;
@@ -76,77 +74,61 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
set dossier(dossier: Dossier) {
this._dossier = dossier;
- if (dossier === this.selectDossier) {
+ if (dossier.dossierName === this.selectDossier.dossierName) {
this.showDiffEditor = false;
this.diffEditorText = '';
return;
}
- this._onDossierChanged(dossier)
+ this._onDossierChanged(dossier.dossierTemplateId, dossier.dossierId)
.pipe(take(1))
.subscribe(entries => {
this.diffEditorText = entries;
this.showDiffEditor = true;
- if (this.showDiffEditor) {
- this._diffEditor?.getOriginalEditor().setValue(this.diffEditorText);
- }
});
}
- get editorValue(): string {
- return this.currentEntries.join('\n');
+ private _dictionary = this.selectDictionary;
+
+ get dictionary() {
+ return this._dictionary;
}
- set editorValue(text: string) {
- this.currentEntries = text.split('\n');
- this.codeEditorTextChanged();
- }
+ set dictionary(dictionary: TypeValue) {
+ this._dictionary = dictionary;
- get hasChanges(): boolean {
- return this.currentEntries.toString() !== this.initialEntries.toString();
- }
-
- get _dossiers() {
- if (this.filterByDossierTemplate) {
- return this.dossiersService.all.filter(dossier => dossier.dossierTemplateId === this.dossierTemplate.dossierTemplateId);
+ if (dictionary.label === this.selectDictionary.label) {
+ this.showDiffEditor = false;
+ this.diffEditorText = '';
+ return;
}
- return this.dossiersService.all;
+
+ const entries = this.appStateService.dictionaryData[this._dictionary.dossierTemplateId][this._dictionary.type].entries;
+
+ this.diffEditorText = this._toString(entries);
+ this.showDiffEditor = true;
+ }
+
+ get _dictionaries() {
+ if (!this._dossierTemplate || this._dossierTemplate.name === this.selectDossierTemplate.name) {
+ return;
+ }
+ return Object.values(this.appStateService.dictionaryData[this.dossierTemplate?.dossierTemplateId]);
}
get dossierTemplateIsNotSelected() {
return this.filterByDossierTemplate && this._dossierTemplate.name === this.selectDossierTemplate.name;
}
- ngOnInit(): void {
- this.currentEntries = [...this.initialEntries];
-
- this.editorOptions = {
- theme: 'vs',
- language: 'text/plain',
- automaticLayout: true,
- readOnly: !this.canEdit
- };
- }
-
- onDiffEditorInit(editor: IDiffEditor): void {
- this._diffEditor = editor;
- }
-
- onCodeEditorInit(editor: ICodeEditor): void {
- this._codeEditor = editor;
- (window as any).monaco.editor.defineTheme('redaction', {
- base: 'vs',
- inherit: true,
- rules: [],
- colors: {
- 'editor.lineHighlightBackground': '#f4f5f7'
- }
- });
- (window as any).monaco.editor.setTheme('redaction');
+ get optionNotSelected() {
+ if (this.filterByDossierTemplate) {
+ return this.selectDictionary.label === this._dictionary.label;
+ }
+ return this.dossier.dossierName === this.selectDossier.dossierName;
}
revert() {
- this.currentEntries = [...this.initialEntries];
+ this.editor?.revert();
this.searchChanged('');
}
@@ -160,13 +142,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
this.nextSearchMatch();
}
- @Debounce()
- codeEditorTextChanged() {
- const newDecorations = this.currentEntries.filter(entry => this._isNew(entry)).map(entry => this._getDecoration(entry));
-
- this._decorations = this._codeEditor.deltaDecorations(this._decorations, newDecorations);
- }
-
nextSearchMatch(): void {
if (this.findMatches.length <= 0) {
return;
@@ -190,30 +165,18 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
}
private _applySearchDecorations() {
- this._searchDecorations = this._codeEditor?.deltaDecorations(this._searchDecorations, []) || [];
+ this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, []) || [];
const decorations = this.findMatches.map(match => this._getSearchDecoration(match));
- this._searchDecorations = this._codeEditor?.deltaDecorations(this._searchDecorations, decorations) || [];
+ this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, decorations) || [];
}
private _getMatches(text: string): FindMatch[] {
- const model = this._codeEditor?.getModel();
+ const model = this.editor.codeEditor?.getModel();
return model?.findMatches(text, false, false, false, null, false) || [];
}
- private _isNew(entry: string): boolean {
- return this.initialEntries.indexOf(entry) < 0 && entry?.trim().length > 0;
- }
-
- private _getDecoration(entry: string): IModelDeltaDecoration {
- const line = this.currentEntries.indexOf(entry) + 1;
- const cssClass = entry.length < MIN_WORD_LENGTH ? 'too-short-marker' : 'changed-row-marker';
- const range = new monaco.Range(line, 1, line, 1);
-
- return { range: range, options: { isWholeLine: true, className: cssClass } };
- }
-
private _getSearchDecoration(match: FindMatch): IModelDeltaDecoration {
return { range: match.range, options: { inlineClassName: 'search-marker' } };
}
@@ -221,12 +184,12 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
private _scrollToCurrentMatch(): void {
const range = this.findMatches[this.currentMatch - 1].range;
- this._codeEditor.setSelection(range);
- this._codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL);
+ this.editor.codeEditor.setSelection(range);
+ this.editor.codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL);
}
- private _onDossierChanged({ id, dossierTemplateId }: Dossier): Observable {
- const dictionary$ = this._dictionaryService.getFor(dossierTemplateId, 'dossier_redaction', id);
+ private _onDossierChanged(dossierTemplateId: string, dossierId?: string, type = 'dossier_redaction'): Observable {
+ const dictionary$ = this._dictionaryService.getFor(dossierTemplateId, type, dossierId);
return dictionary$.pipe(map(data => this._toString([...data.entries])));
}
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
new file mode 100644
index 000000000..4834d2b2a
--- /dev/null
+++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.html
@@ -0,0 +1,14 @@
+
+
+
diff --git a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.scss b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.scss
new file mode 100644
index 000000000..7707ea433
--- /dev/null
+++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.scss
@@ -0,0 +1,6 @@
+:host,
+ngx-monaco-diff-editor,
+ngx-monaco-editor {
+ height: 100%;
+ width: 100%;
+}
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
new file mode 100644
index 000000000..fee65d68c
--- /dev/null
+++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts
@@ -0,0 +1,104 @@
+import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
+import { Debounce, List } from '@iqser/common-ui';
+import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
+import ICodeEditor = monaco.editor.ICodeEditor;
+import IDiffEditor = monaco.editor.IDiffEditor;
+import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
+
+const MIN_WORD_LENGTH = 2;
+
+@Component({
+ selector: 'redaction-editor',
+ templateUrl: './editor.component.html',
+ styleUrls: ['./editor.component.scss']
+})
+export class EditorComponent implements OnInit, OnChanges {
+ editorOptions: IStandaloneEditorConstructionOptions = {};
+ @Input() showDiffEditor = false;
+ @Input() initialEntries: List;
+ @Input() canEdit = false;
+ currentEntries: string[] = [];
+ codeEditor: ICodeEditor;
+ diffEditor: IDiffEditor;
+ private _decorations: string[] = [];
+ _diffEditorText = '';
+
+ get diffEditorText() {
+ return this._diffEditorText;
+ }
+
+ @Input()
+ set diffEditorText(value: string) {
+ this._diffEditorText = value;
+ this.diffEditor?.getOriginalEditor().setValue(value);
+ }
+
+ get value(): string {
+ return this.currentEntries.join('\n');
+ }
+
+ set value(text: string) {
+ this.currentEntries = text.split('\n');
+ this.codeEditorTextChanged();
+ }
+
+ get hasChanges(): boolean {
+ return this.currentEntries.toString() !== this.initialEntries.toString();
+ }
+
+ ngOnInit(): void {
+ this.currentEntries = [...this.initialEntries];
+
+ this.editorOptions = {
+ theme: 'vs',
+ language: 'text/plain',
+ automaticLayout: true,
+ readOnly: !this.canEdit
+ };
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ console.log(changes);
+ this.revert();
+ }
+
+ onDiffEditorInit(editor: IDiffEditor): void {
+ this.diffEditor = editor;
+ }
+
+ onCodeEditorInit(editor: ICodeEditor): void {
+ this.codeEditor = editor;
+ (window as any).monaco.editor.defineTheme('redaction', {
+ base: 'vs',
+ inherit: true,
+ rules: [],
+ colors: {
+ 'editor.lineHighlightBackground': '#f4f5f7'
+ }
+ });
+ (window as any).monaco.editor.setTheme('redaction');
+ }
+
+ @Debounce()
+ codeEditorTextChanged() {
+ const newDecorations = this.currentEntries.filter(entry => this._isNew(entry)).map(entry => this._getDecoration(entry));
+
+ this._decorations = this.codeEditor.deltaDecorations(this._decorations, newDecorations);
+ }
+
+ revert() {
+ this.currentEntries = [...this.initialEntries];
+ }
+
+ private _isNew(entry: string): boolean {
+ return this.initialEntries.indexOf(entry) < 0 && entry?.trim().length > 0;
+ }
+
+ private _getDecoration(entry: string): IModelDeltaDecoration {
+ const line = this.currentEntries.indexOf(entry) + 1;
+ const cssClass = entry.length < MIN_WORD_LENGTH ? 'too-short-marker' : 'changed-row-marker';
+ const range = new monaco.Range(line, 1, line, 1);
+
+ return { range: range, options: { isWholeLine: true, className: cssClass } };
+ }
+}
diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts
index 97ff6f7a2..2698a60f3 100644
--- a/apps/red-ui/src/app/modules/shared/shared.module.ts
+++ b/apps/red-ui/src/app/modules/shared/shared.module.ts
@@ -24,6 +24,7 @@ import { LongPressDirective } from './directives/long-press.directive';
import { NamePipe } from './pipes/name.pipe';
import { TypeFilterComponent } from './components/type-filter/type-filter.component';
import { TeamMembersComponent } from './components/team-members/team-members.component';
+import { EditorComponent } from './components/editor/editor.component';
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
@@ -47,7 +48,7 @@ const utils = [DatePipe, NamePipe, NavigateLastDossiersScreenDirective, LongPres
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
@NgModule({
- declarations: [...components, ...utils],
+ declarations: [...components, ...utils, EditorComponent],
imports: [CommonModule, ...modules, MonacoEditorModule],
exports: [...modules, ...components, ...utils],
providers: [
diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json
index 6769d6015..cad0fbd1f 100644
--- a/apps/red-ui/src/assets/i18n/de.json
+++ b/apps/red-ui/src/assets/i18n/de.json
@@ -435,7 +435,8 @@
"compare": {
"compare": "Vergleichen Sie",
"select-dossier": "Wählen Sie Dossiervorlage",
- "select-dossier-template": ""
+ "select-dossier-template": "",
+ "select-dictionary": ""
},
"dictionary-details": {
"description": "Beschreibung"
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 7bfc55b26..a219ab90e 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -475,7 +475,8 @@
"compare": {
"compare": "Compare",
"select-dossier": "Select Dossier",
- "select-dossier-template": "Select Dossier Template"
+ "select-dossier-template": "Select Dossier Template",
+ "select-dictionary": "Select Dictionary"
},
"dictionary-details": {
"description": "Description"