Merge branch 'master' into master-3.0

This commit is contained in:
piotrpekala7 2021-05-13 16:01:23 +02:00
commit 96919f8c05
16 changed files with 159 additions and 67 deletions

View File

@ -1,21 +1,47 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ToasterService } from '../../../services/toaster.service';
import { MapSettingsService } from '../../../services/mapsettings.service'; import { MapSettingsService } from '../../../services/mapsettings.service';
import { NodeConsoleService } from '../../../services/nodeConsole.service'; import { NodeConsoleService } from '../../../services/nodeConsole.service';
import { ThemeService } from '../../../services/theme.service'; import { ThemeService } from '../../../services/theme.service';
import { ConsoleWrapperComponent } from './console-wrapper.component'; import { ConsoleWrapperComponent } from './console-wrapper.component';
import { MatSnackBarModule } from '@angular/material/snack-bar';
describe('ConsoleWrapperComponent', () => { describe('ConsoleWrapperComponent', () => {
let fixture: ComponentFixture<ConsoleWrapperComponent>;
let component: ConsoleWrapperComponent;
let nodeConsoleService: NodeConsoleService;
let themeService: ThemeService;
let mapSettingsService: MapSettingsService;
let toasterService: ToasterService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, MatSnackBarModule],
providers: [NodeConsoleService, ThemeService, MapSettingsService, ToasterService]
}).compileComponents();
toasterService = TestBed.inject(ToasterService);
nodeConsoleService = TestBed.inject(NodeConsoleService);
themeService = TestBed.inject(ThemeService);
mapSettingsService = TestBed.inject(MapSettingsService);
}));
beforeEach(() => {
fixture = TestBed.createComponent(ConsoleWrapperComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
it('should get actual theme', () => { it('should get actual theme', () => {
const consoleService = new NodeConsoleService();
const themeService = autoSpy(ThemeService);
themeService.getActualTheme.and.returnValue('light');
const mapSettingsService = autoSpy(MapSettingsService);
const component = new ConsoleWrapperComponent(consoleService, themeService, mapSettingsService);
component.ngOnInit(); component.ngOnInit();
expect(component.isLightThemeEnabled).toBe(true); expect(component.isLightThemeEnabled).toBe(false);
}); });
}); });

View File

@ -1,6 +1,7 @@
import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core'; import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ElectronService } from 'ngx-electron'; import { ElectronService } from 'ngx-electron';
@ -20,7 +21,9 @@ import { ContextConsoleMenuComponent } from './context-console-menu.component';
describe('ContextConsoleMenuComponent', () => { describe('ContextConsoleMenuComponent', () => {
let component: ContextConsoleMenuComponent; let component: ContextConsoleMenuComponent;
let fixture: ComponentFixture<ContextConsoleMenuComponent>; let fixture: ComponentFixture<ContextConsoleMenuComponent>;
let toasterService: MockedToasterService = new MockedToasterService(); let nodeConsoleService: NodeConsoleService;
let mapSettingsService: MapSettingsService;
let toasterService: ToasterService;
let router = { let router = {
url: '', url: '',
navigate: jasmine.createSpy('navigate'), navigate: jasmine.createSpy('navigate'),
@ -28,7 +31,6 @@ describe('ContextConsoleMenuComponent', () => {
let node = { let node = {
status: 'started', status: 'started',
}; };
let mapSettingsService = new MapSettingsService();
beforeEach(async(() => { beforeEach(async(() => {
const electronMock = { const electronMock = {
@ -36,20 +38,25 @@ describe('ContextConsoleMenuComponent', () => {
}; };
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [MatMenuModule, BrowserModule], imports: [MatMenuModule, BrowserModule, MatSnackBarModule],
providers: [ providers: [
{ provide: ChangeDetectorRef }, { provide: ChangeDetectorRef },
{ provide: ProjectService, useClass: MockedProjectService }, { provide: ProjectService, useClass: MockedProjectService },
{ provide: ElectronService, useValue: electronMock }, { provide: ElectronService, useValue: electronMock },
{ provide: MapSettingsService, useValue: mapSettingsService }, { provide: MapSettingsService, useValue: mapSettingsService },
{ provide: NodeConsoleService },
{ provide: ConsoleService }, { provide: ConsoleService },
{ provide: ToasterService, useValue: toasterService },
{ provide: Router, useValue: router }, { provide: Router, useValue: router },
NodeConsoleService,
ToasterService,
MapSettingsService
], ],
declarations: [ContextConsoleMenuComponent, ConsoleDeviceActionComponent, ConsoleDeviceActionBrowserComponent], declarations: [ContextConsoleMenuComponent, ConsoleDeviceActionComponent, ConsoleDeviceActionBrowserComponent],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
}).compileComponents(); }).compileComponents();
toasterService = TestBed.inject(ToasterService);
mapSettingsService = TestBed.inject(MapSettingsService);
nodeConsoleService = TestBed.inject(NodeConsoleService);
})); }));
beforeEach(() => { beforeEach(() => {

View File

@ -1,8 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { NodeConsoleService } from '../../../../../services/nodeConsole.service';
import { Node } from '../../../../../cartography/models/node'; import { Node } from '../../../../../cartography/models/node';
import { Server } from '../../../../../models/server'; import { Server } from '../../../../../models/server';
import { ToasterService } from '../../../../../services/toaster.service';
@Component({ @Component({
selector: 'app-http-console-new-tab-action', selector: 'app-http-console-new-tab-action',
@ -12,19 +11,11 @@ export class HttpConsoleNewTabActionComponent implements OnInit {
@Input() server: Server; @Input() server: Server;
@Input() nodes: Node[]; @Input() nodes: Node[];
constructor(private toasterService: ToasterService, private router: Router) {} constructor(private nodeConsoleService: NodeConsoleService) {}
ngOnInit() {} ngOnInit() {}
openConsole() { openConsole() {
this.nodes.forEach((n) => { this.nodeConsoleService.openConsolesForAllNodesInNewTabs(this.nodes);
if (n.status === 'started') {
let url = this.router.url.split('/');
let urlString = `/static/web-ui/${url[1]}/${url[2]}/${url[3]}/${url[4]}/nodes/${n.node_id}`;
window.open(urlString);
} else {
this.toasterService.error('To open console please start the node');
}
});
} }
} }

View File

@ -1,9 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Node } from '../../../../../cartography/models/node'; import { Node } from '../../../../../cartography/models/node';
import { Server } from '../../../../../models/server'; import { Server } from '../../../../../models/server';
import { MapSettingsService } from '../../../../../services/mapsettings.service';
import { NodeConsoleService } from '../../../../../services/nodeConsole.service'; import { NodeConsoleService } from '../../../../../services/nodeConsole.service';
import { ToasterService } from '../../../../../services/toaster.service';
@Component({ @Component({
selector: 'app-http-console-action', selector: 'app-http-console-action',
@ -13,22 +11,11 @@ export class HttpConsoleActionComponent implements OnInit {
@Input() server: Server; @Input() server: Server;
@Input() nodes: Node[]; @Input() nodes: Node[];
constructor( constructor(private nodeConsoleService: NodeConsoleService) {}
private consoleService: NodeConsoleService,
private toasterService: ToasterService,
private mapSettingsService: MapSettingsService
) {}
ngOnInit() {} ngOnInit() {}
openConsole() { openConsole() {
this.nodes.forEach((n) => { this.nodeConsoleService.openConsolesForAllNodesInWidget(this.nodes);
if (n.status === 'started') {
this.mapSettingsService.logConsoleSubject.next(true);
this.consoleService.openConsoleForNode(n);
} else {
this.toasterService.error('To open console please start the node');
}
});
} }
} }

View File

@ -8,12 +8,12 @@
<app-stop-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-stop-node-action> <app-stop-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-stop-node-action>
<app-reload-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-reload-node-action> <app-reload-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-reload-node-action>
<app-http-console-action <app-http-console-action
*ngIf="!projectService.isReadOnly(project) && nodes.length === 1" *ngIf="!projectService.isReadOnly(project) && nodes.length > 0"
[server]="server" [server]="server"
[nodes]="nodes" [nodes]="nodes"
></app-http-console-action> ></app-http-console-action>
<app-http-console-new-tab-action <app-http-console-new-tab-action
*ngIf="!projectService.isReadOnly(project) && nodes.length === 1" *ngIf="!projectService.isReadOnly(project) && nodes.length > 0"
[server]="server" [server]="server"
[nodes]="nodes" [nodes]="nodes"
></app-http-console-new-tab-action> ></app-http-console-new-tab-action>

View File

@ -4,6 +4,8 @@ import { EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { ToasterService } from '../../../services/toaster.service';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource';
import { ProjectWebServiceHandler, WebServiceMessage } from '../../../handlers/project-web-service-handler'; import { ProjectWebServiceHandler, WebServiceMessage } from '../../../handlers/project-web-service-handler';
@ -14,6 +16,8 @@ import { NodeConsoleService } from '../../../services/nodeConsole.service';
import { MockedNodesDataSource, MockedNodeService } from '../project-map.component.spec'; import { MockedNodesDataSource, MockedNodeService } from '../project-map.component.spec';
import { LogConsoleComponent } from './log-console.component'; import { LogConsoleComponent } from './log-console.component';
import { LogEventsDataSource } from './log-events-datasource'; import { LogEventsDataSource } from './log-events-datasource';
import { MapSettingsService } from '../../../services/mapsettings.service';
import { MatSnackBarModule } from '@angular/material/snack-bar';
export class MockedProjectWebServiceHandler { export class MockedProjectWebServiceHandler {
public nodeNotificationEmitter = new EventEmitter<WebServiceMessage>(); public nodeNotificationEmitter = new EventEmitter<WebServiceMessage>();
@ -31,23 +35,32 @@ describe('LogConsoleComponent', () => {
let mockedNodeService: MockedNodeService = new MockedNodeService(); let mockedNodeService: MockedNodeService = new MockedNodeService();
let mockedNodesDataSource: MockedNodesDataSource = new MockedNodesDataSource(); let mockedNodesDataSource: MockedNodesDataSource = new MockedNodesDataSource();
let mockedProjectWebServiceHandler: MockedProjectWebServiceHandler = new MockedProjectWebServiceHandler(); let mockedProjectWebServiceHandler: MockedProjectWebServiceHandler = new MockedProjectWebServiceHandler();
let nodeConsoleService: NodeConsoleService;
let mapSettingsService: MapSettingsService;
let toasterService: ToasterService;
let httpServer = new HttpServer({} as HttpClient, {} as ServerErrorHandler); let httpServer = new HttpServer({} as HttpClient, {} as ServerErrorHandler);
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [HttpClientTestingModule, MatMenuModule, BrowserModule], imports: [HttpClientTestingModule, RouterTestingModule, MatMenuModule, BrowserModule, MatSnackBarModule],
providers: [ providers: [
{ provide: ProjectWebServiceHandler, useValue: mockedProjectWebServiceHandler }, { provide: ProjectWebServiceHandler, useValue: mockedProjectWebServiceHandler },
{ provide: NodeService, useValue: mockedNodeService }, { provide: NodeService, useValue: mockedNodeService },
{ provide: NodesDataSource, useValue: mockedNodesDataSource }, { provide: NodesDataSource, useValue: mockedNodesDataSource },
{ provide: LogEventsDataSource, useClass: LogEventsDataSource }, { provide: LogEventsDataSource, useClass: LogEventsDataSource },
{ provide: HttpServer, useValue: httpServer }, { provide: HttpServer, useValue: httpServer },
{ provide: NodeConsoleService }, NodeConsoleService,
ToasterService,
MapSettingsService
], ],
declarations: [LogConsoleComponent], declarations: [LogConsoleComponent],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
}).compileComponents(); }).compileComponents();
toasterService = TestBed.inject(ToasterService);
mapSettingsService = TestBed.inject(MapSettingsService);
nodeConsoleService = TestBed.inject(NodeConsoleService);
})); }));
beforeEach(() => { beforeEach(() => {

View File

@ -1,4 +1,5 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { MapSettingsService } from '../../../services/mapsettings.service';
import { ElectronService } from 'ngx-electron'; import { ElectronService } from 'ngx-electron';
import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource';
import { Project } from '../../../models/project'; import { Project } from '../../../models/project';
@ -7,6 +8,7 @@ import { NodeService } from '../../../services/node.service';
import { ServerService } from '../../../services/server.service'; import { ServerService } from '../../../services/server.service';
import { SettingsService } from '../../../services/settings.service'; import { SettingsService } from '../../../services/settings.service';
import { ToasterService } from '../../../services/toaster.service'; import { ToasterService } from '../../../services/toaster.service';
import { NodeConsoleService } from '../../../services/nodeConsole.service';
@Component({ @Component({
selector: 'app-nodes-menu', selector: 'app-nodes-menu',
@ -20,10 +22,12 @@ export class NodesMenuComponent {
constructor( constructor(
private nodeService: NodeService, private nodeService: NodeService,
private nodeConsoleService: NodeConsoleService,
private nodesDataSource: NodesDataSource, private nodesDataSource: NodesDataSource,
private toasterService: ToasterService, private toasterService: ToasterService,
private serverService: ServerService, private serverService: ServerService,
private settingsService: SettingsService, private settingsService: SettingsService,
private mapSettingsService: MapSettingsService,
private electronService: ElectronService private electronService: ElectronService
) {} ) {}
@ -48,7 +52,11 @@ export class NodesMenuComponent {
await this.electronService.remote.require('./console-executor.js').openConsole(request); await this.electronService.remote.require('./console-executor.js').openConsole(request);
} }
} else { } else {
this.toasterService.error('Option to start all nodes not available in web browser.'); if (this.mapSettingsService.openConsolesInWidget) {
this.nodeConsoleService.openConsolesForAllNodesInWidget(this.nodesDataSource.getItems());
} else {
this.nodeConsoleService.openConsolesForAllNodesInNewTabs(this.nodesDataSource.getItems());
}
} }
} }

View File

@ -64,7 +64,6 @@
<div class="menu-button-group"> <div class="menu-button-group">
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu> <app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
<app-context-menu [project]="project" [server]="server"></app-context-menu> <app-context-menu [project]="project" [server]="server"></app-context-menu>
<app-context-console-menu [project]="project" [server]="server"></app-context-console-menu>
</div> </div>
</div> </div>
<div> <div>

View File

@ -74,7 +74,6 @@ import { ImportProjectDialogComponent } from '../projects/import-project-dialog/
import { NavigationDialogComponent } from '../projects/navigation-dialog/navigation-dialog.component'; import { NavigationDialogComponent } from '../projects/navigation-dialog/navigation-dialog.component';
import { SaveProjectDialogComponent } from '../projects/save-project-dialog/save-project-dialog.component'; import { SaveProjectDialogComponent } from '../projects/save-project-dialog/save-project-dialog.component';
import { NodeAddedEvent } from '../template/template-list-dialog/template-list-dialog.component'; import { NodeAddedEvent } from '../template/template-list-dialog/template-list-dialog.component';
import { ContextConsoleMenuComponent } from './context-console-menu/context-console-menu.component';
import { ContextMenuComponent } from './context-menu/context-menu.component'; import { ContextMenuComponent } from './context-menu/context-menu.component';
import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer'; import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer';
import { NewTemplateDialogComponent } from './new-template-dialog/new-template-dialog.component'; import { NewTemplateDialogComponent } from './new-template-dialog/new-template-dialog.component';
@ -121,7 +120,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
public isLightThemeEnabled: boolean = false; public isLightThemeEnabled: boolean = false;
@ViewChild(ContextMenuComponent) contextMenu: ContextMenuComponent; @ViewChild(ContextMenuComponent) contextMenu: ContextMenuComponent;
@ViewChild(ContextConsoleMenuComponent) consoleContextMenu: ContextConsoleMenuComponent;
@ViewChild(D3MapComponent) mapChild: D3MapComponent; @ViewChild(D3MapComponent) mapChild: D3MapComponent;
@ViewChild(ProjectMapMenuComponent) projectMapMenuComponent: ProjectMapMenuComponent; @ViewChild(ProjectMapMenuComponent) projectMapMenuComponent: ProjectMapMenuComponent;
@ -514,11 +512,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX); 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(onLinkContextMenu);
this.projectMapSubscription.add(onEthernetLinkContextMenu); this.projectMapSubscription.add(onEthernetLinkContextMenu);
this.projectMapSubscription.add(onSerialLinkContextMenu); this.projectMapSubscription.add(onSerialLinkContextMenu);
@ -527,7 +520,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.projectMapSubscription.add(onContextMenu); this.projectMapSubscription.add(onContextMenu);
this.projectMapSubscription.add(onLabelContextMenu); this.projectMapSubscription.add(onLabelContextMenu);
this.projectMapSubscription.add(onInterfaceLabelContextMenu); this.projectMapSubscription.add(onInterfaceLabelContextMenu);
this.projectMapSubscription.add(onContextConsoleMenu);
this.mapChangeDetectorRef.detectChanges(); this.mapChangeDetectorRef.detectChanges();
} }

View File

@ -13,6 +13,7 @@
<mat-checkbox [(ngModel)]="settings.crash_reports">Send anonymous crash reports</mat-checkbox><br/> <mat-checkbox [(ngModel)]="settings.crash_reports">Send anonymous crash reports</mat-checkbox><br/>
<mat-checkbox [(ngModel)]="integrateLinksLabelsToLinks">Integrate link labels to links</mat-checkbox><br/> <mat-checkbox [(ngModel)]="integrateLinksLabelsToLinks">Integrate link labels to links</mat-checkbox><br/>
<mat-checkbox [(ngModel)]="openReadme">Automatically open project README files</mat-checkbox> <mat-checkbox [(ngModel)]="openReadme">Automatically open project README files</mat-checkbox>
<mat-checkbox [(ngModel)]="openConsolesInWidget">Open consoles in the widget instead of in new tabs after clicking start consoles for all nodes</mat-checkbox>
</div> </div>
<!-- <div> <!-- <div>

View File

@ -23,7 +23,8 @@ describe('SettingsComponent', () => {
let mapSettingsService = { let mapSettingsService = {
integrateLinkLabelsToLinks: true, integrateLinkLabelsToLinks: true,
toggleIntegrateInterfaceLabels(val: boolean) {}, toggleIntegrateInterfaceLabels(val: boolean) {},
toggleOpenReadme(val: boolean) {} toggleOpenReadme(val: boolean) {},
toggleOpenConsolesInWidget(val: boolean) {}
}; };
let consoleService; let consoleService;
let updatesService = autoSpy(UpdatesService); let updatesService = autoSpy(UpdatesService);
@ -76,11 +77,19 @@ describe('SettingsComponent', () => {
}; };
const getAll = spyOn(settingsService, 'getAll').and.returnValue(settings); const getAll = spyOn(settingsService, 'getAll').and.returnValue(settings);
const setAll = spyOn(settingsService, 'setAll'); const setAll = spyOn(settingsService, 'setAll');
spyOn(mapSettingsService, 'toggleIntegrateInterfaceLabels');
spyOn(mapSettingsService, 'toggleOpenConsolesInWidget');
component.ngOnInit(); component.ngOnInit();
expect(getAll).toHaveBeenCalled(); expect(getAll).toHaveBeenCalled();
expect(component.settings).toEqual(settings); expect(component.settings).toEqual(settings);
component.settings.crash_reports = false; component.settings.crash_reports = false;
component.save(); component.save();
expect(setAll).toHaveBeenCalledWith(settings); expect(setAll).toHaveBeenCalledWith(settings);
expect(mapSettingsService.toggleIntegrateInterfaceLabels).toHaveBeenCalled();
expect(mapSettingsService.toggleOpenConsolesInWidget).toHaveBeenCalled();
}); });
}); });

View File

@ -16,6 +16,7 @@ export class SettingsComponent implements OnInit {
consoleCommand: string; consoleCommand: string;
integrateLinksLabelsToLinks: boolean; integrateLinksLabelsToLinks: boolean;
openReadme: boolean; openReadme: boolean;
openConsolesInWidget: boolean;
constructor( constructor(
private settingsService: SettingsService, private settingsService: SettingsService,
@ -31,6 +32,7 @@ export class SettingsComponent implements OnInit {
this.consoleCommand = this.consoleService.command; this.consoleCommand = this.consoleService.command;
this.integrateLinksLabelsToLinks = this.mapSettingsService.integrateLinkLabelsToLinks; this.integrateLinksLabelsToLinks = this.mapSettingsService.integrateLinkLabelsToLinks;
this.openReadme = this.mapSettingsService.openReadme; this.openReadme = this.mapSettingsService.openReadme;
this.openConsolesInWidget = this.mapSettingsService.openConsolesInWidget;
} }
save() { save() {
@ -39,6 +41,7 @@ export class SettingsComponent implements OnInit {
this.mapSettingsService.toggleIntegrateInterfaceLabels(this.integrateLinksLabelsToLinks); this.mapSettingsService.toggleIntegrateInterfaceLabels(this.integrateLinksLabelsToLinks);
this.mapSettingsService.toggleOpenReadme(this.openReadme); this.mapSettingsService.toggleOpenReadme(this.openReadme);
this.mapSettingsService.toggleOpenConsolesInWidget(this.openConsolesInWidget);
} }
setDarkMode(value: boolean) { setDarkMode(value: boolean) {

View File

@ -15,7 +15,7 @@ export class BuiltInTemplatesConfigurationService {
} }
getConsoleTypesForCloudNodes() { getConsoleTypesForCloudNodes() {
return ['telnet', 'none']; return ['telnet', 'vnc', 'spice', 'http', 'https', 'none'];
} }
getCategoriesForEthernetHubs() { getCategoriesForEthernetHubs() {

View File

@ -17,12 +17,14 @@ export class MapSettingsService {
public openReadme: boolean; public openReadme: boolean;
public showInterfaceLabels: boolean = true; public showInterfaceLabels: boolean = true;
public integrateLinkLabelsToLinks: boolean = true; public integrateLinkLabelsToLinks: boolean = true;
public openConsolesInWidget: boolean = false;
constructor() { constructor() {
this.isLayerNumberVisible = localStorage.getItem('layersVisibility') === 'true' ? true : false; this.isLayerNumberVisible = localStorage.getItem('layersVisibility') === 'true' ? true : false;
if (localStorage.getItem('integrateLinkLabelsToLinks')) if (localStorage.getItem('integrateLinkLabelsToLinks'))
this.integrateLinkLabelsToLinks = localStorage.getItem('integrateLinkLabelsToLinks') === 'true' ? true : false; this.integrateLinkLabelsToLinks = localStorage.getItem('integrateLinkLabelsToLinks') === 'true' ? true : false;
if (localStorage.getItem('openConsolesInWidget'))
this.openConsolesInWidget = localStorage.getItem('openConsolesInWidget') === 'true' ? true : false;
let isSymbolScalingEnabled = true; let isSymbolScalingEnabled = true;
if (localStorage.getItem('symbolScaling')) { if (localStorage.getItem('symbolScaling')) {
isSymbolScalingEnabled = localStorage.getItem('symbolScaling') === 'true' ? true : false; isSymbolScalingEnabled = localStorage.getItem('symbolScaling') === 'true' ? true : false;
@ -89,12 +91,22 @@ export class MapSettingsService {
} }
toggleOpenReadme(value: boolean) { toggleOpenReadme(value: boolean) {
this.openReadme = value; this.openReadme = value;
localStorage.removeItem('openReadme'); localStorage.removeItem('openReadme');
if (value) { if (value) {
localStorage.setItem('openReadme', 'true'); localStorage.setItem('openReadme', 'true');
} else { } else {
localStorage.setItem('openReadme', 'false'); localStorage.setItem('openReadme', 'false');
} }
}
toggleOpenConsolesInWidget(value: boolean) {
this.openConsolesInWidget = value;
localStorage.removeItem('openConsolesInWidget');
if (value) {
localStorage.setItem('openConsolesInWidget', 'true');
} else {
localStorage.setItem('openConsolesInWidget', 'false');
}
} }
} }

View File

@ -2,6 +2,10 @@ import { EventEmitter, Injectable } from '@angular/core';
import { Server } from '../models/server'; import { Server } from '../models/server';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { Node } from '../cartography/models/node'; import { Node } from '../cartography/models/node';
import { Router } from '@angular/router';
import { ToasterService } from './toaster.service';
import { MapSettingsService } from './mapsettings.service';
import { node } from 'prop-types';
@Injectable() @Injectable()
export class NodeConsoleService { export class NodeConsoleService {
@ -19,7 +23,11 @@ export class NodeConsoleService {
private lastNumberOfColumns: number; private lastNumberOfColumns: number;
private lastNumberOfRows: number; private lastNumberOfRows: number;
constructor() {} constructor(
private router: Router,
private toasterService: ToasterService,
private mapSettingsService: MapSettingsService
) {}
getNumberOfColumns() { getNumberOfColumns() {
return this.lastNumberOfColumns; return this.lastNumberOfColumns;
@ -65,6 +73,42 @@ export class NodeConsoleService {
return `${protocol}://${server.host}:${server.port}/v3/projects/${node.project_id}/nodes/${node.node_id}/console/ws` return `${protocol}://${server.host}:${server.port}/v3/projects/${node.project_id}/nodes/${node.node_id}/console/ws`
} }
openConsolesForAllNodesInWidget(nodes: Node[]) {
let nodesToStart = 'Please start the following nodes if you want to open consoles for them: ';
let nodesToStartCounter = 0;
nodes.forEach((n) => {
if (n.status === 'started') {
this.mapSettingsService.logConsoleSubject.next(true);
// this timeout is required due to xterm.js implementation
setTimeout(() => { this.openConsoleForNode(n); }, 500);
} else {
nodesToStartCounter++;
nodesToStart += n.name + ' '
}
});
if (nodesToStartCounter > 0) {
this.toasterService.error(nodesToStart);
}
}
openConsolesForAllNodesInNewTabs(nodes: Node[]) {
let nodesToStart = 'Please start the following nodes if you want to open consoles for them: ';
let nodesToStartCounter = 0;
nodes.forEach((n) => {
if (n.status === 'started') {
let url = this.router.url.split('/');
let urlString = `/static/web-ui/${url[1]}/${url[2]}/${url[3]}/${url[4]}/nodes/${n.node_id}`;
window.open(urlString);
} else {
nodesToStartCounter++;
nodesToStart += n.name + ' '
}
});
if (nodesToStartCounter > 0) {
this.toasterService.error(nodesToStart);
}
}
} }
export interface ConsoleResizedEvent { export interface ConsoleResizedEvent {

View File

@ -35,7 +35,7 @@
</script> </script>
</head> </head>
<!-- <body class="mat-app-background" oncontextmenu="return false;"> --> <!-- <body class="mat-app-background" oncontextmenu="return false;"> -->
<body class="mat-app-background"> <body class="mat-app-background" oncontextmenu="return false;">
<app-root></app-root> <app-root></app-root>
<!-- Global site tag (gtag.js) - Google Analytics --> <!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-5D6FZL9923"></script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-5D6FZL9923"></script>