diff --git a/angular.json b/angular.json
index 7a173c6..1094c5b 100644
--- a/angular.json
+++ b/angular.json
@@ -29,6 +29,11 @@
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
+ },
+ {
+ "glob": "**/*",
+ "input": "node_modules/ngx-monaco-editor/assets/monaco",
+ "output": "./assets/monaco/"
}
],
"styles": [
diff --git a/package-lock.json b/package-lock.json
index 2f99926..ff39d68 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7099,6 +7099,14 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
+ "ngx-monaco-editor": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/ngx-monaco-editor/-/ngx-monaco-editor-8.1.1.tgz",
+ "integrity": "sha512-SmUGFG5m2HHWybHD6qXdB1FrtC/XySSHm5O/E1cDGW7moIWzJGqiitCKLJdSh9D2hsoe8oBNEg74vYF1UGznsQ==",
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -10369,8 +10377,7 @@
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
- "dev": true
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"validate-npm-package-license": {
"version": "3.0.4",
diff --git a/package.json b/package.json
index fa6850f..5fabd49 100644
--- a/package.json
+++ b/package.json
@@ -27,8 +27,10 @@
"ag-grid-community": "^22.1.1",
"angular-tree-component": "^8.5.2",
"core-js": "^2.5.4",
+ "ngx-monaco-editor": "^8.1.1",
"rxjs": "~6.5.1",
"tslib": "^1.9.0",
+ "uuid": "^3.4.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 05f2a93..3ee0f61 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -12,6 +12,7 @@ import { HttpClientModule } from '@angular/common/http';
import { ComponentsModule } from './components/components.module';
import { TreeModule } from 'angular-tree-component';
import {AgGridModule} from 'ag-grid-angular';
+import {MonacoEditorModule} from 'ngx-monaco-editor';
@NgModule({
declarations: [AppComponent],
@@ -24,6 +25,7 @@ import {AgGridModule} from 'ag-grid-angular';
ComponentsModule,
TreeModule.forRoot(),
AgGridModule.withComponents([]),
+ MonacoEditorModule.forRoot(),
],
providers: [
StatusBar,
diff --git a/src/app/components/components.module.ts b/src/app/components/components.module.ts
index c75dc64..a2ae438 100644
--- a/src/app/components/components.module.ts
+++ b/src/app/components/components.module.ts
@@ -7,11 +7,13 @@ import {DatabaseComponent} from './editor/database/database.component';
import {AgGridModule} from 'ag-grid-angular';
import {ColumnsComponent} from './editor/database/columns/columns.component';
import {FormsModule} from '@angular/forms';
+import {CodeComponent} from './editor/code/code.component';
+import {MonacoEditorModule} from 'ngx-monaco-editor';
@NgModule({
- declarations: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent],
- imports: [CommonModule, IonicModule, AgGridModule, FormsModule],
- entryComponents: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent],
- exports: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent]
+ declarations: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent, CodeComponent],
+ imports: [CommonModule, IonicModule, AgGridModule, FormsModule, MonacoEditorModule],
+ entryComponents: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent, CodeComponent],
+ exports: [HostComponent, NodePickerComponent, DatabaseComponent, ColumnsComponent, CodeComponent]
})
export class ComponentsModule {}
diff --git a/src/app/components/editor/code/code.component.html b/src/app/components/editor/code/code.component.html
new file mode 100644
index 0000000..f9d5a43
--- /dev/null
+++ b/src/app/components/editor/code/code.component.html
@@ -0,0 +1,24 @@
+
+
+
+ Language
+
+ {{lang}}
+
+
+
+
+
+
+
+
+ Drop Editor
+ Save Changes
+
+
+
diff --git a/src/app/components/editor/code/code.component.scss b/src/app/components/editor/code/code.component.scss
new file mode 100644
index 0000000..ef5db85
--- /dev/null
+++ b/src/app/components/editor/code/code.component.scss
@@ -0,0 +1,4 @@
+div.code-wrapper {
+ border: 2px solid #8c8c8c;
+ border-radius: 3px;
+}
diff --git a/src/app/components/editor/code/code.component.ts b/src/app/components/editor/code/code.component.ts
new file mode 100644
index 0000000..cda9b7b
--- /dev/null
+++ b/src/app/components/editor/code/code.component.ts
@@ -0,0 +1,198 @@
+import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
+import {v4} from 'uuid';
+import HostRecord from '../../../structures/HostRecord';
+import {Observable} from 'rxjs';
+import {ApiService} from '../../../service/api.service';
+import {AlertController, LoadingController} from '@ionic/angular';
+
+@Component({
+ selector: 'editor-code',
+ templateUrl: './code.component.html',
+ styleUrls: ['./code.component.scss'],
+})
+export class CodeComponent implements OnInit {
+ @Input() hostRecord: HostRecord;
+ @Output() hostRecordChange = new EventEmitter();
+ @Output() requestParentSave = new EventEmitter();
+ @Output() requestParentDelete = new EventEmitter();
+ @ViewChild('theEditor', {static: false}) theEditor;
+
+ public dirty = false;
+ public pendingSetup = true;
+ protected dbRecord: any = {};
+
+ public languageOptions: Array = [
+ 'ABAP',
+ 'AES',
+ 'Apex',
+ 'AZCLI',
+ 'Bat',
+ 'C',
+ 'Cameligo',
+ 'Clojure',
+ 'CoffeeScript',
+ 'Cpp',
+ 'Csharp',
+ 'CSP',
+ 'CSS',
+ 'Dockerfile',
+ 'Fsharp',
+ 'Go',
+ 'GraphQL',
+ 'Handlebars',
+ 'HTML',
+ 'INI',
+ 'Java',
+ 'JavaScript',
+ 'JSON',
+ 'Kotlin',
+ 'LeSS',
+ 'Lua',
+ 'Markdown',
+ 'MiPS',
+ 'MSDAX',
+ 'MySQL',
+ 'Objective-C',
+ 'Pascal',
+ 'Pascaligo',
+ 'Perl',
+ 'pgSQL',
+ 'PHP',
+ 'Plaintext',
+ 'Postiats',
+ 'PowerQuery',
+ 'PowerShell',
+ 'Pug',
+ 'Python',
+ 'R',
+ 'Razor',
+ 'Redis',
+ 'RedShift',
+ 'RestructuredText',
+ 'Ruby',
+ 'Rust',
+ 'SB',
+ 'Scheme',
+ 'SCSS',
+ 'Shell',
+ 'SOL',
+ 'SQL',
+ 'St',
+ 'Swift',
+ 'TCL',
+ 'Twig',
+ 'TypeScript',
+ 'VB',
+ 'XML',
+ 'YAML',
+ ];
+
+ public editorOptions = {
+ language: 'javascript',
+ uri: v4(),
+ };
+ public editorValue = '';
+
+ constructor(
+ protected api: ApiService,
+ protected loader: LoadingController,
+ protected alerts: AlertController,
+ ) { }
+
+ ngOnInit() {
+ this.loader.create({message: 'Loading code...'}).then(loader => {
+ loader.present().then(() => {
+ this.getInitObservable().subscribe(() => {
+ this.editorOptions.language = this.dbRecord.language;
+ this.onSelectChange(false);
+ loader.dismiss();
+ });
+ });
+ });
+ }
+
+ getInitObservable(): Observable {
+ return new Observable(sub => {
+ if ( this.hostRecord && this.pendingSetup ) {
+ if ( !this.hostRecord.Value ) {
+ this.hostRecord.Value = {};
+ }
+
+ if ( !this.hostRecord.Value.Value ) {
+ this.api.post(`/code/${this.hostRecord.PageId}/${this.hostRecord.UUID}/create`).subscribe(res => {
+ this.dbRecord = res.data;
+ this.hostRecord.Value.Mode = 'code';
+ this.hostRecord.Value.Value = res.data.UUID;
+ this.hostRecord.value = res.data.UUID;
+ this.hostRecordChange.emit(this.hostRecord);
+ this.pendingSetup = false;
+ sub.next(true);
+ sub.complete();
+ });
+ } else {
+ this.api.get(`/code/${this.hostRecord.PageId}/${this.hostRecord.UUID}/get/${this.hostRecord.Value.Value}`).subscribe(res => {
+ this.dbRecord = res.data;
+ this.editorValue = this.dbRecord.code;
+ this.editorOptions.language = this.dbRecord.language;
+ this.pendingSetup = false;
+ sub.next(true);
+ sub.complete();
+ });
+ }
+ } else {
+ this.pendingSetup = true;
+ }
+ });
+ }
+
+ onSaveClick() {
+ this.dbRecord.code = this.editorValue;
+ this.dbRecord.language = this.editorOptions.language;
+ this.api.post(`/code/${this.hostRecord.PageId}/${this.hostRecord.UUID}/set/${this.hostRecord.Value.Value}`, this.dbRecord)
+ .subscribe(res => {
+ this.dbRecord = res.data;
+ this.editorOptions.language = this.dbRecord.language;
+ this.editorValue = this.dbRecord.code;
+ this.dirty = false;
+ });
+ }
+
+ async onDropClick() {
+ const alert = await this.alerts.create({
+ header: 'Are you sure?',
+ message: `You are about to delete this code. This action cannot be undone.`,
+ buttons: [
+ {
+ text: 'Keep It',
+ role: 'cancel',
+ },
+ {
+ text: 'Delete It',
+ handler: async () => {
+ this.api.post(`/code/${this.hostRecord.PageId}/${this.hostRecord.UUID}/delete/${this.hostRecord.Value.Value}`)
+ .subscribe(res => {
+ this.requestParentDelete.emit(this);
+ });
+ },
+ },
+ ],
+ });
+
+ await alert.present();
+ }
+
+ public onEditorModelChange($event) {
+ if ( this.editorValue !== this.dbRecord.code ) {
+ this.dirty = true;
+ }
+ }
+
+ onSelectChange(updateDbRecord = true) {
+ if ( updateDbRecord ) {
+ this.dbRecord.language = this.editorOptions.language;
+ }
+
+ this.editorOptions = {...this.editorOptions};
+ }
+
+}
diff --git a/src/app/components/editor/database/database.component.ts b/src/app/components/editor/database/database.component.ts
index e0261c3..ce9596f 100644
--- a/src/app/components/editor/database/database.component.ts
+++ b/src/app/components/editor/database/database.component.ts
@@ -203,6 +203,9 @@ export class DatabaseComponent implements OnInit {
getInitObservable(): Observable {
return new Observable(sub => {
if ( this.hostRecord && this.pendingSetup ) {
+ if ( !this.hostRecord.Value ) {
+ this.hostRecord.Value = {};
+ }
if ( !this.hostRecord.Value.Value ) {
this.api.post(`/db/${this.hostRecord.PageId}/${this.hostRecord.UUID}/create`).subscribe(res => {
this.dbRecord = res.data;
diff --git a/src/app/components/editor/host/host.component.html b/src/app/components/editor/host/host.component.html
index e7cc0f8..d265088 100644
--- a/src/app/components/editor/host/host.component.html
+++ b/src/app/components/editor/host/host.component.html
@@ -34,4 +34,12 @@
(requestParentDelete)="onRequestDelete($event)"
>
+
+
+
diff --git a/src/app/components/editor/host/host.component.ts b/src/app/components/editor/host/host.component.ts
index 9aeb144..80168ab 100644
--- a/src/app/components/editor/host/host.component.ts
+++ b/src/app/components/editor/host/host.component.ts
@@ -22,7 +22,6 @@ export class HostComponent implements OnInit {
ngOnInit() {}
onRecordChange($event) {
- console.log({$event});
this.recordChange.emit($event);
}
diff --git a/src/app/components/editor/node-picker/node-picker.component.html b/src/app/components/editor/node-picker/node-picker.component.html
index 5a8d183..466ad27 100644
--- a/src/app/components/editor/node-picker/node-picker.component.html
+++ b/src/app/components/editor/node-picker/node-picker.component.html
@@ -20,7 +20,7 @@
Heading 4
-
+
Monospace Block
@@ -31,4 +31,8 @@
Database
+
+
+ Code Editor
+
diff --git a/src/app/structures/HostRecord.ts b/src/app/structures/HostRecord.ts
index 3613f60..9bebeb3 100644
--- a/src/app/structures/HostRecord.ts
+++ b/src/app/structures/HostRecord.ts
@@ -1,6 +1,6 @@
export default class HostRecord {
public value = '';
- public type: 'paragraph'|'header1'|'header2'|'header3'|'header4'|'block_code'|'click_link'|'database_ref'|'ul' = 'paragraph';
+ public type: 'paragraph'|'header1'|'header2'|'header3'|'header4'|'block_code'|'click_link'|'database_ref'|'ul'|'code_ref' = 'paragraph';
public CreatedAt: string;
public PageId: string;