Add ability to delete nodes in editor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Garrett Mills 2020-10-13 22:47:59 -05:00
parent 331d40e49c
commit b0cf07ab49
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
5 changed files with 76 additions and 2 deletions

View File

@ -40,4 +40,6 @@ export abstract class EditorNodeContract {
public performSave(): void | Promise<void> {} public performSave(): void | Promise<void> {}
public performLoad(): void | Promise<void> {} public performLoad(): void | Promise<void> {}
public performDelete(): void | Promise<void> {}
} }

View File

@ -22,6 +22,12 @@
style="display: flex;" style="display: flex;"
*ngFor="let node of editorService.immutableNodes" *ngFor="let node of editorService.immutableNodes"
> >
<div class="host-icons">
<i class="type-icon norm fa" [ngClass]="typeIcons.norm" title="WYSIWYG Node"></i>
<button (click)="onOptionsClick($event, node)">
<i class="fa fa-ellipsis-v" title="Node options"></i>
</button>
</div>
<ng-container *ngIf="node.isNorm()"> <ng-container *ngIf="node.isNorm()">
<editor-norm style="flex: 1;" [nodeId]="node.UUID"></editor-norm> <editor-norm style="flex: 1;" [nodeId]="node.UUID"></editor-norm>
</ng-container> </ng-container>

View File

@ -6,6 +6,17 @@ ion-icon.invisible {
opacity: 0; opacity: 0;
} }
.title-input { .host-icons {
padding: 5px;
color: #444;
display: flex;
flex-direction: column;
}
.type-icon {
margin-bottom: 15px;
&.norm {
color: var(--noded-background-node);
}
} }

View File

@ -17,6 +17,15 @@ export class EditorPage implements OnInit {
// @ViewChildren('editorHosts') editorHosts; // @ViewChildren('editorHosts') editorHosts;
// @ViewChild('titleBar') titleBar; // @ViewChild('titleBar') titleBar;
public typeIcons = {
branch: 'fa fa-folder',
node: 'fa fa-quote-left',
norm: 'fa fa-quote-left',
page: 'fa fa-sticky-note',
db: 'fa fa-database',
code: 'fa fa-code',
};
@Input() pageId: string; @Input() pageId: string;
public pageName = ''; public pageName = '';
@ -24,6 +33,7 @@ export class EditorPage implements OnInit {
protected route: ActivatedRoute, protected route: ActivatedRoute,
protected router: Router, protected router: Router,
protected loader: LoadingController, protected loader: LoadingController,
protected popover: PopoverController,
public readonly editorService: EditorService, public readonly editorService: EditorService,
) { ) {
this.route.params.subscribe(params => { this.route.params.subscribe(params => {
@ -47,6 +57,31 @@ export class EditorPage implements OnInit {
this.editorService.save(); this.editorService.save();
} }
async onOptionsClick(event: MouseEvent, node: HostRecord) {
if ( !this.editorService.canEdit() ) {
return;
}
const popover = await this.popover.create({
component: HostOptionsComponent,
event,
componentProps: {
editor: this,
index: this.editorService.immutableNodes.indexOf(node),
event,
hostRecord: node,
}
});
popover.onDidDismiss().then(result => {
if ( result.data === 'delete_node' ) {
this.editorService.deleteNode(node.UUID);
}
});
await popover.present();
}
// buttonIsVisible(index) { // buttonIsVisible(index) {
// return this.visibleButtons.includes(index); // return this.visibleButtons.includes(index);
// } // }

View File

@ -120,6 +120,26 @@ export class EditorService {
return dirties.some(Boolean) || needSaves.some(Boolean); return dirties.some(Boolean) || needSaves.some(Boolean);
} }
async deleteNode(nodeId: string) {
if ( !this.currentPage ) {
throw new NoPageLoadedError();
}
const node = this.currentNodes.find(maybeNode => maybeNode.UUID === nodeId);
if ( !node ) {
throw new Error('Invalid node ID.');
}
const editor = this.nodeIdToEditorContract[nodeId];
if ( editor ) {
await editor.performDelete();
delete this.nodeIdToEditorContract[nodeId];
}
this.currentNodes = this.currentNodes.filter(x => x.UUID !== nodeId);
this.dirtyOverride = true;
}
canEdit() { canEdit() {
if ( !this.currentPage ) { if ( !this.currentPage ) {
throw new NoPageLoadedError(); throw new NoPageLoadedError();