You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
frontend/src/app/components/nodes/markdown/markdown.component.ts

130 lines
3.8 KiB

import {Component, ElementRef, HostListener, Input, OnInit, ViewChild} from '@angular/core';
import {EditorNodeContract} from '../EditorNode.contract';
import {EditorService} from '../../../service/editor.service';
import {v4} from 'uuid';
import {EditorComponent} from 'ngx-monaco-editor';
@Component({
selector: 'editor-markdown',
templateUrl: './markdown.component.html',
styleUrls: ['./markdown.component.scss'],
})
export class MarkdownComponent extends EditorNodeContract implements OnInit {
// @ViewChild('editable') editable;
@Input() nodeId: string;
@Input() editorUUID?: string;
@ViewChild('editor') editor: EditorComponent;
@ViewChild('editorContainer') editorContainer: ElementRef;
// public isFocused = false;
public initialValue = 'Double-click to edit...';
protected savedValue = 'Double-click to edit...';
public contents = '';
private dirtyOverride = false;
public showEditor = false;
protected hadOneFocusOut = false;
public singleColumn = false;
public containerHeight = 540;
public editorOptions = {
theme: this.isDark() ? 'vs-dark' : 'vs',
language: 'markdown',
uri: v4(),
readOnly: false,
automaticLayout: true,
wordWrap: 'on',
scrollBeyondLastLine: false,
scrollbar: {
alwaysConsumeMouseWheel: false,
},
};
constructor(
public editorService: EditorService,
) {
super();
this.contents = this.initialValue;
this.savedValue = this.initialValue;
}
public isDark() {
return document.body.classList.contains('dark');
}
ngOnInit() {
this.editorService = this.editorService.getEditor(this.editorUUID);
this.editorService.registerNodeEditor(this.nodeId, this).then(() => {
if ( !this.node.Value ) {
this.node.Value = {};
}
if ( this.node.Value.Value ) {
this.initialValue = this.node.Value.Value;
this.savedValue = this.node.Value.Value;
}
this.contents = this.initialValue;
});
}
onMonacoEditorInit(editor) {
let ignoreEvent = false;
const updateHeight = () => {
const contentHeight = Math.max(540, editor.getContentHeight());
this.containerHeight = contentHeight;
try {
ignoreEvent = true;
editor.layout({ width: this.editorContainer.nativeElement.offsetWidth, height: contentHeight });
} finally {
ignoreEvent = false;
}
};
editor.onDidContentSizeChange(updateHeight);
updateHeight();
}
public isDirty(): boolean | Promise<boolean> {
return this.dirtyOverride || this.contents !== this.savedValue;
}
public writeChangesToNode(): void | Promise<void> {
this.node.Value.Mode = 'markdown';
this.node.Value.Value = this.contents;
this.node.value = this.contents;
this.savedValue = this.contents;
}
onContentsChanged(event) {
if ( event !== this.savedValue ) {
this.editorService.triggerSave();
}
}
onFocusIn() {
this.showEditor = this.editorService.canEdit();
}
@HostListener('document:keyup.escape', ['$event'])
onFocusOut(event) {
if ( !this.hadOneFocusOut ) {
this.hadOneFocusOut = true;
setTimeout(() => {
this.hadOneFocusOut = false;
}, 500);
} else {
this.hadOneFocusOut = false;
this.showEditor = false;
}
}
onEditorHostResize($event) {
if ( $event.newWidth < 700 && !this.singleColumn ) {
this.singleColumn = true;
} else if ( $event.newWidth > 700 && this.singleColumn ) {
this.singleColumn = false;
}
}
}