mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-20 11:38:59 +00:00
Merge branch 'master' into Node-information-dialog-improvements
This commit is contained in:
commit
ca3045d236
@ -149,7 +149,7 @@ const routes: Routes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled'})],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class AppRoutingModule {}
|
export class AppRoutingModule {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as Raven from 'raven-js';
|
import * as Raven from 'raven-js';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule, Title } from '@angular/platform-browser';
|
||||||
import { NgModule, ErrorHandler } from '@angular/core';
|
import { NgModule, ErrorHandler } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { CdkTableModule } from '@angular/cdk/table';
|
import { CdkTableModule } from '@angular/cdk/table';
|
||||||
@ -538,7 +538,8 @@ if (environment.production) {
|
|||||||
NotificationService,
|
NotificationService,
|
||||||
Gns3vmService,
|
Gns3vmService,
|
||||||
ThemeService,
|
ThemeService,
|
||||||
GoogleAnalyticsService
|
GoogleAnalyticsService,
|
||||||
|
Title
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
AddServerDialogComponent,
|
AddServerDialogComponent,
|
||||||
@ -580,7 +581,8 @@ if (environment.production) {
|
|||||||
NavigationDialogComponent,
|
NavigationDialogComponent,
|
||||||
ScreenshotDialogComponent,
|
ScreenshotDialogComponent,
|
||||||
ConfirmationBottomSheetComponent,
|
ConfirmationBottomSheetComponent,
|
||||||
ConfigDialogComponent
|
ConfigDialogComponent,
|
||||||
|
AdbutlerComponent
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -9,7 +9,8 @@ export class ProgressDialogService {
|
|||||||
public open() {
|
public open() {
|
||||||
const ref = this.dialog.open(ProgressDialogComponent, {
|
const ref = this.dialog.open(ProgressDialogComponent, {
|
||||||
width: '250px',
|
width: '250px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,12 @@ import { ToasterService } from '../../services/toaster.service';
|
|||||||
})
|
})
|
||||||
export class AdbutlerComponent implements OnInit {
|
export class AdbutlerComponent implements OnInit {
|
||||||
@ViewChild('ad', {static: false}) ad: ElementRef;
|
@ViewChild('ad', {static: false}) ad: ElementRef;
|
||||||
@Input() theme: string;
|
theme: string;
|
||||||
@Output() onLoad = new EventEmitter();
|
onLoad = new EventEmitter();
|
||||||
htmlCode: string;
|
htmlCode: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient
|
||||||
private toasterService: ToasterService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<mat-progress-bar mode="determinate" [value]="progress"></mat-progress-bar>
|
<mat-progress-bar mode="determinate" [value]="progress"></mat-progress-bar>
|
||||||
<div style="display: flex; height: 102px;">
|
<div style="display: flex; height: 102px;">
|
||||||
<div class="content" [ngClass]="{lightTheme: isLightThemeEnabled}">
|
<div class="content" [ngClass]="{lightTheme: isLightThemeEnabled}">
|
||||||
<app-adbutler (onLoad)="onLoadingAdbutler($event)" theme="dark"></app-adbutler>
|
<template #dynamicComponentContainer></template>
|
||||||
<mat-icon (click)="closeNotification()" class="close-button">close</mat-icon>
|
<mat-icon (click)="closeNotification()" class="close-button">close</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit, OnDestroy, ComponentFactoryResolver, ViewContainerRef, ViewChild } from '@angular/core';
|
||||||
import { timer, Observable, Subscription } from 'rxjs';
|
import { timer, Observable, Subscription } from 'rxjs';
|
||||||
import { ThemeService } from '../../services/theme.service';
|
import { ThemeService } from '../../services/theme.service';
|
||||||
|
import { AdbutlerComponent } from '../adbutler/adbutler.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-notification-box',
|
selector: 'app-notification-box',
|
||||||
@ -8,6 +9,8 @@ import { ThemeService } from '../../services/theme.service';
|
|||||||
styleUrls: ['./notification-box.component.scss']
|
styleUrls: ['./notification-box.component.scss']
|
||||||
})
|
})
|
||||||
export class NotificationBoxComponent implements OnInit, OnDestroy {
|
export class NotificationBoxComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild('dynamicComponentContainer', {read: ViewContainerRef, static: false}) dynamicComponentContainer;
|
||||||
|
|
||||||
timer: Observable<number>;
|
timer: Observable<number>;
|
||||||
viewTimer: Observable<number>;
|
viewTimer: Observable<number>;
|
||||||
timerSubscription: Subscription;
|
timerSubscription: Subscription;
|
||||||
@ -26,7 +29,9 @@ export class NotificationBoxComponent implements OnInit, OnDestroy {
|
|||||||
isLightThemeEnabled: boolean = false;
|
isLightThemeEnabled: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private themeService: ThemeService
|
private themeService: ThemeService,
|
||||||
|
private componentFactoryResolver: ComponentFactoryResolver,
|
||||||
|
private viewContainerRef: ViewContainerRef
|
||||||
){}
|
){}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -34,6 +39,20 @@ export class NotificationBoxComponent implements OnInit, OnDestroy {
|
|||||||
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.createDynamicAdComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
createDynamicAdComponent() : void {
|
||||||
|
const factory = this.componentFactoryResolver.resolveComponentFactory(AdbutlerComponent);
|
||||||
|
const componentRef = this.dynamicComponentContainer.createComponent(factory);
|
||||||
|
componentRef.instance.theme = this.themeService.getActualTheme() === 'light';
|
||||||
|
componentRef.instance.onLoad.subscribe(event => {
|
||||||
|
this.onLoadingAdbutler(event);
|
||||||
|
})
|
||||||
|
componentRef.changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
startTimer() {
|
startTimer() {
|
||||||
this.timer = timer(this.delayTime, 1000);
|
this.timer = timer(this.delayTime, 1000);
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ export class DeleteTemplateComponent {
|
|||||||
data: {
|
data: {
|
||||||
templateName: templateName
|
templateName: templateName
|
||||||
},
|
},
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
||||||
|
@ -20,7 +20,8 @@ export class ChangeSymbolActionComponent implements OnInit {
|
|||||||
const dialogRef = this.dialog.open(ChangeSymbolDialogComponent, {
|
const dialogRef = this.dialog.open(ChangeSymbolDialogComponent, {
|
||||||
width: '1000px',
|
width: '1000px',
|
||||||
height: '500px',
|
height: '500px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -27,7 +27,8 @@ export class ConfigActionComponent {
|
|||||||
@Input() node: Node;
|
@Input() node: Node;
|
||||||
private conf = {
|
private conf = {
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
width: '800px'
|
width: '800px',
|
||||||
|
disableClose: true
|
||||||
};
|
};
|
||||||
dialogRef;
|
dialogRef;
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ export class EditConfigActionComponent {
|
|||||||
const dialogRef = this.dialog.open(ConfigEditorDialogComponent, {
|
const dialogRef = this.dialog.open(ConfigEditorDialogComponent, {
|
||||||
width: '600px',
|
width: '600px',
|
||||||
height: '500px',
|
height: '500px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -25,7 +25,8 @@ export class EditStyleActionComponent implements OnChanges {
|
|||||||
editStyle() {
|
editStyle() {
|
||||||
const dialogRef = this.dialog.open(StyleEditorDialogComponent, {
|
const dialogRef = this.dialog.open(StyleEditorDialogComponent, {
|
||||||
width: '800px',
|
width: '800px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -29,7 +29,8 @@ export class EditTextActionComponent implements OnInit {
|
|||||||
editText() {
|
editText() {
|
||||||
const dialogRef = this.dialog.open(TextEditorDialogComponent, {
|
const dialogRef = this.dialog.open(TextEditorDialogComponent, {
|
||||||
width: '300px',
|
width: '300px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -26,7 +26,8 @@ export class ExportConfigActionComponent {
|
|||||||
} else {
|
} else {
|
||||||
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
||||||
width: '500px',
|
width: '500px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
dialogRef.afterClosed().subscribe((configType: string) => {
|
dialogRef.afterClosed().subscribe((configType: string) => {
|
||||||
|
@ -27,7 +27,8 @@ export class ImportConfigActionComponent {
|
|||||||
if (this.node.node_type !== 'vpcs') {
|
if (this.node.node_type !== 'vpcs') {
|
||||||
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
||||||
width: '500px',
|
width: '500px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
dialogRef.afterClosed().subscribe((configType: string) => {
|
dialogRef.afterClosed().subscribe((configType: string) => {
|
||||||
|
@ -20,7 +20,8 @@ export class PacketFiltersActionComponent {
|
|||||||
const dialogRef = this.dialog.open(PacketFiltersDialogComponent, {
|
const dialogRef = this.dialog.open(PacketFiltersDialogComponent, {
|
||||||
width: '900px',
|
width: '900px',
|
||||||
height: '400px',
|
height: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -18,7 +18,8 @@ export class ShowNodeActionComponent {
|
|||||||
const dialogRef = this.dialog.open(InfoDialogComponent, {
|
const dialogRef = this.dialog.open(InfoDialogComponent, {
|
||||||
width: '600px',
|
width: '600px',
|
||||||
maxHeight: '600px',
|
maxHeight: '600px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.node = this.node;
|
instance.node = this.node;
|
||||||
|
@ -19,7 +19,8 @@ export class StartCaptureActionComponent {
|
|||||||
startCapture() {
|
startCapture() {
|
||||||
const dialogRef = this.dialog.open(StartCaptureDialogComponent, {
|
const dialogRef = this.dialog.open(StartCaptureDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -35,7 +35,8 @@ export class ConfiguratorDialogQemuComponent implements OnInit {
|
|||||||
|
|
||||||
private conf = {
|
private conf = {
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
width: '800px'
|
width: '800px',
|
||||||
|
disableClose: true
|
||||||
};
|
};
|
||||||
dialogRefQemuImageCreator;
|
dialogRefQemuImageCreator;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from "@angular/core";
|
import { Component, Input, ChangeDetectionStrategy } from "@angular/core";
|
||||||
import { Project } from '../../../models/project';
|
import { Project } from '../../../models/project';
|
||||||
import { Server } from '../../../models/server';
|
import { Server } from '../../../models/server';
|
||||||
import { NodeService } from '../../../services/node.service';
|
import { NodeService } from '../../../services/node.service';
|
||||||
@ -11,7 +11,8 @@ import { ServerService } from '../../../services/server.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-nodes-menu',
|
selector: 'app-nodes-menu',
|
||||||
templateUrl: './nodes-menu.component.html',
|
templateUrl: './nodes-menu.component.html',
|
||||||
styleUrls: ['./nodes-menu.component.scss']
|
styleUrls: ['./nodes-menu.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class NodesMenuComponent {
|
export class NodesMenuComponent {
|
||||||
@Input('project') project: Project;
|
@Input('project') project: Project;
|
||||||
|
@ -80,7 +80,8 @@ export class PacketFiltersDialogComponent implements OnInit{
|
|||||||
onHelpClick() {
|
onHelpClick() {
|
||||||
const dialogRef = this.dialog.open(HelpDialogComponent, {
|
const dialogRef = this.dialog.open(HelpDialogComponent, {
|
||||||
width: '500px',
|
width: '500px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.title = 'Help for filters';
|
instance.title = 'Help for filters';
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
mat-icon-button
|
mat-icon-button
|
||||||
class="menu-button"
|
class="menu-button"
|
||||||
(click)="addDrawing('text')">
|
(click)="addDrawing('text')">
|
||||||
<mat-icon [ngClass]="{unmarkedLight: !drawTools.isTextChosen && isLightThemeEnabled, marked: drawTools.isTextChosen}">create</mat-icon>
|
<mat-icon [ngClass]="getCssClassForIcon('text')">create</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
@ -23,14 +23,14 @@
|
|||||||
mat-icon-button
|
mat-icon-button
|
||||||
class="menu-button"
|
class="menu-button"
|
||||||
(click)="addDrawing('rectangle')">
|
(click)="addDrawing('rectangle')">
|
||||||
<mat-icon [ngClass]="{unmarkedLight: !drawTools.isRectangleChosen && isLightThemeEnabled, marked: drawTools.isRectangleChosen}">crop_3_2</mat-icon>
|
<mat-icon [ngClass]="getCssClassForIcon('rectangle')">crop_3_2</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
matTooltip="Draw an ellipse"
|
matTooltip="Draw an ellipse"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
class="menu-button"
|
class="menu-button"
|
||||||
(click)="addDrawing('ellipse')">
|
(click)="addDrawing('ellipse')">
|
||||||
<mat-icon [ngClass]="{unmarkedLight: !drawTools.isEllipseChosen && isLightThemeEnabled, marked: drawTools.isEllipseChosen}">panorama_fish_eye</mat-icon>
|
<mat-icon [ngClass]="getCssClassForIcon('ellipse')">panorama_fish_eye</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="!isLightThemeEnabled"
|
<button *ngIf="!isLightThemeEnabled"
|
||||||
matTooltip="Draw a line"
|
matTooltip="Draw a line"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
|
import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { Project } from '../../../models/project';
|
import { Project } from '../../../models/project';
|
||||||
import { Server } from '../../../models/server';
|
import { Server } from '../../../models/server';
|
||||||
import { ToolsService } from '../../../services/tools.service';
|
import { ToolsService } from '../../../services/tools.service';
|
||||||
@ -14,11 +14,11 @@ import { ScreenshotDialogComponent, Screenshot } from '../screenshot-dialog/scre
|
|||||||
import { saveAsPng, saveAsJpeg } from 'save-html-as-image';
|
import { saveAsPng, saveAsJpeg } from 'save-html-as-image';
|
||||||
import { ThemeService } from '../../../services/theme.service';
|
import { ThemeService } from '../../../services/theme.service';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-project-map-menu',
|
selector: 'app-project-map-menu',
|
||||||
templateUrl: './project-map-menu.component.html',
|
templateUrl: './project-map-menu.component.html',
|
||||||
styleUrls: ['./project-map-menu.component.scss']
|
styleUrls: ['./project-map-menu.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||||
@Input() project: Project;
|
@Input() project: Project;
|
||||||
@ -47,10 +47,29 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
|||||||
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCssClassForIcon(type: string) {
|
||||||
|
if (type === 'text') {
|
||||||
|
return {
|
||||||
|
'unmarkedLight': !this.drawTools.isTextChosen && this.isLightThemeEnabled,
|
||||||
|
'marked': this.drawTools.isTextChosen
|
||||||
|
};
|
||||||
|
} else if (type === 'rectangle') {
|
||||||
|
return {
|
||||||
|
'unmarkedLight': !this.drawTools.isRectangleChosen && this.isLightThemeEnabled,
|
||||||
|
'marked': this.drawTools.isRectangleChosen
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
'unmarkedLight': !this.drawTools.isEllipseChosen && this.isLightThemeEnabled,
|
||||||
|
'marked': this.drawTools.isEllipseChosen
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public takeScreenshot() {
|
public takeScreenshot() {
|
||||||
const dialogRef = this.dialog.open(ScreenshotDialogComponent, {
|
const dialogRef = this.dialog.open(ScreenshotDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
dialogRef.afterClosed().subscribe((result: Screenshot) => {
|
dialogRef.afterClosed().subscribe((result: Screenshot) => {
|
||||||
if (result) this.saveImage(result);
|
if (result) this.saveImage(result);
|
||||||
|
@ -66,6 +66,7 @@ import { ConfirmationBottomSheetComponent } from '../projects/confirmation-botto
|
|||||||
import { NodeAddedEvent } from '../template/template-list-dialog/template-list-dialog.component';
|
import { NodeAddedEvent } from '../template/template-list-dialog/template-list-dialog.component';
|
||||||
import { NotificationService } from '../../services/notification.service';
|
import { NotificationService } from '../../services/notification.service';
|
||||||
import { ThemeService } from '../../services/theme.service';
|
import { ThemeService } from '../../services/theme.service';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -109,7 +110,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
@ViewChild(D3MapComponent, {static: false}) mapChild: D3MapComponent;
|
@ViewChild(D3MapComponent, {static: false}) mapChild: D3MapComponent;
|
||||||
@ViewChild(ProjectMapMenuComponent, {static: false}) projectMapMenuComponent: ProjectMapMenuComponent;
|
@ViewChild(ProjectMapMenuComponent, {static: false}) projectMapMenuComponent: ProjectMapMenuComponent;
|
||||||
|
|
||||||
private subscriptions: Subscription[] = [];
|
private projectMapSubscription: Subscription = new Subscription();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@ -153,7 +154,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private serialLinkWidget: SerialLinkWidget,
|
private serialLinkWidget: SerialLinkWidget,
|
||||||
private bottomSheet: MatBottomSheet,
|
private bottomSheet: MatBottomSheet,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private themeService: ThemeService
|
private themeService: ThemeService,
|
||||||
|
private title: Title
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -178,6 +180,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
}),
|
}),
|
||||||
mergeMap((project: Project) => {
|
mergeMap((project: Project) => {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
|
this.title.setTitle(this.project.name);
|
||||||
|
|
||||||
if (this.mapSettingsService.interfaceLabels.has(project.project_id)) {
|
if (this.mapSettingsService.interfaceLabels.has(project.project_id)) {
|
||||||
this.isInterfaceLabelVisible = this.mapSettingsService.interfaceLabels.get(project.project_id);
|
this.isInterfaceLabelVisible = this.mapSettingsService.interfaceLabels.get(project.project_id);
|
||||||
@ -210,22 +213,22 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.subscriptions.push(routeSub);
|
this.projectMapSubscription.add(routeSub);
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.projectMapSubscription.add(
|
||||||
this.mapSettingsService.mapRenderedEmitter.subscribe((value: boolean) => {
|
this.mapSettingsService.mapRenderedEmitter.subscribe((value: boolean) => {
|
||||||
if (this.scrollEnabled) this.centerCanvas();
|
if (this.scrollEnabled) this.centerCanvas();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.projectMapSubscription.add(
|
||||||
this.drawingsDataSource.changes.subscribe((drawings: Drawing[]) => {
|
this.drawingsDataSource.changes.subscribe((drawings: Drawing[]) => {
|
||||||
this.drawings = drawings;
|
this.drawings = drawings;
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.projectMapSubscription.add(
|
||||||
this.nodesDataSource.changes.subscribe((nodes: Node[]) => {
|
this.nodesDataSource.changes.subscribe((nodes: Node[]) => {
|
||||||
if (!this.server) return;
|
if (!this.server) return;
|
||||||
nodes.forEach((node: Node) => {
|
nodes.forEach((node: Node) => {
|
||||||
@ -237,21 +240,21 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.projectMapSubscription.add(
|
||||||
this.linksDataSource.changes.subscribe((links: Link[]) => {
|
this.linksDataSource.changes.subscribe((links: Link[]) => {
|
||||||
this.links = links;
|
this.links = links;
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.subscriptions.push(this.projectWebServiceHandler.errorNotificationEmitter.subscribe((message) => {
|
this.projectMapSubscription.add(this.projectWebServiceHandler.errorNotificationEmitter.subscribe((message) => {
|
||||||
this.showMessage({
|
this.showMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: message
|
message: message
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.subscriptions.push(this.projectWebServiceHandler.warningNotificationEmitter.subscribe((message) => {
|
this.projectMapSubscription.add(this.projectWebServiceHandler.warningNotificationEmitter.subscribe((message) => {
|
||||||
this.showMessage({
|
this.showMessage({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: message
|
message: message
|
||||||
@ -323,7 +326,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.progressService.deactivate();
|
this.progressService.deactivate();
|
||||||
});
|
});
|
||||||
this.subscriptions.push(subscription);
|
this.projectMapSubscription.add(subscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpProjectWS(project: Project) {
|
setUpProjectWS(project: Project) {
|
||||||
@ -408,14 +411,14 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX);
|
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.subscriptions.push(onLinkContextMenu);
|
this.projectMapSubscription.add(onLinkContextMenu);
|
||||||
this.subscriptions.push(onEthernetLinkContextMenu);
|
this.projectMapSubscription.add(onEthernetLinkContextMenu);
|
||||||
this.subscriptions.push(onSerialLinkContextMenu);
|
this.projectMapSubscription.add(onSerialLinkContextMenu);
|
||||||
this.subscriptions.push(onNodeContextMenu);
|
this.projectMapSubscription.add(onNodeContextMenu);
|
||||||
this.subscriptions.push(onDrawingContextMenu);
|
this.projectMapSubscription.add(onDrawingContextMenu);
|
||||||
this.subscriptions.push(onContextMenu);
|
this.projectMapSubscription.add(onContextMenu);
|
||||||
this.subscriptions.push(onLabelContextMenu);
|
this.projectMapSubscription.add(onLabelContextMenu);
|
||||||
this.subscriptions.push(onInterfaceLabelContextMenu);
|
this.projectMapSubscription.add(onInterfaceLabelContextMenu);
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,10 +427,10 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.nodeService.createFromTemplate(this.server, this.project, nodeAddedEvent.template, nodeAddedEvent.x, nodeAddedEvent.y, nodeAddedEvent.server).subscribe((node: Node) => {
|
this.nodeService.createFromTemplate(this.server, this.project, nodeAddedEvent.template, nodeAddedEvent.x, nodeAddedEvent.y, nodeAddedEvent.server).subscribe((node: Node) => {
|
||||||
if (nodeAddedEvent.name !== nodeAddedEvent.template.name) {
|
// if (nodeAddedEvent.name !== nodeAddedEvent.template.name) {
|
||||||
node.name = nodeAddedEvent.name;
|
// node.name = nodeAddedEvent.name;
|
||||||
this.nodeService.updateNode(this.server, node).subscribe(()=>{});
|
// this.nodeService.updateNode(this.server, node).subscribe(()=>{});
|
||||||
}
|
// }
|
||||||
this.projectService.nodes(this.server, this.project.project_id).subscribe((nodes: Node[]) => {
|
this.projectService.nodes(this.server, this.project.project_id).subscribe((nodes: Node[]) => {
|
||||||
|
|
||||||
nodes.filter((node) => node.label.style === null).forEach((node) => {
|
nodes.filter((node) => node.label.style === null).forEach((node) => {
|
||||||
@ -702,7 +705,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
addNewProject() {
|
addNewProject() {
|
||||||
const dialogRef = this.dialog.open(AddBlankProjectDialogComponent, {
|
const dialogRef = this.dialog.open(AddBlankProjectDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -711,7 +715,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
saveProject() {
|
saveProject() {
|
||||||
const dialogRef = this.dialog.open(SaveProjectDialogComponent, {
|
const dialogRef = this.dialog.open(SaveProjectDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -721,7 +726,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
editProject() {
|
editProject() {
|
||||||
const dialogRef = this.dialog.open(EditProjectDialogComponent, {
|
const dialogRef = this.dialog.open(EditProjectDialogComponent, {
|
||||||
width: '600px',
|
width: '600px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -732,7 +738,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
let uuid: string = '';
|
let uuid: string = '';
|
||||||
const dialogRef = this.dialog.open(ImportProjectDialogComponent, {
|
const dialogRef = this.dialog.open(ImportProjectDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -819,6 +826,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
|
this.title.setTitle('GNS3 Web UI');
|
||||||
this.drawingsDataSource.clear();
|
this.drawingsDataSource.clear();
|
||||||
this.nodesDataSource.clear();
|
this.nodesDataSource.clear();
|
||||||
this.linksDataSource.clear();
|
this.linksDataSource.clear();
|
||||||
@ -829,7 +837,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
if (this.ws) {
|
if (this.ws) {
|
||||||
if (this.ws.OPEN) this.ws.close();
|
if (this.ws.OPEN) this.ws.close();
|
||||||
}
|
}
|
||||||
this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
|
this.projectMapSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,8 @@ export class AddBlankProjectDialogComponent implements OnInit {
|
|||||||
data: {
|
data: {
|
||||||
existingProject: existingProject
|
existingProject: existingProject
|
||||||
},
|
},
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
||||||
|
@ -110,7 +110,8 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
data: {
|
data: {
|
||||||
existingProject: existingProject
|
existingProject: existingProject
|
||||||
},
|
},
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
||||||
|
@ -78,7 +78,8 @@ export class ProjectsComponent implements OnInit {
|
|||||||
const dialogRef = this.dialog.open(ConfigureGns3VMDialogComponent, {
|
const dialogRef = this.dialog.open(ConfigureGns3VMDialogComponent, {
|
||||||
width: '350px',
|
width: '350px',
|
||||||
height: '120px',
|
height: '120px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
||||||
@ -149,7 +150,8 @@ export class ProjectsComponent implements OnInit {
|
|||||||
duplicate(project: Project) {
|
duplicate(project: Project) {
|
||||||
const dialogRef = this.dialog.open(ChooseNameDialogComponent, {
|
const dialogRef = this.dialog.open(ChooseNameDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -162,7 +164,8 @@ export class ProjectsComponent implements OnInit {
|
|||||||
addBlankProject() {
|
addBlankProject() {
|
||||||
const dialogRef = this.dialog.open(AddBlankProjectDialogComponent, {
|
const dialogRef = this.dialog.open(AddBlankProjectDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
@ -172,7 +175,8 @@ export class ProjectsComponent implements OnInit {
|
|||||||
let uuid: string = '';
|
let uuid: string = '';
|
||||||
const dialogRef = this.dialog.open(ImportProjectDialogComponent, {
|
const dialogRef = this.dialog.open(ImportProjectDialogComponent, {
|
||||||
width: '400px',
|
width: '400px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
let instance = dialogRef.componentInstance;
|
let instance = dialogRef.componentInstance;
|
||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
|
@ -94,7 +94,8 @@ export class ServersComponent implements OnInit, OnDestroy {
|
|||||||
createModal() {
|
createModal() {
|
||||||
const dialogRef = this.dialog.open(AddServerDialogComponent, {
|
const dialogRef = this.dialog.open(AddServerDialogComponent, {
|
||||||
width: '350px',
|
width: '350px',
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(server => {
|
dialogRef.afterClosed().subscribe(server => {
|
||||||
|
@ -35,7 +35,8 @@ export class SnapshotMenuItemComponent implements OnInit {
|
|||||||
server: this.server,
|
server: this.server,
|
||||||
project: this.project
|
project: this.project
|
||||||
},
|
},
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(snapshot => {
|
dialogRef.afterClosed().subscribe(snapshot => {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="'CPU usage percent'"
|
[subtitle]="'CPU usage'"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="'Disk usage percent'"
|
[subtitle]="'Disk usage'"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="'Memory usage percent'"
|
[subtitle]="'Memory usage'"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="'SWAP usage percent'"
|
[subtitle]="'SWAP usage'"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -87,7 +87,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="['Load average percent', '(last 1 minute)']"
|
[subtitle]="['Load average', '(last 1 minute)']"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -105,7 +105,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="['Load average percent', '(last 5 minutes)']"
|
[subtitle]="['Load average', '(last 5 minutes)']"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
@ -123,7 +123,7 @@
|
|||||||
[unitsFontSize]="20"
|
[unitsFontSize]="20"
|
||||||
[titleColor]="'#C0C0C0'"
|
[titleColor]="'#C0C0C0'"
|
||||||
[titleFontSize]="30"
|
[titleFontSize]="30"
|
||||||
[subtitle]="['Load average percent', '(last 15 minutes)']"
|
[subtitle]="['Load average', '(last 15 minutes)']"
|
||||||
[subtitleColor]="'#C0C0C0'"
|
[subtitleColor]="'#C0C0C0'"
|
||||||
[subtitleFontSize]="15"
|
[subtitleFontSize]="15"
|
||||||
></circle-progress>
|
></circle-progress>
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@
|
|||||||
<h6>Configuration</h6>
|
<h6>Configuration</h6>
|
||||||
</div>
|
</div>
|
||||||
<form [formGroup]="configurationForm">
|
<form [formGroup]="configurationForm">
|
||||||
<mat-form-field class="form-field">
|
<!-- <mat-form-field class="form-field">
|
||||||
<input type="text" matInput formControlName="name" placeholder="Enter name (default is taken from template)" />
|
<input type="text" matInput formControlName="name" placeholder="Enter name (default is taken from template)" />
|
||||||
</mat-form-field>
|
</mat-form-field> -->
|
||||||
<mat-form-field class="form-field">
|
<mat-form-field class="form-field">
|
||||||
<input type="number" matInput formControlName="numberOfNodes" placeholder="Enter number of nodes (default value is 1)" />
|
<input type="number" matInput formControlName="numberOfNodes" placeholder="Enter number of nodes (default value is 1)" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@ -41,7 +41,7 @@ export class TemplateListDialogComponent implements OnInit {
|
|||||||
this.server = data['server'];
|
this.server = data['server'];
|
||||||
this.project = data['project'];
|
this.project = data['project'];
|
||||||
this.configurationForm = this.formBuilder.group({
|
this.configurationForm = this.formBuilder.group({
|
||||||
name: new FormControl('new node', Validators.required),
|
// name: new FormControl('new node', Validators.required),
|
||||||
numberOfNodes: new FormControl(1, [Validators.required, nonNegativeValidator.get])
|
numberOfNodes: new FormControl(1, [Validators.required, nonNegativeValidator.get])
|
||||||
});
|
});
|
||||||
this.positionForm = this.formBuilder.group({
|
this.positionForm = this.formBuilder.group({
|
||||||
@ -70,13 +70,13 @@ export class TemplateListDialogComponent implements OnInit {
|
|||||||
|
|
||||||
chooseTemplate(event) {
|
chooseTemplate(event) {
|
||||||
this.selectedTemplate = event.value;
|
this.selectedTemplate = event.value;
|
||||||
this.configurationForm.controls['name'].setValue(this.selectedTemplate.default_name_format);
|
// this.configurationForm.controls['name'].setValue(this.selectedTemplate.default_name_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddClick(): void {
|
onAddClick(): void {
|
||||||
if (!this.selectedTemplate || this.filteredTemplates.length === 0) {
|
if (!this.selectedTemplate || this.filteredTemplates.length === 0) {
|
||||||
this.toasterService.error('Please firstly choose template.');
|
this.toasterService.error('Please firstly choose template.');
|
||||||
} else if (!this.positionForm.valid || !this.configurationForm.valid) {
|
} else if (!this.positionForm.valid || !this.configurationForm.valid || !this.selectedTemplate.compute_id) {
|
||||||
this.toasterService.error('Please fill all required fields.');
|
this.toasterService.error('Please fill all required fields.');
|
||||||
} else {
|
} else {
|
||||||
let x: number = this.positionForm.get('left').value;
|
let x: number = this.positionForm.get('left').value;
|
||||||
@ -87,7 +87,7 @@ export class TemplateListDialogComponent implements OnInit {
|
|||||||
let event: NodeAddedEvent = {
|
let event: NodeAddedEvent = {
|
||||||
template: this.selectedTemplate,
|
template: this.selectedTemplate,
|
||||||
server: this.selectedTemplate.compute_id,
|
server: this.selectedTemplate.compute_id,
|
||||||
name: this.configurationForm.get('name').value,
|
// name: this.configurationForm.get('name').value,
|
||||||
numberOfNodes: this.configurationForm.get('numberOfNodes').value,
|
numberOfNodes: this.configurationForm.get('numberOfNodes').value,
|
||||||
x: x,
|
x: x,
|
||||||
y: y
|
y: y
|
||||||
@ -101,7 +101,7 @@ export class TemplateListDialogComponent implements OnInit {
|
|||||||
export interface NodeAddedEvent {
|
export interface NodeAddedEvent {
|
||||||
template: Template,
|
template: Template,
|
||||||
server: string,
|
server: string,
|
||||||
name: string,
|
name?: string,
|
||||||
numberOfNodes: number;
|
numberOfNodes: number;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
@ -27,7 +27,8 @@ export class TemplateComponent implements OnInit {
|
|||||||
server: this.server,
|
server: this.server,
|
||||||
project: this.project
|
project: this.project
|
||||||
},
|
},
|
||||||
autoFocus: false
|
autoFocus: false,
|
||||||
|
disableClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((nodeAddedEvent: NodeAddedEvent) => {
|
dialogRef.afterClosed().subscribe((nodeAddedEvent: NodeAddedEvent) => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, OnDestroy, Input, AfterViewInit, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, OnDestroy, Input, AfterViewInit, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { Project } from '../../models/project';
|
import { Project } from '../../models/project';
|
||||||
import { Server } from '../../models/server';
|
import { Server } from '../../models/server';
|
||||||
import { NodesDataSource } from '../../cartography/datasources/nodes-datasource';
|
import { NodesDataSource } from '../../cartography/datasources/nodes-datasource';
|
||||||
@ -16,7 +16,8 @@ import { ThemeService } from '../../services/theme.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-topology-summary',
|
selector: 'app-topology-summary',
|
||||||
templateUrl: './topology-summary.component.html',
|
templateUrl: './topology-summary.component.html',
|
||||||
styleUrls: ['./topology-summary.component.scss']
|
styleUrls: ['./topology-summary.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.Default
|
||||||
})
|
})
|
||||||
export class TopologySummaryComponent implements OnInit, OnDestroy {
|
export class TopologySummaryComponent implements OnInit, OnDestroy {
|
||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
|
@ -46,6 +46,13 @@ export class NodeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createFromTemplate(server: Server, project: Project, template: Template, x: number, y: number, compute_id: string): Observable<Node> {
|
createFromTemplate(server: Server, project: Project, template: Template, x: number, y: number, compute_id: string): Observable<Node> {
|
||||||
|
if (!compute_id) {
|
||||||
|
return this.httpServer.post(server, `/projects/${project.project_id}/templates/${template.template_id}`, {
|
||||||
|
x: Math.round(x),
|
||||||
|
y: Math.round(y),
|
||||||
|
compute_id: 'local'
|
||||||
|
});
|
||||||
|
}
|
||||||
return this.httpServer.post(server, `/projects/${project.project_id}/templates/${template.template_id}`, {
|
return this.httpServer.post(server, `/projects/${project.project_id}/templates/${template.template_id}`, {
|
||||||
x: Math.round(x),
|
x: Math.round(x),
|
||||||
y: Math.round(y),
|
y: Math.round(y),
|
||||||
|
@ -7,7 +7,7 @@ export class QemuConfigurationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDiskInterfaces() {
|
getDiskInterfaces() {
|
||||||
return ['ide', 'sata', 'scsi', 'sd', 'mtd', 'floppy', 'pflash', 'virtio', 'none'];
|
return ['ide', 'sata', 'scsi', 'sd', 'mtd', 'floppy', 'pflash', 'virtio', 'nvme', 'none'];
|
||||||
}
|
}
|
||||||
|
|
||||||
getNetworkTypes() {
|
getNetworkTypes() {
|
||||||
@ -33,7 +33,12 @@ export class QemuConfigurationService {
|
|||||||
// ["virtio-net-pci", "Paravirtualized Network I/O"],
|
// ["virtio-net-pci", "Paravirtualized Network I/O"],
|
||||||
// ["vmxnet3", "VMWare Paravirtualized Ethernet v3"]];
|
// ["vmxnet3", "VMWare Paravirtualized Ethernet v3"]];
|
||||||
|
|
||||||
let networkTypes = ["e1000", "Intel Gigabit Ethernet",
|
let networkTypes = ["e1000",
|
||||||
|
"e1000-82544gc",
|
||||||
|
"e1000-82545em",
|
||||||
|
"e1000e",
|
||||||
|
"rocker",
|
||||||
|
"Intel Gigabit Ethernet",
|
||||||
"i82550",
|
"i82550",
|
||||||
"i82551",
|
"i82551",
|
||||||
"i82557a",
|
"i82557a",
|
||||||
|
14
src/main.ts
14
src/main.ts
@ -1,14 +1,20 @@
|
|||||||
import 'hammerjs';
|
import 'hammerjs';
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode, ApplicationRef } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
import { AppModule } from './app/app.module';
|
||||||
import { environment } from './environments/environment';
|
import { environment } from './environments/environment';
|
||||||
|
import { enableDebugTools } from '@angular/platform-browser';
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic()
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
.bootstrapModule(AppModule)
|
.then(moduleRef => {
|
||||||
.catch(err => console.error(err));
|
const applicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
|
const componentRef = applicationRef.components[0];
|
||||||
|
// allows to run `ng.profiler.timeChangeDetection();`
|
||||||
|
enableDebugTools(componentRef);
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
Loading…
Reference in New Issue
Block a user