mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-28 13:04:21 +00:00
Draw line menu
This commit is contained in:
parent
e19503d1a3
commit
0b61093dff
@ -46,6 +46,7 @@ import { StartNodeActionComponent } from './shared/node-context-menu/actions/sta
|
||||
import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop-node-action/stop-node-action.component';
|
||||
import { ApplianceComponent } from './appliance/appliance.component';
|
||||
import { ApplianceListDialogComponent } from './appliance/appliance-list-dialog/appliance-list-dialog.component';
|
||||
import { NodeSelectInterfaceComponent } from './shared/node-select-interface/node-select-interface.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -64,6 +65,7 @@ import { ApplianceListDialogComponent } from './appliance/appliance-list-dialog/
|
||||
StopNodeActionComponent,
|
||||
ApplianceComponent,
|
||||
ApplianceListDialogComponent,
|
||||
NodeSelectInterfaceComponent,
|
||||
],
|
||||
imports: [
|
||||
NgbModule.forRoot(),
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Label} from "./label.model";
|
||||
import {Port} from "../../../shared/models/port";
|
||||
|
||||
export class Node {
|
||||
command_line: string;
|
||||
@ -15,7 +16,7 @@ export class Node {
|
||||
node_type: string;
|
||||
port_name_format: string;
|
||||
port_segment_size: number;
|
||||
ports: number[];
|
||||
ports: Port[];
|
||||
project_id: string;
|
||||
status: string;
|
||||
symbol: string;
|
||||
|
@ -10,6 +10,7 @@ export class NodesWidget implements Widget {
|
||||
private debug = false;
|
||||
|
||||
private onContextMenuCallback: (event: any, node: Node) => void;
|
||||
private onNodeClickedCallback: (event: any, node: Node) => void;
|
||||
private onNodeDraggedCallback: (event: any, node: Node) => void;
|
||||
private onNodeDraggingCallbacks: ((event: any, node: Node) => void)[] = [];
|
||||
|
||||
@ -21,6 +22,10 @@ export class NodesWidget implements Widget {
|
||||
this.onContextMenuCallback = onContextMenuCallback;
|
||||
}
|
||||
|
||||
public setOnNodeClickedCallback(onNodeClickedCallback: (event: any, node: Node) => void) {
|
||||
this.onNodeClickedCallback = onNodeClickedCallback;
|
||||
}
|
||||
|
||||
public setOnNodeDraggedCallback(onNodeDraggedCallback: (event: any, node: Node) => void) {
|
||||
this.onNodeDraggedCallback = onNodeDraggedCallback;
|
||||
}
|
||||
@ -102,13 +107,20 @@ export class NodesWidget implements Widget {
|
||||
.attr('y', '0');
|
||||
}
|
||||
|
||||
const node_merge = node.merge(node_enter)
|
||||
.on("contextmenu", function (n: Node, i: number) {
|
||||
event.preventDefault();
|
||||
if (self.onContextMenuCallback !== null) {
|
||||
self.onContextMenuCallback(event, n);
|
||||
}
|
||||
});
|
||||
const node_merge = node
|
||||
.merge(node_enter)
|
||||
.on("contextmenu", function (n: Node, i: number) {
|
||||
event.preventDefault();
|
||||
if (self.onContextMenuCallback !== null) {
|
||||
self.onContextMenuCallback(event, n);
|
||||
}
|
||||
})
|
||||
.on('click', (n: Node) => {
|
||||
if (self.onNodeClickedCallback) {
|
||||
self.onNodeClickedCallback(event, n);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.revise(node_merge);
|
||||
|
||||
|
@ -19,6 +19,16 @@
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-toolbar-row>
|
||||
<button mat-icon-button (click)="turnOnDrawLineMode()" *ngIf="!drawLineMode">
|
||||
<mat-icon>timeline</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button color="primary" (click)="turnOffDrawLineMode()" *ngIf="drawLineMode">
|
||||
<mat-icon>timeline</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-toolbar-row>
|
||||
<button mat-icon-button (click)="createSnapshotModal()">
|
||||
<mat-icon>snooze</mat-icon>
|
||||
@ -33,6 +43,6 @@
|
||||
</div>
|
||||
|
||||
<app-node-context-menu [server]="server"></app-node-context-menu>
|
||||
|
||||
<app-node-select-interface></app-node-select-interface>
|
||||
</div>
|
||||
|
||||
|
@ -30,6 +30,7 @@ import { NodeContextMenuComponent } from "../shared/node-context-menu/node-conte
|
||||
import {Appliance} from "../shared/models/appliance";
|
||||
import {NodeService} from "../shared/services/node.service";
|
||||
import {Symbol} from "../shared/models/symbol";
|
||||
import {NodeSelectInterfaceComponent} from "../shared/node-select-interface/node-select-interface.component";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -48,10 +49,13 @@ export class ProjectMapComponent implements OnInit {
|
||||
public server: Server;
|
||||
|
||||
private ws: Subject<any>;
|
||||
private drawLineMode = false;
|
||||
|
||||
|
||||
@ViewChild(MapComponent) mapChild: MapComponent;
|
||||
|
||||
@ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent;
|
||||
@ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@ -182,6 +186,13 @@ export class ProjectMapComponent implements OnInit {
|
||||
this.nodeContextMenu.open(node, event.clientY, event.clientX);
|
||||
});
|
||||
|
||||
this.mapChild.graphLayout.getNodesWidget().setOnNodeClickedCallback((event: any, node: Node) => {
|
||||
if (this.drawLineMode) {
|
||||
this.nodeSelectInterfaceMenu.open(node, event.clientY, event.clientX);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this.mapChild.graphLayout.getNodesWidget().setOnNodeDraggedCallback((event: any, node: Node) => {
|
||||
const index = this.nodes.findIndex((n: Node) => n.node_id === node.node_id);
|
||||
if (index >= 0) {
|
||||
@ -245,6 +256,14 @@ export class ProjectMapComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public turnOnDrawLineMode() {
|
||||
this.drawLineMode = true;
|
||||
}
|
||||
|
||||
public turnOffDrawLineMode() {
|
||||
this.drawLineMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
7
src/app/shared/models/port.ts
Normal file
7
src/app/shared/models/port.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export class Port {
|
||||
adapter_number: number;
|
||||
link_type: string;
|
||||
name: string;
|
||||
port_number: number;
|
||||
short_name: string;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition" *ngIf="node">
|
||||
<span [matMenuTriggerFor]="selectInterfaceMenu"></span>
|
||||
<mat-menu #selectInterfaceMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let port of node.ports">
|
||||
<mat-icon>info</mat-icon>
|
||||
<span>{{ port.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
@ -0,0 +1,3 @@
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NodeSelectInterfaceComponent } from './node-select-interface.component';
|
||||
|
||||
describe('NodeSelectInterfaceComponent', () => {
|
||||
let component: NodeSelectInterfaceComponent;
|
||||
let fixture: ComponentFixture<NodeSelectInterfaceComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NodeSelectInterfaceComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NodeSelectInterfaceComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,40 @@
|
||||
import {ChangeDetectorRef, Component, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {MatMenuTrigger} from "@angular/material";
|
||||
import {DomSanitizer} from "@angular/platform-browser";
|
||||
import {Node} from "../../cartography/shared/models/node.model";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-node-select-interface',
|
||||
templateUrl: './node-select-interface.component.html',
|
||||
styleUrls: ['./node-select-interface.component.scss']
|
||||
})
|
||||
export class NodeSelectInterfaceComponent implements OnInit {
|
||||
|
||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||
|
||||
private topPosition;
|
||||
private leftPosition;
|
||||
private node: Node;
|
||||
|
||||
constructor(
|
||||
private sanitizer: DomSanitizer,
|
||||
private changeDetector: ChangeDetectorRef) {}
|
||||
|
||||
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 open(node: Node, top: number, left: number) {
|
||||
this.node = node;
|
||||
this.setPosition(top, left);
|
||||
this.contextMenu.openMenu();
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user