mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-10 04:22:56 +00:00
Appliances list, ref: #14
This commit is contained in:
parent
4caeb2a4c7
commit
084ded34b2
@ -32,6 +32,7 @@ import { HttpServer } from "./shared/services/http-server.service";
|
|||||||
import { SnapshotService } from "./shared/services/snapshot.service";
|
import { SnapshotService } from "./shared/services/snapshot.service";
|
||||||
import { ProgressDialogService } from "./shared/progress-dialog/progress-dialog.service";
|
import { ProgressDialogService } from "./shared/progress-dialog/progress-dialog.service";
|
||||||
import { NodeService } from "./shared/services/node.service";
|
import { NodeService } from "./shared/services/node.service";
|
||||||
|
import { ApplianceService } from "./shared/services/appliance.service";
|
||||||
|
|
||||||
import { ProjectsComponent } from './projects/projects.component';
|
import { ProjectsComponent } from './projects/projects.component';
|
||||||
import { DefaultLayoutComponent } from './default-layout/default-layout.component';
|
import { DefaultLayoutComponent } from './default-layout/default-layout.component';
|
||||||
@ -43,6 +44,8 @@ import { ServersComponent, AddServerDialogComponent } from './servers/servers.co
|
|||||||
import { NodeContextMenuComponent } from './shared/node-context-menu/node-context-menu.component';
|
import { NodeContextMenuComponent } from './shared/node-context-menu/node-context-menu.component';
|
||||||
import { StartNodeActionComponent } from './shared/node-context-menu/actions/start-node-action/start-node-action.component';
|
import { StartNodeActionComponent } from './shared/node-context-menu/actions/start-node-action/start-node-action.component';
|
||||||
import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop-node-action/stop-node-action.component';
|
import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop-node-action/stop-node-action.component';
|
||||||
|
import { ApplianceComponent } from './appliance/appliance.component';
|
||||||
|
import { ApplianceListDialogComponent } from './appliance/appliance-list-dialog/appliance-list-dialog.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -59,6 +62,8 @@ import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop
|
|||||||
NodeContextMenuComponent,
|
NodeContextMenuComponent,
|
||||||
StartNodeActionComponent,
|
StartNodeActionComponent,
|
||||||
StopNodeActionComponent,
|
StopNodeActionComponent,
|
||||||
|
ApplianceComponent,
|
||||||
|
ApplianceListDialogComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
@ -86,6 +91,7 @@ import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop
|
|||||||
ProjectService,
|
ProjectService,
|
||||||
SymbolService,
|
SymbolService,
|
||||||
ServerService,
|
ServerService,
|
||||||
|
ApplianceService,
|
||||||
NodeService,
|
NodeService,
|
||||||
IndexedDbService,
|
IndexedDbService,
|
||||||
HttpServer,
|
HttpServer,
|
||||||
@ -95,7 +101,8 @@ import { StopNodeActionComponent } from './shared/node-context-menu/actions/stop
|
|||||||
entryComponents: [
|
entryComponents: [
|
||||||
AddServerDialogComponent,
|
AddServerDialogComponent,
|
||||||
CreateSnapshotDialogComponent,
|
CreateSnapshotDialogComponent,
|
||||||
ProgressDialogComponent
|
ProgressDialogComponent,
|
||||||
|
ApplianceListDialogComponent
|
||||||
],
|
],
|
||||||
bootstrap: [ AppComponent ]
|
bootstrap: [ AppComponent ]
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
<h1 mat-dialog-title>Appliances list</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<mat-table #table [dataSource]="dataSource">
|
||||||
|
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row"> <button [routerLink]="['/server', row.id, 'projects']" mat-button>{{row.name}}</button></mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||||
|
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||||
|
</mat-table>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions>
|
||||||
|
<button mat-button (click)="onNoClick()" tabindex="-1" color="accent">No Thanks</button>
|
||||||
|
<button mat-button (click)="onAddClick()" tabindex="2" mat-raised-button color="primary">Add</button>
|
||||||
|
</div>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ApplianceListDialogComponent } from './appliance-list-dialog.component';
|
||||||
|
|
||||||
|
describe('ApplianceListDialogComponent', () => {
|
||||||
|
let component: ApplianceListDialogComponent;
|
||||||
|
let fixture: ComponentFixture<ApplianceListDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ApplianceListDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ApplianceListDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,53 @@
|
|||||||
|
import {Component, Inject, Input, OnInit} from '@angular/core';
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material";
|
||||||
|
import {DataSource} from "@angular/cdk/collections";
|
||||||
|
import {Observable} from "rxjs/Observable";
|
||||||
|
import {Appliance} from "../../shared/models/appliance";
|
||||||
|
import {ApplianceService} from "../../shared/services/appliance.service";
|
||||||
|
import {Server} from "../../shared/models/server";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-appliance-list-dialog',
|
||||||
|
templateUrl: './appliance-list-dialog.component.html',
|
||||||
|
styleUrls: ['./appliance-list-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class ApplianceListDialogComponent implements OnInit {
|
||||||
|
server: Server;
|
||||||
|
dataSource: ApplianceDataSource;
|
||||||
|
displayedColumns = ['name'];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ApplianceListDialogComponent>,
|
||||||
|
private applianceService: ApplianceService,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||||
|
this.server = data['server'];
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.dataSource = new ApplianceDataSource(this.server, this.applianceService);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class ApplianceDataSource extends DataSource<Appliance> {
|
||||||
|
constructor(private server: Server, private applianceService: ApplianceService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(): Observable<Appliance[]> {
|
||||||
|
return this.applianceService.list(this.server);
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {}
|
||||||
|
|
||||||
|
}
|
3
src/app/appliance/appliance.component.html
Normal file
3
src/app/appliance/appliance.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<button mat-icon-button (click)="listAppliancesModal()">
|
||||||
|
<mat-icon>add_to_queue</mat-icon>
|
||||||
|
</button>
|
0
src/app/appliance/appliance.component.scss
Normal file
0
src/app/appliance/appliance.component.scss
Normal file
25
src/app/appliance/appliance.component.spec.ts
Normal file
25
src/app/appliance/appliance.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ApplianceComponent } from './appliance.component';
|
||||||
|
|
||||||
|
describe('ApplianceComponent', () => {
|
||||||
|
let component: ApplianceComponent;
|
||||||
|
let fixture: ComponentFixture<ApplianceComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ApplianceComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ApplianceComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
33
src/app/appliance/appliance.component.ts
Normal file
33
src/app/appliance/appliance.component.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
import {MatDialog} from "@angular/material";
|
||||||
|
import {ApplianceListDialogComponent} from "./appliance-list-dialog/appliance-list-dialog.component";
|
||||||
|
|
||||||
|
import {Server} from "../shared/models/server";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-appliance',
|
||||||
|
templateUrl: './appliance.component.html',
|
||||||
|
styleUrls: ['./appliance.component.scss']
|
||||||
|
})
|
||||||
|
export class ApplianceComponent implements OnInit {
|
||||||
|
@Input() server: Server;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private dialog: MatDialog) { }
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
listAppliancesModal() {
|
||||||
|
const dialogRef = this.dialog.open(ApplianceListDialogComponent, {
|
||||||
|
width: '600px',
|
||||||
|
data: {
|
||||||
|
'server': this.server
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
|
||||||
|
<mat-toolbar-row>
|
||||||
|
<app-appliance [server]="server"></app-appliance>
|
||||||
|
</mat-toolbar-row>
|
||||||
|
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
10
src/app/shared/models/appliance.ts
Normal file
10
src/app/shared/models/appliance.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export class Appliance {
|
||||||
|
appliance_id: string;
|
||||||
|
builtin: boolean;
|
||||||
|
category: string;
|
||||||
|
compute_id: string;
|
||||||
|
default_name_format: string;
|
||||||
|
name: string;
|
||||||
|
node_type: string;
|
||||||
|
symbol: string;
|
||||||
|
}
|
15
src/app/shared/services/appliance.service.spec.ts
Normal file
15
src/app/shared/services/appliance.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ApplianceService } from './appliance.service';
|
||||||
|
|
||||||
|
describe('ApplianceService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [ApplianceService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([ApplianceService], (service: ApplianceService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
20
src/app/shared/services/appliance.service.ts
Normal file
20
src/app/shared/services/appliance.service.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
import { Server } from "../models/server";
|
||||||
|
import { HttpServer } from "./http-server.service";
|
||||||
|
import {Appliance} from "../models/appliance";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ApplianceService {
|
||||||
|
|
||||||
|
constructor(private httpServer: HttpServer) { }
|
||||||
|
|
||||||
|
list(server: Server): Observable<Appliance[]> {
|
||||||
|
return this.httpServer
|
||||||
|
.get(server, '/appliances')
|
||||||
|
.map(response => response.json() as Appliance[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,6 +6,7 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
import { Server } from "../models/server";
|
import { Server } from "../models/server";
|
||||||
import { HttpServer } from "./http-server.service";
|
import { HttpServer } from "./http-server.service";
|
||||||
|
import {Appliance} from "../models/appliance";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -25,4 +26,10 @@ export class NodeService {
|
|||||||
.map(response => response.json() as Node);
|
.map(response => response.json() as Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createFromAppliance(server: Server, project: Project, appliance: Appliance): Observable<Node> {
|
||||||
|
return this.httpServer
|
||||||
|
.post(server, `/projects/${project.project_id}/appliances/${appliance.appliance_id}`, {})
|
||||||
|
.map(response => response.json() as Node);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user