mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-04-09 03:24:13 +00:00
Actions for all nodes added
This commit is contained in:
parent
f3ef8dc273
commit
8cda33c0d9
@ -168,6 +168,7 @@ import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapsho
|
||||
import { DateFilter } from './filters/dateFilter.pipe';
|
||||
import { NameFilter } from './filters/nameFilter.pipe';
|
||||
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
|
||||
import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component';
|
||||
|
||||
if (environment.production) {
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
@ -273,7 +274,8 @@ if (environment.production) {
|
||||
DateFilter,
|
||||
NameFilter,
|
||||
ListOfSnapshotsComponent,
|
||||
CustomAdaptersComponent
|
||||
CustomAdaptersComponent,
|
||||
NodesMenuComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -0,0 +1,32 @@
|
||||
<button
|
||||
matTooltip="Start/Resume all nodes"
|
||||
mat-icon-button
|
||||
(click)="startNodes()"
|
||||
class="menu-button"
|
||||
>
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="Suspend all nodes"
|
||||
mat-icon-button
|
||||
(click)="suspendNodes()"
|
||||
class="menu-button"
|
||||
>
|
||||
<mat-icon>pause</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="Stop all nodes"
|
||||
mat-icon-button
|
||||
(click)="stopNodes()"
|
||||
class="menu-button"
|
||||
>
|
||||
<mat-icon>stop</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="Reload all nodes"
|
||||
mat-icon-button
|
||||
(click)="reloadNodes()"
|
||||
class="menu-button"
|
||||
>
|
||||
<mat-icon>replay</mat-icon>
|
||||
</button>
|
@ -0,0 +1,12 @@
|
||||
.menu-button {
|
||||
outline: 0 !important;
|
||||
transition: 0.5s;
|
||||
margin-bottom: 16px;
|
||||
width: 40px;
|
||||
margin-right: 12px !important;
|
||||
margin-left: 12px !important;
|
||||
background: #263238;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NodesMenuComponent } from './nodes-menu.component';
|
||||
import { MockedToasterService } from '../../../services/toaster.service.spec';
|
||||
import { MockedNodeService } from '../project-map.component.spec';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NodeService } from '../../../services/node.service';
|
||||
import { ToasterService } from '../../../services/toaster.service';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
describe('NodesMenuComponent', () => {
|
||||
let component: NodesMenuComponent;
|
||||
let fixture: ComponentFixture<NodesMenuComponent>;
|
||||
let mockedToasterService: MockedToasterService = new MockedToasterService();
|
||||
let mockedNodeService: MockedNodeService = new MockedNodeService();
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [MatButtonModule, MatIconModule, CommonModule, NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: NodeService, useValue: mockedNodeService },
|
||||
{ provide: ToasterService, useValue: mockedToasterService }
|
||||
],
|
||||
declarations: [
|
||||
NodesMenuComponent,
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NodesMenuComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should call start all nodes', () => {
|
||||
spyOn(mockedNodeService, 'startAll').and.returnValue(of());
|
||||
|
||||
component.startNodes();
|
||||
|
||||
expect(mockedNodeService.startAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call stop all nodes', () => {
|
||||
spyOn(mockedNodeService, 'stopAll').and.returnValue(of());
|
||||
|
||||
component.stopNodes();
|
||||
|
||||
expect(mockedNodeService.stopAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call suspend all nodes', () => {
|
||||
spyOn(mockedNodeService, 'suspendAll').and.returnValue(of());
|
||||
|
||||
component.suspendNodes();
|
||||
|
||||
expect(mockedNodeService.suspendAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call reload all nodes', () => {
|
||||
spyOn(mockedNodeService, 'reloadAll').and.returnValue(of());
|
||||
|
||||
component.reloadNodes();
|
||||
|
||||
expect(mockedNodeService.reloadAll).toHaveBeenCalled();
|
||||
});
|
||||
});
|
@ -0,0 +1,44 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { Project } from '../../../models/project';
|
||||
import { Server } from '../../../models/server';
|
||||
import { NodeService } from '../../../services/node.service';
|
||||
import { ToasterService } from '../../../services/toaster.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nodes-menu',
|
||||
templateUrl: './nodes-menu.component.html',
|
||||
styleUrls: ['./nodes-menu.component.scss']
|
||||
})
|
||||
export class NodesMenuComponent {
|
||||
@Input('project') project: Project;
|
||||
@Input('server') server: Server;
|
||||
|
||||
constructor(
|
||||
private nodeService: NodeService,
|
||||
private toasterService: ToasterService
|
||||
) {}
|
||||
|
||||
startNodes() {
|
||||
this.nodeService.startAll(this.server, this.project).subscribe(() => {
|
||||
this.toasterService.success('All nodes successfully started');
|
||||
});
|
||||
}
|
||||
|
||||
stopNodes() {
|
||||
this.nodeService.stopAll(this.server, this.project).subscribe(() => {
|
||||
this.toasterService.success('All nodes successfully stopped');
|
||||
});
|
||||
}
|
||||
|
||||
suspendNodes() {
|
||||
this.nodeService.suspendAll(this.server, this.project).subscribe(() => {
|
||||
this.toasterService.success('All nodes successfully suspended');
|
||||
});
|
||||
}
|
||||
|
||||
reloadNodes() {
|
||||
this.nodeService.reloadAll(this.server, this.project).subscribe(() => {
|
||||
this.toasterService.success('All nodes successfully reloaded');
|
||||
});
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@
|
||||
<div class="project-toolbar">
|
||||
<mat-toolbar color="primary" class="project-toolbar">
|
||||
<mat-toolbar-row>
|
||||
<button mat-icon-button [matMenuTriggerFor]="mainMenu"><mat-icon svgIcon="gns3"></mat-icon></button>
|
||||
<button matTooltip="Open menu" mat-icon-button [matMenuTriggerFor]="mainMenu"><mat-icon svgIcon="gns3"></mat-icon></button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-menu #mainMenu="matMenu" [overlapTrigger]="false">
|
||||
@ -48,7 +48,7 @@
|
||||
</mat-menu>
|
||||
|
||||
<mat-toolbar-row>
|
||||
<button mat-icon-button [matMenuTriggerFor]="viewMenu"><mat-icon>view_module</mat-icon></button>
|
||||
<button matTooltip="Show/hide interface labels" mat-icon-button [matMenuTriggerFor]="viewMenu"><mat-icon>view_module</mat-icon></button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-menu #viewMenu="matMenu" [overlapTrigger]="false">
|
||||
@ -60,13 +60,13 @@
|
||||
</mat-menu>
|
||||
|
||||
<mat-toolbar-row *ngIf="!readonly">
|
||||
<button mat-icon-button [color]="tools.draw_link ? 'primary' : 'basic'" (click)="toggleDrawLineMode()">
|
||||
<button matTooltip="Add a link" mat-icon-button [color]="tools.draw_link ? 'primary' : 'basic'" (click)="toggleDrawLineMode()">
|
||||
<mat-icon>timeline</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-toolbar-row>
|
||||
<button mat-icon-button [color]="tools.moving ? 'primary' : 'basic'" (click)="toggleMovingMode()">
|
||||
<button matTooltip="Enable/disable moving mode" mat-icon-button [color]="tools.moving ? 'primary' : 'basic'" (click)="toggleMovingMode()">
|
||||
<mat-icon>zoom_out_map</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
@ -80,7 +80,7 @@
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-toolbar-row *ngIf="!readonly">
|
||||
<button mat-icon-button routerLink="/server/{{server.id}}/preferences">
|
||||
<button matTooltip="Go to preferences" mat-icon-button routerLink="/server/{{server.id}}/preferences">
|
||||
<mat-icon>settings_applications</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
@ -92,6 +92,8 @@
|
||||
</div>
|
||||
|
||||
<div id="menu-wrapper" [ngClass]="{ extended: drawTools.visibility }">
|
||||
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
|
||||
<mat-divider class="style-fix" [vertical]="true"></mat-divider>
|
||||
<button
|
||||
matTooltip="Add a note"
|
||||
mat-icon-button
|
||||
@ -119,7 +121,7 @@
|
||||
>
|
||||
<mat-icon>panorama_fish_eye</mat-icon>
|
||||
</button>
|
||||
<button matTooltip="Draw line" mat-icon-button class="menu-button" (click)="addDrawing('line')">
|
||||
<button matTooltip="Draw a line" mat-icon-button class="menu-button" (click)="addDrawing('line')">
|
||||
<svg height="40" width="40">
|
||||
<line
|
||||
[ngClass]="{ selected: drawTools.isLineChosen }"
|
||||
|
@ -53,6 +53,7 @@ g.node:hover {
|
||||
overflow: hidden;
|
||||
transition: 0.15s;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
display: flex;
|
||||
|
||||
.menu-button {
|
||||
outline: 0 !important;
|
||||
@ -75,11 +76,18 @@ g.node:hover {
|
||||
}
|
||||
|
||||
.extended {
|
||||
width: 296px !important;
|
||||
width: 570px !important;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
mat-divider.style-fix {
|
||||
height: 40px;
|
||||
margin-left: 1px;
|
||||
margin-right: 7px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
/** fixes gray background of drawing menu on Firefox **/
|
||||
.mat-drawer-content {
|
||||
|
@ -39,6 +39,7 @@ import { SelectionTool } from '../../cartography/tools/selection-tool';
|
||||
import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProject.service';
|
||||
import { MapLinkToLinkConverter } from '../../cartography/converters/map/map-link-to-link-converter';
|
||||
import { Link } from '../../models/link';
|
||||
import { Project } from '../..//models/project';
|
||||
|
||||
export class MockedProgressService {
|
||||
public activate() {}
|
||||
@ -59,6 +60,22 @@ export class MockedNodeService {
|
||||
delete(server: Server, node: Node) {
|
||||
return of();
|
||||
}
|
||||
|
||||
startAll(server: Server, project: Project) {
|
||||
return of();
|
||||
}
|
||||
|
||||
stopAll(server: Server, project: Project) {
|
||||
return of();
|
||||
}
|
||||
|
||||
suspendAll(server: Server, project: Project) {
|
||||
return of();
|
||||
}
|
||||
|
||||
reloadAll(server: Server, project: Project) {
|
||||
return of();
|
||||
}
|
||||
}
|
||||
|
||||
export class MockedDrawingService {
|
||||
|
@ -1 +1 @@
|
||||
<button mat-icon-button (click)="createSnapshotModal()"><mat-icon>snooze</mat-icon></button>
|
||||
<button matTooltip="Manage snapshots" mat-icon-button (click)="createSnapshotModal()"><mat-icon>snooze</mat-icon></button>
|
||||
|
@ -1 +1 @@
|
||||
<button mat-icon-button (click)="listTemplatesModal()"><mat-icon>add_to_queue</mat-icon></button>
|
||||
<button matTooltip="Browse all devices" mat-icon-button (click)="listTemplatesModal()"><mat-icon>add_to_queue</mat-icon></button>
|
||||
|
@ -64,6 +64,54 @@ describe('NodeService', () => {
|
||||
expect(req.request.body).toEqual({});
|
||||
}));
|
||||
|
||||
it('should start all nodes', inject([NodeService], (service: NodeService) => {
|
||||
let project = {
|
||||
project_id: '1'
|
||||
} as Project;
|
||||
|
||||
service.startAll(server, project).subscribe();
|
||||
|
||||
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v2/projects/1/nodes/start');
|
||||
expect(req.request.method).toEqual('POST');
|
||||
expect(req.request.body).toEqual({});
|
||||
}));
|
||||
|
||||
it('should stop all nodes', inject([NodeService], (service: NodeService) => {
|
||||
let project = {
|
||||
project_id: '1'
|
||||
} as Project;
|
||||
|
||||
service.stopAll(server, project).subscribe();
|
||||
|
||||
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v2/projects/1/nodes/stop');
|
||||
expect(req.request.method).toEqual('POST');
|
||||
expect(req.request.body).toEqual({});
|
||||
}));
|
||||
|
||||
it('should suspend all nodes', inject([NodeService], (service: NodeService) => {
|
||||
let project = {
|
||||
project_id: '1'
|
||||
} as Project;
|
||||
|
||||
service.suspendAll(server, project).subscribe();
|
||||
|
||||
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v2/projects/1/nodes/suspend');
|
||||
expect(req.request.method).toEqual('POST');
|
||||
expect(req.request.body).toEqual({});
|
||||
}));
|
||||
|
||||
it('should reload all nodes', inject([NodeService], (service: NodeService) => {
|
||||
let project = {
|
||||
project_id: '1'
|
||||
} as Project;
|
||||
|
||||
service.reloadAll(server, project).subscribe();
|
||||
|
||||
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v2/projects/1/nodes/reload');
|
||||
expect(req.request.method).toEqual('POST');
|
||||
expect(req.request.body).toEqual({});
|
||||
}));
|
||||
|
||||
it('should createFromTemplate node', inject([NodeService], (service: NodeService) => {
|
||||
const project = new Project();
|
||||
project.project_id = 'myproject';
|
||||
|
@ -17,10 +17,26 @@ export class NodeService {
|
||||
return this.httpServer.post<Node>(server, `/projects/${node.project_id}/nodes/${node.node_id}/start`, {});
|
||||
}
|
||||
|
||||
startAll(server: Server, project: Project) {
|
||||
return this.httpServer.post(server, `/projects/${project.project_id}/nodes/start`, {});
|
||||
}
|
||||
|
||||
stop(server: Server, node: Node) {
|
||||
return this.httpServer.post<Node>(server, `/projects/${node.project_id}/nodes/${node.node_id}/stop`, {});
|
||||
}
|
||||
|
||||
stopAll(server: Server, project: Project) {
|
||||
return this.httpServer.post(server, `/projects/${project.project_id}/nodes/stop`, {});
|
||||
}
|
||||
|
||||
suspendAll(server: Server, project: Project) {
|
||||
return this.httpServer.post(server, `/projects/${project.project_id}/nodes/suspend`, {});
|
||||
}
|
||||
|
||||
reloadAll(server: Server, project: Project) {
|
||||
return this.httpServer.post(server, `/projects/${project.project_id}/nodes/reload`, {});
|
||||
}
|
||||
|
||||
createFromTemplate(server: Server, project: Project, template: Template, x: number, y: number, compute_id: string) {
|
||||
return this.httpServer.post(server, `/projects/${project.project_id}/templates/${template.template_id}`, {
|
||||
x: Math.round(x),
|
||||
|
Loading…
x
Reference in New Issue
Block a user