mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-31 08:25:35 +00:00
Merge branch 'master' into Screenshot-SVG-image-issue
This commit is contained in:
commit
e982c6d4c7
@ -250,6 +250,7 @@ import { AlignHorizontallyActionComponent } from './components/project-map/conte
|
||||
import { AlignVerticallyActionComponent } from './components/project-map/context-menu/actions/align_vertically/align-vertically.component';
|
||||
import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component';
|
||||
import { DeviceDetectorModule } from 'ngx-device-detector';
|
||||
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
||||
|
||||
if (environment.production) {
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
@ -421,7 +422,8 @@ if (environment.production) {
|
||||
PageNotFoundComponent,
|
||||
AlignHorizontallyActionComponent,
|
||||
AlignVerticallyActionComponent,
|
||||
ConfirmationBottomSheetComponent
|
||||
ConfirmationBottomSheetComponent,
|
||||
ConfigDialogComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -546,7 +548,8 @@ if (environment.production) {
|
||||
ChooseNameDialogComponent,
|
||||
NavigationDialogComponent,
|
||||
ScreenshotDialogComponent,
|
||||
ConfirmationBottomSheetComponent
|
||||
ConfirmationBottomSheetComponent,
|
||||
ConfigDialogComponent
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
@ -2,6 +2,8 @@ import { Component, Input } from '@angular/core';
|
||||
import { Node } from '../../../../../cartography/models/node';
|
||||
import { NodeService } from '../../../../../services/node.service';
|
||||
import { Server } from '../../../../../models/server';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { ConfigDialogComponent } from '../../dialogs/config-dialog/config-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-export-config-action',
|
||||
@ -12,13 +14,33 @@ export class ExportConfigActionComponent {
|
||||
@Input() node: Node;
|
||||
|
||||
constructor(
|
||||
private nodeService: NodeService
|
||||
private nodeService: NodeService,
|
||||
private dialog: MatDialog
|
||||
) {}
|
||||
|
||||
exportConfig() {
|
||||
this.nodeService.getStartupConfiguration(this.server, this.node).subscribe((config: any) => {
|
||||
this.downloadByHtmlTag(config);
|
||||
});
|
||||
if (this.node.node_type === 'vpcs') {
|
||||
this.nodeService.getStartupConfiguration(this.server, this.node).subscribe((config: any) => {
|
||||
this.downloadByHtmlTag(config);
|
||||
});
|
||||
} else {
|
||||
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
||||
width: '500px',
|
||||
autoFocus: false
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
dialogRef.afterClosed().subscribe((configType: string) => {
|
||||
if (configType === 'startup-config') {
|
||||
this.nodeService.getStartupConfiguration(this.server, this.node).subscribe((config: any) => {
|
||||
this.downloadByHtmlTag(config);
|
||||
});
|
||||
} else if (configType === 'private-config') {
|
||||
this.nodeService.getPrivateConfiguration(this.server, this.node).subscribe((config: any) => {
|
||||
this.downloadByHtmlTag(config);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private downloadByHtmlTag(config: string) {
|
||||
|
@ -1,4 +1,10 @@
|
||||
<button mat-menu-item (click)="importConfig()">
|
||||
<input
|
||||
type="file"
|
||||
accept=".txt, .vpc"
|
||||
class="non-visible"
|
||||
#fileInput
|
||||
(change)="importConfig($event)"/>
|
||||
<button mat-menu-item (click)="triggerClick()">
|
||||
<mat-icon>call_received</mat-icon>
|
||||
<span>Import config</span>
|
||||
</button>
|
||||
|
@ -0,0 +1,3 @@
|
||||
.non-visible {
|
||||
display: none;
|
||||
}
|
@ -1,19 +1,64 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, Input, ViewChild, ElementRef } from '@angular/core';
|
||||
import { Node } from '../../../../../cartography/models/node';
|
||||
import { NodeService } from '../../../../../services/node.service';
|
||||
import { Server } from '../../../../../models/server';
|
||||
import { ToasterService } from '../../../../../services/toaster.service';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { ConfigDialogComponent } from '../../dialogs/config-dialog/config-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-import-config-action',
|
||||
templateUrl: './import-config-action.component.html'
|
||||
templateUrl: './import-config-action.component.html',
|
||||
styleUrls: ['./import-config-action.component.scss']
|
||||
})
|
||||
export class ImportConfigActionComponent {
|
||||
@Input() server: Server;
|
||||
@Input() node: Node;
|
||||
@ViewChild('fileInput', {static: false}) fileInput: ElementRef;
|
||||
configType: string;
|
||||
|
||||
constructor() {}
|
||||
constructor(
|
||||
private nodeService: NodeService,
|
||||
private toasterService: ToasterService,
|
||||
private dialog: MatDialog
|
||||
) {}
|
||||
|
||||
importConfig() {
|
||||
//needs implementation
|
||||
triggerClick() {
|
||||
if (this.node.node_type !== 'vpcs') {
|
||||
const dialogRef = this.dialog.open(ConfigDialogComponent, {
|
||||
width: '500px',
|
||||
autoFocus: false
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
dialogRef.afterClosed().subscribe((configType: string) => {
|
||||
this.configType = configType;
|
||||
this.fileInput.nativeElement.click();
|
||||
});
|
||||
} else {
|
||||
this.configType = 'startup-config';
|
||||
this.fileInput.nativeElement.click();
|
||||
}
|
||||
}
|
||||
|
||||
importConfig(event) {
|
||||
let file: File = event.target.files[0];
|
||||
let fileReader: FileReader = new FileReader();
|
||||
fileReader.onload = (e) => {
|
||||
let content: string | ArrayBuffer = fileReader.result;
|
||||
if (typeof content !== 'string'){
|
||||
content = content.toString();
|
||||
}
|
||||
|
||||
if (this.configType === 'startup-config') {
|
||||
this.nodeService.saveConfiguration(this.server, this.node, content).subscribe(() => {
|
||||
this.toasterService.success(`Configuration for node ${this.node.name} imported.`);
|
||||
});
|
||||
} else if (this.configType === 'private-config') {
|
||||
this.nodeService.savePrivateConfiguration(this.server, this.node, content).subscribe(() => {
|
||||
this.toasterService.success(`Configuration for node ${this.node.name} imported.`);
|
||||
});
|
||||
}
|
||||
};
|
||||
fileReader.readAsText(file);
|
||||
}
|
||||
}
|
||||
|
@ -59,14 +59,14 @@
|
||||
[project]="project"
|
||||
[node]="nodes[0]"
|
||||
></app-edit-config-action>
|
||||
<app-export-config-action *ngIf="nodes.length===1 && nodes[0].node_type==='vpcs'"
|
||||
<app-export-config-action *ngIf="nodes.length===1 && (nodes[0].node_type==='vpcs' || nodes[0].node_type==='iou' || nodes[0].node_type==='dynamips')"
|
||||
[server]="server"
|
||||
[node]="nodes[0]"
|
||||
></app-export-config-action>
|
||||
<!-- <app-import-config-action *ngIf="nodes.length===1"
|
||||
<app-import-config-action *ngIf="nodes.length===1 && (nodes[0].node_type==='vpcs' || nodes[0].node_type==='iou' || nodes[0].node_type==='dynamips')"
|
||||
[server]="server"
|
||||
[node]="nodes[0]"
|
||||
></app-import-config-action> -->
|
||||
></app-import-config-action>
|
||||
<app-move-layer-up-action
|
||||
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length)"
|
||||
[server]="server"
|
||||
|
@ -0,0 +1,16 @@
|
||||
<h1 mat-dialog-title>Choose configuration file</h1>
|
||||
|
||||
<div class="modal-form-container">
|
||||
<div class="container">
|
||||
<div>
|
||||
<button mat-raised-button color="primary" (click)="close('startup-config')">
|
||||
startup configuration
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button mat-raised-button color="primary" (click)="close('private-config')">
|
||||
private configuration
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-dialog',
|
||||
templateUrl: './config-dialog.component.html',
|
||||
styleUrls: ['./config-dialog.component.scss']
|
||||
})
|
||||
export class ConfigDialogComponent {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ConfigDialogComponent>,
|
||||
) {}
|
||||
|
||||
close(fileType: string) {
|
||||
this.dialogRef.close(fileType);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user