new component for editor and fix compare for template dictionaries
This commit is contained in:
parent
760a446fd5
commit
43a46d04e8
@ -42,7 +42,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
|||||||
}
|
}
|
||||||
|
|
||||||
get hasChanges() {
|
get hasChanges() {
|
||||||
return this._dictionaryManager.hasChanges;
|
return this._dictionaryManager.editor.hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@ -85,7 +85,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
|||||||
}
|
}
|
||||||
|
|
||||||
download(): void {
|
download(): void {
|
||||||
const content = this._dictionaryManager.editorValue;
|
const content = this._dictionaryManager.editor.value;
|
||||||
const blob = new Blob([content], {
|
const blob = new Blob([content], {
|
||||||
type: 'text/plain;charset=utf-8'
|
type: 'text/plain;charset=utf-8'
|
||||||
});
|
});
|
||||||
@ -98,7 +98,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
|||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
fileReader.onload = () => {
|
fileReader.onload = () => {
|
||||||
this._dictionaryManager.editorValue = fileReader.result as string;
|
this._dictionaryManager.editor.value = fileReader.result as string;
|
||||||
this._fileInput.nativeElement.value = null;
|
this._fileInput.nativeElement.value = null;
|
||||||
};
|
};
|
||||||
fileReader.readAsText(file);
|
fileReader.readAsText(file);
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
get changed() {
|
get changed() {
|
||||||
return this._dictionaryManager.hasChanges;
|
return this._dictionaryManager.editor.hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
get disabled() {
|
get disabled() {
|
||||||
@ -58,7 +58,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
|
|||||||
async save() {
|
async save() {
|
||||||
await this._dictionaryService
|
await this._dictionaryService
|
||||||
.saveEntries(
|
.saveEntries(
|
||||||
this._dictionaryManager.currentEntries,
|
this._dictionaryManager.editor.currentEntries,
|
||||||
this._dictionaryManager.initialEntries,
|
this._dictionaryManager.initialEntries,
|
||||||
this.dossier.dossierTemplateId,
|
this.dossier.dossierTemplateId,
|
||||||
'dossier_redaction',
|
'dossier_redaction',
|
||||||
|
|||||||
@ -30,18 +30,31 @@
|
|||||||
{{ 'dictionary-overview.compare.compare' | translate }}
|
{{ 'dictionary-overview.compare.compare' | translate }}
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="filterByDossierTemplate" class="iqser-input-group w-200 mt-0 mr-8">
|
|
||||||
<mat-select [(ngModel)]="dossierTemplate" [disabled]="!compare">
|
<ng-container *ngIf="filterByDossierTemplate">
|
||||||
<mat-option [value]="selectDossierTemplate">{{ selectDossierTemplate.name | translate }}</mat-option>
|
<div class="iqser-input-group w-200 mt-0 mr-8">
|
||||||
<mat-option *ngFor="let dossierTemplate of dossierTemplatesService.all$ | async" [value]="dossierTemplate">
|
<mat-select [(ngModel)]="dossierTemplate" [disabled]="!compare">
|
||||||
{{ dossierTemplate.name }}
|
<mat-option [value]="selectDossierTemplate">{{ selectDossierTemplate.name | translate }}</mat-option>
|
||||||
</mat-option>
|
<mat-option *ngFor="let dossierTemplate of dossierTemplatesService.all$ | async" [value]="dossierTemplate">
|
||||||
</mat-select>
|
{{ dossierTemplate.name }}
|
||||||
</div>
|
</mat-option>
|
||||||
<div class="iqser-input-group w-200 mt-0">
|
</mat-select>
|
||||||
<mat-select [(ngModel)]="dossier" [disabled]="!compare || dossierTemplateIsNotSelected">
|
</div>
|
||||||
|
|
||||||
|
<div class="iqser-input-group w-200 mt-0">
|
||||||
|
<mat-select [(ngModel)]="dictionary" [disabled]="!compare || dossierTemplateIsNotSelected">
|
||||||
|
<mat-option [value]="selectDictionary">{{ selectDictionary.label | translate }}</mat-option>
|
||||||
|
<mat-option *ngFor="let dictionary of dictionaries" [value]="dictionary">
|
||||||
|
{{ dictionary.label }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div *ngIf="!filterByDossierTemplate" class="iqser-input-group w-200 mt-0">
|
||||||
|
<mat-select [(ngModel)]="dossier" [disabled]="!compare">
|
||||||
<mat-option [value]="selectDossier">{{ selectDossier.dossierName | translate }}</mat-option>
|
<mat-option [value]="selectDossier">{{ selectDossier.dossierName | translate }}</mat-option>
|
||||||
<mat-option *ngFor="let dossier of dossiers" [value]="dossier">
|
<mat-option *ngFor="let dossier of dossiersService.all$ | async" [value]="dossier">
|
||||||
{{ dossier.dossierName }}
|
{{ dossier.dossierName }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
@ -50,30 +63,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<ngx-monaco-editor
|
<redaction-editor
|
||||||
(init)="onCodeEditorInit($event)"
|
[canEdit]="canEdit"
|
||||||
*ngIf="!compare || !showDiffEditor"
|
[diffEditorText]="diffEditorText"
|
||||||
[(ngModel)]="editorValue"
|
[initialEntries]="initialEntries"
|
||||||
[options]="editorOptions"
|
[showDiffEditor]="compare && showDiffEditor"
|
||||||
></ngx-monaco-editor>
|
></redaction-editor>
|
||||||
|
|
||||||
<ngx-monaco-diff-editor
|
<div *ngIf="compare && optionNotSelected" class="no-dictionary-selected">
|
||||||
(init)="onDiffEditorInit($event)"
|
|
||||||
*ngIf="compare && showDiffEditor"
|
|
||||||
[modified]="editorValue"
|
|
||||||
[options]="editorOptions"
|
|
||||||
[original]="diffEditorText"
|
|
||||||
></ngx-monaco-diff-editor>
|
|
||||||
|
|
||||||
<div *ngIf="compare && dossier.dossierName === selectDossier.dossierName" class="no-dictionary-selected">
|
|
||||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||||
<span class="heading-l" translate="dictionary-overview.select-dictionary"></span>
|
<span class="heading-l" translate="dictionary-overview.select-dictionary"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="withFloatingActions && hasChanges && canEdit" [class.offset]="compare" class="changes-box">
|
<div *ngIf="withFloatingActions && !!editor?.hasChanges && canEdit" [class.offset]="compare" class="changes-box">
|
||||||
<iqser-icon-button
|
<iqser-icon-button
|
||||||
(action)="saveDictionary.emit(currentEntries)"
|
(action)="saveDictionary.emit(editor?.currentEntries)"
|
||||||
[label]="'dictionary-overview.save-changes' | translate"
|
[label]="'dictionary-overview.save-changes' | translate"
|
||||||
[type]="iconButtonTypes.primary"
|
[type]="iconButtonTypes.primary"
|
||||||
icon="iqser:check"
|
icon="iqser:check"
|
||||||
|
|||||||
@ -36,12 +36,6 @@ form {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx-monaco-diff-editor,
|
|
||||||
ngx-monaco-editor {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core';
|
||||||
import { Debounce, IconButtonTypes, List } from '@iqser/common-ui';
|
import { Debounce, IconButtonTypes, List } from '@iqser/common-ui';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, take } from 'rxjs/operators';
|
||||||
@ -8,13 +8,12 @@ import { DictionaryService } from '@shared/services/dictionary.service';
|
|||||||
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||||
import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service';
|
import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service';
|
||||||
import { DossierTemplate } from '@models/file/dossier-template';
|
import { DossierTemplate } from '@models/file/dossier-template';
|
||||||
import ICodeEditor = monaco.editor.ICodeEditor;
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import IDiffEditor = monaco.editor.IDiffEditor;
|
import { EditorComponent } from '@shared/components/editor/editor.component';
|
||||||
|
import { TypeValue } from '@models/file/type-value';
|
||||||
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
|
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
|
||||||
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
|
|
||||||
import FindMatch = monaco.editor.FindMatch;
|
import FindMatch = monaco.editor.FindMatch;
|
||||||
|
|
||||||
const MIN_WORD_LENGTH = 2;
|
|
||||||
const SMOOTH_SCROLL = 0;
|
const SMOOTH_SCROLL = 0;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -22,7 +21,7 @@ const SMOOTH_SCROLL = 0;
|
|||||||
templateUrl: './dictionary-manager.component.html',
|
templateUrl: './dictionary-manager.component.html',
|
||||||
styleUrls: ['./dictionary-manager.component.scss']
|
styleUrls: ['./dictionary-manager.component.scss']
|
||||||
})
|
})
|
||||||
export class DictionaryManagerComponent implements OnChanges, OnInit {
|
export class DictionaryManagerComponent implements OnChanges {
|
||||||
readonly iconButtonTypes = IconButtonTypes;
|
readonly iconButtonTypes = IconButtonTypes;
|
||||||
|
|
||||||
@Input() withFloatingActions = true;
|
@Input() withFloatingActions = true;
|
||||||
@ -30,32 +29,30 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
@Input() initialEntries: List;
|
@Input() initialEntries: List;
|
||||||
@Input() canEdit = false;
|
@Input() canEdit = false;
|
||||||
@Output() readonly saveDictionary = new EventEmitter<string[]>();
|
@Output() readonly saveDictionary = new EventEmitter<string[]>();
|
||||||
|
@ViewChild(EditorComponent) readonly editor: EditorComponent;
|
||||||
|
|
||||||
currentMatch = 0;
|
currentMatch = 0;
|
||||||
findMatches: FindMatch[] = [];
|
findMatches: FindMatch[] = [];
|
||||||
currentEntries: string[] = [];
|
|
||||||
editorOptions: IStandaloneEditorConstructionOptions = {};
|
|
||||||
diffEditorText = '';
|
diffEditorText = '';
|
||||||
showDiffEditor = false;
|
showDiffEditor = false;
|
||||||
searchText = '';
|
searchText = '';
|
||||||
|
selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') } as Dossier;
|
||||||
selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') };
|
selectDictionary = {
|
||||||
selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') };
|
label: _('dictionary-overview.compare.select-dictionary')
|
||||||
|
} as TypeValue;
|
||||||
|
selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') } as DossierTemplate;
|
||||||
compare: false;
|
compare: false;
|
||||||
dossiers: List<Dossier> = this._dossiers;
|
dictionaries: List<TypeValue> = this._dictionaries;
|
||||||
|
|
||||||
private _codeEditor: ICodeEditor;
|
|
||||||
private _diffEditor: IDiffEditor;
|
|
||||||
private _decorations: string[] = [];
|
|
||||||
private _searchDecorations: string[] = [];
|
private _searchDecorations: string[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _dictionaryService: DictionaryService,
|
private readonly _dictionaryService: DictionaryService,
|
||||||
readonly dossiersService: DossiersService,
|
readonly dossiersService: DossiersService,
|
||||||
|
readonly appStateService: AppStateService,
|
||||||
readonly dossierTemplatesService: DossierTemplatesService
|
readonly dossierTemplatesService: DossierTemplatesService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private _dossierTemplate: DossierTemplate = this.selectDossierTemplate as DossierTemplate;
|
private _dossierTemplate = this.selectDossierTemplate;
|
||||||
|
|
||||||
get dossierTemplate() {
|
get dossierTemplate() {
|
||||||
return this._dossierTemplate;
|
return this._dossierTemplate;
|
||||||
@ -63,11 +60,12 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
set dossierTemplate(value) {
|
set dossierTemplate(value) {
|
||||||
this._dossierTemplate = value;
|
this._dossierTemplate = value;
|
||||||
this.dossier = this.selectDossier as Dossier;
|
this.dictionaries = this._dictionaries;
|
||||||
this.dossiers = this._dossiers;
|
this._dictionary = this.selectDictionary;
|
||||||
|
this.showDiffEditor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _dossier: Dossier = this.selectDossier as Dossier;
|
private _dossier = this.selectDossier;
|
||||||
|
|
||||||
get dossier() {
|
get dossier() {
|
||||||
return this._dossier;
|
return this._dossier;
|
||||||
@ -76,77 +74,61 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
set dossier(dossier: Dossier) {
|
set dossier(dossier: Dossier) {
|
||||||
this._dossier = dossier;
|
this._dossier = dossier;
|
||||||
|
|
||||||
if (dossier === this.selectDossier) {
|
if (dossier.dossierName === this.selectDossier.dossierName) {
|
||||||
this.showDiffEditor = false;
|
this.showDiffEditor = false;
|
||||||
this.diffEditorText = '';
|
this.diffEditorText = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._onDossierChanged(dossier)
|
this._onDossierChanged(dossier.dossierTemplateId, dossier.dossierId)
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
.subscribe(entries => {
|
.subscribe(entries => {
|
||||||
this.diffEditorText = entries;
|
this.diffEditorText = entries;
|
||||||
this.showDiffEditor = true;
|
this.showDiffEditor = true;
|
||||||
if (this.showDiffEditor) {
|
|
||||||
this._diffEditor?.getOriginalEditor().setValue(this.diffEditorText);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get editorValue(): string {
|
private _dictionary = this.selectDictionary;
|
||||||
return this.currentEntries.join('\n');
|
|
||||||
|
get dictionary() {
|
||||||
|
return this._dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
set editorValue(text: string) {
|
set dictionary(dictionary: TypeValue) {
|
||||||
this.currentEntries = text.split('\n');
|
this._dictionary = dictionary;
|
||||||
this.codeEditorTextChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasChanges(): boolean {
|
if (dictionary.label === this.selectDictionary.label) {
|
||||||
return this.currentEntries.toString() !== this.initialEntries.toString();
|
this.showDiffEditor = false;
|
||||||
}
|
this.diffEditorText = '';
|
||||||
|
return;
|
||||||
get _dossiers() {
|
|
||||||
if (this.filterByDossierTemplate) {
|
|
||||||
return this.dossiersService.all.filter(dossier => dossier.dossierTemplateId === this.dossierTemplate.dossierTemplateId);
|
|
||||||
}
|
}
|
||||||
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() {
|
get dossierTemplateIsNotSelected() {
|
||||||
return this.filterByDossierTemplate && this._dossierTemplate.name === this.selectDossierTemplate.name;
|
return this.filterByDossierTemplate && this._dossierTemplate.name === this.selectDossierTemplate.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
get optionNotSelected() {
|
||||||
this.currentEntries = [...this.initialEntries];
|
if (this.filterByDossierTemplate) {
|
||||||
|
return this.selectDictionary.label === this._dictionary.label;
|
||||||
this.editorOptions = {
|
}
|
||||||
theme: 'vs',
|
return this.dossier.dossierName === this.selectDossier.dossierName;
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
revert() {
|
revert() {
|
||||||
this.currentEntries = [...this.initialEntries];
|
this.editor?.revert();
|
||||||
this.searchChanged('');
|
this.searchChanged('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,13 +142,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
this.nextSearchMatch();
|
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 {
|
nextSearchMatch(): void {
|
||||||
if (this.findMatches.length <= 0) {
|
if (this.findMatches.length <= 0) {
|
||||||
return;
|
return;
|
||||||
@ -190,30 +165,18 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _applySearchDecorations() {
|
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));
|
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[] {
|
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) || [];
|
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 {
|
private _getSearchDecoration(match: FindMatch): IModelDeltaDecoration {
|
||||||
return { range: match.range, options: { inlineClassName: 'search-marker' } };
|
return { range: match.range, options: { inlineClassName: 'search-marker' } };
|
||||||
}
|
}
|
||||||
@ -221,12 +184,12 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
|||||||
private _scrollToCurrentMatch(): void {
|
private _scrollToCurrentMatch(): void {
|
||||||
const range = this.findMatches[this.currentMatch - 1].range;
|
const range = this.findMatches[this.currentMatch - 1].range;
|
||||||
|
|
||||||
this._codeEditor.setSelection(range);
|
this.editor.codeEditor.setSelection(range);
|
||||||
this._codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL);
|
this.editor.codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onDossierChanged({ id, dossierTemplateId }: Dossier): Observable<string> {
|
private _onDossierChanged(dossierTemplateId: string, dossierId?: string, type = 'dossier_redaction'): Observable<string> {
|
||||||
const dictionary$ = this._dictionaryService.getFor(dossierTemplateId, 'dossier_redaction', id);
|
const dictionary$ = this._dictionaryService.getFor(dossierTemplateId, type, dossierId);
|
||||||
|
|
||||||
return dictionary$.pipe(map(data => this._toString([...data.entries])));
|
return dictionary$.pipe(map(data => this._toString([...data.entries])));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
<ngx-monaco-editor
|
||||||
|
(init)="onCodeEditorInit($event)"
|
||||||
|
*ngIf="!showDiffEditor"
|
||||||
|
[(ngModel)]="value"
|
||||||
|
[options]="editorOptions"
|
||||||
|
></ngx-monaco-editor>
|
||||||
|
|
||||||
|
<ngx-monaco-diff-editor
|
||||||
|
(init)="onDiffEditorInit($event)"
|
||||||
|
*ngIf="showDiffEditor"
|
||||||
|
[modified]="value"
|
||||||
|
[options]="editorOptions"
|
||||||
|
[original]="diffEditorText"
|
||||||
|
></ngx-monaco-diff-editor>
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
:host,
|
||||||
|
ngx-monaco-diff-editor,
|
||||||
|
ngx-monaco-editor {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@ -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 } };
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@ import { LongPressDirective } from './directives/long-press.directive';
|
|||||||
import { NamePipe } from './pipes/name.pipe';
|
import { NamePipe } from './pipes/name.pipe';
|
||||||
import { TypeFilterComponent } from './components/type-filter/type-filter.component';
|
import { TypeFilterComponent } from './components/type-filter/type-filter.component';
|
||||||
import { TeamMembersComponent } from './components/team-members/team-members.component';
|
import { TeamMembersComponent } from './components/team-members/team-members.component';
|
||||||
|
import { EditorComponent } from './components/editor/editor.component';
|
||||||
|
|
||||||
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ const utils = [DatePipe, NamePipe, NavigateLastDossiersScreenDirective, LongPres
|
|||||||
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
|
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [...components, ...utils],
|
declarations: [...components, ...utils, EditorComponent],
|
||||||
imports: [CommonModule, ...modules, MonacoEditorModule],
|
imports: [CommonModule, ...modules, MonacoEditorModule],
|
||||||
exports: [...modules, ...components, ...utils],
|
exports: [...modules, ...components, ...utils],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@ -435,7 +435,8 @@
|
|||||||
"compare": {
|
"compare": {
|
||||||
"compare": "Vergleichen Sie",
|
"compare": "Vergleichen Sie",
|
||||||
"select-dossier": "Wählen Sie Dossiervorlage",
|
"select-dossier": "Wählen Sie Dossiervorlage",
|
||||||
"select-dossier-template": ""
|
"select-dossier-template": "",
|
||||||
|
"select-dictionary": ""
|
||||||
},
|
},
|
||||||
"dictionary-details": {
|
"dictionary-details": {
|
||||||
"description": "Beschreibung"
|
"description": "Beschreibung"
|
||||||
|
|||||||
@ -475,7 +475,8 @@
|
|||||||
"compare": {
|
"compare": {
|
||||||
"compare": "Compare",
|
"compare": "Compare",
|
||||||
"select-dossier": "Select Dossier",
|
"select-dossier": "Select Dossier",
|
||||||
"select-dossier-template": "Select Dossier Template"
|
"select-dossier-template": "Select Dossier Template",
|
||||||
|
"select-dictionary": "Select Dictionary"
|
||||||
},
|
},
|
||||||
"dictionary-details": {
|
"dictionary-details": {
|
||||||
"description": "Description"
|
"description": "Description"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user