Basic implementation of context menu for drawings

This commit is contained in:
Piotr Pekala
2019-01-10 06:42:20 -08:00
parent 9b9c0cdf4d
commit b39cf7033f
27 changed files with 205 additions and 89 deletions

View File

@ -0,0 +1,4 @@
<button mat-menu-item (click)="editStyle()">
<mat-icon>style</mat-icon>
<span>Edit style</span>
</button>

View File

@ -0,0 +1,24 @@
import { Component, OnInit, Input } from "@angular/core";
import { Drawing } from '../../../../../cartography/models/drawing';
import { Server } from '../../../../../models/server';
import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource';
import { DrawingService } from '../../../../../services/drawing.service';
@Component({
selector: 'app-edit-style-action',
templateUrl: './edit-style-action.component.html'
})
export class EditStyleActionComponent implements OnInit {
@Input() server: Server;
@Input() drawing: Drawing;
constructor(
private drawingsDataSource: DrawingsDataSource,
private drawingService: DrawingService
) {}
ngOnInit() {}
editStyle(){}
}

View File

@ -0,0 +1,4 @@
<button mat-menu-item (click)="moveLayerDown()">
<mat-icon>keyboard_arrow_down</mat-icon>
<span>Move layer down</span>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MoveLayerDownActionComponent } from './move-layer-down-action.component';
describe('MoveLayerDownActionComponent', () => {
let component: MoveLayerDownActionComponent;
let fixture: ComponentFixture<MoveLayerDownActionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MoveLayerDownActionComponent ]
})
.compileComponents();
}));
// beforeEach(() => {
// fixture = TestBed.createComponent(MoveLayerDownActionComponent);
// component = fixture.componentInstance;
// fixture.detectChanges();
// });
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});

View File

@ -0,0 +1,45 @@
import { Component, OnInit, Input } from '@angular/core';
import { Server } from '../../../../../models/server';
import { Node } from '../../../../../cartography/models/node';
import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource';
import { NodeService } from '../../../../../services/node.service';
import { Drawing } from '../../../../../cartography/models/drawing';
import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource';
import { DrawingService } from '../../../../../services/drawing.service';
@Component({
selector: 'app-move-layer-down-action',
templateUrl: './move-layer-down-action.component.html'
})
export class MoveLayerDownActionComponent implements OnInit {
@Input() server: Server;
@Input() node: Node;
@Input() drawing: Drawing;
constructor(
private nodesDataSource: NodesDataSource,
private drawingsDataSource: DrawingsDataSource,
private nodeService: NodeService,
private drawingService: DrawingService
) {}
ngOnInit() {}
moveLayerDown() {
if (this.node) {
this.node.z--;
this.nodesDataSource.update(this.node);
this.nodeService
.update(this.server, this.node)
.subscribe((node: Node) => {});
} else if(this.drawing) {
this.drawing.z--;
this.drawingsDataSource.update(this.drawing);
this.drawingService
.update(this.server, this.drawing)
.subscribe((drawing: Drawing) => {});
}
}
}

View File

@ -0,0 +1,4 @@
<button mat-menu-item (click)="moveLayerUp()">
<mat-icon>keyboard_arrow_up</mat-icon>
<span>Move layer up</span>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MoveLayerUpActionComponent } from './move-layer-up-action.component';
describe('MoveLayerUpActionComponent', () => {
let component: MoveLayerUpActionComponent;
let fixture: ComponentFixture<MoveLayerUpActionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MoveLayerUpActionComponent ]
})
.compileComponents();
}));
// beforeEach(() => {
// fixture = TestBed.createComponent(MoveLayerUpActionComponent);
// component = fixture.componentInstance;
// fixture.detectChanges();
// });
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});

View File

@ -0,0 +1,45 @@
import { Component, OnInit, Input } from '@angular/core';
import { Server } from '../../../../../models/server';
import { Node } from '../../../../../cartography/models/node';
import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource';
import { NodeService } from '../../../../../services/node.service';
import { Drawing } from '../../../../../cartography/models/drawing';
import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource';
import { DrawingService } from '../../../../../services/drawing.service';
@Component({
selector: 'app-move-layer-up-action',
templateUrl: './move-layer-up-action.component.html'
})
export class MoveLayerUpActionComponent implements OnInit {
@Input() server: Server;
@Input() node: Node;
@Input() drawing: Drawing;
constructor(
private nodesDataSource: NodesDataSource,
private drawingsDataSource: DrawingsDataSource,
private nodeService: NodeService,
private drawingService: DrawingService
) { }
ngOnInit() {}
moveLayerUp() {
if (this.node) {
this.node.z++;
this.nodesDataSource.update(this.node);
this.nodeService
.update(this.server, this.node)
.subscribe((node: Node) => {});
} else if(this.drawing) {
this.drawing.z++;
this.drawingsDataSource.update(this.drawing);
this.drawingService
.update(this.server, this.drawing)
.subscribe((drawing: Drawing) => {});
}
}
}

View File

@ -0,0 +1,4 @@
<button mat-menu-item *ngIf="node.status == 'stopped'" (click)="startNode()">
<mat-icon>play_arrow</mat-icon>
<span>Start</span>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { StartNodeActionComponent } from './start-node-action.component';
describe('StartNodeActionComponent', () => {
let component: StartNodeActionComponent;
let fixture: ComponentFixture<StartNodeActionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ StartNodeActionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(StartNodeActionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});

View File

@ -0,0 +1,27 @@
import {Component, Input, OnInit} from '@angular/core';
import {Server} from "../../../../../models/server";
import {NodeService} from "../../../../../services/node.service";
import {Node} from "../../../../../cartography/models/node";
@Component({
selector: 'app-start-node-action',
templateUrl: './start-node-action.component.html',
})
export class StartNodeActionComponent implements OnInit {
@Input() server: Server;
@Input() node: Node;
constructor(private nodeService: NodeService) { }
ngOnInit() {}
startNode() {
this.nodeService
.start(this.server, this.node)
.subscribe((n: Node) => {
});
}
}

View File

@ -0,0 +1,4 @@
<button mat-menu-item *ngIf="node.status == 'started'" (click)="stopNode()">
<mat-icon>stop</mat-icon>
<span>Stop</span>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { StopNodeActionComponent } from './stop-node-action.component';
describe('StopNodeActionComponent', () => {
let component: StopNodeActionComponent;
let fixture: ComponentFixture<StopNodeActionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ StopNodeActionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(StopNodeActionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});

View File

@ -0,0 +1,27 @@
import {Component, Input, OnInit} from '@angular/core';
import {Server} from "../../../../../models/server";
import {NodeService} from "../../../../../services/node.service";
import {Node} from "../../../../../cartography/models/node";
@Component({
selector: 'app-stop-node-action',
templateUrl: './stop-node-action.component.html'
})
export class StopNodeActionComponent implements OnInit {
@Input() server: Server;
@Input() node: Node;
constructor(private nodeService: NodeService) { }
ngOnInit() {
}
stopNode() {
this.nodeService
.stop(this.server, this.node)
.subscribe((n: Node) => {
});
}
}

View File

@ -0,0 +1,10 @@
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition" *ngIf="node || drawing">
<span [matMenuTriggerFor]="contextMenu"></span>
<mat-menu #contextMenu="matMenu" class="context-menu-items">
<app-start-node-action *ngIf="hasNodeCapabilities" [server]="server" [node]="node"></app-start-node-action>
<app-stop-node-action *ngIf="hasNodeCapabilities" [server]="server" [node]="node"></app-stop-node-action>
<app-edit-style-action *ngIf="hasDrawingCapabilities" [server]="server" [drawing]="drawing"></app-edit-style-action>
<app-move-layer-up-action *ngIf="!projectService.isReadOnly(project)" [server]="server" [node]="node" [drawing]="drawing"></app-move-layer-up-action>
<app-move-layer-down-action *ngIf="!projectService.isReadOnly(project)" [server]="server" [node]="node" [drawing]="drawing"></app-move-layer-down-action>
</mat-menu>
</div>

View File

@ -0,0 +1,3 @@
.context-menu {
position: absolute;
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ContextMenuComponent } from './context-menu.component';
describe('NodeContextMenuComponent', () => {
let component: ContextMenuComponent;
let fixture: ComponentFixture<ContextMenuComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContextMenuComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContextMenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});

View File

@ -0,0 +1,70 @@
import { ChangeDetectorRef, Component, Input, OnInit, ViewChild } from '@angular/core';
import { MatMenuTrigger } from "@angular/material";
import { DomSanitizer } from "@angular/platform-browser";
import { Node } from "../../../cartography/models/node";
import { Server } from "../../../models/server";
import { Project } from "../../../models/project";
import { ProjectService } from "../../../services/project.service";
import { Drawing } from '../../../cartography/models/drawing';
@Component({
selector: 'app-context-menu',
templateUrl: './context-menu.component.html',
styleUrls: ['./context-menu.component.scss']
})
export class ContextMenuComponent implements OnInit {
@Input() project: Project;
@Input() server: Server;
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
topPosition;
leftPosition;
node: Node;
drawing: Drawing;
private hasNodeCapabilities: boolean = false;
private hasDrawingCapabilities: boolean = false;
constructor(
private sanitizer: DomSanitizer,
private changeDetector: ChangeDetectorRef,
protected projectService: ProjectService) {}
ngOnInit() {
this.setPosition(0, 0);
}
public setPosition(top: number, left: number) {
this.topPosition = this.sanitizer.bypassSecurityTrustStyle(top + "px");
this.leftPosition = this.sanitizer.bypassSecurityTrustStyle(left + "px");
this.changeDetector.detectChanges();
}
public openMenuForNode(node: Node, top: number, left: number) {
this.resetCapabilities();
this.hasNodeCapabilities = true;
this.node = node;
this.setPosition(top, left);
this.contextMenu.openMenu();
}
public openMenuForDrawing(drawing: Drawing, top: number, left: number) {
this.resetCapabilities();
this.hasDrawingCapabilities = true;
this.drawing = drawing;
this.setPosition(top, left);
this.contextMenu.openMenu();
}
private resetCapabilities() {
this.node = null;
this.drawing = null;
this.hasDrawingCapabilities = false;
this.hasNodeCapabilities = false;
}
}