mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-18 18:56:26 +00:00
Double click to open new console
This commit is contained in:
parent
3667a4d755
commit
8ffbf1be30
@ -37,6 +37,7 @@ import { ProjectMapComponent } from './components/project-map/project-map.compon
|
||||
import { ServersComponent } from './components/servers/servers.component';
|
||||
import { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component';
|
||||
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
|
||||
import { ContextConsoleMenuComponent } from './components/project-map/context-console-menu/context-console-menu.component';
|
||||
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
||||
import { StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
|
||||
import { TemplateComponent } from './components/template/template.component';
|
||||
@ -299,6 +300,7 @@ import { TemplateNameDialogComponent } from './components/project-map/new-templa
|
||||
DefaultLayoutComponent,
|
||||
ProgressDialogComponent,
|
||||
ContextMenuComponent,
|
||||
ContextConsoleMenuComponent,
|
||||
StartNodeActionComponent,
|
||||
StopNodeActionComponent,
|
||||
TemplateComponent,
|
||||
|
@ -15,6 +15,7 @@ import { MapSettingsService } from '../../services/mapsettings.service';
|
||||
@Injectable()
|
||||
export class NodeWidget implements Widget {
|
||||
public onContextMenu = new EventEmitter<NodeContextMenu>();
|
||||
public onContextConsoleMenu = new EventEmitter<NodeContextMenu>();
|
||||
public onNodeClicked = new EventEmitter<NodeClicked>();
|
||||
|
||||
constructor(
|
||||
@ -85,6 +86,10 @@ export class NodeWidget implements Widget {
|
||||
event.preventDefault();
|
||||
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
||||
})
|
||||
.on('dblclick', function(n: MapNode, i: number) {
|
||||
event.preventDefault();
|
||||
self.onContextConsoleMenu.emit(new NodeContextMenu(event, n));
|
||||
})
|
||||
.attr('xnode:href', (n: MapNode) => n.symbolUrl)
|
||||
.attr('width', (n: MapNode) => {
|
||||
if (n.nodeType === 'cloud' || n.nodeType === 'nat') return 120;
|
||||
|
@ -0,0 +1,22 @@
|
||||
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition">
|
||||
<span [matMenuTriggerFor]="contextConsoleMenu"></span>
|
||||
<mat-menu #contextConsoleMenu="matMenu" class="context-menu-items">
|
||||
<span class="title">
|
||||
Choose default behavior for double click on node
|
||||
</span>
|
||||
<button mat-menu-item (click)="openConsole()">
|
||||
<mat-icon>web_asset</mat-icon>
|
||||
<span>Open console</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="openWebConsole()">
|
||||
<mat-icon>http</mat-icon>
|
||||
<span>Open web console</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="openWebConsoleInNewTab()">
|
||||
<mat-icon>http</mat-icon>
|
||||
<span>Open web console in new tab</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<template [hidden]="true" #container></template>
|
@ -0,0 +1,12 @@
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
min-height: 0px;
|
||||
}
|
||||
|
||||
.mat-menu-panel ng-trigger ng-trigger-transformMenu ng-tns-c7-5 context-menu-items mat-menu-after mat-menu-below ng-star-inserted mat-elevation-z4 {
|
||||
min-height: 0px!important;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 10px;
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
import { ChangeDetectorRef, Component, ComponentFactory, ComponentRef, Input, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { Node } from '../../../cartography/models/node';
|
||||
import { Server } from '../../../models/server';
|
||||
import { Project } from '../../../models/project';
|
||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||
import { ElectronService } from 'ngx-electron';
|
||||
import { NodeConsoleService } from '../../../services/nodeConsole.service';
|
||||
import { ToasterService } from '../../../services/toaster.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { ComponentFactoryResolver } from '@angular/core';
|
||||
import { ConsoleDeviceActionComponent } from '../context-menu/actions/console-device-action/console-device-action.component';
|
||||
import { ConsoleDeviceActionBrowserComponent } from '../context-menu/actions/console-device-action-browser/console-device-action-browser.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-context-console-menu',
|
||||
templateUrl: './context-console-menu.component.html',
|
||||
styleUrls: ['./context-console-menu.component.scss']
|
||||
})
|
||||
export class ContextConsoleMenuComponent implements OnInit {
|
||||
@Input() project: Project;
|
||||
@Input() server: Server;
|
||||
@ViewChild(MatMenuTrigger) contextConsoleMenu: MatMenuTrigger;
|
||||
@ViewChild("container", { read: ViewContainerRef }) container;
|
||||
componentRef: ComponentRef<ConsoleDeviceActionComponent>;
|
||||
componentBrowserRef: ComponentRef<ConsoleDeviceActionBrowserComponent>;
|
||||
|
||||
topPosition;
|
||||
leftPosition;
|
||||
isElectronApp = false;
|
||||
node: Node;;
|
||||
|
||||
constructor(
|
||||
private sanitizer: DomSanitizer,
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private mapSettingsService: MapSettingsService,
|
||||
private electronService: ElectronService,
|
||||
private consoleService: NodeConsoleService,
|
||||
private toasterService: ToasterService,
|
||||
private router: Router,
|
||||
private resolver: ComponentFactoryResolver
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.setPosition(0, 0);
|
||||
this.isElectronApp = this.electronService.isElectronApp;
|
||||
}
|
||||
|
||||
public setPosition(top: number, left: number) {
|
||||
this.topPosition = this.sanitizer.bypassSecurityTrustStyle(top + 'px');
|
||||
this.leftPosition = this.sanitizer.bypassSecurityTrustStyle(left + 'px');
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
public openMenu(node: Node, top: number, left: number) {
|
||||
this.node = node;
|
||||
let action = this.mapSettingsService.getConsoleContextManuAction();
|
||||
if (action) {
|
||||
if (action === 'web console') {
|
||||
this.openWebConsole();
|
||||
} else if (action === 'web console in new tab') {
|
||||
this.openWebConsoleInNewTab();
|
||||
} else if (action === 'console') {
|
||||
this.openConsole();
|
||||
}
|
||||
} else {
|
||||
this.setPosition(top, left);
|
||||
this.contextConsoleMenu.openMenu();
|
||||
}
|
||||
}
|
||||
|
||||
openConsole() {
|
||||
this.mapSettingsService.setConsoleContextMenuAction('console');
|
||||
if (this.isElectronApp) {
|
||||
const factory: ComponentFactory<ConsoleDeviceActionComponent> = this.resolver.resolveComponentFactory(ConsoleDeviceActionComponent);
|
||||
this.componentRef = this.container.createComponent(factory);
|
||||
this.componentRef.instance.server = this.server;
|
||||
this.componentRef.instance.nodes = [this.node];
|
||||
|
||||
this.componentRef.instance.console();
|
||||
} else {
|
||||
const factory: ComponentFactory<ConsoleDeviceActionBrowserComponent> = this.resolver.resolveComponentFactory(ConsoleDeviceActionBrowserComponent);
|
||||
this.componentBrowserRef = this.container.createComponent(factory);
|
||||
this.componentBrowserRef.instance.server = this.server;
|
||||
this.componentBrowserRef.instance.node = this.node;
|
||||
|
||||
this.componentBrowserRef.instance.openConsole();
|
||||
}
|
||||
}
|
||||
|
||||
openWebConsole() {
|
||||
this.mapSettingsService.setConsoleContextMenuAction('web console');
|
||||
if (this.node.status === 'started') {
|
||||
this.mapSettingsService.logConsoleSubject.next(true);
|
||||
this.consoleService.openConsoleForNode(this.node);
|
||||
} else {
|
||||
this.toasterService.error('To open console please start the node');
|
||||
}
|
||||
}
|
||||
|
||||
openWebConsoleInNewTab() {
|
||||
this.mapSettingsService.setConsoleContextMenuAction('web console in new tab');
|
||||
if (this.node.status === 'started') {
|
||||
let url = this.router.url.split('/');
|
||||
let urlString = `/static/web-ui/${url[1]}/${url[2]}/${url[3]}/${url[4]}/nodes/${this.node.node_id}`
|
||||
window.open(urlString);
|
||||
} else {
|
||||
this.toasterService.error('To open console please start the node');
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.componentRef.destroy();
|
||||
}
|
||||
}
|
@ -5,4 +5,4 @@
|
||||
|
||||
.mat-menu-panel ng-trigger ng-trigger-transformMenu ng-tns-c7-5 context-menu-items mat-menu-after mat-menu-below ng-star-inserted mat-elevation-z4 {
|
||||
min-height: 0px!important;
|
||||
}
|
||||
}
|
@ -179,6 +179,7 @@
|
||||
</div>
|
||||
|
||||
<app-context-menu [project]="project" [server]="server"></app-context-menu>
|
||||
<app-context-console-menu [project]="project" [server]="server"></app-context-console-menu>
|
||||
</div>
|
||||
|
||||
<div [ngClass]="{lightTheme: isLightThemeEnabled}" class="zoom-buttons">
|
||||
|
@ -13,6 +13,7 @@ import { ProjectService } from '../../services/project.service';
|
||||
import { Server } from '../../models/server';
|
||||
import { Drawing } from '../../cartography/models/drawing';
|
||||
import { ContextMenuComponent } from './context-menu/context-menu.component';
|
||||
import { ContextConsoleMenuComponent } from './context-console-menu/context-console-menu.component';
|
||||
import { Template } from '../../models/template';
|
||||
import { NodeService } from '../../services/node.service';
|
||||
import { Symbol } from '../../models/symbol';
|
||||
@ -112,6 +113,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
public isLightThemeEnabled: boolean = false;
|
||||
|
||||
@ViewChild(ContextMenuComponent) contextMenu: ContextMenuComponent;
|
||||
@ViewChild(ContextConsoleMenuComponent) consoleContextMenu: ContextConsoleMenuComponent;
|
||||
@ViewChild(D3MapComponent) mapChild: D3MapComponent;
|
||||
@ViewChild(ProjectMapMenuComponent) projectMapMenuComponent: ProjectMapMenuComponent;
|
||||
|
||||
@ -437,6 +439,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX);
|
||||
});
|
||||
|
||||
const onContextConsoleMenu = this.nodeWidget.onContextConsoleMenu.subscribe((eventNode: NodeContextMenu) => {
|
||||
const node = this.mapNodeToNode.convert(eventNode.node);
|
||||
this.consoleContextMenu.openMenu(node, eventNode.event.pageY, eventNode.event.pageX);
|
||||
});
|
||||
|
||||
this.projectMapSubscription.add(onLinkContextMenu);
|
||||
this.projectMapSubscription.add(onEthernetLinkContextMenu);
|
||||
this.projectMapSubscription.add(onSerialLinkContextMenu);
|
||||
@ -445,6 +452,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
this.projectMapSubscription.add(onContextMenu);
|
||||
this.projectMapSubscription.add(onLabelContextMenu);
|
||||
this.projectMapSubscription.add(onInterfaceLabelContextMenu);
|
||||
this.projectMapSubscription.add(onContextConsoleMenu);
|
||||
this.mapChangeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,14 @@ export class MapSettingsService {
|
||||
this.isMapLocked.next(value);
|
||||
}
|
||||
|
||||
setConsoleContextMenuAction(action: string) {
|
||||
localStorage.setItem('consoleContextMenu', action);
|
||||
}
|
||||
|
||||
getConsoleContextManuAction(): string {
|
||||
return localStorage.getItem('consoleContextMenu');
|
||||
}
|
||||
|
||||
toggleTopologySummary(value: boolean) {
|
||||
this.isTopologySummaryVisible = value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user