mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-02 16:52:50 +00:00
Merge branch 'master' into Packet-capture-preferences
This commit is contained in:
commit
226a04a638
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gns3-web-ui",
|
"name": "gns3-web-ui",
|
||||||
"version": "2019.1.0-alpha.2dev",
|
"version": "2019.1.0-alpha.3dev",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "GNS3 Technology Inc.",
|
"name": "GNS3 Technology Inc.",
|
||||||
"email": "developers@gns3.com"
|
"email": "developers@gns3.com"
|
||||||
|
@ -211,6 +211,7 @@ def build_command(arguments):
|
|||||||
("gns3server/appliances", "appliances"),
|
("gns3server/appliances", "appliances"),
|
||||||
("gns3server/templates", "templates"),
|
("gns3server/templates", "templates"),
|
||||||
("gns3server/symbols", "symbols"),
|
("gns3server/symbols", "symbols"),
|
||||||
|
("gns3server/static/web-ui", "static/web-ui")
|
||||||
]
|
]
|
||||||
|
|
||||||
include_files = [(os.path.join(source_directory, x), y) for x, y in include_files]
|
include_files = [(os.path.join(source_directory, x), y) for x, y in include_files]
|
||||||
|
@ -120,6 +120,10 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'server/:server_id/project/:project_id', component: ProjectMapComponent,
|
path: 'server/:server_id/project/:project_id', component: ProjectMapComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '**',
|
||||||
|
redirectTo: 'servers'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { ServerService } from '../../services/server.service';
|
|||||||
import { MockedServerService } from '../../services/server.service.spec';
|
import { MockedServerService } from '../../services/server.service.spec';
|
||||||
import { Server } from '../../models/server';
|
import { Server } from '../../models/server';
|
||||||
|
|
||||||
|
|
||||||
describe('LocalServerComponent', () => {
|
describe('LocalServerComponent', () => {
|
||||||
let component: LocalServerComponent;
|
let component: LocalServerComponent;
|
||||||
let fixture: ComponentFixture<LocalServerComponent>;
|
let fixture: ComponentFixture<LocalServerComponent>;
|
||||||
@ -24,7 +25,8 @@ describe('LocalServerComponent', () => {
|
|||||||
spyOn(serverService, 'getLocalServer').and.returnValue(Promise.resolve(server));
|
spyOn(serverService, 'getLocalServer').and.returnValue(Promise.resolve(server));
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [{ provide: Router, useValue: router }, { provide: ServerService, useValue: serverService }],
|
providers: [{ provide: Router, useValue: router },
|
||||||
|
{ provide: ServerService, useValue: serverService }],
|
||||||
declarations: [LocalServerComponent]
|
declarations: [LocalServerComponent]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { ServerService } from '../../services/server.service';
|
import { ServerService } from '../../services/server.service';
|
||||||
import { Server } from '../../models/server';
|
import { Server } from '../../models/server';
|
||||||
|
import { DOCUMENT } from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-local-server',
|
selector: 'app-local-server',
|
||||||
@ -10,10 +11,16 @@ import { Server } from '../../models/server';
|
|||||||
styleUrls: ['./local-server.component.scss']
|
styleUrls: ['./local-server.component.scss']
|
||||||
})
|
})
|
||||||
export class LocalServerComponent implements OnInit {
|
export class LocalServerComponent implements OnInit {
|
||||||
constructor(private router: Router, private serverService: ServerService) {}
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private serverService: ServerService,
|
||||||
|
@Inject(DOCUMENT) private document) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serverService.getLocalServer(location.hostname, parseInt(location.port, 10)).then((server: Server) => {
|
this.serverService.getLocalServer(
|
||||||
|
this.document.location.hostname,
|
||||||
|
parseInt(this.document.location.port, 10))
|
||||||
|
.then((server: Server) => {
|
||||||
this.router.navigate(['/server', server.id, 'projects']);
|
this.router.navigate(['/server', server.id, 'projects']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
<div id="menu-wrapper" [ngClass]="{ extended: drawTools.visibility }">
|
<div id="menu-wrapper" [ngClass]="{ extended: drawTools.visibility }">
|
||||||
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
|
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
|
||||||
<mat-divider class="style-fix" [vertical]="true"></mat-divider>
|
<mat-divider class="divider" [vertical]="true"></mat-divider>
|
||||||
<button
|
<button
|
||||||
matTooltip="Add a note"
|
matTooltip="Add a note"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
@ -81,11 +81,12 @@ g.node:hover {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-divider.style-fix {
|
mat-divider.divider {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-moz-document url-prefix() {
|
@-moz-document url-prefix() {
|
||||||
|
@ -3,9 +3,14 @@
|
|||||||
<button mat-button class="top-button" color="accent" (click)="onNoClick()" routerLink="/server/{{server.id}}/project/{{project.project_id}}/snapshots">Go to snapshots</button>
|
<button mat-button class="top-button" color="accent" (click)="onNoClick()" routerLink="/server/{{server.id}}/project/{{project.project_id}}/snapshots">Go to snapshots</button>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field class="name-input">
|
<form [formGroup]="inputForm">
|
||||||
<input matInput tabindex="1" [(ngModel)]="snapshot.name" placeholder="Name" />
|
<mat-form-field class="name-input">
|
||||||
</mat-form-field>
|
<input
|
||||||
|
matInput tabindex="1"
|
||||||
|
formControlName="snapshotName"
|
||||||
|
placeholder="Name" />
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-button (click)="onNoClick()" tabindex="-1" color="accent">No Thanks</button>
|
<button mat-button (click)="onNoClick()" tabindex="-1" color="accent">No Thanks</button>
|
||||||
|
@ -3,6 +3,11 @@ import { Snapshot } from '../../../models/snapshot';
|
|||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
import { Server } from '../../../models/server';
|
import { Server } from '../../../models/server';
|
||||||
import { Project } from '../../../models/project';
|
import { Project } from '../../../models/project';
|
||||||
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
|
import { ToasterService } from '../../../services/toaster.service';
|
||||||
|
import { SnapshotService } from '../../../services/snapshot.service';
|
||||||
|
import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource';
|
||||||
|
import { Node } from '../../../cartography/models/node';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -14,17 +19,53 @@ export class CreateSnapshotDialogComponent {
|
|||||||
server: Server;
|
server: Server;
|
||||||
project: Project;
|
project: Project;
|
||||||
snapshot: Snapshot = new Snapshot();
|
snapshot: Snapshot = new Snapshot();
|
||||||
|
inputForm: FormGroup;
|
||||||
|
snapshots: string[] = [];
|
||||||
|
isInRunningState: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<CreateSnapshotDialogComponent>,
|
public dialogRef: MatDialogRef<CreateSnapshotDialogComponent>,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private toasterService: ToasterService,
|
||||||
|
private snapshotService: SnapshotService,
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any
|
@Inject(MAT_DIALOG_DATA) public data: any
|
||||||
) {
|
) {
|
||||||
this.server = data['server'];
|
this.server = data['server'];
|
||||||
this.project = data['project'];
|
this.project = data['project'];
|
||||||
|
|
||||||
|
this.inputForm = this.formBuilder.group({
|
||||||
|
snapshotName: new FormControl('', Validators.required)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.snapshotService.list(this.server, this.project.project_id).subscribe((snapshots: Snapshot[]) => {
|
||||||
|
snapshots.forEach((snapshot: Snapshot) => {
|
||||||
|
this.snapshots.push(snapshot.name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.nodesDataSource.getItems().forEach((node: Node) => {
|
||||||
|
if (node.status !== 'stopped' && !this.isAlwaysRunningNode(node.node_type)) {
|
||||||
|
this.isInRunningState = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isAlwaysRunningNode(nodeType: string) {
|
||||||
|
return !["qemu", "docker", "dynamips", "vpcs", "vmware", "virtualbox", "iou", "traceng"].includes(nodeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddClick(): void {
|
onAddClick(): void {
|
||||||
this.dialogRef.close(this.snapshot);
|
if (this.inputForm.invalid) {
|
||||||
|
this.toasterService.error(`Fill all required fields`);
|
||||||
|
} else if (this.snapshots.includes(this.inputForm.get('snapshotName').value)) {
|
||||||
|
this.toasterService.error(`Snapshot with this name already exists`);
|
||||||
|
} else if (this.isInRunningState) {
|
||||||
|
this.toasterService.error(`Project must be stopped in order to export it`);
|
||||||
|
} else {
|
||||||
|
this.snapshot.name = this.inputForm.get('snapshotName').value;
|
||||||
|
this.dialogRef.close(this.snapshot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
|
@ -151,7 +151,7 @@ describe('ServerService', () => {
|
|||||||
expectedServer.name = 'local';
|
expectedServer.name = 'local';
|
||||||
expectedServer.host = 'hostname';
|
expectedServer.host = 'hostname';
|
||||||
expectedServer.port = 9999;
|
expectedServer.port = 9999;
|
||||||
expectedServer.location = 'local';
|
expectedServer.location = 'remote';
|
||||||
expectedServer.is_local = true;
|
expectedServer.is_local = true;
|
||||||
|
|
||||||
service.getLocalServer('hostname', 9999).then(() => {
|
service.getLocalServer('hostname', 9999).then(() => {
|
||||||
|
@ -70,7 +70,7 @@ export class ServerService {
|
|||||||
server.name = 'local';
|
server.name = 'local';
|
||||||
server.host = host;
|
server.host = host;
|
||||||
server.port = port;
|
server.port = port;
|
||||||
server.location = 'local';
|
server.location = 'remote';
|
||||||
server.is_local = true;
|
server.is_local = true;
|
||||||
this.create(server).then(created => {
|
this.create(server).then(created => {
|
||||||
resolve(created);
|
resolve(created);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user