Actions for all nodes added

This commit is contained in:
Piotr Pekala 2019-03-11 04:35:27 -07:00
parent f3ef8dc273
commit 8cda33c0d9
12 changed files with 265 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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