mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-31 08:25:35 +00:00
Progress screen
This commit is contained in:
parent
0cb1b4197a
commit
934c2f9933
@ -6,7 +6,7 @@ import { RouterModule, Routes } from '@angular/router';
|
|||||||
import { ProjectMapComponent } from './project-map/project-map.component';
|
import { ProjectMapComponent } from './project-map/project-map.component';
|
||||||
import { ServersComponent } from "./servers/servers.component";
|
import { ServersComponent } from "./servers/servers.component";
|
||||||
import { ProjectsComponent } from "./projects/projects.component";
|
import { ProjectsComponent } from "./projects/projects.component";
|
||||||
import { DefaultLayoutComponent } from "./default-layout/default-layout.component";
|
import { DefaultLayoutComponent } from "./layouts/default-layout/default-layout.component";
|
||||||
import { SettingsComponent } from "./settings/settings.component";
|
import { SettingsComponent } from "./settings/settings.component";
|
||||||
import { LocalServerComponent } from "./local-server/local-server.component";
|
import { LocalServerComponent } from "./local-server/local-server.component";
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@ import {
|
|||||||
MatListModule,
|
MatListModule,
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatSelectModule
|
MatSelectModule,
|
||||||
|
MatTooltipModule
|
||||||
} from '@angular/material';
|
} from '@angular/material';
|
||||||
|
|
||||||
import { D3Service } from 'd3-ng2-service';
|
import { D3Service } from 'd3-ng2-service';
|
||||||
@ -47,7 +48,7 @@ import { ApplianceService } from "./shared/services/appliance.service";
|
|||||||
import { LinkService } from "./shared/services/link.service";
|
import { LinkService } from "./shared/services/link.service";
|
||||||
|
|
||||||
import { ProjectsComponent } from './projects/projects.component';
|
import { ProjectsComponent } from './projects/projects.component';
|
||||||
import { DefaultLayoutComponent } from './default-layout/default-layout.component';
|
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||||
import { ProgressDialogComponent } from './shared/progress-dialog/progress-dialog.component';
|
import { ProgressDialogComponent } from './shared/progress-dialog/progress-dialog.component';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
@ -76,6 +77,8 @@ import { SettingsService } from "./shared/services/settings.service";
|
|||||||
|
|
||||||
import { RavenErrorHandler } from "./raven-error-handler";
|
import { RavenErrorHandler } from "./raven-error-handler";
|
||||||
import { LocalServerComponent } from './local-server/local-server.component';
|
import { LocalServerComponent } from './local-server/local-server.component';
|
||||||
|
import { ProgressComponent } from './progress/progress.component';
|
||||||
|
import { ProgressService } from "./progress/progress.service";
|
||||||
|
|
||||||
Raven
|
Raven
|
||||||
.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726')
|
.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726')
|
||||||
@ -104,6 +107,7 @@ Raven
|
|||||||
ProjectMapShortcutsComponent,
|
ProjectMapShortcutsComponent,
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
LocalServerComponent,
|
LocalServerComponent,
|
||||||
|
ProgressComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
@ -130,6 +134,7 @@ Raven
|
|||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
|
MatTooltipModule,
|
||||||
CartographyModule,
|
CartographyModule,
|
||||||
HotkeyModule.forRoot(),
|
HotkeyModule.forRoot(),
|
||||||
PersistenceModule,
|
PersistenceModule,
|
||||||
@ -151,6 +156,7 @@ Raven
|
|||||||
SnapshotService,
|
SnapshotService,
|
||||||
ProgressDialogService,
|
ProgressDialogService,
|
||||||
ToasterService,
|
ToasterService,
|
||||||
|
ProgressService,
|
||||||
ProjectWebServiceHandler,
|
ProjectWebServiceHandler,
|
||||||
LinksDataSource,
|
LinksDataSource,
|
||||||
NodesDataSource,
|
NodesDataSource,
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<app-progress></app-progress>
|
||||||
|
|
||||||
<footer class="footer mat-app-background">
|
<footer class="footer mat-app-background">
|
||||||
GNS3 Web UI demo © 2018
|
GNS3 Web UI demo © 2018
|
||||||
</footer>
|
</footer>
|
@ -1,16 +1,51 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { LocalServerComponent } from './local-server.component';
|
import { LocalServerComponent } from './local-server.component';
|
||||||
|
import { Location } from "@angular/common";
|
||||||
|
import { RouterTestingModule } from "@angular/router/testing";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ServerService } from "../shared/services/server.service";
|
||||||
|
import { MockedServerService } from "../shared/services/server.service.spec";
|
||||||
|
|
||||||
|
|
||||||
|
class MockedLocation {
|
||||||
|
private _hostname: string;
|
||||||
|
private _port: number;
|
||||||
|
|
||||||
|
get hostname(): string {
|
||||||
|
return this._hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
set hostname(hostname: string) {
|
||||||
|
this._hostname = hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
get port(): number {
|
||||||
|
return this._port;
|
||||||
|
}
|
||||||
|
|
||||||
|
set port(port: number) {
|
||||||
|
this._port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('LocalServerComponent', () => {
|
describe('LocalServerComponent', () => {
|
||||||
let component: LocalServerComponent;
|
let component: LocalServerComponent;
|
||||||
let fixture: ComponentFixture<LocalServerComponent>;
|
let fixture: ComponentFixture<LocalServerComponent>;
|
||||||
|
let router: Router;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ RouterTestingModule.withRoutes([]) ],
|
||||||
|
providers: [
|
||||||
|
{ provide: Location, useClass: MockedLocation},
|
||||||
|
{ provide: ServerService, useClass: MockedServerService }
|
||||||
|
],
|
||||||
declarations: [ LocalServerComponent ]
|
declarations: [ LocalServerComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
|
|
||||||
|
router = TestBed.get(Router);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
8
src/app/progress/progress.component.html
Normal file
8
src/app/progress/progress.component.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div class="overlay" *ngIf="visible">
|
||||||
|
<div class="loading-spinner">
|
||||||
|
<mat-spinner color="primary">
|
||||||
|
</mat-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
18
src/app/progress/progress.component.scss
Normal file
18
src/app/progress/progress.component.scss
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.overlay {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
25
src/app/progress/progress.component.spec.ts
Normal file
25
src/app/progress/progress.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ProgressComponent } from './progress.component';
|
||||||
|
|
||||||
|
describe('ProgressComponent', () => {
|
||||||
|
let component: ProgressComponent;
|
||||||
|
let fixture: ComponentFixture<ProgressComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ProgressComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ProgressComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
22
src/app/progress/progress.component.ts
Normal file
22
src/app/progress/progress.component.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ProgressService } from "./progress.service";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-progress',
|
||||||
|
templateUrl: './progress.component.html',
|
||||||
|
styleUrls: ['./progress.component.scss']
|
||||||
|
})
|
||||||
|
export class ProgressComponent implements OnInit {
|
||||||
|
visible = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private progressService: ProgressService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.progressService.state.subscribe((state) => {
|
||||||
|
this.visible = state.visible;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/app/progress/progress.service.spec.ts
Normal file
15
src/app/progress/progress.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ProgressService } from './progress.service';
|
||||||
|
|
||||||
|
describe('ProgressService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [ProgressService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([ProgressService], (service: ProgressService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
28
src/app/progress/progress.service.ts
Normal file
28
src/app/progress/progress.service.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { BehaviorSubject } from "rxjs/BehaviorSubject";
|
||||||
|
|
||||||
|
|
||||||
|
export class State {
|
||||||
|
public visible: boolean;
|
||||||
|
|
||||||
|
constructor(visible: boolean) {
|
||||||
|
this.visible = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ProgressService {
|
||||||
|
state = new BehaviorSubject<State>(new State(false));
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
public activate() {
|
||||||
|
this.state.next(new State(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public deactivate() {
|
||||||
|
this.state.next(new State(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,7 +17,13 @@
|
|||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row" style="text-align: right">
|
<mat-cell *matCellDef="let row" style="text-align: right">
|
||||||
<button mat-icon-button (click)="delete(row)" *ngIf="settings.experimental_features">
|
<button mat-icon-button matTooltip="Open project" (click)="open(row)" *ngIf="row.status == 'closed'">
|
||||||
|
<mat-icon aria-label="Open project">play_arrow</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button matTooltip="Close project" (click)="close(row)" *ngIf="row.status == 'opened'">
|
||||||
|
<mat-icon aria-label="Close project">pause</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button matTooltip="Delete project" (click)="delete(row)" *ngIf="settings.experimental_features">
|
||||||
<mat-icon aria-label="Delete project">delete</mat-icon>
|
<mat-icon aria-label="Delete project">delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -10,6 +10,7 @@ import { BehaviorSubject } from "rxjs/BehaviorSubject";
|
|||||||
import { DataSource } from "@angular/cdk/collections";
|
import { DataSource } from "@angular/cdk/collections";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
import { SettingsService, Settings } from "../shared/services/settings.service";
|
import { SettingsService, Settings } from "../shared/services/settings.service";
|
||||||
|
import { ProgressService } from "../progress/progress.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -29,7 +30,8 @@ export class ProjectsComponent implements OnInit {
|
|||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private serverService: ServerService,
|
private serverService: ServerService,
|
||||||
private projectService: ProjectService,
|
private projectService: ProjectService,
|
||||||
private settingsService: SettingsService
|
private settingsService: SettingsService,
|
||||||
|
private progressService: ProgressService
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -65,6 +67,23 @@ export class ProjectsComponent implements OnInit {
|
|||||||
this.projectDatabase.remove(project);
|
this.projectDatabase.remove(project);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open(project: Project) {
|
||||||
|
this.progressService.activate();
|
||||||
|
|
||||||
|
this.projectService.open(this.server, project.project_id).subscribe(() => {
|
||||||
|
}, () => {}, () => {
|
||||||
|
this.progressService.deactivate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
close(project: Project) {
|
||||||
|
this.progressService.activate();
|
||||||
|
|
||||||
|
this.projectService.close(this.server, project.project_id).subscribe(() => {}, () => {}, () => {
|
||||||
|
this.progressService.deactivate();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,6 +71,16 @@ describe('ProjectService', () => {
|
|||||||
expect(req.request.body).toEqual({});
|
expect(req.request.body).toEqual({});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should close the project', inject([ProjectService], (service: ProjectService) => {
|
||||||
|
service.close(server, "myproject").subscribe();
|
||||||
|
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
'http://127.0.0.1:3080/v2/projects/myproject/close');
|
||||||
|
expect(req.request.method).toEqual("POST");
|
||||||
|
expect(req.request.body).toEqual({});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should list projects', inject([ProjectService], (service: ProjectService) => {
|
it('should list projects', inject([ProjectService], (service: ProjectService) => {
|
||||||
service.list(server).subscribe();
|
service.list(server).subscribe();
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@ export class ProjectService {
|
|||||||
.post<Project>(server, `/projects/${project_id}/open`, {});
|
.post<Project>(server, `/projects/${project_id}/open`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(server: Server, project_id: string) {
|
||||||
|
return this.httpServer
|
||||||
|
.post<Project>(server, `/projects/${project_id}/close`, {});
|
||||||
|
}
|
||||||
|
|
||||||
list(server: Server) {
|
list(server: Server) {
|
||||||
return this.httpServer
|
return this.httpServer
|
||||||
.get<Project[]>(server, '/projects');
|
.get<Project[]>(server, '/projects');
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
import { ServerService } from './server.service';
|
import { ServerService } from './server.service';
|
||||||
|
import { Server } from "../models/server";
|
||||||
|
|
||||||
|
export class MockedServerService {
|
||||||
|
public getLocalServer(hostname: string, port: number) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const server = new Server();
|
||||||
|
server.id = 99;
|
||||||
|
resolve(server);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('ServerService', () => {
|
describe('ServerService', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [ServerService]
|
providers: [ ServerService ]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user