Skip to content

Commit

Permalink
Revert "NAS-124392: Remove web shell (#8967)" (#9032)
Browse files Browse the repository at this point in the history
This reverts commit b8a4319.
  • Loading branch information
undsoft authored Oct 10, 2023
1 parent b8a4319 commit 8743934
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export const rootRouterConfig: Routes = [{
loadChildren: 'app/pages/systemprocesses/system-processes.module#SystemProcessesModule',
data: { title: 'System Processes', breadcrumb: 'System Processes' },
},
{
path: 'shell',
loadChildren: './pages/shell/shell.module#ShellModule',
data: { title: 'Shell', breadcrumb: 'Shell' },
},
{
path: 'guide',
loadChildren: './pages/guide/guide.module#GuideModule',
Expand Down
1 change: 1 addition & 0 deletions src/app/pages/shell/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './shell.component';
13 changes: 13 additions & 0 deletions src/app/pages/shell/shell.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.shellTooltip {
position: absolute !important;
right: 20px;
}

#terminal {
margin-bottom: 10px;
overflow: hidden;
}

mat-card {
min-width: 700px;
}
33 changes: 33 additions & 0 deletions src/app/pages/shell/shell.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<mat-card class="p-0">
<mat-card-title class="mat-bg-primary m-0">
<div class="card-title-text">
{{"Shell" | translate}}
</div>
</mat-card-title>

<div
id="terminal"
[ngStyle]="{'font-size' : font_size+'px'}"
#terminal
(window:resize)="onResize($event)"
(contextmenu)="onRightClick()"
></div>

<mat-card-content *ngIf="shellConnected; else Reconnect">
<!-- <mat-divider class="mb-1"></mat-divider> -->
{{"Set font size" | translate}}:
<mat-slider min="10" max="20" step="1" [(ngModel)]="font_size"
ix-auto ix-auto-type="slider" ix-auto-identifier="Set font size"></mat-slider>
<button mat-button class="mat-basic" (click)="resetDefault()" matTooltip="{{'Reset font size to default value' | translate }}"
ix-auto ix-auto-type="button" ix-auto-identifier="RESTORE DEFAULT">{{"Restore default" | translate}}</button>
<tooltip class="shellTooltip" position="left" [message]=usage_tooltip
ix-auto ix-auto-type="tooltip-icon" ix-auto-identifier="Shell"></tooltip>
</mat-card-content>
<ng-template #Reconnect>
<mat-card-content>
<button mat-button color="primary" (click)="reconnect()"
ix-auto ix-auto-type="button" ix-auto-identifier="RECONNECT"
>{{"Reconnect" | translate}}</button>
</mat-card-content>
</ng-template>
</mat-card>
140 changes: 140 additions & 0 deletions src/app/pages/shell/shell.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChange, ViewChild,
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material/dialog';
import { ShellService, WebSocketService } from '../../services';
import helptext from '../../helptext/shell/shell';
import { CopyPasteMessageComponent } from './copy-paste-message.component';

@Component({
selector: 'app-shell',
templateUrl: './shell.component.html',
styleUrls: ['./shell.component.css'],
providers: [ShellService],
})
export class ShellComponent implements OnInit, OnChanges, OnDestroy {
// sets the shell prompt
@Input() prompt = '';
// xter container
@ViewChild('terminal', { static: true }) container: ElementRef;
// xterm variables
cols: string;
rows: string;
font_size = 14;
token: any;
xterm: any;
resize_terminal = true;
private shellSubscription: any;

usage_tooltip = helptext.usage_tooltip;

clearLine = '\u001b[2K\r';
shellConnected = false;

ngOnInit() {
this.getAuthToken().subscribe((res) => {
this.initializeWebShell(res);
this.shellSubscription = this.ss.shellOutput.subscribe((value) => {
if (value !== undefined) {
this.xterm.write(value);
}
});
this.initializeTerminal();
});
}

ngOnDestroy() {
if (this.ss.connected) {
this.ss.socket.close();
}
if (this.shellSubscription) {
this.shellSubscription.unsubscribe();
}
}

onResize(event) {
// this.resizeTerm();
}

resetDefault() {
this.font_size = 14;
}

ngOnChanges(changes: {
[propKey: string]: SimpleChange;
}) {
const log: string[] = [];
for (const propName in changes) {
const changedProp = changes[propName];
// reprint prompt
if (propName === 'prompt' && this.xterm != null) {
this.xterm.write(this.clearLine + this.prompt);
}
}
}

onRightClick(): false {
this.dialog.open(CopyPasteMessageComponent);
return false;
}

initializeTerminal() {
const domHeight = document.body.offsetHeight;
const domWidth = document.body.offsetWidth;
let colNum = (domWidth * 0.75 - 104) / 10;
if (colNum < 80) {
colNum = 80;
}
let rowNum = (domHeight * 0.75 - 104) / 21;
if (rowNum < 10) {
rowNum = 10;
}

this.xterm = new (<any>window).Terminal({
cursorBlink: false,
tabStopWidth: 8,
// 'cols': parseInt(colNum.toFixed(),10),
// 'rows': parseInt(rowNum.toFixed(),10),
focus: true,
});
this.xterm.open(this.container.nativeElement, true);
this.xterm.attach(this.ss);
this.xterm._initialized = true;
}

resizeTerm() {
const domHeight = document.body.offsetHeight;
const domWidth = document.body.offsetWidth;
let colNum = (domWidth * 0.75 - 104) / 10;
if (colNum < 80) {
colNum = 80;
}
let rowNum = (domHeight * 0.75 - 104) / 21;
if (rowNum < 10) {
rowNum = 10;
}
this.xterm.resize(colNum, rowNum);
return true;
}

initializeWebShell(res: string) {
this.ss.token = res;
this.ss.connect();

this.ss.shellConnected.subscribe((res) => {
this.shellConnected = res;
});
}

getAuthToken() {
return this.ws.call('auth.generate_token');
}

reconnect() {
this.ss.connect();
}

constructor(private ws: WebSocketService, public ss: ShellService, public translate: TranslateService, private dialog: MatDialog) {
}
}
18 changes: 18 additions & 0 deletions src/app/pages/shell/shell.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Common Modules
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MaterialModule } from '../../appMaterial.module';
import { EntityModule } from '../common/entity/entity.module';
import { CommonDirectivesModule } from '../../directives/common/common-directives.module';
// Component Modules
import { ShellComponent } from './shell.component';
import { routing } from './shell.routing';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponents } from 'app/core/components/corecomponents.module';

@NgModule({
imports: [CommonModule, FormsModule, EntityModule, routing, MaterialModule, TranslateModule, CoreComponents, CommonDirectivesModule],
declarations: [ShellComponent],
})
export class ShellModule {}
11 changes: 11 additions & 0 deletions src/app/pages/shell/shell.routing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ModuleWithProviders } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { ShellComponent } from './shell.component';

export const routes: Routes = [{
path: '',
component: ShellComponent,
}];

export const routing: ModuleWithProviders = RouterModule.forChild(routes);
7 changes: 7 additions & 0 deletions src/app/services/navigation/navigation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ export class NavigationService {
icon: 'perm_data_setting',
state: 'systemprocesses',
},
{
name: T('Shell'),
type: 'link',
tooltip: T('Shell'),
icon: 'console-line',
state: 'shell',
},
{
name: T('Guide'),
type: 'extLink',
Expand Down

0 comments on commit 8743934

Please sign in to comment.