Double click to open new console

This commit is contained in:
piotrpekala7 2020-09-22 18:01:31 +02:00
parent 3667a4d755
commit 8ffbf1be30
10 changed files with 175 additions and 1 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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>

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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">

View File

@ -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();
}

View File

@ -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;
}