Commit 48dee5e8 authored by ibuler's avatar ibuler

[Update] 删掉原来的contrl

parent e2b50d3d
import {Component, Input, OnInit} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';
import {NavList} from '../../pages/control/control/control.component';
import {User, DataStore} from '../../globals';
import {HttpService, LogService} from '../../app.service';
import {environment} from '../../../environments/environment';
import {CookieService} from 'ngx-cookie-service';
@Component({
selector: 'elements-iframe',
......@@ -13,15 +8,9 @@ import {CookieService} from 'ngx-cookie-service';
styleUrls: ['./iframe.component.scss']
})
export class ElementIframeComponent implements OnInit {
@Input() host: any;
@Input() userid: any;
@Input() index: number;
target: string;
constructor(private sanitizer: DomSanitizer,
private _http: HttpService,
private _cookie: CookieService,
private _logger: LogService) {
constructor(private sanitizer: DomSanitizer) {
}
ngOnInit() {
......@@ -30,8 +19,4 @@ export class ElementIframeComponent implements OnInit {
trust(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
Disconnect() {
NavList.List[this.index].connected = false;
}
}
......@@ -3,14 +3,11 @@ import {ElementRef} from '@angular/core';
import {Terminal} from 'xterm';
import {fit} from 'xterm/lib/addons/fit/fit';
import {Observable} from 'rxjs/Rx';
import {CookieService} from 'ngx-cookie-service';
import * as $ from 'jquery/dist/jquery.min.js';
import 'rxjs/Observable';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import {NavList} from '../../pages/control/control/control.component';
@Component({
selector: 'elements-term',
......@@ -31,9 +28,7 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
this.winSizeChange$
.subscribe(() => {
if (NavList.List[NavList.Active].type !== 'rdp') {
this.resizeTerm();
}
});
}
......@@ -80,7 +75,6 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
resizeTerm() {
const size = this.getWinSize();
// Todo: 修改大小
if (isNaN(size[0]) || isNaN(size[1])) {
fit(this.term);
} else {
......
<div class="sidebar" fxLayout="column" ngxSplit="column">
<div fxflex="0 0 30px" class="search">
<input #keyword id="keyword" class="left-search"
placeholder=" {{'Search'| trans }} ..."
maxlength="2048"
name="q"
autocomplete="off"
title="Search"
type="text" tabindex="1" spellcheck="false" [(ngModel)]="q">
</div>
<div class="overflow ngx-scroll-overlay" fxflex="1 1 90%">
<elements-asset-tree [query]="q" ></elements-asset-tree>
</div>
<div class="footer-version" fxflex="0 0 26px">
<p> Version <strong>{{version}}</strong></p>
</div>
</div>
.sidebar {
height: 100%;
width: 100%;
overflow: auto;
}
:root {
font-family: "Hiragino Kaku Gothic ProN", Meiryo, sans-serif;
}
label {
margin-bottom: 0;
}
.filetree {
padding-left: 20px;
height: inherit;
}
.filetree input[type="checkbox"] {
display: none;
}
.filetree input[type=checkbox] + label:before {
font-family: FontAwesome;
display: inline-block;
}
.filetree input[type=checkbox] + label:before {
content: "\f114";
letter-spacing: 10px;
width: 30px;
}
.filetree input[type=checkbox]:checked + label:before {
content: "\f115";
}
.filetree ul {
height: 0;
overflow: hidden;
}
.filetree > li input:checked ~ ul, .filetree > li ul.insearch {
height: auto;
}
.filetree li {
list-style: none;
cursor: pointer;
color: #ffffff;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.filetree label {
line-height: 33px;
display: inline-block;
}
.fa.fa-undefined:before {
content: "\f26c";
}
.left-search {
padding-left: 14px;
width: 100%;
border: none;
background: #2f2a2a;
color: #ffffff;
}
.search {
border-left-width: 0;
border-bottom: #19aa8d 2px inset;
//padding-top: 30px;
width: 100%;
//position: fixed;
//height: 28px;
}
.search > input {
height: 30px;
}
.overflow {
height: 100%;
width: 100%;
float: left;
position: inherit;
background: #2f2a2a;
color: #d6cbcb;
}
.footer-version {
background: #2f2a2a;
font-size: 9pt;
left: 0;
width: 100%;
padding: 1px 20px 0 20px;
border-top: 1px solid #e7eaec;
bottom: 0;
//height: 30px;
//position: fixed;
}
.footer-version > p {
height: 8px;
padding-top: 2px;
padding-bottom: 2px;
}
//@import "~@swimlane/ngx-ui/release/styles/components/scrollbars";
.ngx-scroll-overlay {
overflow: auto; // for FF
//-ms-overflow-style: -ms-autohiding-scrollbar;
//
//&::-webkit-scrollbar {
// display: none;
//}
//
//&:hover::-webkit-scrollbar {
// display: initial;
//}
}
//.sidebar::-webkit-scrollbar-track {
// -webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.3);
// background-color: #676a6c;
//}
//
//.sidebar::-webkit-scrollbar {
// width: 8px;
//}
//
//.sidebar::-webkit-scrollbar-thumb {
// background-color: #F5F5F5;
// border-radius: 6px;
// border: 2px solid transparent;
//}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CleftbarComponent } from './cleftbar.component';
describe('CleftbarComponent', () => {
let component: CleftbarComponent;
let fixture: ComponentFixture<CleftbarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CleftbarComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CleftbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
/**
* 控制页面的左边栏主机树状页
*
* 以树状方式列出所有主机
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, Inject, OnInit, ViewChild, ElementRef} from '@angular/core';
import {AppService, HttpService, LogService} from '../../../app.service';
import {SearchComponent} from '../search/search.component';
import {DataStore} from '../../../globals';
import {version} from '../../../../environments/environment';
import {NavList, View} from '../control/control.component';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {ElementServerMenuComponent} from '../../../elements/server-menu/server-menu.component';
import {DialogService} from '../../../elements/dialog/dialog.service';
export interface Node {
id: string;
name: string;
comment: string;
title: string;
isParent: boolean;
pId: string;
open: boolean;
iconSkin: string;
meta: object;
}
export class Host {
name: string;
id: string;
type: string;
}
@Component({
selector: 'pages-control-cleftbar',
templateUrl: './cleftbar.component.html',
styleUrls: ['./cleftbar.component.scss'],
providers: [SearchComponent, ElementServerMenuComponent]
})
export class CleftbarComponent {
DataStore = DataStore;
version = version;
q: string;
event: MouseEvent;
clientX = 0;
clientY = 0;
TooltipPosition = 'above';
static Reload() {
}
static Hide() {
DataStore.showLeftBar = false;
DataStore.Nav.map(function (value, i) {
value['children'].forEach((v, key) => {
if (DataStore.Nav[i]['children'][key]['id'] === 'HideLeftManager') {
DataStore.Nav[i]['children'][key] = {
'id': 'ShowLeftManager',
'click': 'ShowLeft',
'name': 'Show left manager'
};
}
});
});
window.dispatchEvent(new Event('resize'));
}
static Show() {
DataStore.showLeftBar = true;
DataStore.Nav.map(function (value, i) {
value['children'].forEach((v, key) => {
if (DataStore.Nav[i]['children'][key]['id'] === 'ShowLeftManager') {
DataStore.Nav[i]['children'][key] = {
'id': 'HideLeftManager',
'click': 'HideLeft',
'name': 'Hide left manager'
};
}
});
});
window.dispatchEvent(new Event('resize'));
}
constructor(private _appService: AppService,
private _http: HttpService,
private _search: SearchComponent,
private _logger: LogService,
private _menu: ElementServerMenuComponent,
public _dialog: MatDialog,
private _layer: DialogService) {
this._logger.log('nav.ts:NavComponent');
}
Search(q) {
this._search.Search(q);
}
onRightClick(event: MouseEvent): void {
this.clientX = event.clientX;
this.clientY = event.clientY;
}
}
div {
height: 100%;
width: 100%;
padding: 0;
background-color: #1f1b1b;
margin: 0;
position: initial;
}
pages-control-cleftbar, pages-control-control {
background: #2f2a2a;
color: #d6cbcb;
}
.container-fluid {
padding-top: 30px;
}
<div class="container-fluid row" fxLayout="row" ngxSplit="row">
<div fxFlex="1 1 20%" minBasis="100px" maxBasis="800px" fxFlexFill ngxSplitArea *ngIf="DataStore.leftbarshow">
<pages-control-cleftbar></pages-control-cleftbar>
</div>
<div fxFlex="0" ngxSplitHandle [style.display]="activeViewIsRdp() ? 'none' : 'block'" (mouseup)="dragSplitBtn($event)"></div>
<div [fxFlex]="DataStore.leftbarshow ? '1 1 80%' : '1 1 100%'" ngxSplitArea class="content">
<pages-control-control></pages-control-control>
</div>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesControlComponent } from './control.component';
describe('ControlPageComponent', () => {
let component: PagesControlComponent;
let fixture: ComponentFixture<PagesControlComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PagesControlComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PagesControlComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
/**
* 控制页面
*
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, OnInit} from '@angular/core';
import {DataStore, User} from '../../globals';
import {NavList} from './control/control.component';
@Component({
selector: 'pages-control',
templateUrl: './control.component.html',
styleUrls: ['./control.component.css'],
})
export class PagesControlComponent implements OnInit {
dataStore = DataStore;
user = User;
constructor() {
}
activeViewIsRdp() {
return NavList.List[NavList.Active].type === 'rdp';
}
dragSplitBtn(evt) {
window.dispatchEvent(new Event('resize'));
}
ngOnInit() {
}
}
div, elements-term, elements-guacamole, elements-settings {
height: 100%;
}
elements-term, elements-guacamole, elements-settings {
/*padding-bottom: 30px;*/
}
.window {
display: none;
/*padding: 15px;*/
}
.active {
display: block;
}
.right-side {
height: 100%;
width: 100%;
background-color: gray;
}
<div fxLayout="column" ngxSplit="column" style="width: 100%;height: 100%;">
<div fxFlex="0 0 30px" class="search">
<pages-control-nav></pages-control-nav>
</div>
<div fxFlex="0 0 calc(100%-35px)" id="winContainer">
<div class="window" *ngFor="let m of NavList.List;let i=index"
[ngClass]="{'active':i==NavList.Active}" style="height: 100%">
<elements-ssh-term [index]="i"
[host]="m.host"
[sysUser]="m.user"
*ngIf="m.type=='ssh'">
</elements-ssh-term>
<elements-guacamole [index]="i"
[host]="m.host"
[sysUser]="m.user"
[remoteAppId]="m.remoteApp"
*ngIf="m.type=='rdp'">
</elements-guacamole>
<app-sftp *ngIf="m.type=='sftp'" [host]="m.host">
</app-sftp>
<!--<elements-settings [index]="i"-->
<!--*ngIf="m.type=='settings'">-->
<!--</elements-settings>-->
</div>
</div>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ControlComponent } from './control.component';
describe('ControlComponent', () => {
let component: ControlComponent;
let fixture: ComponentFixture<ControlComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ControlComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ControlComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
/**
* 控制页面
*
* 主管已连接的主机标签卡,各连接方式的web展现(WebTerminal、RDP、VNC等)
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, OnInit} from '@angular/core';
import {TermWS} from '../../../globals';
export class View {
nick: string;
type: string;
edit: boolean;
connected: boolean;
hide: boolean;
closed: boolean;
host: any;
user: any;
remoteApp: string;
room: string;
Rdp: any;
Term: any;
}
export let NavList: {
List: Array<View>;
Active: number;
} = {
List: [new View()],
Active: 0,
};
@Component({
selector: 'pages-control-control',
templateUrl: './control.component.html',
styleUrls: ['./control.component.css']
})
export class ControlComponent implements OnInit {
NavList = NavList;
static active(id) {
NavList.List.forEach((v, k) => {
v.hide = id.toString() !== k;
});
NavList.Active = id;
}
static TerminalDisconnect(id) {
if (NavList.List[id].connected) {
NavList.List[id].connected = false;
NavList.List[id].Term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
TermWS.emit('logout', NavList.List[id].room);
}
}
static RdpDisconnect(id) {
NavList.List[id].connected = false;
}
static DisconnectAll() {
for (let i = 0; i < NavList.List.length; i++) {
ControlComponent.TerminalDisconnect(i);
}
}
constructor() {
}
ngOnInit() {
}
// trackByFn(index: number, item: View) {
// return item.id;
// }
}
.tabs {
height: 30px;
overflow-y: hidden;
overflow-x: hidden;
position: relative;
}
.tabs ul li.disconnected {
background-color: darkgray;
}
.tabs ul li.hidden {
display: none;
}
.tabs ul {
list-style-type: none;
height: 30px;
background-color: #3a3333;
display: block;
min-width: 100%;
padding-left: 0;
}
.tabs ul li {
display: inline-table;
width: 150px;
height: 30px;
position: relative;
box-sizing: content-box;
float: left;;
}
.tabs ul li.active {
box-sizing: border-box;
/*border-bottom: 3px solid #19aa8d !important;*/
}
.tabs ul li span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: gray;
font-family: 'Roboto', sans-serif;
font-size: 13px;
text-decoration: none;
padding-left: 12px;
padding-right: 14px;
line-height: 26px;
cursor: default;
width: 115px;
height: 21px;
}
.tabs ul li a.close {
font-family: 'Roboto', sans-serif;
font-size: 13px;
position: absolute;
color: gray;
top: 0;
right: 5px;
cursor: pointer;
line-height: 26px;
display: inline-block;
}
.tabs ul li.active a {
color: white;
}
.tabs ul li.active span {
padding-left: 12px;
line-height: 26px;
color: white;
height: 18px;
}
.tabs ul li input {
font-family: 'Roboto', sans-serif;
font-size: 13px;
width: 115px;
border: none;
background-color: inherit;
color: white;
padding: 5px 20px 4px 15px;
height: 18px;
}
/*
* scrollbar
*/
.tabs::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: #676a6c;
}
.tabs::-webkit-scrollbar {
height: 2px;
}
.tabs::-webkit-scrollbar-thumb {
background-color: #F5F5F5;
}
.scroll-botton {
font-size: 20px;
float: left;
height: 30px;
overflow: hidden;
background-color: #3a3333;
color: white
}
<div class="scroll-botton" style="padding: 0 5px">
<a class="left" (click)="scrollleft()"><i class="fa fa-caret-left"></i></a>
<a class="right" (click)="scrollright()"><i class="fa fa-caret-right"></i></a>
</div>
<div class="tabs">
<ul [ngStyle]="{'width':150*NavList.List.length+'px'}">
<li *ngFor="let m of NavList.List;let i = index"
[ngClass]="{'active':i==NavList.Active,'disconnected':!m.connected, 'hidden': m.closed != false}"
id="termnav-{{i}}" (click)="setActive(i)" (dblclick)="m.edit=true;setActive(i)">
<span *ngIf="!m.edit">{{m.nick | truncatechars:25 }}</span>
<input *ngIf="m.edit" [(ngModel)]="m.nick" (blur)="m.edit=false" (keyup.enter)="m.edit=false" autofocus="true"/>
<a class="close" (click)="close(m,i)">&times;</a>
</li>
</ul>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesControlNavComponent } from './nav.component';
describe('ControlPagesControlNavComponent', () => {
let component: PagesControlNavComponent;
let fixture: ComponentFixture<PagesControlNavComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PagesControlNavComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PagesControlNavComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
/**
* 控制页面的已连接主机选项卡
*
* 展示所有已连接的主机
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ControlComponent, NavList} from '../control.component';
import * as jQuery from 'jquery/dist/jquery.min.js';
@Component({
selector: 'pages-control-nav',
templateUrl: './nav.component.html',
styleUrls: ['./nav.component.css'],
})
export class PagesControlNavComponent implements OnInit {
setActive = PagesControlNavComponent.setActive;
NavList = NavList;
static checkActive(index) {
const len = NavList.List.length;
if (len === 1) {
// 唯一一个
NavList.Active = 0;
} else if (len - 1 === index) {
// 删了最后一个
NavList.Active = len - 2;
} else {
NavList.Active = index;
}
PagesControlNavComponent.setActive(NavList.Active);
}
static setActive(index) {
NavList.List.forEach((value, key) => {
NavList.List[key].hide = true;
});
NavList.List[index].hide = false;
NavList.Active = index;
if (!NavList.List[index].edit) {
if (NavList.List[index].type === 'ssh') {
NavList.List[index].Term.focus();
} else if (NavList.List[index].type === 'rdp') {
// NavList.List[index].Rdp.focus();
}
} else {
}
}
constructor() {
}
ngOnInit() {
}
close(host, index) {
if (host.type === 'rdp') {
ControlComponent.RdpDisconnect(index);
} else if (host.type === 'ssh') {
ControlComponent.TerminalDisconnect(index);
}
NavList.List.splice(index, 1);
PagesControlNavComponent.checkActive(index);
}
scrollleft() {
jQuery('.tabs').scrollLeft(jQuery('.tabs').scrollLeft() - 100);
}
scrollright() {
jQuery('.tabs').scrollLeft(jQuery('.tabs').scrollLeft() + 100);
}
}
.left-search {
padding-left: 14px;
width: 100%;
border: none;
}
<input class="left-search" placeholder=" Search ..." maxlength="2048" name="q" autocomplete="off"
title="Search"
type="text" tabindex="1" spellcheck="false" autofocus [(ngModel)]="q" (keyup.enter)="Search(q)"
(ngModelChange)="modelChange($event)">
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SearchComponent } from './search.component';
describe('SearchComponent', () => {
let component: SearchComponent;
let fixture: ComponentFixture<SearchComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SearchComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
/**
* 控制页面的搜索框
*
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, OnChanges, Input, Pipe, PipeTransform} from '@angular/core';
import {AppService, HttpService, LogService} from '../../../app.service';
export let Q = '';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnChanges {
q: string;
@Input() input;
searchrequest: any;
constructor(private _appService: AppService,
private _http: HttpService,
private _logger: LogService) {
this._logger.log('LeftbarComponent.ts:SearchBar');
}
ngOnChanges(changes) {
Q = changes.input.currentValue;
}
modelChange($event) {
this.Search(Q);
}
public Search(q) {
if (this.searchrequest) {
this.searchrequest.unsubscribe();
}
this.searchrequest = this._http.search(q)
.subscribe(
data => {
this._logger.log(data);
},
err => {
this._logger.error(err);
},
() => {
}
);
this._logger.log(q);
}
}
@Pipe({name: 'SearchFilter'})
export class SearchFilter implements PipeTransform {
transform(value: any, input: string) {
if (input) {
input = input.toLowerCase();
return value.filter(function (el: any) {
// ToDo: search with a simple SQL like language, and a bug search a group's hosts
return JSON.stringify(el).toLowerCase().indexOf(input) > -1;
});
}
return value;
}
}
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