Unverified Commit 76928733 authored by BaiJiangJie's avatar BaiJiangJie Committed by GitHub

Merge pull request #121 from jumpserver/dev

Dev
parents 100a1ac4 c9090d26
......@@ -9,7 +9,7 @@ import {MAT_LABEL_GLOBAL_OPTIONS} from '@angular/material';
// service
import {AllServices} from '@app/services';
import {AppRouterModule} from './router/router.module';
import {AppRouterModule} from './router.module';
import {Pipes} from './pipes/pipes';
import {AppComponent} from './pages/app.component';
import {PagesComponents} from './pages/pages.component';
......
<div>
<p *ngIf="loading" style="padding: 3px">{{ "Loading"|trans }} ...</p>
<ul id="assetsTree" class="ztree">
{{ "Loading"|trans }} ...
</ul>
<ul id="remoteAppsTree" class="ztree">
{{ "Loading"|trans }} ...
</ul>
</div>
......
......@@ -46,6 +46,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
treeFilterSubscription: any;
isLoadTreeAsync: boolean;
filterAssetCancel$: Subject<boolean> = new Subject();
loading = true;
constructor(private _appSvc: AppService,
private _treeFilterSvc: TreeFilterService,
......@@ -103,7 +104,9 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
};
}
this.loading = true;
this._http.getMyGrantedNodes(this.isLoadTreeAsync, refresh).subscribe(resp => {
this.loading = false;
const assetsTree = $.fn.zTree.init($('#assetsTree'), setting, resp);
this.assetsTree = assetsTree;
this.rootNodeAddDom(assetsTree, () => {
......@@ -134,7 +137,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
};
this._http.getMyGrantedRemoteApps().subscribe(
resp => {
if (!resp) {
if (resp.length === 1) {
return;
}
const tree = $.fn.zTree.init($('#remoteAppsTree'), setting, resp);
......@@ -325,21 +328,22 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
this.assetsTree.removeChildNodes(searchNode[0]);
this.assetsTree.removeNode(searchNode[0]);
}
const treeNodes = this.assetsTree.getNodes();
if (!keyword) {
const treeNodes = this.assetsTree.getNodes();
if (treeNodes.length !== 0) {
this.assetsTree.showNode(treeNodes[0]);
}
return;
}
this.filterAssetCancel$.next(true);
if (treeNodes.length !== 0) {
this.assetsTree.hideNode(treeNodes[0]);
}
this.loading = true;
this._http.getMyGrantedAssets(keyword)
.pipe(takeUntil(this.filterAssetCancel$))
.subscribe(nodes => {
const treeNodes = this.assetsTree.getNodes();
if (treeNodes.length !== 0) {
this.assetsTree.hideNode(treeNodes[0]);
}
this.loading = false;
let name = translate('Search');
const assetsAmount = nodes.length;
name = `${name} (${assetsAmount})`;
......
......@@ -13,8 +13,10 @@ import {ElementDialogAlertComponent} from './dialog/dialog.service';
import {ElementGuacamoleComponent} from './guacamole/guacamole.component';
import {ElementSshTermComponent} from './ssh-term/ssh-term.component';
import {ElementConnectComponent, AssetTreeDialogComponent, ManualPasswordDialogComponent} from './connect/connect.component';
import {ElementSftpComponent} from '@app/elements/sftp/sftp.component';
import {ElementSettingComponent} from '@app/elements/setting/setting.component';
import {ElementSftpComponent} from './sftp/sftp.component';
import {ElementSettingComponent} from './setting/setting.component';
import {ElementReplayGuacamoleComponent} from './replay/guacamole/guacamole.component';
import {ElementReplayJsonComponent} from './replay/json/json.component';
export const ElementComponents = [
ElementLeftBarComponent,
......@@ -33,6 +35,8 @@ export const ElementComponents = [
ElementSshTermComponent,
ElementConnectComponent,
ElementSftpComponent,
ElementReplayGuacamoleComponent,
ElementReplayJsonComponent,
AssetTreeDialogComponent,
ChangLanWarningDialogComponent,
ManualPasswordDialogComponent,
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReplayGuacamoleComponent } from './guacamole.component';
import { ElementReplayGuacamoleComponent } from './guacamole.component';
describe('ReplayGuacamoleComponent', () => {
let component: ReplayGuacamoleComponent;
let fixture: ComponentFixture<ReplayGuacamoleComponent>;
let component: ElementReplayGuacamoleComponent;
let fixture: ComponentFixture<ElementReplayGuacamoleComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReplayGuacamoleComponent ]
declarations: [ ElementReplayGuacamoleComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ReplayGuacamoleComponent);
fixture = TestBed.createComponent(ElementReplayGuacamoleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
......
import { Component, OnInit, Input } from '@angular/core';
import * as Guacamole from 'guacamole-common-js/dist/guacamole-common';
import { Replay } from '../replay.model';
import { Replay } from '@app/model';
function zeroPad(num, minLength) {
let str = num.toString();
......@@ -46,11 +46,11 @@ function formatTime(millis: number) {
@Component({
selector: 'app-replay-guacamole',
selector: 'elements-replay-guacamole',
templateUrl: './guacamole.component.html',
styleUrls: ['./guacamole.component.scss']
})
export class ReplayGuacamoleComponent implements OnInit {
export class ElementReplayGuacamoleComponent implements OnInit {
isPlaying = false;
recording: any;
playerRef: any;
......@@ -80,9 +80,6 @@ export class ReplayGuacamoleComponent implements OnInit {
recordingElement.style.margin = '0 auto';
this.screenRef.appendChild(recordingElement);
this.initRecording();
// this.toggle();
}
initRecording() {
......@@ -99,7 +96,7 @@ export class ReplayGuacamoleComponent implements OnInit {
this.recording.onprogress = (millis) => {
this.duration = formatTime(millis);
this.max = millis;
this.toggle();
this.play();
};
// If paused, the play/pause button should read "Play"
......@@ -140,13 +137,25 @@ export class ReplayGuacamoleComponent implements OnInit {
e.stopPropagation();
}
toggle() {
play() {
if (!this.recording.isPlaying()) {
this.recording.play();
this.isPlaying = true;
} else {
}
}
pause() {
if (this.recording.isPlaying()) {
this.recording.pause();
this.isPlaying = false;
}
}
toggle() {
if (!this.recording.isPlaying()) {
this.play();
} else {
this.pause();
}
}
}
......@@ -14,13 +14,19 @@
<input id="scrubber" type="range" [(ngModel)]="time" min=0 [attr.max]="max" (mouseup)="runFrom()"/>
<span id="position">{{ position }}</span>
<span id="position" style="padding-left: 10px">{{ position }}</span>
<span>/</span>
<span id="duration">{{ duration }}</span>
{{"Speed"|trans}}: {{speed}}
<span style="float: right;padding-top: 5px;padding-right: 20px">
<span style="padding-left: 10px">{{"cols"|trans}}: <input type="number" style="width: 60px" [(ngModel)]="termCols"></span>
<span style="padding-left: 10px">{{"rows"|trans}}: <input type="number" style="width: 60px" [(ngModel)]="termRows"></span>
<span style="padding-left: 10px"><input type="button" value="{{'confirm'|trans}}" (click)="resizeTerm()"></span>
</span>
</div>
<div id="winContainer" style="height: 90%;width: 100%">
<elements-term [term]="term"></elements-term>
<elements-term #termRef [term]="term" [stopWatchWinChange]="true" (winSizeChangeTrigger)="onTermSizeChange($event)"></elements-term>
</div>
<!--<asciinema-player></asciinema-player>-->
import {Component, Input, OnInit} from '@angular/core';
import {Component, Input, OnInit, OnChanges} from '@angular/core';
import {Terminal} from 'xterm';
import {HttpService, LogService} from '@app/services';
import {Replay} from '../replay.model';
import {Replay} from '@app/model';
function zeroPad(num, minLength) {
let str = num.toString();
......@@ -47,11 +47,11 @@ function formatTime(millis: number) {
@Component({
selector: 'app-replay-json',
selector: 'elements-replay-json',
templateUrl: './json.component.html',
styleUrls: ['./json.component.css']
})
export class JsonComponent implements OnInit {
export class ElementReplayJsonComponent implements OnInit {
isPlaying = false;
recording: any;
playerRef: any;
......@@ -67,6 +67,9 @@ export class JsonComponent implements OnInit {
timer: any; // 多长时间播放下一个
pos = 0; // 播放点
term: Terminal;
termCols = 80;
termRows = 24;
get position() {
return formatTime(this.time);
}
......@@ -110,6 +113,7 @@ export class JsonComponent implements OnInit {
clearInterval(this.timer);
this.term.reset();
this.pos = 0;
this.time = 0;
this.isPlaying = true;
this.timer = setInterval(() => {
this.advance();
......@@ -173,4 +177,16 @@ export class JsonComponent implements OnInit {
}
this.advance();
}
resizeTerm() {
this.term.resize(this.termCols, this.termRows);
this.restart();
}
onTermSizeChange(evt) {
setTimeout(() => {
this.termCols = evt[0];
this.termRows = evt[1];
}, 500);
}
}
......@@ -8,7 +8,7 @@
</mat-form-field>
<mat-form-field>
<input [(value)]="setting.fontSize" matInput placeholder='{{"Font size"|trans}}' name="fontSize" type="number" min="5" max="60" >
<input [(ngModel)]="setting.fontSize" matInput placeholder='{{"Font size"|trans}}' name="fontSize" type="number" min="5" max="60" >
</mat-form-field>
<mat-form-field>
......
......@@ -3,7 +3,7 @@ import {ElementRef} from '@angular/core';
import {Terminal} from 'xterm';
import {fit} from 'xterm/lib/addons/fit/fit';
import {LogService} from '@app/services';
import {Observable, fromEvent} from 'rxjs';
import {Observable, fromEvent, Subscription} from 'rxjs';
import {debounceTime, distinctUntilChanged } from 'rxjs/operators';
import * as $ from 'jquery/dist/jquery.min.js';
import 'rxjs/Observable';
......@@ -18,12 +18,12 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
@ViewChild('term') el: ElementRef;
@Input() term: Terminal;
@Input() offset: Array<number>;
@Input() stopWatchWinChange = false;
@Output() winSizeChangeTrigger = new EventEmitter<Array<number>>();
winSizeChange$: Observable<any>;
winSizeSub: Subscription;
constructor(private _logger: LogService) {
}
constructor(private _logger: LogService) {}
ngOnInit() {
this.winSizeChange$ = fromEvent(window, 'resize').pipe(
......@@ -31,7 +31,7 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
distinctUntilChanged(),
);
this.winSizeChange$
this.winSizeSub = this.winSizeChange$
.subscribe(() => {
this._logger.debug('Get win size change event');
this.resizeTerm();
......@@ -41,6 +41,9 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
ngAfterViewInit() {
this.term.open(this.el.nativeElement);
this.resizeTerm();
if (this.stopWatchWinChange) {
this.winSizeSub.unsubscribe();
}
}
getWinSize() {
......
......@@ -193,3 +193,16 @@ export class Setting {
isLoadTreeAsync: string = '1';
isSkipAllManualPassword: string = '0';
}
export class Replay {
id: string;
src: string;
type: string;
status: string;
timelist: Array<number>;
totalTime: number;
json: any;
height: number;
width: number;
}
......@@ -5,20 +5,17 @@ import {PagesMonitorComponent} from './monitor/monitor.component';
import {PagesReplayComponent} from './replay/replay.component';
import {PagesNotFoundComponent} from './not-found/not-found.component';
import {PagesLoginComponent} from './login/login.component';
import {JsonComponent} from './replay/json/json.component';
import {PagesMonitorLinuxComponent} from './monitor/linux/linux.component';
import {PagesMonitorWindowsComponent} from './monitor/windows/windows.component';
import {ReplayGuacamoleComponent} from './replay/guacamole/guacamole.component';
export const PagesComponents = [
PageMainComponent,
PagesBlankComponent,
PagesConnectComponent,
PagesMonitorComponent,
PagesReplayComponent, JsonComponent,
PagesReplayComponent,
PagesNotFoundComponent,
PagesLoginComponent,
PagesMonitorLinuxComponent,
PagesMonitorWindowsComponent,
ReplayGuacamoleComponent
];
<app-replay-json [replay]="replay" *ngIf="replay.type=='json'"></app-replay-json>
<app-replay-guacamole [replay]="replay" *ngIf="replay.type=='guacamole'"></app-replay-guacamole>
<elements-replay-json [replay]="replay" *ngIf="replay.type=='json'"></elements-replay-json>
<elements-replay-guacamole [replay]="replay" *ngIf="replay.type=='guacamole'"></elements-replay-guacamole>
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {HttpService, LogService} from '@app/services';
import {Replay} from './replay.model';
import {Replay} from '@app/model';
@Component({
selector: 'pages-replay',
......
export class Replay {
id: string;
src: string;
type: string;
status: string;
timelist: Array<number>;
totalTime: number;
json: any;
height: number;
width: number;
}
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {PagesBlankComponent} from '../pages/blank/blank.component';
import {PagesConnectComponent} from '../pages/connect/connect.component';
import {PagesReplayComponent} from '../pages/replay/replay.component';
import {PageMainComponent} from '../pages/main/main.component';
import {PagesMonitorComponent} from '../pages/monitor/monitor.component';
import {ElementSftpComponent} from '../elements/sftp/sftp.component';
import {PagesBlankComponent} from './pages/blank/blank.component';
import {PagesConnectComponent} from './pages/connect/connect.component';
import {PagesReplayComponent} from './pages/replay/replay.component';
import {PageMainComponent} from './pages/main/main.component';
import {PagesMonitorComponent} from './pages/monitor/monitor.component';
import {ElementSftpComponent} from './elements/sftp/sftp.component';
const appRoutes: Routes = [
......
......@@ -74,5 +74,7 @@
"open in new window": "新窗口打开",
"setting": "设置",
"yes": "是",
"no": "否"
"no": "否",
"cols": "列数",
"rows": "行数"
}
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