@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
101 lines • 18 kB
JavaScript
import { Component, ViewEncapsulation } from '@angular/core';
import { ActionBarItemComponent, C8yTranslatePipe, IconDirective, TitleComponent } from '@c8y/ngx-components';
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { ShellAdapter } from './shell-adapter';
import { RemoteAccessService } from '@c8y/ngx-components/remote-access/data';
import { ActivatedRoute } from '@angular/router';
// workaround as we were unable to import this in component styles
import '@xterm/xterm/css/xterm.css';
import { NgIf } from '@angular/common';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components/remote-access/data";
import * as i2 from "@angular/router";
export class TerminalViewerComponent {
constructor(remoteAccess, activatedRoute) {
this.remoteAccess = remoteAccess;
this.activatedRoute = activatedRoute;
this.title = '';
this.container = null;
this.terminal = null;
this.socket = null;
this.firstDeviceMessageReceived = false;
this.configurationId = this.activatedRoute.snapshot.params.configurationId;
this.deviceId = this.activatedRoute.parent.snapshot.params.id;
}
ngOnDestroy() {
this.observer?.disconnect();
const stringToSend = 'exit\n';
const sendQueue = [];
for (let i = 0; i < stringToSend.length; i++) {
sendQueue.push(stringToSend.charCodeAt(i));
}
this.socket?.send(new Uint8Array(sendQueue));
this.socket?.close();
}
ngAfterViewInit() {
this.container = document.getElementById('terminal-screen');
this.terminal = new Terminal({
fontSize: 18,
fontFamily: 'consolas, monospace',
cursorBlink: true
});
const fitAddon = new FitAddon();
this.socket = new WebSocket(this.remoteAccess.getWebSocketUri(this.deviceId, this.configurationId), 'binary');
this.socket.binaryType = 'arraybuffer';
this.terminal.loadAddon(fitAddon);
this.terminal.open(this.container);
fitAddon.fit();
const shellAdapter = new ShellAdapter(this.terminal);
this.observer = new ResizeObserver(() => {
fitAddon.fit();
});
this.observer.observe(this.container);
this.terminal.writeln('\u001b[92mEstablishing Websocket connection... \u001b[39m \r\n');
this.terminal.focus();
this.socket.onopen = () => {
this.terminal.writeln('\u001b[92mWebsocket connection was established successfully, waiting for device... \u001b[39m \r\n');
};
this.socket.onclose = () => {
this.terminal.writeln('');
this.terminal.writeln('\r\n\u001b[91mDevice disconnected. \u001b[39m \r\n');
this.terminal.writeln('\r\n\u001b[91mWebsocket connection was closed. \u001b[39m \r\n');
};
this.socket.onmessage = message => {
if (!this.firstDeviceMessageReceived) {
this.firstDeviceMessageReceived = true;
this.terminal.writeln('\u001b[92mDevice connection was established successfully. \u001b[39m \r\n');
}
const filteredData = shellAdapter.filterReceiveData(message.data);
if (filteredData.dataToSend.length) {
this.socket.send(filteredData.dataToSend);
}
if (filteredData.dataToDisplay.length) {
this.terminal.write(filteredData.dataToDisplay);
}
};
this.terminal.onData(data => {
if (this.firstDeviceMessageReceived) {
const encodedToSend = shellAdapter.filterSendData(data);
if (encodedToSend.length) {
this.socket.send(encodedToSend);
}
}
});
}
toggleFullscreen() {
if (document.fullscreenElement) {
document.exitFullscreen();
}
else {
this.container.requestFullscreen();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TerminalViewerComponent, deps: [{ token: i1.RemoteAccessService }, { token: i2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TerminalViewerComponent, isStandalone: true, selector: "c8y-terminal-viewer", ngImport: i0, template: "<c8y-title>Terminal Viewer: {{ title | translate }}</c8y-title>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"firstDeviceMessageReceived\">\n <button\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"'expand'\"></i>\n <span translate>Fullscreen</span>\n </button>\n </c8y-action-bar-item>\n\n<div class=\"content-fullpage\" >\n <div id=\"terminal-screen\" class=\"inner-scroll\"></div>\n</div>", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TerminalViewerComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-terminal-viewer', encapsulation: ViewEncapsulation.None, standalone: true, imports: [TitleComponent, C8yTranslatePipe, ActionBarItemComponent, IconDirective, NgIf], template: "<c8y-title>Terminal Viewer: {{ title | translate }}</c8y-title>\n\n<c8y-action-bar-item [placement]=\"'right'\" *ngIf=\"firstDeviceMessageReceived\">\n <button\n class=\"btn btn-link\"\n (click)=\"toggleFullscreen()\"\n >\n <i [c8yIcon]=\"'expand'\"></i>\n <span translate>Fullscreen</span>\n </button>\n </c8y-action-bar-item>\n\n<div class=\"content-fullpage\" >\n <div id=\"terminal-screen\" class=\"inner-scroll\"></div>\n</div>" }]
}], ctorParameters: () => [{ type: i1.RemoteAccessService }, { type: i2.ActivatedRoute }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVybWluYWwtdmlld2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3JlbW90ZS1hY2Nlc3MvdGVybWluYWwtdmlld2VyL3Rlcm1pbmFsLXZpZXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9yZW1vdGUtYWNjZXNzL3Rlcm1pbmFsLXZpZXdlci90ZXJtaW5hbC12aWV3ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixTQUFTLEVBQWEsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkYsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixnQkFBZ0IsRUFDaEIsYUFBYSxFQUNiLGNBQWMsRUFDZixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsa0VBQWtFO0FBQ2xFLE9BQU8sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7O0FBU3ZDLE1BQU0sT0FBTyx1QkFBdUI7SUFVbEMsWUFDVSxZQUFpQyxFQUNqQyxjQUE4QjtRQUQ5QixpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFDakMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBWHhDLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxjQUFTLEdBQXVCLElBQUksQ0FBQztRQUNyQyxhQUFRLEdBQW9CLElBQUksQ0FBQztRQUNqQyxXQUFNLEdBQXFCLElBQUksQ0FBQztRQUNoQywr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WUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDckMsQ0FBQztJQUNILENBQUM7K0dBbEdVLHVCQUF1QjttR0FBdkIsdUJBQXVCLCtFQ3ZCcEMsbWRBY00sNENET00sY0FBYyw4RUFBRSxnQkFBZ0Isa0RBQUUsc0JBQXNCLDBKQUFFLGFBQWEsMkVBQUUsSUFBSTs7NEZBRTVFLHVCQUF1QjtrQkFQbkMsU0FBUzsrQkFDRSxxQkFBcUIsaUJBRWhCLGlCQUFpQixDQUFDLElBQUksY0FDekIsSUFBSSxXQUNQLENBQUMsY0FBYyxFQUFFLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIE9uRGVzdHJveSwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFjdGlvbkJhckl0ZW1Db21wb25lbnQsXG4gIEM4eVRyYW5zbGF0ZVBpcGUsXG4gIEljb25EaXJlY3RpdmUsXG4gIFRpdGxlQ29tcG9uZW50XG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVGVybWluYWwgfSBmcm9tICdAeHRlcm0veHRlcm0nO1xuaW1wb3J0IHsgRml0QWRkb24gfSBmcm9tICdAeHRlcm0vYWRkb24tZml0JztcbmltcG9ydCB7IFNoZWxsQWRhcHRlciB9IGZyb20gJy4vc2hlbGwtYWRhcHRlcic7XG5pbXBvcnQgeyBSZW1vdGVBY2Nlc3NTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9yZW1vdGUtYWNjZXNzL2RhdGEnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuLy8gd29ya2Fyb3VuZCBhcyB3ZSB3ZXJlIHVuYWJsZSB0byBpbXBvcnQgdGhpcyBpbiBjb21wb25lbnQgc3R5bGVzXG5pbXBvcnQgJ0B4dGVybS94dGVybS9jc3MveHRlcm0uY3NzJztcbmltcG9ydCB7IE5nSWYgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktdGVybWluYWwtdmlld2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Rlcm1pbmFsLXZpZXdlci5jb21wb25lbnQuaHRtbCcsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtUaXRsZUNvbXBvbmVudCwgQzh5VHJhbnNsYXRlUGlwZSwgQWN0aW9uQmFySXRlbUNvbXBvbmVudCwgSWNvbkRpcmVjdGl2ZSwgTmdJZl1cbn0pXG5leHBvcnQgY2xhc3MgVGVybWluYWxWaWV3ZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICB0aXRsZSA9ICcnO1xuICBjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHRlcm1pbmFsOiBUZXJtaW5hbCB8IG51bGwgPSBudWxsO1xuICBzb2NrZXQ6IFdlYlNvY2tldCB8IG51bGwgPSBudWxsO1xuICBmaXJzdERldmljZU1lc3NhZ2VSZWNlaXZlZCA9IGZhbHNlO1xuICByZWFkb25seSBjb25maWd1cmF0aW9uSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcbiAgcHJvdGVjdGVkIG9ic2VydmVyOiBSZXNpemVPYnNlcnZlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlbW90ZUFjY2VzczogUmVtb3RlQWNjZXNzU2VydmljZSxcbiAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVxuICApIHtcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb25JZCA9IHRoaXMuYWN0aXZhdGVkUm91dGUuc25hcHNob3QucGFyYW1zLmNvbmZpZ3VyYXRpb25JZDtcbiAgICB0aGlzLmRldmljZUlkID0gdGhpcy5hY3RpdmF0ZWRSb3V0ZS5wYXJlbnQuc25hcHNob3QucGFyYW1zLmlkO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIGNvbnN0IHN0cmluZ1RvU2VuZCA9ICdleGl0XFxuJztcbiAgICBjb25zdCBzZW5kUXVldWUgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0cmluZ1RvU2VuZC5sZW5ndGg7IGkrKykge1xuICAgICAgc2VuZFF1ZXVlLnB1c2goc3RyaW5nVG9TZW5kLmNoYXJDb2RlQXQoaSkpO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldD8uc2VuZChuZXcgVWludDhBcnJheShzZW5kUXVldWUpKTtcbiAgICB0aGlzLnNvY2tldD8uY2xvc2UoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXJtaW5hbC1zY3JlZW4nKTtcbiAgICB0aGlzLnRlcm1pbmFsID0gbmV3IFRlcm1pbmFsKHtcbiAgICAgIGZvbnRTaXplOiAxOCxcbiAgICAgIGZvbnRGYW1pbHk6ICdjb25zb2xhcywgbW9ub3NwYWNlJyxcbiAgICAgIGN1cnNvckJsaW5rOiB0cnVlXG4gICAgfSk7XG4gICAgY29uc3QgZml0QWRkb24gPSBuZXcgRml0QWRkb24oKTtcbiAgICB0aGlzLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQoXG4gICAgICB0aGlzLnJlbW90ZUFjY2Vzcy5nZXRXZWJTb2NrZXRVcmkodGhpcy5kZXZpY2VJZCwgdGhpcy5jb25maWd1cmF0aW9uSWQpLFxuICAgICAgJ2JpbmFyeSdcbiAgICApO1xuICAgIHRoaXMuc29ja2V0LmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICAgIHRoaXMudGVybWluYWwubG9hZEFkZG9uKGZpdEFkZG9uKTtcbiAgICB0aGlzLnRlcm1pbmFsLm9wZW4odGhpcy5jb250YWluZXIpO1xuICAgIGZpdEFkZG9uLmZpdCgpO1xuICAgIGNvbnN0IHNoZWxsQWRhcHRlciA9IG5ldyBTaGVsbEFkYXB0ZXIodGhpcy50ZXJtaW5hbCk7XG4gICAgdGhpcy5vYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBmaXRBZGRvbi5maXQoKTtcbiAgICB9KTtcbiAgICB0aGlzLm9ic2VydmVyLm9ic2VydmUodGhpcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy50ZXJtaW5hbC53cml0ZWxuKCdcXHUwMDFiWzkybUVzdGFibGlzaGluZyBXZWJzb2NrZXQgY29ubmVjdGlvbi4uLiBcXHUwMDFiWzM5bSBcXHJcXG4nKTtcbiAgICB0aGlzLnRlcm1pbmFsLmZvY3VzKCk7XG4gICAgdGhpcy5zb2NrZXQub25vcGVuID0gKCkgPT4ge1xuICAgICAgdGhpcy50ZXJtaW5hbC53cml0ZWxuKFxuICAgICAgICAnXFx1MDAxYls5Mm1XZWJzb2NrZXQgY29ubmVjdGlvbiB3YXMgZXN0YWJsaXNoZWQgc3VjY2Vzc2Z1bGx5LCB3YWl0aW5nIGZvciBkZXZpY2UuLi4gXFx1MDAxYlszOW0gXFxyXFxuJ1xuICAgICAgKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zb2NrZXQub25jbG9zZSA9ICgpID0+IHtcbiAgICAgIHRoaXMudGVybWluYWwud3JpdGVsbignJyk7XG4gICAgICB0aGlzLnRlcm1pbmFsLndyaXRlbG4oJ1xcclxcblxcdTAwMWJbOTFtRGV2aWNlIGRpc2Nvbm5lY3RlZC4gXFx1MDAxYlszOW0gXFxyXFxuJyk7XG4gICAgICB0aGlzLnRlcm1pbmFsLndyaXRlbG4oJ1xcclxcblxcdTAwMWJbOTFtV2Vic29ja2V0IGNvbm5lY3Rpb24gd2FzIGNsb3NlZC4gXFx1MDAxYlszOW0gXFxyXFxuJyk7XG4gICAgfTtcblxuICAgIHRoaXMuc29ja2V0Lm9ubWVzc2FnZSA9IG1lc3NhZ2UgPT4ge1xuICAgICAgaWYgKCF0aGlzLmZpcnN0RGV2aWNlTWVzc2FnZVJlY2VpdmVkKSB7XG4gICAgICAgIHRoaXMuZmlyc3REZXZpY2VNZXNzYWdlUmVjZWl2ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnRlcm1pbmFsLndyaXRlbG4oXG4gICAgICAgICAgJ1xcdTAwMWJbOTJtRGV2aWNlIGNvbm5lY3Rpb24gd2FzIGVzdGFibGlzaGVkIHN1Y2Nlc3NmdWxseS4gXFx1MDAxYlszOW0gXFxyXFxuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gc2hlbGxBZGFwdGVyLmZpbHRlclJlY2VpdmVEYXRhKG1lc3NhZ2UuZGF0YSk7XG4gICAgICBpZiAoZmlsdGVyZWREYXRhLmRhdGFUb1NlbmQubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuc29ja2V0LnNlbmQoZmlsdGVyZWREYXRhLmRhdGFUb1NlbmQpO1xuICAgICAgfVxuICAgICAgaWYgKGZpbHRlcmVkRGF0YS5kYXRhVG9EaXNwbGF5Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLnRlcm1pbmFsLndyaXRlKGZpbHRlcmVkRGF0YS5kYXRhVG9EaXNwbGF5KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy50ZXJtaW5hbC5vbkRhdGEoZGF0YSA9PiB7XG4gICAgICBpZiAodGhpcy5maXJzdERldmljZU1lc3NhZ2VSZWNlaXZlZCkge1xuICAgICAgICBjb25zdCBlbmNvZGVkVG9TZW5kID0gc2hlbGxBZGFwdGVyLmZpbHRlclNlbmREYXRhKGRhdGEpO1xuXG4gICAgICAgIGlmIChlbmNvZGVkVG9TZW5kLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc29ja2V0LnNlbmQoZW5jb2RlZFRvU2VuZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHRvZ2dsZUZ1bGxzY3JlZW4oKSB7XG4gICAgaWYgKGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50KSB7XG4gICAgICBkb2N1bWVudC5leGl0RnVsbHNjcmVlbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRhaW5lci5yZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgIH1cbiAgfVxufVxuIiwiPGM4eS10aXRsZT5UZXJtaW5hbCBWaWV3ZXI6IHt7IHRpdGxlIHwgdHJhbnNsYXRlIH19PC9jOHktdGl0bGU+XG5cbjxjOHktYWN0aW9uLWJhci1pdGVtIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiICpuZ0lmPVwiZmlyc3REZXZpY2VNZXNzYWdlUmVjZWl2ZWRcIj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImJ0biBidG4tbGlua1wiXG4gICAgICAoY2xpY2spPVwidG9nZ2xlRnVsbHNjcmVlbigpXCJcbiAgICA+XG4gICAgICA8aSBbYzh5SWNvbl09XCInZXhwYW5kJ1wiPjwvaT5cbiAgICAgIDxzcGFuIHRyYW5zbGF0ZT5GdWxsc2NyZWVuPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbjxkaXYgY2xhc3M9XCJjb250ZW50LWZ1bGxwYWdlXCIgPlxuICAgIDxkaXYgaWQ9XCJ0ZXJtaW5hbC1zY3JlZW5cIiBjbGFzcz1cImlubmVyLXNjcm9sbFwiPjwvZGl2PlxuPC9kaXY+Il19