Filters added

This commit is contained in:
Piotr Pekala 2019-08-14 06:10:41 -07:00
parent 8581753520
commit 909e197b9a
6 changed files with 179 additions and 9 deletions

View File

@ -191,6 +191,7 @@ import { DuplicateActionComponent } from './components/project-map/context-menu/
import { MapSettingService } from './services/mapsettings.service'; import { MapSettingService } from './services/mapsettings.service';
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component'; import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
import { HelpComponent } from './components/help/help.component'; import { HelpComponent } from './components/help/help.component';
import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component';
if (environment.production) { if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@ -312,7 +313,8 @@ if (environment.production) {
ConsoleComponent, ConsoleComponent,
NodesMenuComponent, NodesMenuComponent,
ProjectMapMenuComponent, ProjectMapMenuComponent,
HelpComponent HelpComponent,
TopologySummaryComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -120,3 +120,4 @@
<app-node-label-dragged [server]="server"></app-node-label-dragged> <app-node-label-dragged [server]="server"></app-node-label-dragged>
<app-text-added [server]="server" [project]="project" (drawingSaved)="onDrawingSaved()"> </app-text-added> <app-text-added [server]="server" [project]="project" (drawingSaved)="onDrawingSaved()"> </app-text-added>
<app-text-edited [server]="server"></app-text-edited> <app-text-edited [server]="server"></app-text-edited>
<app-topology-summary *ngIf="project" [server]="server" [project]="project"></app-topology-summary>

View File

@ -0,0 +1,53 @@
<div class="summaryWrapper" *ngIf="projectsStatistics">
<div class="summaryHeader">
<span class="title">Topology summary ({{projectsStatistics.snapshots}} snapshots)</span>
<mat-icon>close</mat-icon>
</div>
<mat-divider class="divider"></mat-divider>
<div class="summaryFilters">
Filters <br/>
<mat-checkbox (change)="applyStatusFilter($event.checked)">Running state</mat-checkbox>
</div>
<div class="summarySorting">
Sorting <br/>
<div class="radio-group">
<mat-radio-group aria-label="Sorting">
<mat-radio-button value="1" (click)="setSortingOrder('asc')" checked>By name ascending </mat-radio-button><br/>
<mat-radio-button value="2" (click)="setSortingOrder('desc')">By name descending</mat-radio-button>
</mat-radio-group>
</div>
</div>
<mat-divider class="divider"></mat-divider>
<div class="summaryContent">
<div class="nodeRow" *ngFor="let node of filteredNodes">
<div>
<svg *ngIf="node.status==='started'" width="10" height="10">
<rect class="status_started" x="0" y="0" width="10" height="10" fill="green"></rect>
</svg>
<svg *ngIf="node.status==='stopped'" width="10" height="10">
<rect class="status_stopped" x="0" y="0" width="10" height="10" fill="red"></rect>
</svg>
{{node.name}}
</div>
<div>
{{node.console_type}} {{node.console_host}}:{{node.console}}
</div>
</div>
<!-- <div>
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{element.name}}</td>
</ng-container>
<ng-container matColumnDef="console">
<th mat-header-cell *matHeaderCellDef>Console</th>
<td mat-cell *matCellDef="let element">{{element.console}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div> -->
</div>
</div>

View File

@ -0,0 +1,67 @@
.summaryWrapper {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
position: fixed;
top: 20px;
right: 20px;
height: 400px;
width: 300px;
background: #263238;
color: white;
overflow: hidden;
font-size: 12px;
}
.summaryHeaderMenu {
height: 24px;
}
.summaryHeader {
width: 100%;
height: 24px;
display: flex;
justify-content: space-between;
margin-right: 5px;
}
.summaryFilters {
margin-left: 5px;
margin-right: 5px;
}
.summarySorting {
margin-left: 5px;
margin-right: 5px;
}
.summaryContent {
margin-left: 5px;
margin-right: 5px;
}
.title {
margin-left: 5px;
margin-top: 4px;
}
.divider {
margin: 5px;
width: 290px;
height: 2px;
}
.nodeRow {
width: 100%;
display: flex;
justify-content: space-between;
}
mat-icon {
font-size: 18px;
width: 20px;
height: 20px;
margin-top: 4px;
}
.radio-group {
margin-top: 5px;
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, AfterViewInit } 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';
@ -15,33 +15,80 @@ import { ProjectStatistics } from '../../models/project-statistics';
styleUrls: ['./topology-summary.component.scss'] styleUrls: ['./topology-summary.component.scss']
}) })
export class TopologySummaryComponent implements OnInit, OnDestroy { export class TopologySummaryComponent implements OnInit, OnDestroy {
@Input() project: Project;
@Input() server: Server; @Input() server: Server;
@Input() project: Project;
private subscriptions: Subscription[]; private subscriptions: Subscription[] = [];
projectsStatistics: ProjectStatistics; projectsStatistics: ProjectStatistics;
nodes: Node[] = []; nodes: Node[] = [];
filteredNodes: Node[] = [];
//filters to introduce -> should be generic dataSource: Node[] = [];
displayedColumns: string[] = ['name', 'console'];
sortingOrder: string = 'asc';
statusFilterEnabled: boolean = false;
constructor( constructor(
private nodesDataSource: NodesDataSource, private nodesDataSource: NodesDataSource,
private projectService: ProjectService private projectService: ProjectService,
private nodeService: NodeService
) {} ) {}
ngOnInit() { ngOnInit() {
this.subscriptions.push( this.subscriptions.push(
this.nodesDataSource.changes.subscribe((nodes: Node[]) => { this.nodesDataSource.changes.subscribe((nodes: Node[]) => {
this.nodes = nodes; this.nodes = nodes;
if (this.sortingOrder === 'asc') {
this.filteredNodes = nodes.sort(this.compareAsc);
} else {
this.filteredNodes = nodes.sort(this.compareDesc);
}
}) })
); );
this.projectService.getStatistics(this.server, this.project.project_id).subscribe((stats: ProjectStatistics) => { this.projectService.getStatistics(this.server, this.project.project_id).subscribe((stats) => {
this.projectsStatistics = stats; this.projectsStatistics = stats;
}); });
} }
compareAsc(first: Node, second: Node) {
if (first.name < second.name) return -1;
return 1;
}
compareDesc(first: Node, second: Node) {
if (first.name < second.name) return 1;
return -1;
}
ngOnDestroy() { ngOnDestroy() {
this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe()); this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
} }
setSortingOrder(order: string) {
this.sortingOrder = order;
if (this.sortingOrder === 'asc') {
this.filteredNodes = this.filteredNodes.sort(this.compareAsc);
} else {
this.filteredNodes = this.filteredNodes.sort(this.compareDesc);
}
}
applyStatusFilter(value: boolean) {
this.statusFilterEnabled = value;
this.applyFilters();
}
applyFilters() {
var nodes = this.nodes;
if (this.statusFilterEnabled) {
nodes = nodes.filter(n => n.status === 'started');
}
if (this.sortingOrder === 'asc') {
this.filteredNodes = nodes.sort(this.compareAsc);
} else {
this.filteredNodes = nodes.sort(this.compareDesc);
}
}
} }

View File

@ -49,7 +49,7 @@ export class ProjectService {
return this.httpServer.delete(server, `/projects/${project_id}`); return this.httpServer.delete(server, `/projects/${project_id}`);
} }
getStatistics(server: Server, project_id: string) { getStatistics(server: Server, project_id: string): Observable<any> {
return this.httpServer.get(server, `/projects/${project_id}/stats`); return this.httpServer.get(server, `/projects/${project_id}/stats`);
} }