mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-24 17:15:22 +00:00
Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
0ddf4f6e95 | |||
8d466d655e | |||
2c7dd5f179 | |||
64999f2b72 | |||
253c65b8c1 | |||
74c1a82524 | |||
4e42bd7a54 | |||
891e65b094 | |||
c808477914 | |||
8503a17187 | |||
8afea664ff | |||
538ae8b7fb | |||
370694f3b0 | |||
5175b3beac | |||
2df1956dbc | |||
56384fbcc0 | |||
15faca6d89 | |||
4142144d4d | |||
e2e87db039 | |||
c868f08a25 | |||
9aedd410bb | |||
5fb76d7d11 | |||
a7c343aa7c | |||
cfe8c4760b | |||
7cbcc84cc1 | |||
357e478fb8 | |||
063d8c9dc7 | |||
63ecacb6b6 | |||
6cecacf611 | |||
c389404e58 | |||
b1aba60410 |
1
.angular/cache/babel-webpack/d6a73bccc4e531ea9b921fbd7f814650.json
vendored
Normal file
1
.angular/cache/babel-webpack/d6a73bccc4e531ea9b921fbd7f814650.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/.angular
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
@ -176,6 +176,7 @@
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"sourceMap": false,
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
|
79
package.json
79
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gns3-web-ui",
|
||||
"version": "2.2.24",
|
||||
"version": "2.2.27",
|
||||
"author": {
|
||||
"name": "GNS3 Technology Inc.",
|
||||
"email": "developers@gns3.com"
|
||||
@ -41,26 +41,27 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^12.2.2",
|
||||
"@angular/cdk": "^12.2.2",
|
||||
"@angular/common": "^12.2.2",
|
||||
"@angular/compiler": "^12.2.2",
|
||||
"@angular/core": "^12.2.2",
|
||||
"@angular/forms": "^12.2.2",
|
||||
"@angular/material": "^12.2.2",
|
||||
"@angular/platform-browser": "^12.2.2",
|
||||
"@angular/platform-browser-dynamic": "^12.2.2",
|
||||
"@angular/router": "^12.2.2",
|
||||
"@sentry/browser": "^6.11.0",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@angular/animations": "^13.0.0",
|
||||
"@angular/cdk": "^13.0.0",
|
||||
"@angular/common": "^13.0.0",
|
||||
"@angular/compiler": "^13.0.0",
|
||||
"@angular/core": "^13.0.0",
|
||||
"@angular/forms": "^13.0.0",
|
||||
"@angular/material": "^13.0.0",
|
||||
"@angular/platform-browser": "^13.0.0",
|
||||
"@angular/platform-browser-dynamic": "^13.0.0",
|
||||
"@angular/router": "^13.0.0",
|
||||
"@sentry/browser": "^6.14.1",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/react": "^17.0.19",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"angular-draggable-droppable": "^4.6.0",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"angular-draggable-droppable": "^5.0.0",
|
||||
"angular-resizable-element": "^3.4.0",
|
||||
"bootstrap": "^5.1.0",
|
||||
"bootstrap": "^5.1.3",
|
||||
"command-exists": "^1.2.9",
|
||||
"core-js": "^3.16.2",
|
||||
"core-js": "^3.19.1",
|
||||
"css-tree": "^1.1.3",
|
||||
"d3-ng2-service": "^2.2.0",
|
||||
"eev": "^0.1.5",
|
||||
"ini": "^2.0.0",
|
||||
@ -71,42 +72,42 @@
|
||||
"ngx-childprocess": "^0.0.6",
|
||||
"ngx-device-detector": "^2.1.1",
|
||||
"ngx-electron": "^2.2.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-fetch": "^3.0.0",
|
||||
"notosans-fontface": "1.2.2",
|
||||
"prettier-plugin-organize-imports": "^2.3.3",
|
||||
"prettier-plugin-organize-imports": "^2.3.4",
|
||||
"rxjs": "^6.6.7",
|
||||
"rxjs-compat": "^6.6.7",
|
||||
"save-svg-as-png": "^1.4.17",
|
||||
"snyk": "^1.687.0",
|
||||
"spark-md5": "^3.0.1",
|
||||
"snyk": "^1.757.0",
|
||||
"spark-md5": "^3.0.2",
|
||||
"svg-crowbar": "^0.7.0",
|
||||
"tree-kill": "^1.2.2",
|
||||
"tslib": "^2.3.1",
|
||||
"typeface-roboto": "^1.1.13",
|
||||
"xterm": "^4.13.0",
|
||||
"xterm": "^4.15.0",
|
||||
"xterm-addon-attach": "^0.6.0",
|
||||
"xterm-addon-fit": "^0.5.0",
|
||||
"yargs": "^17.1.1",
|
||||
"yargs": "^17.2.1",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^12.2.2",
|
||||
"@angular/cli": "^12.2.2",
|
||||
"@angular/compiler-cli": "^12.2.2",
|
||||
"@angular/language-service": "^12.2.2",
|
||||
"@sentry/cli": "^1.68.0",
|
||||
"@sentry/electron": "^2.5.1",
|
||||
"@types/jasmine": "^3.8.2",
|
||||
"@angular-devkit/build-angular": "^13.0.1",
|
||||
"@angular/cli": "^13.0.1",
|
||||
"@angular/compiler-cli": "^13.0.0",
|
||||
"@angular/language-service": "^13.0.0",
|
||||
"@sentry/cli": "^1.71.0",
|
||||
"@sentry/electron": "^2.5.4",
|
||||
"@types/jasmine": "^3.10.2",
|
||||
"@types/jasminewd2": "^2.0.10",
|
||||
"@types/node": "16.7.1",
|
||||
"@types/node": "16.11.6",
|
||||
"codelyzer": "^6.0.2",
|
||||
"electron": "^13.2.2",
|
||||
"electron-builder": "^22.9.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"jasmine-core": "~3.9.0",
|
||||
"jasmine-core": "~3.10.1",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"jquery": "^3.6.0",
|
||||
"karma": "^6.3.4",
|
||||
"karma": "^6.3.8",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-cli": "^2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
@ -114,16 +115,16 @@
|
||||
"karma-jasmine-html-reporter": "^1.7.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"popper.js": "^1.16.1",
|
||||
"prettier": "^2.3.2",
|
||||
"prettier": "^2.4.1",
|
||||
"protractor": "^7.0.0",
|
||||
"replace": "^1.2.1",
|
||||
"rxjs-tslint": "^0.1.8",
|
||||
"ts-mockito": "^2.6.1",
|
||||
"ts-node": "~10.2.1",
|
||||
"ts-node": "~10.4.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typescript": "4.3.5",
|
||||
"webpack": "5.51.1",
|
||||
"typescript": "4.4.2",
|
||||
"webpack": "5.62.1",
|
||||
"yarn-upgrade-all": "^0.5.4"
|
||||
},
|
||||
"greenkeeper": {
|
||||
@ -132,4 +133,4 @@
|
||||
]
|
||||
},
|
||||
"snyk": true
|
||||
}
|
||||
}
|
@ -110,6 +110,9 @@
|
||||
placeholder="Please enter name"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<div *ngIf="uploadedFile">
|
||||
<mat-progress-bar mode="determinate" [value]="uploadProgress" aria-valuemin="0" aria-valuemax="100"></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
@ -32,6 +32,8 @@ export class AddQemuVmTemplateComponent implements OnInit {
|
||||
chosenImage: string = '';
|
||||
qemuTemplate: QemuTemplate;
|
||||
uploader: FileUploader;
|
||||
uploadedFile: boolean = false;
|
||||
uploadProgress: number = 0;
|
||||
|
||||
nameForm: FormGroup;
|
||||
memoryForm: FormGroup;
|
||||
@ -86,6 +88,9 @@ export class AddQemuVmTemplateComponent implements OnInit {
|
||||
});
|
||||
this.toasterService.success('Image uploaded');
|
||||
};
|
||||
this.uploader.onProgressItem = (progress: any) => {
|
||||
this.uploadProgress = progress['progress'];
|
||||
};
|
||||
|
||||
const server_id = this.route.snapshot.paramMap.get('server_id');
|
||||
this.serverService.get(parseInt(server_id, 10)).then((server: Server) => {
|
||||
@ -127,6 +132,7 @@ export class AddQemuVmTemplateComponent implements OnInit {
|
||||
}
|
||||
|
||||
uploadImageFile(event) {
|
||||
this.uploadedFile = true;
|
||||
let name = event.target.files[0].name;
|
||||
this.diskForm.controls['fileName'].setValue(name);
|
||||
|
||||
|
@ -220,8 +220,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
async lazyLoadTopologySummary() {
|
||||
if (this.isTopologySummaryVisible) {
|
||||
const {TopologySummaryComponent} = await import('../topology-summary/topology-summary.component');
|
||||
const componentFactory = this.cfr.resolveComponentFactory(TopologySummaryComponent);
|
||||
this.instance = this.topologySummaryContainer.createComponent(componentFactory, null, this.injector);
|
||||
this.instance = this.topologySummaryContainer.createComponent(TopologySummaryComponent);
|
||||
this.instance.instance.server = this.server;
|
||||
this.instance.instance.project = this.project;
|
||||
} else if (this.instance) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">Projects</h1>
|
||||
<button class="col" mat-raised-button (click)="goToSystemStatus()" class="add-button">Go to system status</button>
|
||||
<button class="col" mat-raised-button (click)="goToPreferences()" class="add-button">Go to preferences</button>
|
||||
<button class="col" mat-raised-button color="primary" (click)="addBlankProject()" class="add-button">
|
||||
Add blank project
|
||||
|
@ -89,6 +89,12 @@ export class ProjectsComponent implements OnInit {
|
||||
.catch((error) => this.toasterService.error('Cannot navigate to the preferences'));
|
||||
}
|
||||
|
||||
goToSystemStatus() {
|
||||
this.router
|
||||
.navigate(['/server', this.server.id, 'systemstatus'])
|
||||
.catch((error) => this.toasterService.error('Cannot navigate to the system status'));
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.projectService.list(this.server).subscribe(
|
||||
(projects: Project[]) => {
|
||||
|
@ -45,25 +45,25 @@
|
||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i])">
|
||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i])" />
|
||||
</div>
|
||||
<div class="templateText">{{ filteredTemplates[i].name }}</div>
|
||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i].name }}</div>
|
||||
</span>
|
||||
<span *ngIf="filteredTemplates[i + 1]" class="templateIcon">
|
||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 1])">
|
||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 1])" />
|
||||
</div>
|
||||
<div class="templateText">{{ filteredTemplates[i + 1].name }}</div>
|
||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 1].name }}</div>
|
||||
</span>
|
||||
<span *ngIf="filteredTemplates[i + 2]" class="templateIcon">
|
||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 2])">
|
||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 2])" />
|
||||
</div>
|
||||
<div class="templateText">{{ filteredTemplates[i + 2].name }}</div>
|
||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 2].name }}</div>
|
||||
</span>
|
||||
<span *ngIf="filteredTemplates[i + 3]" class="templateIcon">
|
||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 3])">
|
||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 3])" />
|
||||
</div>
|
||||
<div class="templateText">{{ filteredTemplates[i + 3].name }}</div>
|
||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 3].name }}</div>
|
||||
</span>
|
||||
</span>
|
||||
</mat-list-item>
|
||||
|
@ -49,6 +49,11 @@
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.lightTemplateText {
|
||||
word-wrap: break-word;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.templateIcon {
|
||||
width: 80px !important;
|
||||
padding: 10px;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ThemeService } from '../../services/theme.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Project } from '../../models/project';
|
||||
import { Server } from '../../models/server';
|
||||
@ -18,7 +20,7 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
||||
@Input() server: Server;
|
||||
@Input() project: Project;
|
||||
@Output() onNodeCreation = new EventEmitter<any>();
|
||||
|
||||
overlay;
|
||||
templates: Template[] = [];
|
||||
filteredTemplates: Template[] = [];
|
||||
searchText: string = '';
|
||||
@ -45,13 +47,19 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
||||
startY: number;
|
||||
|
||||
private subscription: Subscription;
|
||||
private themeSubscription: Subscription;
|
||||
private isLightThemeEnabled: boolean = false;
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private templateService: TemplateService,
|
||||
private scaleService: MapScaleService,
|
||||
private symbolService: SymbolService
|
||||
) {}
|
||||
private symbolService: SymbolService,
|
||||
private themeService: ThemeService,
|
||||
private overlayContainer: OverlayContainer,
|
||||
) {
|
||||
this.overlay = overlayContainer.getContainerElement();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.subscription = this.templateService.newTemplateCreated.subscribe((template: Template) => {
|
||||
@ -64,6 +72,23 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
||||
this.templates = listOfTemplates;
|
||||
});
|
||||
this.symbolService.list(this.server);
|
||||
if (this.themeService.getActualTheme() === 'light') this.isLightThemeEnabled = true;
|
||||
this.themeSubscription = this.themeService.themeChanged.subscribe((value: string) => {
|
||||
if (value === 'light-theme') this.isLightThemeEnabled = true;
|
||||
this.toggleTheme();
|
||||
});
|
||||
}
|
||||
|
||||
toggleTheme(): void {
|
||||
if (this.overlay.classList.contains("dark-theme")) {
|
||||
this.overlay.classList.remove("dark-theme");
|
||||
this.overlay.classList.add("light-theme");
|
||||
} else if (this.overlay.classList.contains("light-theme")) {
|
||||
this.overlay.classList.remove("light-theme");
|
||||
this.overlay.classList.add("dark-theme");
|
||||
} else {
|
||||
this.overlay.classList.add("light-theme");
|
||||
}
|
||||
}
|
||||
|
||||
sortTemplates() {
|
||||
|
@ -5,7 +5,9 @@ import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@ang
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
|
||||
teardown: { destroyAfterEach: false }
|
||||
});
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '~@angular/material/theming';
|
||||
@import '@angular/material/theming';
|
||||
@import '~material-design-icons/iconfont/material-icons.css';
|
||||
@import '~typeface-roboto/index.css';
|
||||
@include mat-core();
|
||||
|
Reference in New Issue
Block a user