diff --git a/package.json b/package.json
index f973a565..066d2671 100644
--- a/package.json
+++ b/package.json
@@ -80,6 +80,7 @@
"tree-kill": "^1.2.1",
"typeface-roboto": "^0.0.75",
"xterm": "^4.1.0",
+ "xterm-addon-attach": "^0.5.0",
"yargs": "^15.0.2",
"zone.js": "^0.10.2"
},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 110717b4..657c1be0 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -268,6 +268,10 @@ import { OpenFileExplorerActionComponent } from './components/project-map/contex
import { NgxChildProcessModule } from 'ngx-childprocess';
import { ServerResolve } from './resolvers/server-resolve';
import { ProjectMapGuard } from './guards/project-map-guard';
+import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component';
+import { WebConsoleComponent } from './components/project-map/web-console/web-console.component';
+import { ConsoleWrapperComponent } from './components/project-map/console-wrapper/console-wrapper.component';
+import { NodeConsoleService } from './services/nodeConsole.service';
if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@@ -449,7 +453,10 @@ if (environment.production) {
SystemStatusComponent,
StatusInfoComponent,
StatusChartComponent,
- OpenFileExplorerActionComponent
+ OpenFileExplorerActionComponent,
+ HttpConsoleActionComponent,
+ WebConsoleComponent,
+ ConsoleWrapperComponent
],
imports: [
BrowserModule,
@@ -541,6 +548,7 @@ if (environment.production) {
Gns3vmService,
ThemeService,
GoogleAnalyticsService,
+ NodeConsoleService,
ServerResolve,
ProjectMapGuard,
Title
diff --git a/src/app/components/project-map/console-wrapper/console-wrapper.component.html b/src/app/components/project-map/console-wrapper/console-wrapper.component.html
new file mode 100644
index 00000000..7b2280a4
--- /dev/null
+++ b/src/app/components/project-map/console-wrapper/console-wrapper.component.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ GNS3 console
+
+
+
+ place for log console
+
+
+
+
+ {{node.name}}
+
+
+
+
+
+
+
+
diff --git a/src/app/components/project-map/console-wrapper/console-wrapper.component.scss b/src/app/components/project-map/console-wrapper/console-wrapper.component.scss
new file mode 100644
index 00000000..374dd797
--- /dev/null
+++ b/src/app/components/project-map/console-wrapper/console-wrapper.component.scss
@@ -0,0 +1,96 @@
+.consoleWrapper {
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+ position: fixed;
+ bottom: 20px;
+ left: 20px;
+ height: 180px;
+ width: 600px;
+ background: #263238;
+ color: white;
+ overflow: hidden;
+ font-size: 12px;
+}
+
+.lightTheme {
+ background: white!important;
+ color: black;
+}
+
+.filterButton {
+ background: transparent;
+ color: white;
+ border: none;
+ margin-top: 0px;
+ outline: none;
+ color: #dbd5d5;
+ font-weight: bold;
+ padding: 0px;
+}
+
+.consoleFiltering {
+ display: flex;
+}
+
+.consoleHeader {
+ width: 100%;
+ height: 30px;
+ font-size: 12px;
+ overflow: hidden;
+ display: flex;
+ padding: 2px;
+ justify-content: space-between;
+}
+
+.console {
+ width: 596px;
+ height: 120px;
+ overflow-y: scroll;
+ padding: 2px;
+ color: #dbd5d5;
+ scrollbar-color: darkgrey #263238;
+ scrollbar-width: thin;
+}
+
+.consoleInput {
+ width: 100%;
+ height: 30px;
+ padding: 2px;
+ display: flex;
+}
+
+.commandLine {
+ background-color: transparent;
+ color: white;
+ border: none;
+}
+
+.inputIcon {
+ margin-top: 2px;
+}
+
+mat-icon {
+ font-size: 20px;
+ width: 20px;
+ height: 20px;
+}
+
+input:focus{
+ outline: none;
+}
+
+::-webkit-scrollbar {
+ width: 0.5em;
+}
+
+::-webkit-scrollbar-track {
+ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
+}
+
+::-webkit-scrollbar-thumb {
+ background-color: darkgrey;
+ outline: 1px solid #263238;
+}
+
+.closeButton {
+ cursor: pointer;
+}
diff --git a/src/app/components/project-map/console-wrapper/console-wrapper.component.spec.ts b/src/app/components/project-map/console-wrapper/console-wrapper.component.spec.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/components/project-map/console-wrapper/console-wrapper.component.ts b/src/app/components/project-map/console-wrapper/console-wrapper.component.ts
new file mode 100644
index 00000000..102ca13c
--- /dev/null
+++ b/src/app/components/project-map/console-wrapper/console-wrapper.component.ts
@@ -0,0 +1,127 @@
+import { Component, OnInit, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
+import { Subscription } from 'rxjs';
+import { Project } from '../../../models/project';
+import { Server } from '../../../models/server';
+import { ResizeEvent } from 'angular-resizable-element';
+import { ThemeService } from '../../../services/theme.service';
+import { FormControl } from '@angular/forms';
+import { NodeConsoleService } from '../../../services/nodeConsole.service';
+
+
+@Component({
+ selector: 'app-console-wrapper',
+ templateUrl: './console-wrapper.component.html',
+ styleUrls: ['./console-wrapper.component.scss']
+})
+export class ConsoleWrapperComponent implements OnInit, AfterViewInit, OnDestroy {
+ @Input() server: Server;
+ @Input() project: Project;
+ @Output() closeConsole = new EventEmitter();
+
+ filters: string[] = ['all', 'errors', 'warnings', 'info', 'map updates', 'server requests'];
+ selectedFilter: string = 'all';
+
+ public style: object = {};
+ public styleInside: object = { height: `120px` };
+
+ public isDraggingEnabled: boolean = false;
+ public isLightThemeEnabled: boolean = false;
+
+ constructor(
+ private consoleService: NodeConsoleService,
+ private themeService: ThemeService
+ ) {}
+
+ nodes: Node[] = [];
+ selected = new FormControl(0);
+
+ ngOnInit() {
+ this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
+ this.style = { bottom: '20px', left: '20px', width: '600px', height: '180px'}; // style properties
+
+ this.consoleService.nodeConsoleTrigger.subscribe((node) => {
+ this.addTab(node, true);
+ });
+ }
+
+ ngAfterViewInit() {
+ // this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
+ }
+
+ ngOnDestroy() {}
+
+ addTab(node: Node, selectAfterAdding: boolean) {
+ this.nodes.push(node);
+
+ if (selectAfterAdding) {
+ this.selected.setValue(this.nodes.length);
+ }
+ }
+
+ removeTab(index: number) {
+ this.nodes.splice(index, 1);
+ }
+
+ toggleDragging(value: boolean) {
+ this.isDraggingEnabled = value;
+ }
+
+ dragWidget(event) {
+ let x: number = Number(event.movementX);
+ let y: number = Number(event.movementY);
+
+ let width: number = Number(this.style['width'].split('px')[0]);
+ let height: number = Number(this.style['height'].split('px')[0]);
+ let left: number = Number(this.style['left'].split('px')[0]) + x;
+ if (this.style['top']) {
+ let top: number = Number(this.style['top'].split('px')[0]) + y;
+ this.style = {
+ position: 'fixed',
+ left: `${left}px`,
+ top: `${top}px`,
+ width: `${width}px`,
+ height: `${height}px`
+ };
+ } else {
+ let bottom: number = Number(this.style['bottom'].split('px')[0]) - y;
+ this.style = {
+ position: 'fixed',
+ left: `${left}px`,
+ bottom: `${bottom}px`,
+ width: `${width}px`,
+ height: `${height}px`
+ };
+ }
+ }
+
+ 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`
+ };
+ }
+
+ close() {
+ this.closeConsole.emit(false);
+ }
+}
diff --git a/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.html b/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.html
new file mode 100644
index 00000000..55f6dcce
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.html
@@ -0,0 +1,4 @@
+
diff --git a/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.spec.ts b/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.spec.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.ts b/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.ts
new file mode 100644
index 00000000..6ead7e85
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/http-console/http-console-action.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { Node } from '../../../../../cartography/models/node';
+import { Server } from '../../../../../models/server';
+import { NodeConsoleService } from '../../../../../services/nodeConsole.service';
+
+
+@Component({
+ selector: 'app-http-console-action',
+ templateUrl: './http-console-action.component.html'
+})
+export class HttpConsoleActionComponent implements OnInit {
+ @Input() server: Server;
+ @Input() nodes: Node[];
+
+ constructor(
+ private consoleService: NodeConsoleService
+ ) { }
+
+ ngOnInit() {}
+
+ openConsole() {
+ this.consoleService.openConsoleForNode(this.nodes[0]);
+ }
+}
diff --git a/src/app/components/project-map/context-menu/context-menu.component.html b/src/app/components/project-map/context-menu/context-menu.component.html
index 3bc02127..6b35ff5d 100644
--- a/src/app/components/project-map/context-menu/context-menu.component.html
+++ b/src/app/components/project-map/context-menu/context-menu.component.html
@@ -15,6 +15,11 @@
+
-
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 8e6d4657..c685f7cf 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
@@ -14,6 +14,7 @@ import { HttpServer } from '../../../services/http-server.service';
import { LogEvent } from '../../../models/logEvent';
import { ResizeEvent } from 'angular-resizable-element';
import { ThemeService } from '../../../services/theme.service';
+import { FormControl } from '@angular/forms';
@Component({
@@ -22,10 +23,12 @@ import { ThemeService } from '../../../services/theme.service';
styleUrls: ['./log-console.component.scss']
})
export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
- @Input() project: Project;
@Input() server: Server;
+ @Input() project: Project;
@Output() closeConsole = new EventEmitter();
+
@ViewChild('console', {static: false}) console: ElementRef;
+
private nodeSubscription: Subscription;
private linkSubscription: Subscription;
private drawingSubscription: Subscription;
@@ -60,6 +63,21 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
private httpService: HttpServer,
private themeService: ThemeService
) {}
+
+ tabs = ['GNS3 console', 'PC2'];
+ selected = new FormControl(0);
+
+ addTab(selectAfterAdding: boolean) {
+ this.tabs.push('New');
+
+ if (selectAfterAdding) {
+ this.selected.setValue(this.tabs.length - 1);
+ }
+ }
+
+ removeTab(index: number) {
+ this.tabs.splice(index, 1);
+ }
ngOnInit() {
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
@@ -155,7 +173,7 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
}
ngAfterViewInit() {
- this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
+ // this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
}
ngOnDestroy() {
@@ -294,13 +312,13 @@ export class LogConsoleComponent implements OnInit, AfterViewInit, OnDestroy {
}
showMessage(event: LogEvent) {
- this.logEventsDataSource.add(event);
- this.filteredEvents = this.getFilteredEvents();
- this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
+ // this.logEventsDataSource.add(event);
+ // this.filteredEvents = this.getFilteredEvents();
+ // this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
- setTimeout( () => {
- this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
- }, 100 );
+ // setTimeout( () => {
+ // this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
+ // }, 100 );
}
getFilteredEvents(): LogEvent[] {
diff --git a/src/app/components/project-map/project-map.component.html b/src/app/components/project-map/project-map.component.html
index 8276557c..bc4c464a 100644
--- a/src/app/components/project-map/project-map.component.html
+++ b/src/app/components/project-map/project-map.component.html
@@ -51,6 +51,14 @@
developer_board
Go to servers
+
+