Start new WYSIWYG node editor
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:
parent
35eb824b45
commit
8a9f6d508e
@ -26,6 +26,8 @@ import {CurrencyRendererComponent} from './editor/database/renderers/currency-re
|
|||||||
import {BooleanRendererComponent} from './editor/database/renderers/boolean-renderer.component';
|
import {BooleanRendererComponent} from './editor/database/renderers/boolean-renderer.component';
|
||||||
import {SearchComponent} from './search/Search.component';
|
import {SearchComponent} from './search/Search.component';
|
||||||
|
|
||||||
|
import {NormComponent} from './nodes/norm/norm.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
HostComponent,
|
HostComponent,
|
||||||
@ -49,6 +51,8 @@ import {SearchComponent} from './search/Search.component';
|
|||||||
CurrencyRendererComponent,
|
CurrencyRendererComponent,
|
||||||
BooleanRendererComponent,
|
BooleanRendererComponent,
|
||||||
SearchComponent,
|
SearchComponent,
|
||||||
|
|
||||||
|
NormComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@ -79,6 +83,8 @@ import {SearchComponent} from './search/Search.component';
|
|||||||
CurrencyRendererComponent,
|
CurrencyRendererComponent,
|
||||||
BooleanRendererComponent,
|
BooleanRendererComponent,
|
||||||
SearchComponent,
|
SearchComponent,
|
||||||
|
|
||||||
|
NormComponent,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
HostComponent,
|
HostComponent,
|
||||||
@ -102,6 +108,8 @@ import {SearchComponent} from './search/Search.component';
|
|||||||
CurrencyRendererComponent,
|
CurrencyRendererComponent,
|
||||||
BooleanRendererComponent,
|
BooleanRendererComponent,
|
||||||
SearchComponent,
|
SearchComponent,
|
||||||
|
|
||||||
|
NormComponent,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ComponentsModule {}
|
export class ComponentsModule {}
|
||||||
|
32
src/app/components/nodes/EditorNode.contract.ts
Normal file
32
src/app/components/nodes/EditorNode.contract.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import PageRecord from '../../structures/PageRecord';
|
||||||
|
|
||||||
|
export abstract class EditorNodeContract {
|
||||||
|
protected pageRec!: PageRecord;
|
||||||
|
protected nodeRec!: any; // TODO
|
||||||
|
|
||||||
|
get page() {
|
||||||
|
return this.pageRec;
|
||||||
|
}
|
||||||
|
|
||||||
|
set page(page: PageRecord) {
|
||||||
|
this.pageRec = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
get identifier() {
|
||||||
|
return this.nodeRec.UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract isDirty(): boolean | Promise<boolean>;
|
||||||
|
|
||||||
|
public needsSave(): boolean | Promise<boolean> {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public needsLoad(): boolean | Promise<boolean> {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public performSave(): void | Promise<void> {}
|
||||||
|
|
||||||
|
public performLoad(): void | Promise<void> {}
|
||||||
|
}
|
66
src/app/components/nodes/norm/norm.component.html
Normal file
66
src/app/components/nodes/norm/norm.component.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<div class="container"
|
||||||
|
(focusin)="onFocusIn($event)"
|
||||||
|
(focusout)="onFocusOut($event)">
|
||||||
|
<div class="toolbar-base" *ngIf="isFocused">
|
||||||
|
<div class="toolbar-button" title="Bold">
|
||||||
|
<i class="icon fa fa-bold"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Italic">
|
||||||
|
<i class="icon fa fa-italic"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Underline">
|
||||||
|
<i class="icon fa fa-underline"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Strikethrough">
|
||||||
|
<i class="icon fa fa-strikethrough"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-sep"></div>
|
||||||
|
|
||||||
|
<div class="toolbar-button" title="Align Right">
|
||||||
|
<i class="icon fa fa-align-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Align Center">
|
||||||
|
<i class="icon fa fa-align-center"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Align Left">
|
||||||
|
<i class="icon fa fa-align-left"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-sep"></div>
|
||||||
|
|
||||||
|
<div class="toolbar-button" title="Undo">
|
||||||
|
<i class="icon fa fa-undo"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Redo">
|
||||||
|
<i class="icon fa fa-redo"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-sep"></div>
|
||||||
|
|
||||||
|
<div class="toolbar-button" title="Increase Heading Level">
|
||||||
|
<i class="icon fa fa-heading"></i>
|
||||||
|
<i class="icon fa fa-long-arrow-alt-up"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Decrease Heading Level">
|
||||||
|
<i class="icon fa fa-heading"></i>
|
||||||
|
<i class="icon fa fa-long-arrow-alt-down"></i>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-button" title="Format Monospace">
|
||||||
|
<i class="icon fa fa-code"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-sep"></div>
|
||||||
|
|
||||||
|
<div class="toolbar-button" title="Begin Bulleted List">
|
||||||
|
<i class="icon fa fa-list-ul"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="editable-base"
|
||||||
|
[ngClass]="isFocused ? 'focused' : ''"
|
||||||
|
contenteditable
|
||||||
|
>
|
||||||
|
Content editable!
|
||||||
|
</div>
|
||||||
|
</div>
|
33
src/app/components/nodes/norm/norm.component.scss
Normal file
33
src/app/components/nodes/norm/norm.component.scss
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
.editable-base {
|
||||||
|
padding: 20px;
|
||||||
|
background: aliceblue; // TODO temporary
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-base {
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.toolbar-button {
|
||||||
|
height: calc(100% - 6px);
|
||||||
|
min-width: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 3px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: lightgrey;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-sep {
|
||||||
|
height: 100%;
|
||||||
|
width: 1px;
|
||||||
|
border: 1px solid lightgrey;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
23
src/app/components/nodes/norm/norm.component.ts
Normal file
23
src/app/components/nodes/norm/norm.component.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {EditorNodeContract} from '../EditorNode.contract';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'editor-norm',
|
||||||
|
templateUrl: './norm.component.html',
|
||||||
|
styleUrls: ['./norm.component.scss'],
|
||||||
|
})
|
||||||
|
export class NormComponent extends EditorNodeContract {
|
||||||
|
public isFocused = false;
|
||||||
|
|
||||||
|
public isDirty(): boolean | Promise<boolean> {
|
||||||
|
return false; // TODO implement
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusIn(event: MouseEvent) {
|
||||||
|
this.isFocused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusOut(event: MouseEvent) {
|
||||||
|
this.isFocused = false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,47 +1,61 @@
|
|||||||
<ng-container>
|
<ng-container>
|
||||||
<ion-header (keydown)="onEditorKeydown($event)">
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-buttons slot="start">
|
<ion-buttons slot="start">
|
||||||
<ion-menu-button></ion-menu-button>
|
<ion-menu-button></ion-menu-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title #titleBar>
|
<ion-title #titleBar>
|
||||||
<div contenteditable="true"> {{ pageRecord.Name }} </div>
|
<ion-input
|
||||||
|
[(ngModel)]="pageName"
|
||||||
|
placeholder="Click to edit page name..."
|
||||||
|
class="title-input"
|
||||||
|
></ion-input>
|
||||||
</ion-title>
|
</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content (keydown)="onEditorKeydown($event)">
|
<ion-content>
|
||||||
<ng-container>
|
<ng-container>
|
||||||
<div class="editor-root ion-padding">
|
<div class="editor-root ion-padding">
|
||||||
<div
|
<div class="host-container" style="display: flex;">
|
||||||
*ngFor="let record of hostRecords; let i = index"
|
<editor-norm style="flex: 1;"></editor-norm>
|
||||||
class="host-container" style="display: flex;"
|
|
||||||
(mouseenter)="makeVisible(i)"
|
|
||||||
(mouseleave)="makeInvisible(i)"
|
|
||||||
>
|
|
||||||
<ion-button fill="invisible" color="primary" (click)="onOptionsClick($event, i)" *ngIf="pageRecord.level !== 'view'">
|
|
||||||
<ion-icon
|
|
||||||
name="options"
|
|
||||||
color="medium"
|
|
||||||
[ngClass]="{'invisible': !buttonIsVisible(i)}"
|
|
||||||
></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
<editor-host
|
|
||||||
style="width: 100%;"
|
|
||||||
#editorHosts
|
|
||||||
[page]="pageRecord"
|
|
||||||
[record]="hostRecords[i]"
|
|
||||||
(recordChange)="onHostRecordChange($event, i)"
|
|
||||||
(newHostRequested)="onNewHostRequested($event)"
|
|
||||||
(destroyHostRequested)="onDestroyHostRequested($event)"
|
|
||||||
(saveHostRequested)="onSaveClick()">
|
|
||||||
</editor-host>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-buttons" style="margin-bottom: 50px;" *ngIf="pageRecord.level !== 'view'">
|
|
||||||
<ion-button (click)="onAddClick($event)" class="ion-padding ion-margin-start" fill="outline" color="medium">Add Node</ion-button>
|
|
||||||
<ion-button (click)="onSaveClick()" class="ion-padding" fill="outline" color="medium">Save</ion-button>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
||||||
|
<!-- <ion-content (keydown)="onEditorKeydown($event)">-->
|
||||||
|
<!-- <ng-container>-->
|
||||||
|
<!-- <div class="editor-root ion-padding">-->
|
||||||
|
<!-- <div-->
|
||||||
|
<!-- *ngFor="let record of hostRecords; let i = index"-->
|
||||||
|
<!-- class="host-container" style="display: flex;"-->
|
||||||
|
<!-- (mouseenter)="makeVisible(i)"-->
|
||||||
|
<!-- (mouseleave)="makeInvisible(i)"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <ion-button fill="invisible" color="primary" (click)="onOptionsClick($event, i)" *ngIf="pageRecord.level !== 'view'">-->
|
||||||
|
<!-- <ion-icon-->
|
||||||
|
<!-- name="options"-->
|
||||||
|
<!-- color="medium"-->
|
||||||
|
<!-- [ngClass]="{'invisible': !buttonIsVisible(i)}"-->
|
||||||
|
<!-- ></ion-icon>-->
|
||||||
|
<!-- </ion-button>-->
|
||||||
|
<!-- <editor-host-->
|
||||||
|
<!-- style="width: 100%;"-->
|
||||||
|
<!-- #editorHosts-->
|
||||||
|
<!-- [page]="pageRecord"-->
|
||||||
|
<!-- [record]="hostRecords[i]"-->
|
||||||
|
<!-- (recordChange)="onHostRecordChange($event, i)"-->
|
||||||
|
<!-- (newHostRequested)="onNewHostRequested($event)"-->
|
||||||
|
<!-- (destroyHostRequested)="onDestroyHostRequested($event)"-->
|
||||||
|
<!-- (saveHostRequested)="onSaveClick()">-->
|
||||||
|
<!-- </editor-host>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div class="editor-buttons" style="margin-bottom: 50px;" *ngIf="pageRecord.level !== 'view'">-->
|
||||||
|
<!-- <ion-button (click)="onAddClick($event)" class="ion-padding ion-margin-start" fill="outline" color="medium">Add Node</ion-button>-->
|
||||||
|
<!-- <ion-button (click)="onSaveClick()" class="ion-padding" fill="outline" color="medium">Save</ion-button>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </ng-container>-->
|
||||||
|
<!-- </ion-content>-->
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -5,3 +5,7 @@ ion-icon {
|
|||||||
ion-icon.invisible {
|
ion-icon.invisible {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title-input {
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Component, Host, OnInit, ViewChild, ViewChildren} from '@angular/core';
|
import {Component, Host, Input, OnInit, ViewChild, ViewChildren} from '@angular/core';
|
||||||
import HostRecord from '../../structures/HostRecord';
|
import HostRecord from '../../structures/HostRecord';
|
||||||
import PageRecord from '../../structures/PageRecord';
|
import PageRecord from '../../structures/PageRecord';
|
||||||
import {PageService} from '../../service/page.service';
|
import {PageService} from '../../service/page.service';
|
||||||
@ -13,19 +13,15 @@ import {HostOptionsComponent} from '../../components/editor/host-options/host-op
|
|||||||
styleUrls: ['./editor.page.scss'],
|
styleUrls: ['./editor.page.scss'],
|
||||||
})
|
})
|
||||||
export class EditorPage implements OnInit {
|
export class EditorPage implements OnInit {
|
||||||
public hostRecords: Array<HostRecord> = [new HostRecord('Click to edit page...')];
|
// @ViewChildren('editorHosts') editorHosts;
|
||||||
public pageRecord: PageRecord = new PageRecord();
|
// @ViewChild('titleBar') titleBar;
|
||||||
public pageId: string;
|
|
||||||
public visibleButtons: Array<number> = [];
|
|
||||||
|
|
||||||
@ViewChildren('editorHosts') editorHosts;
|
@Input() pageId: string;
|
||||||
@ViewChild('titleBar') titleBar;
|
public pageName = '';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected pages: PageService,
|
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected popover: PopoverController,
|
|
||||||
protected loader: LoadingController,
|
protected loader: LoadingController,
|
||||||
) {
|
) {
|
||||||
this.route.params.subscribe(params => {
|
this.route.params.subscribe(params => {
|
||||||
@ -35,215 +31,215 @@ export class EditorPage implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
buttonIsVisible(index) {
|
// buttonIsVisible(index) {
|
||||||
return this.visibleButtons.includes(index);
|
// return this.visibleButtons.includes(index);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
makeVisible(index) {
|
// makeVisible(index) {
|
||||||
if ( !this.buttonIsVisible(index) ) {
|
// if ( !this.buttonIsVisible(index) ) {
|
||||||
this.visibleButtons.push(index);
|
// this.visibleButtons.push(index);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
makeInvisible(index) {
|
// makeInvisible(index) {
|
||||||
this.visibleButtons = this.visibleButtons.filter(x => x !== index);
|
// this.visibleButtons = this.visibleButtons.filter(x => x !== index);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
ionViewDidEnter() {
|
// ionViewDidEnter() {
|
||||||
if ( this.pageId ) {
|
// if ( this.pageId ) {
|
||||||
this.pages.load(this.pageId).subscribe(pageRecord => {
|
// this.pages.load(this.pageId).subscribe(pageRecord => {
|
||||||
this.pageRecord = pageRecord;
|
// this.pageRecord = pageRecord;
|
||||||
this.pages.get_nodes(pageRecord).subscribe((hosts: Array<HostRecord>) => {
|
// this.pages.get_nodes(pageRecord).subscribe((hosts: Array<HostRecord>) => {
|
||||||
this.hostRecords = hosts;
|
// this.hostRecords = hosts;
|
||||||
if ( !pageRecord.isViewOnly() ) {
|
// if ( !pageRecord.isViewOnly() ) {
|
||||||
this.onSaveClick();
|
// this.onSaveClick();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
} else {
|
// } else {
|
||||||
this.router.navigate(['/home']);
|
// this.router.navigate(['/home']);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
onHostRecordChange($event, i) {
|
// onHostRecordChange($event, i) {
|
||||||
if ( !this.pageRecord.isViewOnly() ) {
|
// if ( !this.pageRecord.isViewOnly() ) {
|
||||||
this.hostRecords[i] = $event;
|
// this.hostRecords[i] = $event;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
async onAddClick($event) {
|
// async onAddClick($event) {
|
||||||
if ( this.pageRecord.isViewOnly() ) {
|
// if ( this.pageRecord.isViewOnly() ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
const popover = await this.popover.create({
|
// const popover = await this.popover.create({
|
||||||
component: NodePickerComponent,
|
// component: NodePickerComponent,
|
||||||
event: $event,
|
// event: $event,
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
popover.onDidDismiss().then(arg => {
|
// popover.onDidDismiss().then(arg => {
|
||||||
const defValue = this.getDefaultValue(arg.data);
|
// const defValue = this.getDefaultValue(arg.data);
|
||||||
const hostRec = new HostRecord(defValue);
|
// const hostRec = new HostRecord(defValue);
|
||||||
hostRec.type = arg.data;
|
// hostRec.type = arg.data;
|
||||||
hostRec.PageId = this.pageRecord.UUID;
|
// hostRec.PageId = this.pageRecord.UUID;
|
||||||
|
//
|
||||||
if ( hostRec.type === 'ul' ) {
|
// if ( hostRec.type === 'ul' ) {
|
||||||
hostRec.value = JSON.stringify([{value: '', indentationLevel: 0}]);
|
// hostRec.value = JSON.stringify([{value: '', indentationLevel: 0}]);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
this.hostRecords.push(hostRec);
|
// this.hostRecords.push(hostRec);
|
||||||
if ( hostRec.isNorm() ) {
|
// if ( hostRec.isNorm() ) {
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
this.editorHosts.toArray().reverse()[0].takeFocus();
|
// this.editorHosts.toArray().reverse()[0].takeFocus();
|
||||||
}, 0);
|
// }, 0);
|
||||||
} else {
|
// } else {
|
||||||
this.onSaveClick();
|
// this.onSaveClick();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
await popover.present();
|
// await popover.present();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
getDefaultValue(type: string) {
|
// getDefaultValue(type: string) {
|
||||||
if ( type === 'paragraph' ) {
|
// if ( type === 'paragraph' ) {
|
||||||
return '';
|
// return '';
|
||||||
} else if ( type === 'header1' ) {
|
// } else if ( type === 'header1' ) {
|
||||||
return '# ';
|
// return '# ';
|
||||||
} else if ( type === 'header2' ) {
|
// } else if ( type === 'header2' ) {
|
||||||
return '## ';
|
// return '## ';
|
||||||
} else if ( type === 'header3' ) {
|
// } else if ( type === 'header3' ) {
|
||||||
return '### ';
|
// return '### ';
|
||||||
} else if ( type === 'header4' ) {
|
// } else if ( type === 'header4' ) {
|
||||||
return '#### ';
|
// return '#### ';
|
||||||
} else if ( type === 'block_code' ) {
|
// } else if ( type === 'block_code' ) {
|
||||||
return '```';
|
// return '```';
|
||||||
} else if ( type === 'click_link' ) {
|
// } else if ( type === 'click_link' ) {
|
||||||
return 'https://';
|
// return 'https://';
|
||||||
} else if ( type === 'page_sep' ) {
|
// } else if ( type === 'page_sep' ) {
|
||||||
return '===';
|
// return '===';
|
||||||
} else {
|
// } else {
|
||||||
return '';
|
// return '';
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
onNewHostRequested($event) {
|
// onNewHostRequested($event) {
|
||||||
if ( this.pageRecord.isViewOnly() ) {
|
// if ( this.pageRecord.isViewOnly() ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
const insertAfter = this.getIndexFromRecord($event.record);
|
// const insertAfter = this.getIndexFromRecord($event.record);
|
||||||
const record = new HostRecord('');
|
// const record = new HostRecord('');
|
||||||
const newHosts = []
|
// const newHosts = []
|
||||||
this.hostRecords.forEach((rec, i) => {
|
// this.hostRecords.forEach((rec, i) => {
|
||||||
newHosts.push(rec);
|
// newHosts.push(rec);
|
||||||
if ( i === insertAfter ) {
|
// if ( i === insertAfter ) {
|
||||||
newHosts.push(record);
|
// newHosts.push(record);
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
this.hostRecords = newHosts;
|
// this.hostRecords = newHosts;
|
||||||
|
//
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
this.editorHosts.toArray()[insertAfter + 1].takeFocus();
|
// this.editorHosts.toArray()[insertAfter + 1].takeFocus();
|
||||||
}, 0);
|
// }, 0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
onDestroyHostRequested($event) {
|
// onDestroyHostRequested($event) {
|
||||||
if ( this.pageRecord.isViewOnly() ) {
|
// if ( this.pageRecord.isViewOnly() ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let removedIndex = 0;
|
// let removedIndex = 0;
|
||||||
const newHostRecords = this.editorHosts.filter((host, i) => {
|
// const newHostRecords = this.editorHosts.filter((host, i) => {
|
||||||
if ( $event.record === host.record ) {
|
// if ( $event.record === host.record ) {
|
||||||
removedIndex = i;
|
// removedIndex = i;
|
||||||
}
|
// }
|
||||||
return host.record !== $event.record;
|
// return host.record !== $event.record;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
const removedHost = this.editorHosts[removedIndex];
|
// const removedHost = this.editorHosts[removedIndex];
|
||||||
|
//
|
||||||
const hostRecords = newHostRecords.map(host => host.record);
|
// const hostRecords = newHostRecords.map(host => host.record);
|
||||||
this.hostRecords = hostRecords;
|
// this.hostRecords = hostRecords;
|
||||||
|
//
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
let focusIndex;
|
// let focusIndex;
|
||||||
if ( removedIndex === 0 && this.editorHosts.toArray().length ) {
|
// if ( removedIndex === 0 && this.editorHosts.toArray().length ) {
|
||||||
focusIndex = 0;
|
// focusIndex = 0;
|
||||||
} else if ( removedIndex !== 0 ) {
|
// } else if ( removedIndex !== 0 ) {
|
||||||
focusIndex = removedIndex - 1;
|
// focusIndex = removedIndex - 1;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( focusIndex >= 0 ) {
|
// if ( focusIndex >= 0 ) {
|
||||||
this.editorHosts.toArray()[focusIndex].takeFocus(false);
|
// this.editorHosts.toArray()[focusIndex].takeFocus(false);
|
||||||
}
|
// }
|
||||||
}, 0);
|
// }, 0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected getIndexFromRecord(record) {
|
// protected getIndexFromRecord(record) {
|
||||||
let index;
|
// let index;
|
||||||
this.editorHosts.toArray().forEach((host, i) => {
|
// this.editorHosts.toArray().forEach((host, i) => {
|
||||||
if ( host.record === record ) {
|
// if ( host.record === record ) {
|
||||||
index = i;
|
// index = i;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return index;
|
// return index;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
onSaveClick() {
|
// onSaveClick() {
|
||||||
if ( this.pageRecord.isViewOnly() ) {
|
// if ( this.pageRecord.isViewOnly() ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
this.loader.create({message: 'Saving changes...'}).then(loader => {
|
// this.loader.create({message: 'Saving changes...'}).then(loader => {
|
||||||
loader.present().then(() => {
|
// loader.present().then(() => {
|
||||||
this.pageRecord.Name = this.titleBar.el.innerText.trim();
|
// this.pageRecord.Name = this.titleBar.el.innerText.trim();
|
||||||
|
//
|
||||||
// First, save the page record itself
|
// // First, save the page record itself
|
||||||
this.pages.save(this.pageRecord).subscribe(pageRecord => {
|
// this.pages.save(this.pageRecord).subscribe(pageRecord => {
|
||||||
this.pageRecord = pageRecord;
|
// this.pageRecord = pageRecord;
|
||||||
|
//
|
||||||
// Now, save the nodes
|
// // Now, save the nodes
|
||||||
this.pages.save_nodes(pageRecord, this.hostRecords).subscribe(result => {
|
// this.pages.save_nodes(pageRecord, this.hostRecords).subscribe(result => {
|
||||||
this.hostRecords = result;
|
// this.hostRecords = result;
|
||||||
loader.dismiss();
|
// loader.dismiss();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
async onOptionsClick($event, i) {
|
// async onOptionsClick($event, i) {
|
||||||
if ( this.pageRecord.isViewOnly() ) {
|
// if ( this.pageRecord.isViewOnly() ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
const popover = await this.popover.create({
|
// const popover = await this.popover.create({
|
||||||
component: HostOptionsComponent,
|
// component: HostOptionsComponent,
|
||||||
event: $event,
|
// event: $event,
|
||||||
componentProps: {
|
// componentProps: {
|
||||||
editor: this,
|
// editor: this,
|
||||||
index: i,
|
// index: i,
|
||||||
event: $event,
|
// event: $event,
|
||||||
hostRecord: this.hostRecords[i],
|
// hostRecord: this.hostRecords[i],
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
popover.onDidDismiss().then((result) => {
|
// popover.onDidDismiss().then((result) => {
|
||||||
if ( result.data === 'delete_node' ) {
|
// if ( result.data === 'delete_node' ) {
|
||||||
$event.record = this.hostRecords[i];
|
// $event.record = this.hostRecords[i];
|
||||||
this.onDestroyHostRequested($event);
|
// this.onDestroyHostRequested($event);
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
await popover.present();
|
// await popover.present();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
onEditorKeydown($event) {
|
// onEditorKeydown($event) {
|
||||||
if ( $event.key === 's' && $event.ctrlKey ) {
|
// if ( $event.key === 's' && $event.ctrlKey ) {
|
||||||
$event.preventDefault();
|
// $event.preventDefault();
|
||||||
this.onSaveClick();
|
// this.onSaveClick();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user