Add markdown editor node
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -14,6 +14,7 @@ import { TreeModule } from '@circlon/angular-tree-component';
|
||||
import {AgGridModule} from 'ag-grid-angular';
|
||||
import {MonacoEditorModule} from 'ngx-monaco-editor';
|
||||
import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
|
||||
import { MarkdownModule } from 'ngx-markdown';
|
||||
|
||||
/**
|
||||
* This function is used internal to get a string instance of the `<base href="" />` value from `index.html`.
|
||||
@@ -42,6 +43,7 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
|
||||
TreeModule,
|
||||
AgGridModule.withComponents([]),
|
||||
MonacoEditorModule.forRoot(),
|
||||
MarkdownModule.forRoot(),
|
||||
],
|
||||
providers: [
|
||||
StatusBar,
|
||||
|
||||
@@ -27,7 +27,9 @@ import {BooleanRendererComponent} from './editor/database/renderers/boolean-rend
|
||||
import {SearchComponent} from './search/Search.component';
|
||||
|
||||
import {NormComponent} from './nodes/norm/norm.component';
|
||||
import {MarkdownComponent as MarkdownEditorComponent} from './nodes/markdown/markdown.component';
|
||||
import {DirectivesModule} from '../directives/directives.module';
|
||||
import {MarkdownModule} from "ngx-markdown";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -53,17 +55,19 @@ import {DirectivesModule} from '../directives/directives.module';
|
||||
SearchComponent,
|
||||
|
||||
NormComponent,
|
||||
MarkdownEditorComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
AgGridModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ContenteditableModule,
|
||||
MonacoEditorModule,
|
||||
DirectivesModule,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
AgGridModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ContenteditableModule,
|
||||
MonacoEditorModule,
|
||||
DirectivesModule,
|
||||
MarkdownModule,
|
||||
],
|
||||
entryComponents: [
|
||||
NodePickerComponent,
|
||||
DatabaseComponent,
|
||||
@@ -87,6 +91,7 @@ import {DirectivesModule} from '../directives/directives.module';
|
||||
SearchComponent,
|
||||
|
||||
NormComponent,
|
||||
MarkdownEditorComponent,
|
||||
],
|
||||
exports: [
|
||||
NodePickerComponent,
|
||||
@@ -111,6 +116,7 @@ import {DirectivesModule} from '../directives/directives.module';
|
||||
SearchComponent,
|
||||
|
||||
NormComponent,
|
||||
MarkdownEditorComponent,
|
||||
]
|
||||
})
|
||||
export class ComponentsModule {}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
<i class="fa" slot="start" [ngClass]="typeIcons.node"></i>
|
||||
<ion-label>Paragraph</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button (click)="onSelect('markdown')" class="markdown">
|
||||
<i class="fa" slot="start" [ngClass]="typeIcons.markdown"></i>
|
||||
<ion-label>Markdown</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button (click)="onSelect('database_ref')" class="db">
|
||||
<i class="fa" slot="start" [ngClass]="typeIcons.db"></i>
|
||||
<ion-label>Database</ion-label>
|
||||
|
||||
@@ -25,3 +25,9 @@ i {
|
||||
color: var(--noded-background-files);
|
||||
}
|
||||
}
|
||||
|
||||
.markdown {
|
||||
i {
|
||||
color: var(--noded-background-markdown);
|
||||
}
|
||||
}
|
||||
|
||||
11
src/app/components/nodes/markdown/markdown.component.html
Normal file
11
src/app/components/nodes/markdown/markdown.component.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="container" (click)="onFocusIn()">
|
||||
<div class="editor-container" *ngIf="showEditor">
|
||||
<ngx-monaco-editor class="editor"
|
||||
[options]="editorOptions"
|
||||
[(ngModel)]="contents"
|
||||
(ngModelChange)="onContentsChanged($event)"
|
||||
#editor
|
||||
></ngx-monaco-editor>
|
||||
</div>
|
||||
<div class="display" markdown katex [data]="contents"></div>
|
||||
</div>
|
||||
23
src/app/components/nodes/markdown/markdown.component.scss
Normal file
23
src/app/components/nodes/markdown/markdown.component.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
.container {
|
||||
display: flex;
|
||||
min-height: 600px;
|
||||
flex-direction: row;
|
||||
|
||||
.editor-container, .display {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editor {
|
||||
border: 1px solid lightgrey;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.display {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
77
src/app/components/nodes/markdown/markdown.component.ts
Normal file
77
src/app/components/nodes/markdown/markdown.component.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import {Component, HostListener, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {EditorNodeContract} from '../EditorNode.contract';
|
||||
import {EditorService} from '../../../service/editor.service';
|
||||
import {v4} from 'uuid';
|
||||
|
||||
@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;
|
||||
|
||||
// public isFocused = false;
|
||||
public initialValue = 'Click to edit...';
|
||||
protected savedValue = 'Click to edit...';
|
||||
public contents = '';
|
||||
private dirtyOverride = false;
|
||||
public showEditor = false;
|
||||
|
||||
public editorOptions = {
|
||||
language: 'markdown',
|
||||
uri: v4(),
|
||||
readOnly: false,
|
||||
automaticLayout: true,
|
||||
};
|
||||
|
||||
constructor(
|
||||
public readonly editorService: EditorService,
|
||||
) {
|
||||
super();
|
||||
this.contents = this.initialValue;
|
||||
this.savedValue = this.initialValue;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
public isDirty(): boolean | Promise<boolean> {
|
||||
return this.dirtyOverride || this.contents !== this.savedValue;
|
||||
}
|
||||
|
||||
public writeChangesToNode(): void | Promise<void> {
|
||||
this.node.Value.Mode = 'code';
|
||||
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 = true;
|
||||
}
|
||||
|
||||
@HostListener('document:keyup.escape', ['$event'])
|
||||
onFocusOut(event) {
|
||||
this.showEditor = false;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,9 @@
|
||||
<ng-container *ngIf="node.isNorm()">
|
||||
<editor-norm style="flex: 1;" [nodeId]="node.UUID"></editor-norm>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="node.type === 'markdown'">
|
||||
<editor-markdown style="flex: 1;" [nodeId]="node.UUID"></editor-markdown>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="node.type === 'database_ref'">
|
||||
<editor-database style="flex: 1;" [nodeId]="node.UUID"></editor-database>
|
||||
</ng-container>
|
||||
|
||||
@@ -32,6 +32,10 @@ ion-icon.invisible {
|
||||
&.file_ref {
|
||||
color: var(--noded-background-files);
|
||||
}
|
||||
|
||||
&.markdown {
|
||||
color: var(--noded-background-markdown);
|
||||
}
|
||||
}
|
||||
|
||||
.host-add-button {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default class HostRecord {
|
||||
public value = '';
|
||||
public type: 'paragraph'|'database_ref'|'code_ref'|'file_ref' = 'paragraph';
|
||||
public type: 'paragraph'|'database_ref'|'code_ref'|'file_ref'|'markdown' = 'paragraph';
|
||||
|
||||
public CreatedAt: string;
|
||||
public PageId: string;
|
||||
|
||||
@@ -9,4 +9,5 @@ export const NodeTypeIcons = {
|
||||
code_ref: 'fa fa-code',
|
||||
file_ref: 'fa fa-archive',
|
||||
files: 'fa fa-archive',
|
||||
markdown: 'fab fa-markdown',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user