Merge pull request #542 from GNS3/Widget-resizing

Topology summary widget & servers summary & console widget with option to resize
This commit is contained in:
piotrpekala7 2019-10-23 13:35:12 +02:00 committed by GitHub
commit 6d81bd4a0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 110 additions and 11 deletions

View File

@ -50,6 +50,8 @@
"@angular/platform-browser-dynamic": "^8.2.11",
"@angular/router": "^8.2.11",
"angular-persistence": "^1.0.1",
"angular-resizable-element": "^3.2.6",
"angular2-draggable": "^2.3.2",
"angular2-hotkeys": "^2.1.5",
"angular2-indexeddb": "^1.2.3",
"bootstrap": "4.3.1",

View File

@ -242,6 +242,7 @@ import { StartCaptureOnStartedLinkActionComponent } from './components/project-m
import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component';
import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component';
import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component';
import { ResizableModule } from 'angular-resizable-element';
if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@ -425,6 +426,7 @@ if (environment.production) {
NgxElectronModule,
FileUploadModule,
MatSidenavModule,
ResizableModule,
MATERIAL_IMPORTS
],
providers: [

View File

@ -1,9 +1,15 @@
<div class="consoleWrapper">
<div
class="consoleWrapper"
[ngStyle]="style"
mwlResizable
[validateResize]="validate"
[resizeEdges]="{ right: true, left: true, bottom: true, top: true }"
[enableGhostResize]="true"
(resizeEnd)="onResizeEnd($event)">
<div class="consoleHeader">
<div class="consoleFiltering">
<div class="consoleName">Console</div>
<button class="filterButton" [matMenuTriggerFor]="filterMenu">
<mat-icon>keyboard_arrow_down</mat-icon>
Apply filter
</button>
<mat-menu #filterMenu="matMenu" xPosition="after">
<button (click)="applyFilter('all')" mat-menu-item>all</button>
@ -20,7 +26,7 @@
</div>
</div>
<div #console class="console">
<div #console class="console" [ngStyle]="styleInside">
<span class="console-item" *ngFor="let event of filteredEvents">
{{event.message}} <br/>
</span>

View File

@ -15,6 +15,11 @@
background: #263238;
color: white;
border: none;
margin-top: 0px;
outline: none;
color: #dbd5d5;
font-weight: bold;
padding: 0px;
}
.consoleFiltering {

View File

@ -12,6 +12,7 @@ import { Port } from '../../../models/port';
import { LogEventsDataSource } from './log-events-datasource';
import { HttpServer } from '../../../services/http-server.service';
import { LogEvent } from '../../../models/logEvent';
import { ResizeEvent } from 'angular-resizable-element';
@Component({
@ -44,6 +45,9 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
private regexShow: RegExp = /^show (.*?)$/;
private regexConsole: RegExp = /^console (.*?)$/;
public style: object = {};
public styleInside: object = { height: `120px` };
constructor(
private projectWebServiceHandler: ProjectWebServiceHandler,
private nodeService: NodeService,
@ -124,6 +128,33 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
this.infoSubscription.unsubscribe();
}
validate(event: ResizeEvent): boolean {
if (
event.rectangle.width &&
event.rectangle.height &&
(event.rectangle.width < 600 ||
event.rectangle.height < 180)
) {
return false;
}
return true;
}
onResizeEnd(event: ResizeEvent): void {
this.style = {
position: 'fixed',
left: `${event.rectangle.left}px`,
top: `${event.rectangle.top}px`,
width: `${event.rectangle.width}px`,
height: `${event.rectangle.height}px`
};
this.styleInside = {
height: `${event.rectangle.height - 60}px`,
width: `${event.rectangle.width}px`
};
}
applyFilter(filter: string) {
this.selectedFilter = filter;
this.filteredEvents = this.getFilteredEvents();

View File

@ -79,8 +79,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
public server: Server;
public ws: WebSocket;
public isProjectMapMenuVisible: boolean = false;
public isConsoleVisible: boolean = false;
public isTopologySummaryVisible: boolean = false;
public isConsoleVisible: boolean = true;
public isTopologySummaryVisible: boolean = true;
public isInterfaceLabelVisible: boolean = false;
public notificationsVisibility: boolean = false;
public layersVisibility: boolean = false;

View File

@ -1,4 +1,12 @@
<div class="summaryWrapper" *ngIf="projectsStatistics">
<div
class="summaryWrapper"
*ngIf="projectsStatistics"
[ngStyle]="style"
mwlResizable
[validateResize]="validate"
[resizeEdges]="{ right: true, left: true, bottom: true, top: true }"
[enableGhostResize]="true"
(resizeEnd)="onResizeEnd($event)">
<div class="summaryHeader">
<button class="titleButton" [ngClass]="{ marked: isTopologyVisible }" (click)="toogleTopologyVisibility(true)" mat-button>Map topology</button>
<button class="titleButton" [ngClass]="{ marked: !isTopologyVisible }" (click)=toogleTopologyVisibility(false) mat-button>Servers</button>
@ -29,7 +37,9 @@
</div>
</div>
<mat-divider class="divider"></mat-divider>
<div class="summaryContent">
<div
[ngStyle]="styleInside"
class="summaryContent">
<div class="nodeRow" *ngFor="let node of filteredNodes">
<div>
<svg *ngIf="node.status==='started'" width="10" height="10">

View File

@ -36,7 +36,6 @@
.summaryContent {
margin-left: 5px;
margin-right: 5px;
max-height: 180px;
overflow: auto;
scrollbar-color: darkgrey #263238;
scrollbar-width: thin;
@ -62,8 +61,9 @@
}
.divider {
margin: 5px;
width: 290px;
margin-top: 5px;
margin-bottom: 5px;
width: 100%;
height: 2px;
}

View File

@ -9,6 +9,7 @@ import { ProjectStatistics } from '../../models/project-statistics';
import { Compute } from '../../models/compute';
import { ComputeService } from '../../services/compute.service';
import { LinksDataSource } from '../../cartography/datasources/links-datasource';
import { ResizeEvent } from 'angular-resizable-element';
@Component({
@ -22,6 +23,8 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
@Output() closeTopologySummary = new EventEmitter<boolean>();
public style: object = {};
public styleInside: object = { height: `180px` };
private subscriptions: Subscription[] = [];
projectsStatistics: ProjectStatistics;
nodes: Node[] = [];
@ -63,6 +66,32 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
});
}
validate(event: ResizeEvent): boolean {
if (
event.rectangle.width &&
event.rectangle.height &&
(event.rectangle.width < 290 ||
event.rectangle.height < 260)
) {
return false;
}
return true;
}
onResizeEnd(event: ResizeEvent): void {
this.style = {
position: 'fixed',
left: `${event.rectangle.left}px`,
top: `${event.rectangle.top}px`,
width: `${event.rectangle.width}px`,
height: `${event.rectangle.height}px`
};
this.styleInside = {
height: `${event.rectangle.height - 220}px`
};
}
toogleTopologyVisibility(value: boolean) {
this.isTopologyVisible = value;
}

View File

@ -1066,6 +1066,20 @@ angular-persistence@^1.0.1:
resolved "https://registry.npmjs.org/angular-persistence/-/angular-persistence-1.0.1.tgz#79ffe7317f1f7aed88e69f07705f0ac32ccdb9da"
integrity sha1-ef/nMX8feu2I5p8HcF8KwyzNudo=
angular-resizable-element@^3.2.6:
version "3.2.6"
resolved "https://registry.npmjs.org/angular-resizable-element/-/angular-resizable-element-3.2.6.tgz#1df9b14853691e00b99c74492e729b7a35cf70a0"
integrity sha512-8vp5w4YFIrZ2M8EmGpIt/yMwLBjkUJe7aPLPxDDQhi5HQWF0HLJ6lb4tXgEzW572roxNnHFg105EM6XGAMZDIg==
dependencies:
tslib "^1.9.0"
angular2-draggable@^2.3.2:
version "2.3.2"
resolved "https://registry.npmjs.org/angular2-draggable/-/angular2-draggable-2.3.2.tgz#54ca569a6b3aa9ca1a8a4d663d3eee3024c48af3"
integrity sha512-rw2O/icgVang8uSVIU7nmm59f1DceSAUQkOuSGYnKbv/h8EbhJ9099sCjh/I5LymZBza1XPKeFZofIvhekdE+A==
dependencies:
tslib "^1.9.0"
angular2-hotkeys@^2.1.5:
version "2.1.5"
resolved "https://registry.npmjs.org/angular2-hotkeys/-/angular2-hotkeys-2.1.5.tgz#d4d5df7cecd231d556089832609283f37674fdea"