From 801b3ebfac5a68b8a3ff509b7055909a116d4d9c Mon Sep 17 00:00:00 2001 From: Piotr Pekala Date: Mon, 26 Aug 2019 05:17:50 -0700 Subject: [PATCH] Introducing filters --- .../log-console/log-console.component.html | 23 +++- .../log-console/log-console.component.scss | 18 ++- .../log-console/log-console.component.ts | 106 ++++++++++++------ .../log-console/log-events-datasource.ts | 5 +- .../project-map/project-map.component.ts | 3 + src/app/models/logEvent.ts | 4 + src/app/services/mapsettings.service.ts | 5 + 7 files changed, 120 insertions(+), 44 deletions(-) create mode 100644 src/app/models/logEvent.ts diff --git a/src/app/components/project-map/log-console/log-console.component.html b/src/app/components/project-map/log-console/log-console.component.html index a2e78268..c7c2bea3 100644 --- a/src/app/components/project-map/log-console/log-console.component.html +++ b/src/app/components/project-map/log-console/log-console.component.html @@ -1,13 +1,29 @@
- Console +
+ Console + + Select filter + + + {{filter}} + + + +
+
close
+ +
+ + {{event.message}}
+
+
-
-
+
keyboard_arrow_right
+
diff --git a/src/app/components/project-map/log-console/log-console.component.scss b/src/app/components/project-map/log-console/log-console.component.scss index 79e3abe4..f3428e8b 100644 --- a/src/app/components/project-map/log-console/log-console.component.scss +++ b/src/app/components/project-map/log-console/log-console.component.scss @@ -3,7 +3,7 @@ position: fixed; bottom: 20px; left: 20px; - height: 120px; + height: 180px; width: 600px; background: #263238; color: white; @@ -13,18 +13,18 @@ .consoleHeader { width: 100%; - height: 24px; + height: 50px; font-size: 12px; overflow: hidden; margin-right: 5px; display: flex; - padding: 2px; + padding: 5px; justify-content: space-between; } .console { width: 596px; - height: 64px; + height: 100px; overflow-y: scroll; margin: 2px; color: #dbd5d5; @@ -34,7 +34,7 @@ .consoleInput { width: 100%; - height: 24px; + height: 30px; padding: 2px; display: flex; } @@ -53,11 +53,17 @@ } mat-icon { - font-size: 18px; + margin-top: 4px; + font-size: 20px; width: 20px; height: 20px; } +mat-checkbox { + margin-right: 5px; + margin-left: 5px; +} + input:focus{ outline: none; } diff --git a/src/app/components/project-map/log-console/log-console.component.ts b/src/app/components/project-map/log-console/log-console.component.ts index 52b6eec6..3febd6a9 100644 --- a/src/app/components/project-map/log-console/log-console.component.ts +++ b/src/app/components/project-map/log-console/log-console.component.ts @@ -11,6 +11,7 @@ import { Node } from '../../../cartography/models/node'; import { Port } from '../../../models/port'; import { LogEventsDataSource } from './log-events-datasource'; import { HttpServer } from '../../../services/http-server.service'; +import { LogEvent } from '../../../models/logEvent'; @Component({ @@ -29,6 +30,10 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy { private serverRequestsSubscription: Subscription; command: string = ''; + filters: string[] = ['all', 'errors', 'warnings', 'map updates', 'server requests']; + selectedFilter: string = 'all'; + filteredEvents: LogEvent[] = []; + private regexStart: RegExp = /^start (.*?)$/; private regexStop: RegExp = /^stop (.*?)$/; private regexSuspend: RegExp = /^suspend (.*?)$/; @@ -47,25 +52,36 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy { this.nodeSubscription = this.projectWebServiceHandler.nodeNotificationEmitter.subscribe((event) => { let node: Node = event.event as Node; let message = `Event received: ${event.action} - ${this.printNode(node)}.` - this.showMessage(message); + this.showMessage({ + type: 'map update', + message: message + }); }); this.linkSubscription = this.projectWebServiceHandler.linkNotificationEmitter.subscribe((event) => { let link: Link = event.event as Link; let message = `Event received: ${event.action} - ${this.printLink(link)}.` - this.showMessage(message); + this.showMessage({ + type: 'map update', + message: message + }); }); this.drawingSubscription = this.projectWebServiceHandler.drawingNotificationEmitter.subscribe((event) => { let drawing: Drawing = event.event as Drawing; let message = `Event received: ${event.action} - ${this.printDrawing(drawing)}.` - this.showMessage(message); + this.showMessage({ + type: 'map update', + message: message + }); }); - this.serverRequestsSubscription = this.httpService.requestsNotificationEmitter.subscribe((event) => { - this.showMessage(event); + this.serverRequestsSubscription = this.httpService.requestsNotificationEmitter.subscribe((message) => { + this.showMessage({ + type: 'server request', + message: message + }); }); } ngAfterViewInit() { - this.console.nativeElement.innerHTML = this.logEventsDataSource.getItems()[0] ? this.logEventsDataSource.getItems()[0] : ''; this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight; } @@ -73,6 +89,11 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy { this.nodeSubscription.unsubscribe(); this.linkSubscription.unsubscribe(); this.drawingSubscription.unsubscribe(); + this.serverRequestsSubscription.unsubscribe(); + } + + applyFilter() { + this.filteredEvents = this.getFilteredEvents(); } onKeyDown(event) { @@ -83,28 +104,28 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy { handleCommand() { if (this.command === 'help') { - this.showMessage("Available commands: help, version, start all, start {node name}, stop all, stop {node name}, suspend all, suspend {node name}, reload all, reload {node name}, show {node name}.") + this.showCommand("Available commands: help, version, start all, start {node name}, stop all, stop {node name}, suspend all, suspend {node name}, reload all, reload {node name}, show {node name}.") } else if (this.command === 'version') { - this.showMessage("Current version: 2019.2.0"); + this.showCommand("Current version: 2019.2.0"); } else if (this.command === 'start all') { - this.showMessage("Starting all nodes..."); + this.showCommand("Starting all nodes..."); this.nodeService.startAll(this.server, this.project).subscribe(() => { - this.showMessage("All nodes started.") + this.showCommand("All nodes started.") }); } else if (this.command === 'stop all') { - this.showMessage("Stopping all nodes..."); + this.showCommand("Stopping all nodes..."); this.nodeService.stopAll(this.server, this.project).subscribe(() => { - this.showMessage("All nodes stopped.") + this.showCommand("All nodes stopped.") }); } else if (this.command === 'suspend all') { - this.showMessage("Suspending all nodes..."); + this.showCommand("Suspending all nodes..."); this.nodeService.suspendAll(this.server, this.project).subscribe(() => { - this.showMessage("All nodes suspended.") + this.showCommand("All nodes suspended.") }); } else if (this.command === 'reload all') { - this.showMessage("Reloading all nodes..."); + this.showCommand("Reloading all nodes..."); this.nodeService.reloadAll(this.server, this.project).subscribe(() => { - this.showMessage("All nodes reloaded.") + this.showCommand("All nodes reloaded.") }); } else if ( this.regexStart.test(this.command) || this.regexStop.test(this.command) || this.regexSuspend.test(this.command) || this.regexReload.test(this.command) || this.regexShow.test(this.command)) { @@ -112,47 +133,66 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy { let node = this.nodesDataSource.getItems().find(n => n.name.valueOf() === splittedCommand[1].valueOf()); if (node) { if (this.regexStart.test(this.command)) { - this.showMessage(`Starting node ${splittedCommand[1]}...`); - this.nodeService.start(this.server, node).subscribe(() => this.showMessage(`Node ${node.name} started.`)); + this.showCommand(`Starting node ${splittedCommand[1]}...`); + this.nodeService.start(this.server, node).subscribe(() => this.showCommand(`Node ${node.name} started.`)); } else if (this.regexStop.test(this.command)) { - this.showMessage(`Stopping node ${splittedCommand[1]}...`); - this.nodeService.stop(this.server, node).subscribe(() => this.showMessage(`Node ${node.name} stopped.`)); + this.showCommand(`Stopping node ${splittedCommand[1]}...`); + this.nodeService.stop(this.server, node).subscribe(() => this.showCommand(`Node ${node.name} stopped.`)); } else if (this.regexSuspend.test(this.command)) { - this.showMessage(`Suspending node ${splittedCommand[1]}...`); - this.nodeService.suspend(this.server, node).subscribe(() => this.showMessage(`Node ${node.name} suspended.`)); + this.showCommand(`Suspending node ${splittedCommand[1]}...`); + this.nodeService.suspend(this.server, node).subscribe(() => this.showCommand(`Node ${node.name} suspended.`)); } else if (this.regexReload.test(this.command)) { - this.showMessage(`Reloading node ${splittedCommand[1]}...`); - this.nodeService.reload(this.server, node).subscribe(() => this.showMessage(`Node ${node.name} reloaded.`)); + this.showCommand(`Reloading node ${splittedCommand[1]}...`); + this.nodeService.reload(this.server, node).subscribe(() => this.showCommand(`Node ${node.name} reloaded.`)); } else if (this.regexShow.test(this.command)) { - this.showMessage(`Information about node ${node.name}:`); - this.showMessage(this.printNode(node)); + this.showCommand(`Information about node ${node.name}:`); + this.showCommand(this.printNode(node)); } } else { - this.showMessage(`Node with ${splittedCommand[1]} name was not found.`); + this.showCommand(`Node with ${splittedCommand[1]} name was not found.`); } } else { - this.showMessage(`Unknown syntax: ${this.command}`); + this.showCommand(`Unknown syntax: ${this.command}`); } this.command = ''; } clearConsole() { - this.console.nativeElement.innerHTML = ''; + this.filteredEvents = []; this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight; } - showMessage(message: string) { - this.logEventsDataSource.clear(); - this.logEventsDataSource.add(this.console.nativeElement.innerHTML + message + "
"); + showCommand(message: string) { + this.showMessage({ + type: 'command', + message: message + }); + } - this.console.nativeElement.innerHTML += message += "
"; + showMessage(event: LogEvent) { + this.logEventsDataSource.add(event); + this.filteredEvents = this.getFilteredEvents(); this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight; } + getFilteredEvents(): LogEvent[] { + if (this.selectedFilter === 'server requests') { + return this.logEventsDataSource.getItems().filter(n => n.type === 'server request' || n.type === 'command'); + } else if (this.selectedFilter === 'errors') { + return this.logEventsDataSource.getItems().filter(n => n.type === 'error' || n.type === 'command'); + } else if (this.selectedFilter === 'warnings') { + return this.logEventsDataSource.getItems().filter(n => n.type === 'warning' || n.type === 'command'); + } else if (this.selectedFilter === 'map updates') { + return this.logEventsDataSource.getItems().filter(n => n.type === 'map update' || n.type === 'command'); + } else { + return this.logEventsDataSource.getItems(); + } + } + printNode(node: Node): string { return `command_line: ${node.command_line}, compute_id: ${node.compute_id}, diff --git a/src/app/components/project-map/log-console/log-events-datasource.ts b/src/app/components/project-map/log-console/log-events-datasource.ts index 29fa4801..9bc21a23 100644 --- a/src/app/components/project-map/log-console/log-events-datasource.ts +++ b/src/app/components/project-map/log-console/log-events-datasource.ts @@ -1,9 +1,10 @@ import { Injectable } from '@angular/core'; import { DataSource } from '../../../cartography/datasources/datasource'; +import { LogEvent } from '../../../models/logEvent'; @Injectable() -export class LogEventsDataSource extends DataSource { - protected getItemKey(log: string) { +export class LogEventsDataSource extends DataSource { + protected getItemKey(log: LogEvent) { return log; } } diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index 3f84ea0a..e49eaaf6 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -136,6 +136,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { ngOnInit() { this.settings = this.settingsService.getAll(); this.isTopologySummaryVisible = this.mapSettingsService.isTopologySummaryVisible; + this.isConsoleVisible = this.mapSettingsService.isLogConsoleVisible; this.progressService.activate(); const routeSub = this.route.paramMap.subscribe((paramMap: ParamMap) => { @@ -275,6 +276,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { this.ws = new WebSocket(this.projectService.notificationsPath(this.server, project.project_id)); this.ws.onmessage = (event: MessageEvent) => { + // console.log(event); this.projectWebServiceHandler.handleMessage(JSON.parse(event.data)); }; @@ -406,6 +408,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { public toggleShowConsole(visible: boolean) { this.isConsoleVisible = visible; + this.mapSettingsService.toggleLogConsole(this.isConsoleVisible); } public toggleShowTopologySummary(visible: boolean) { diff --git a/src/app/models/logEvent.ts b/src/app/models/logEvent.ts new file mode 100644 index 00000000..4f3e7110 --- /dev/null +++ b/src/app/models/logEvent.ts @@ -0,0 +1,4 @@ +export class LogEvent { + type: string; + message: string; +} diff --git a/src/app/services/mapsettings.service.ts b/src/app/services/mapsettings.service.ts index caf4a6c8..2f1764e5 100644 --- a/src/app/services/mapsettings.service.ts +++ b/src/app/services/mapsettings.service.ts @@ -5,6 +5,7 @@ import { Subject } from 'rxjs'; export class MapSettingsService { public isMapLocked = new Subject(); public isTopologySummaryVisible: boolean = false; + public isLogConsoleVisible: boolean = false; constructor() {} @@ -15,4 +16,8 @@ export class MapSettingsService { toggleTopologySummary(value: boolean) { this.isTopologySummaryVisible = value; } + + toggleLogConsole(value: boolean) { + this.isLogConsoleVisible = value; + } }