Commit 9dd90dd4 authored by ibuler's avatar ibuler

[Update] 更新term模块

parent e93e9045
......@@ -47,7 +47,7 @@ import {AssetTreeDialogComponent} from './elements/asset-tree/asset-tree.compone
TestPageComponent,
...Pipes,
...ElementComponents,
...PagesComponents
...PagesComponents,
],
entryComponents: [
AssetTreeDialogComponent,
......
......@@ -3,9 +3,6 @@ import {NavList, View} from '../../pages/control/control/control.component';
import {AppService, LogService} from '../../app.service';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {FormControl, Validators} from '@angular/forms';
import {DataStore} from '../../globals';
import {ElementServerMenuComponent} from '../server-menu/server-menu.component';
import {DialogService} from '../dialog/dialog.service';
declare var $: any;
......@@ -149,39 +146,6 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
}
// autologin() {
// const asset_id = this._appService.getQueryString('asset_id');
// const user_id = this._appService.getQueryString('user_id');
// let tag = false;
// if (asset_id) {
// for (let g of this.Data) {
// if (g['assets_granted']) {
// for (let host of g['assets_granted']) {
// if (host.id.toString() === asset_id) {
// if (user_id) {
// host['system_users_granted'].forEach((user, kk) => {
// if (user.id.toString() === user_id.toString()) {
// this.login(host, user);
// tag = true;
// return;
// }
// });
// } else {
// this.Connect(host);
// tag = true;
// return;
// }
// }
// }
// }
// }
// if (!tag) {
// this._layer.alert('Maybe you do not have permission on that host');
// }
// }
// DataStore.autologin = true;
// }
login(host, user) {
const id = NavList.List.length - 1;
this._logger.debug(NavList);
......
......@@ -12,6 +12,7 @@ import {ElementServerMenuComponent} from './server-menu/server-menu.component';
import {ElementIframeComponent} from './iframe/iframe.component';
import {ElementDialogAlertComponent} from './dialog/dialog.service';
import {ElementGuacamoleComponent} from './guacamole/guacamole.component';
import {ElementSshTermComponent} from './ssh-term/ssh-term.component';
import {AssetTreeDialogComponent, ElementAssetTreeComponent} from './asset-tree/asset-tree.component';
export const ElementComponents = [
......@@ -29,5 +30,6 @@ export const ElementComponents = [
ElementDialogAlertComponent,
ElementGuacamoleComponent,
ElementAssetTreeComponent,
ElementSshTermComponent,
AssetTreeDialogComponent
];
<elements-term [term]="term"></elements-term>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SshTermComponent } from './ssh-term.component';
describe('SshTermComponent', () => {
let component: SshTermComponent;
let fixture: ComponentFixture<SshTermComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SshTermComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SshTermComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {AfterViewInit, Component, Input, OnInit } from '@angular/core';
import * as io from 'socket.io-client';
// import {ws} from '../../globals';
import * as Terminal from 'xterm/dist/xterm';
import {NavList} from '../../pages/control/control/control.component';
import {UUIDService} from '../../app.service';
const ws = io.connect('/ssh');
@Component({
selector: 'elements-ssh-term',
templateUrl: './ssh-term.component.html',
styleUrls: ['./ssh-term.component.scss']
})
export class ElementSshTermComponent implements OnInit, AfterViewInit {
@Input() host: any;
@Input() userid: any;
@Input() index: number;
@Input() token: string;
term: Terminal;
secret: string;
constructor(private _uuid: UUIDService) {
}
ngOnInit() {
this.secret = this._uuid.gen();
this.term = new Terminal({
// cols: 80,
// rows: 24,
useStyle: true,
screenKeys: true,
});
}
ngAfterViewInit() {
this.joinRoom();
}
joinRoom() {
NavList.List[this.index].Term = this.term;
if (this.host) {
ws.emit('host', {'uuid': this.host.id, 'userid': this.userid, 'secret': this.secret});
}
if (this.token) {
ws.emit('token', {'token': this.token, 'secret': this.secret});
}
const that = this;
this.term.on('data', function (data) {
ws.emit('data', {'data': data, 'room': NavList.List[that.index].room});
});
ws.on('data', data => {
if (data['room'] === NavList.List[that.index].room) {
that.term.write(data['data']);
}
});
ws.on('disconnect', () => {
that.disconnect();
});
ws.on('logout', (data) => {
if (data['room'] === NavList.List[that.index].room) {
NavList.List[that.index].connected = false;
// this.term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
}
});
ws.on('room', data => {
console.log('Compile secret: ', data['secret'], this.secret);
if (data['secret'] === this.secret) {
console.log('Set room: ', data['room']);
NavList.List[that.index].room = data['room'];
console.log('get', that.index, 'room: ', NavList.List[that.index].room);
}
});
}
disconnect() {
NavList.List[this.index].connected = false;
// this.term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
ws.emit('logout', NavList.List[this.index].room);
}
active() {
this.term.focus();
}
}
<div id="term" #term (mouseenter)="active()"></div>
<div #term (mouseenter)="active()"></div>
import {AfterViewInit, Component, Input, OnInit, ViewChild} from '@angular/core';
import {ElementRef} from '@angular/core';
import {term, Terminal, TermWS} from '../../globals';
import * as Terminal from 'xterm/dist/xterm';
// import { Terminal } from 'xterm';
import {NavList} from '../../pages/control/control/control.component';
import * as jQuery from 'jquery/dist/jquery.min.js';
import {UUIDService} from '../../app.service';
import {CookieService} from 'ngx-cookie-service';
import * as $ from 'jquery/dist/jquery.min.js';
import {Observable} from 'rxjs/Rx';
import 'rxjs/Observable';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({
selector: 'elements-term',
......@@ -13,110 +14,43 @@ import {CookieService} from 'ngx-cookie-service';
styleUrls: ['./term.component.css']
})
export class ElementTermComponent implements OnInit, AfterViewInit {
@Input() host: any;
@Input() userid: any;
@Input() index: number;
@Input() token: string;
@Input() monitor: string;
@ViewChild('term') el: ElementRef;
secret: string;
term: any;
@Input() term: Terminal;
col = 80;
row = 24;
winSizeChange$: Observable<any>;
constructor(private _uuid: UUIDService,
private _cookie: CookieService) {
constructor() {
}
ngOnInit() {
this.secret = this._uuid.gen();
this.term = Terminal({
cols: 80,
rows: 24,
useStyle: true,
screenKeys: true,
});
// NavList.List[this.index].room = this.room;
this.winSizeChange$ = Observable.fromEvent(window, 'resize')
.debounceTime(500)
.distinctUntilChanged();
this.winSizeChange$
.subscribe(() => this.resizeTerm());
}
ngAfterViewInit() {
// if (this.host || this.token) {
// if (this._cookie.get('cols')) {
// this.col = parseInt(this._cookie.get('cols'), 10);
// }
// if (this._cookie.get('rows')) {
// this.row = parseInt(this._cookie.get('rows'), 10);
// }
// } else {
this.col = Math.floor(jQuery('.content').width() / jQuery('#marker').width() * 6) - 8;
this.row = Math.floor(jQuery('.content').height() / jQuery('#marker').height()) - 3;
// term.term = this.term;
// }
this.term.open(this.el.nativeElement, true);
const that = this;
window.onresize = function () {
console.log('Height: ', jQuery('.content').height(), jQuery('#marker').height());
that.col = Math.floor(jQuery('.content').width() / jQuery('#marker').width() * 6) - 8;
that.row = Math.floor(jQuery('.content').height() / jQuery('#marker').height()) - 3;
if (that.col < 80) {
that.col = 80;
}
if (that.row < 24) {
that.row = 24;
}
that.term.resize(that.col, that.row);
if (that.host) {
that._cookie.set('cols', term.col.toString(), 99, '/', document.domain);
that._cookie.set('rows', term.row.toString(), 99, '/', document.domain);
TermWS.emit('resize', {'cols': that.col, 'rows': that.row});
}
};
jQuery(window).resize();
NavList.List[this.index].Term = this.term;
if (this.host) {
TermWS.emit('host', {'uuid': this.host.id, 'userid': this.userid, 'secret': this.secret});
}
if (this.token) {
TermWS.emit('token', {'token': this.token, 'secret': this.secret});
}
if (this.monitor) {
TermWS.emit('monitor', {'token': this.monitor, 'secret': this.secret});
} else {
this.term.on('data', function (data) {
TermWS.emit('data', {'data': data, 'room': NavList.List[that.index].room});
});
}
TermWS.on('data', function (data) {
if (data['room'] === NavList.List[that.index].room) {
that.term.write(data['data']);
}
});
TermWS.on('disconnect', function () {
that.TerminalDisconnect();
});
TermWS.on('logout', function (data) {
if (data['room'] === NavList.List[that.index].room) {
NavList.List[this.index].connected = false;
// this.term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
}
});
TermWS.on('room', function (data) {
if (data['secret'] === that.secret) {
NavList.List[that.index].room = data['room'];
}
});
$(window).resize();
}
TerminalDisconnect() {
NavList.List[this.index].connected = false;
// this.term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
TermWS.emit('logout', NavList.List[this.index].room);
resizeTerm() {
let contentElement = $('.window.active');
if (contentElement.length === 0) {
contentElement = $('body');
}
const markerElement = $('#marker');
const col = Math.floor(contentElement.width() / markerElement.width() * 6) - 8;
const row = Math.floor(contentElement.height() / markerElement.height()) - 2;
this.col = col > 80 ? col : 80;
this.row = row > 24 ? row : 24;
console.log('Box size: ', contentElement.width(), '*', contentElement.height());
console.log('Mark size: ', markerElement.width(), '*', markerElement.height());
console.log('Resize term size: ', this.col, this.row);
this.term.resize(this.col, this.row);
}
active() {
......
<elements-term
<elements-ssh-term
[token]="token"
[index]="0"
*ngIf="system =='linux'">
</elements-term>
</elements-ssh-term>
<elements-guacamole
[target]="target"
[index]="0"
......
......@@ -4,12 +4,12 @@
</div>
<div fxFlex>
<div class="window" *ngFor="let m of NavList.List;let i=index"
[ngClass]="{'active':i==NavList.Active}">
<elements-term [index]="i"
[ngClass]="{'active':i==NavList.Active}" style="height: 100%">
<elements-ssh-term [index]="i"
[host]="m.host"
[userid]="m.user.id"
*ngIf="m.type=='ssh'">
</elements-term>
</elements-ssh-term>
<elements-guacamole [index]="i"
[host]="m.host"
[userid]="m.user.id"
......
<elements-term
[index]="0"
[monitor]="token"
></elements-term>
import {Component, Input, OnInit} from '@angular/core';
import {term} from '../../../globals';
import {HttpService, LogService} from '../../../app.service';
import {Video} from '../replay.model';
import {Replay} from '../replay.model';
@Component({
selector: 'app-replay-json',
......@@ -13,29 +13,30 @@ export class JsonComponent implements OnInit {
setPercent = 0;
toggle = false;
TICK = 33;
TIMESTEP = 33;
TIMESTEMP = 33;
time = 1;
timer: any;
pos = 0;
scrubber: number;
@Input() video: Video;
@Input() replay: Replay;
constructor(private _http: HttpService,
private _logger: LogService) {
}
ngOnInit() {
if (this.video.src !== 'READY') {
this._http.get_replay_data(this.video.src)
if (this.replay.src !== 'READY') {
console.log('SRC', this.replay.src);
this._http.get_replay_data(this.replay.src)
.subscribe(
data => {
this.video.json = data;
this.video.timelist = Object.keys(this.video.json).map(Number);
this.video.timelist = this.video.timelist.sort(function (a, b) {
this.replay.json = data;
this.replay.timelist = Object.keys(this.replay.json).map(Number);
this.replay.timelist = this.replay.timelist.sort((a, b) => {
return a - b;
});
this.video.totalTime = this.video.timelist[this.video.timelist.length - 1] * 1000;
this.replay.totalTime = this.replay.timelist[this.replay.timelist.length - 1] * 1000;
},
err => {
alert('无法下载');
......@@ -46,21 +47,21 @@ export class JsonComponent implements OnInit {
const that = this;
let r = true;
window.onresize = function () {
window.addEventListener('resize', () => {
if (r) {
that.pause();
r = false;
}
};
});
}
setSpeed() {
if (this.speed === 0) {
this.TIMESTEP = this.TICK;
this.TIMESTEMP = this.TICK;
} else if (this.speed < 0) {
this.TIMESTEP = this.TICK / -this.speed;
this.TIMESTEMP = this.TICK / -this.speed;
} else {
this.TIMESTEP = this.TICK * this.speed;
this.TIMESTEMP = this.TICK * this.speed;
}
}
......@@ -88,26 +89,26 @@ export class JsonComponent implements OnInit {
}
advance(that) {
that.scrubber = Math.ceil((that.time / this.video.totalTime) * 100);
that.scrubber = Math.ceil((that.time / this.replay.totalTime) * 100);
// document.getElementById('beforeScrubberText').innerHTML = this.buildTimeString(this.time);
for (; that.pos < this.video.timelist.length; that.pos++) {
if (this.video.timelist[that.pos] * 1000 <= that.time) {
term.term.write(this.video.json[this.video.timelist[that.pos].toString()]);
for (; that.pos < this.replay.timelist.length; that.pos++) {
if (this.replay.timelist[that.pos] * 1000 <= that.time) {
term.term.write(this.replay.json[this.replay.timelist[that.pos].toString()]);
} else {
break;
}
}
if (that.pos >= this.video.timelist.length) {
if (that.pos >= this.replay.timelist.length) {
this.toggle = !this.toggle;
clearInterval(that.timer);
}
if (this.video.timelist[that.pos] - this.video.timelist[that.pos - 1] > 5) {
if (this.replay.timelist[that.pos] - this.replay.timelist[that.pos - 1] > 5) {
that.time += 5000;
}
that.time += that.TIMESTEP;
that.setPercent = that.time / this.video.totalTime * 100;
that.time += that.TIMESTEMP;
that.setPercent = that.time / this.replay.totalTime * 100;
}
stop() {
......@@ -119,14 +120,14 @@ export class JsonComponent implements OnInit {
this.pos = 0;
term.term.reset();
this.toggle = false;
for (; this.pos < this.video.timelist.length; this.pos++) {
if (this.video.timelist[this.pos] * 1000 <= this.setPercent / 100 * this.video.totalTime) {
term.term.write(this.video.json[this.video.timelist[this.pos].toString()]);
for (; this.pos < this.replay.timelist.length; this.pos++) {
if (this.replay.timelist[this.pos] * 1000 <= this.setPercent / 100 * this.replay.totalTime) {
term.term.write(this.replay.json[this.replay.timelist[this.pos].toString()]);
} else {
break;
}
}
this.time = this.video.totalTime * this.setPercent / 100;
this.time = this.replay.totalTime * this.setPercent / 100;
}
}
<div [ngStyle]="{'width.px': video.width,'height.px':video.height}">
<div [ngStyle]="{'width.px': replay.width,'height.px':replay.height}">
<video controls>
<source [src]="video.src" type="video/mp4">
<source [src]="replay.src" type="video/mp4">
Your browser does not support the video tag.
<br>
您的浏览器不支持,请升级
......
import {Component, Input, OnInit} from '@angular/core';
import {Video} from '../replay.model';
import {Replay} from '../replay.model';
@Component({
selector: 'app-replay-mp4',
......@@ -7,16 +7,16 @@ import {Video} from '../replay.model';
styleUrls: ['./mp4.component.css']
})
export class Mp4Component implements OnInit {
@Input() video: Video;
@Input() replay: Replay;
constructor() {
}
ngOnInit() {
if (this.video.height === 0) {
this.video.height = 600;
if (this.replay.height === 0) {
this.replay.height = 600;
}
if (this.video.width === 0) {
this.video.width = 800;
if (this.replay.width === 0) {
this.replay.width = 800;
}
}
......
<app-replay-json [video]="video" *ngIf="video.type=='json'"></app-replay-json>
<app-replay-mp4 [video]="video" *ngIf="video.type=='mp4'"></app-replay-mp4>
<app-replay-json [replay]="replay" *ngIf="replay.type=='json'"></app-replay-json>
<app-replay-mp4 [replay]="replay" *ngIf="replay.type=='mp4'"></app-replay-mp4>
......@@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, Params} from '@angular/router';
import {HttpService, LogService} from '../../app.service';
import {DataStore} from '../../globals';
import {Video} from './replay.model';
import {Replay} from './replay.model';
@Component({
selector: 'pages-replay',
......@@ -10,50 +10,49 @@ import {Video} from './replay.model';
styleUrls: ['./replay.component.css']
})
export class PagesReplayComponent implements OnInit {
video: Video;
replay: Replay = new Replay();
constructor(private activatedRoute: ActivatedRoute,
constructor(private route: ActivatedRoute,
private _http: HttpService,
private _logger: LogService) {
// this.video = {'type': 'none'};
DataStore.NavShow = false;
}
ngOnInit() {
let token: string;
this.activatedRoute.params.subscribe((params: Params) => {
token = params['token'];
});
// this._http.get_replay_json(token)
// .subscribe(
// data => {
// Video.type = data['type'];
// Video.src = data['src'];
// Video.id = data['id'];
// // Video.width = data['width'];
// // Video.height = data['height'];
// },
// err => {
// this._http.get_replay(token)
// .subscribe(
// data => {
// Video.type = 'json';
// Video.json = data;
// Video.src = 'READY';
// Video.timelist = Object.keys(Video.json).map(Number);
// Video.timelist = Video.timelist.sort(function (a, b) {
// return a - b;
// });
// Video.totalTime = Video.timelist[Video.timelist.length - 1] * 1000;
//
// }, err2 => {
// alert('无法下载');
// this._logger.error(err2);
// },
// );
//
// }
// );
let token = '';
this.route.params
.subscribe(params => {
token = params['token'];
});
this._http.get_replay_json(token)
.subscribe(
data => {
// this.replay = data.json() as Replay;
this.replay.type = data['type'];
this.replay.src = data['src'];
this.replay.id = data['id'];
}
);
// err => {
// this._http.get_replay(token)
// .subscribe(
// data => {
// this.replay.type = 'json';
// this.replay.json = data;
// this.replay.src = 'READY';
// this.replay.timelist = Object.keys(this.replay.json).map(Number);
// this.replay.timelist = this.replay.timelist.sort(function (a, b) {
// return a - b;
// });
// this.replay.totalTime = this.replay.timelist[this.replay.timelist.length - 1] * 1000;
//
// }, err2 => {
// alert('无法下载');
// this._logger.error(err2);
// },
// );
// }
// );
}
}
export class Video {
export class Replay {
id: string;
src: string;
type: string;
height: number;
width: number;
json: object;
status: string;
timelist: Array<number>;
totalTime: number;
json: any;
height: number;
width: number;
}
......@@ -7,11 +7,9 @@
*/
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {environment} from '../../environments/environment';
import {PagesBlankComponent} from '../pages/blank/blank.component';
import {TestPageComponent} from '../test-page/test-page.component';
// import {PagesSettingComponent} from '../pages/setting/setting.component';
import {PagesConnectComponent} from '../pages/connect/connect.component';
import {PagesReplayComponent} from '../pages/replay/replay.component';
import {PagesControlComponent} from '../pages/control/control.component';
......@@ -20,12 +18,10 @@ import {PagesMonitorComponent} from '../pages/monitor/monitor.component';
const appRoutes: Routes = [
// {path: 'users/login', component: LoginComponent},
{path: 'replay/:token', component: PagesReplayComponent},
{path: 'monitor/:token', component: PagesMonitorComponent},
{path: 'test', component: TestPageComponent},
{path: 'connect', component: PagesConnectComponent},
// {path: 'setting', component: PagesSettingComponent},
{path: 'undefined', component: PagesBlankComponent},
{path: '', component: PagesControlComponent},
{path: '**', component: PagesNotFoundComponent}
......
......@@ -1422,7 +1422,7 @@ body.mini-navbar.fixed-sidebar .logo-element {
display: none;
}
// Remove animation on fullscreen video
// Remove animation on fullscreen replay
.fullscreen-video .animated {
animation: none;
......
......@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Jumpserver</title>
<title>Luna - Jumpserver web terminal</title>
<base href="/luna">
<meta name="viewport" content="width=device-width, initial-scale=1">
......@@ -11,5 +11,6 @@
<body>
<app-root></app-root>
<span id="marker" style="display: none">marker</span>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment