Unverified Commit ec8a866f authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #111 from jumpserver/dev_beta

Dev beta
parents 8f8a29e7 45a66fab
...@@ -7,9 +7,7 @@ import {CookieService} from 'ngx-cookie-service'; ...@@ -7,9 +7,7 @@ import {CookieService} from 'ngx-cookie-service';
import {MAT_LABEL_GLOBAL_OPTIONS} from '@angular/material'; import {MAT_LABEL_GLOBAL_OPTIONS} from '@angular/material';
// service // service
import {AppService, HttpService, LocalStorageService, NavService, LogService, import {AllServices} from '@app/services';
UUIDService, TreeFilterService, ViewService,
} from './app.service';
import {AppRouterModule} from './router/router.module'; import {AppRouterModule} from './router/router.module';
import {Pipes} from './pipes/pipes'; import {Pipes} from './pipes/pipes';
...@@ -18,7 +16,8 @@ import {PagesComponents} from './pages/pages.component'; ...@@ -18,7 +16,8 @@ import {PagesComponents} from './pages/pages.component';
import {ElementComponents} from './elements/elements.component'; import {ElementComponents} from './elements/elements.component';
import {PageMainComponent} from '@app/pages/main/main.component'; import {PageMainComponent} from '@app/pages/main/main.component';
import {PluginModules} from './plugins/plugins'; import {PluginModules} from './plugins/plugins';
import {ChangLanWarningDialogComponent, RDPSolutionDialogComponent, FontDialogComponent} from './elements/nav/nav.component'; import {ChangLanWarningDialogComponent} from './elements/nav/nav.component';
import {ElementSettingComponent} from '@app/elements/setting/setting.component';
import {AssetTreeDialogComponent, ManualPasswordDialogComponent} from './elements/connect/connect.component'; import {AssetTreeDialogComponent, ManualPasswordDialogComponent} from './elements/connect/connect.component';
...@@ -41,23 +40,15 @@ import {AssetTreeDialogComponent, ManualPasswordDialogComponent} from './element ...@@ -41,23 +40,15 @@ import {AssetTreeDialogComponent, ManualPasswordDialogComponent} from './element
AssetTreeDialogComponent, AssetTreeDialogComponent,
ManualPasswordDialogComponent, ManualPasswordDialogComponent,
ChangLanWarningDialogComponent, ChangLanWarningDialogComponent,
RDPSolutionDialogComponent,
FontDialogComponent,
PageMainComponent, PageMainComponent,
ElementSettingComponent,
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
providers: [ providers: [
// {provide: LoggerConfig, useValue: {level: LoggerLevel.WARN}}, // {provide: LoggerConfig, useValue: {level: LoggerLevel.WARN}},
// {provide: BrowserXhr, useClass: NgProgressBrowserXhr}, // {provide: BrowserXhr, useClass: NgProgressBrowserXhr},
AppService, ...AllServices,
HttpService,
LogService,
NavService,
UUIDService,
LocalStorageService,
CookieService, CookieService,
TreeFilterService,
ViewService,
NGXLogger, NGXLogger,
{provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: {float: 'always'}} {provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: {float: 'always'}}
] ]
......
...@@ -3,7 +3,7 @@ import {MatDialog} from '@angular/material'; ...@@ -3,7 +3,7 @@ import {MatDialog} from '@angular/material';
import {BehaviorSubject} from 'rxjs'; import {BehaviorSubject} from 'rxjs';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {AppService, HttpService, LogService, NavService, TreeFilterService} from '@app/app.service'; import {AppService, HttpService, LogService, NavService, SettingService, TreeFilterService} from '@app/services';
import {connectEvt, translate} from '@app/globals'; import {connectEvt, translate} from '@app/globals';
import {TreeNode, ConnectEvt} from '@app/model'; import {TreeNode, ConnectEvt} from '@app/model';
...@@ -43,6 +43,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy { ...@@ -43,6 +43,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
rightClickSelectNode: any; rightClickSelectNode: any;
hasLoginTo = false; hasLoginTo = false;
treeFilterSubscription: any; treeFilterSubscription: any;
isLoadTreeAsync: boolean;
constructor(private _appSvc: AppService, constructor(private _appSvc: AppService,
private _treeFilterSvc: TreeFilterService, private _treeFilterSvc: TreeFilterService,
...@@ -50,10 +51,11 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy { ...@@ -50,10 +51,11 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
public _logger: LogService, public _logger: LogService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private _http: HttpService, private _http: HttpService,
private _navSvc: NavService private settingSvc: SettingService
) {} ) {}
ngOnInit() { ngOnInit() {
this.isLoadTreeAsync = this.settingSvc.isLoadTreeAsync();
this.initTree(); this.initTree();
document.addEventListener('click', this.hideRMenu.bind(this), false); document.addEventListener('click', this.hideRMenu.bind(this), false);
...@@ -90,7 +92,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy { ...@@ -90,7 +92,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
onClick: this.onAssetsNodeClick.bind(this), onClick: this.onAssetsNodeClick.bind(this),
onRightClick: this.onRightClick.bind(this) onRightClick: this.onRightClick.bind(this)
}; };
if (this._navSvc.treeLoadAsync) { if (this.isLoadTreeAsync) {
setting['async'] = { setting['async'] = {
enable: true, enable: true,
url: '/api/perms/v1/users/nodes/children-with-assets/tree/?cache_policy=1', url: '/api/perms/v1/users/nodes/children-with-assets/tree/?cache_policy=1',
...@@ -99,7 +101,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy { ...@@ -99,7 +101,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
}; };
} }
this._http.getMyGrantedNodes(this._navSvc.treeLoadAsync, refresh).subscribe(resp => { this._http.getMyGrantedNodes(this.isLoadTreeAsync, refresh).subscribe(resp => {
const assetsTree = $.fn.zTree.init($('#assetsTree'), setting, resp); const assetsTree = $.fn.zTree.init($('#assetsTree'), setting, resp);
this.assetsTree = assetsTree; this.assetsTree = assetsTree;
this.rootNodeAddDom(assetsTree, () => { this.rootNodeAddDom(assetsTree, () => {
...@@ -258,7 +260,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy { ...@@ -258,7 +260,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
} }
filterAssets(keyword) { filterAssets(keyword) {
if (this._navSvc.treeLoadAsync) { if (this.isLoadTreeAsync) {
this._logger.debug('Filter assets server'); this._logger.debug('Filter assets server');
this.filterAssetsServer(keyword); this.filterAssetsServer(keyword);
} else { } else {
......
import {Component, OnInit, Output, Inject, OnDestroy, EventEmitter} from '@angular/core'; import {Component, OnInit, Output, Inject, OnDestroy, EventEmitter} from '@angular/core';
import 'rxjs/add/operator/toPromise'; import 'rxjs/add/operator/toPromise';
import {connectEvt} from '@app/globals'; import {connectEvt} from '@app/globals';
import {AppService, HttpService, LogService, NavService} from '@app/app.service'; import {AppService, HttpService, LogService, NavService, SettingService} from '@app/services';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material'; import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {FormControl, Validators} from '@angular/forms'; import {FormControl, Validators} from '@angular/forms';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
...@@ -21,7 +21,7 @@ export class ElementConnectComponent implements OnInit, OnDestroy { ...@@ -21,7 +21,7 @@ export class ElementConnectComponent implements OnInit, OnDestroy {
constructor(private _appSvc: AppService, constructor(private _appSvc: AppService,
public _dialog: MatDialog, public _dialog: MatDialog,
public _logger: LogService, public _logger: LogService,
private _navSrv: NavService, private settingSvc: SettingService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private _http: HttpService, private _http: HttpService,
) { ) {
...@@ -52,6 +52,15 @@ export class ElementConnectComponent implements OnInit, OnDestroy { ...@@ -52,6 +52,15 @@ export class ElementConnectComponent implements OnInit, OnDestroy {
} }
} }
); );
this._http.getMyGrantedRemoteApps(login_to).subscribe(
nodes => {
if (nodes.length === 1) {
this.hasLoginTo = true;
const node = nodes[0];
this.Connect(node);
}
}
);
} }
}); });
} }
...@@ -117,7 +126,7 @@ export class ElementConnectComponent implements OnInit, OnDestroy { ...@@ -117,7 +126,7 @@ export class ElementConnectComponent implements OnInit, OnDestroy {
} }
manualSetUserAuthLoginIfNeed(user: SystemUser): Promise<SystemUser> { manualSetUserAuthLoginIfNeed(user: SystemUser): Promise<SystemUser> {
if (!user || user.login_mode !== 'manual' || user.protocol !== 'rdp' || this._navSrv.skipAllManualPassword) { if (!user || user.login_mode !== 'manual' || user.protocol !== 'rdp' || this.settingSvc.isSkipAllManualPassword()) {
return Promise.resolve(user); return Promise.resolve(user);
} }
user = Object.assign({}, user); user = Object.assign({}, user);
......
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {View, ViewAction} from '@app/model'; import {View, ViewAction} from '@app/model';
import {ViewService} from '@app/app.service'; import {ViewService} from '@app/services';
@Component({ @Component({
selector: 'elements-content', selector: 'elements-content',
......
import {Component, Inject, Injectable, OnInit} from '@angular/core'; import {Component, Inject, Injectable, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material'; import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {LogService} from '@app/app.service'; import {LogService} from '@app/services';
import {FormControl, Validators} from '@angular/forms'; import {FormControl, Validators} from '@angular/forms';
// import * as layer from 'layui-layer/src/layer.js'; // import * as layer from 'layui-layer/src/layer.js';
......
...@@ -13,8 +13,8 @@ import {ElementDialogAlertComponent} from './dialog/dialog.service'; ...@@ -13,8 +13,8 @@ import {ElementDialogAlertComponent} from './dialog/dialog.service';
import {ElementGuacamoleComponent} from './guacamole/guacamole.component'; import {ElementGuacamoleComponent} from './guacamole/guacamole.component';
import {ElementSshTermComponent} from './ssh-term/ssh-term.component'; import {ElementSshTermComponent} from './ssh-term/ssh-term.component';
import {ElementConnectComponent, AssetTreeDialogComponent, ManualPasswordDialogComponent} from './connect/connect.component'; import {ElementConnectComponent, AssetTreeDialogComponent, ManualPasswordDialogComponent} from './connect/connect.component';
import {RDPSolutionDialogComponent, FontDialogComponent} from './nav/nav.component';
import {ElementSftpComponent} from '@app/elements/sftp/sftp.component'; import {ElementSftpComponent} from '@app/elements/sftp/sftp.component';
import {ElementSettingComponent} from '@app/elements/setting/setting.component';
export const ElementComponents = [ export const ElementComponents = [
ElementLeftBarComponent, ElementLeftBarComponent,
...@@ -36,6 +36,5 @@ export const ElementComponents = [ ...@@ -36,6 +36,5 @@ export const ElementComponents = [
AssetTreeDialogComponent, AssetTreeDialogComponent,
ChangLanWarningDialogComponent, ChangLanWarningDialogComponent,
ManualPasswordDialogComponent, ManualPasswordDialogComponent,
RDPSolutionDialogComponent, ElementSettingComponent
FontDialogComponent
]; ];
import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core'; import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
import {HttpService, LogService} from '@app/app.service'; import {HttpService, LogService} from '@app/services';
import {DataStore, User} from '@app/globals'; import {DataStore, User} from '@app/globals';
import {DomSanitizer} from '@angular/platform-browser'; import {DomSanitizer} from '@angular/platform-browser';
import {View} from '@app/model'; import {View} from '@app/model';
......
<h1 mat-dialog-title>{{"Set font"|trans}}</h1>
<mat-form-field>
<input matInput placeholder='{{"Font size"|trans}}' name="fontSize" type="number" min="5" max="60" [(ngModel)]="fontSize">
</mat-form-field>
<div style="float: right">
<button mat-raised-button (click)="onNoClick()">{{"Cancel"|trans}}</button>
<button mat-raised-button color="primary" [disabled]="!isValid()" (click)="onSubmit()">{{"Confirm"|trans}}</button>
</div>
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
} }
.nav .dropdown-content li { .nav .dropdown-content li {
float: left; /*float: left;*/
display: flex; display: flex;
} }
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
} }
.nav .dropdown-content li a span { .nav .dropdown-content li a span {
float: right; /*float: right;*/
} }
.dropdown-content li:hover { .dropdown-content li:hover {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</li> </li>
<li *ngFor="let v of navs" [ngClass]="{'dropdown': v.children}" > <li *ngFor="let v of navs" [ngClass]="{'dropdown': v.children}" >
<a>{{v.name|trans}}</a> <a>{{v.name|trans}}</a>
<ul [ngClass]="{'dropdown-content': v.children}"> <ul [ngClass]="{'dropdown-content': v.children}" *ngIf="v.children">
<li *ngFor="let vv of v.children" [ngClass]="{'disabled': vv.disable}"> <li *ngFor="let vv of v.children" [ngClass]="{'disabled': vv.disable}">
<a *ngIf="vv.href" [routerLink]="[vv.href]">{{vv.name|trans}}</a> <a *ngIf="vv.href" [routerLink]="[vv.href]">{{vv.name|trans}}</a>
<a id="{{vv.id}}" *ngIf="vv.click && !vv.hide" (click)="click(vv.click)">{{vv.name|trans}}</a> <a id="{{vv.id}}" *ngIf="vv.click && !vv.hide" (click)="click(vv.click)">{{vv.name|trans}}</a>
......
/**
* 主页导航条
*
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import {Component, Inject, OnInit} from '@angular/core'; import {Component, Inject, OnInit} from '@angular/core';
import {HttpService, LocalStorageService, NavService, LogService, ViewService} from '@app/app.service'; import {HttpService, LocalStorageService, NavService, LogService, ViewService} from '@app/services';
import {DataStore, i18n} from '@app/globals'; import {DataStore, i18n} from '@app/globals';
import * as jQuery from 'jquery/dist/jquery.min.js';
import {ElementLeftBarComponent} from '@app/elements/left-bar/left-bar.component'; import {ElementLeftBarComponent} from '@app/elements/left-bar/left-bar.component';
import {ElementSettingComponent} from '@app/elements/setting/setting.component';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material'; import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {View} from '@app/model'; import {Nav, View} from '@app/model';
@Component({ @Component({
selector: 'elements-nav', selector: 'elements-nav',
...@@ -20,14 +13,10 @@ import {View} from '@app/model'; ...@@ -20,14 +13,10 @@ import {View} from '@app/model';
}) })
export class ElementNavComponent implements OnInit { export class ElementNavComponent implements OnInit {
DataStore = DataStore; DataStore = DataStore;
navs: Array<any>; navs: Array<Nav>;
_asyncTree = false; _asyncTree = false;
viewList: Array<View>; viewList: Array<View>;
static Hide() {
jQuery('elements-nav').hide();
}
constructor(private _http: HttpService, constructor(private _http: HttpService,
private _logger: LogService, private _logger: LogService,
public _dialog: MatDialog, public _dialog: MatDialog,
...@@ -65,8 +54,8 @@ export class ElementNavComponent implements OnInit { ...@@ -65,8 +54,8 @@ export class ElementNavComponent implements OnInit {
this.refreshNav(); this.refreshNav();
break; break;
} }
case 'Settings': { case 'Setting': {
this.Settings(); this.Setting();
break; break;
} }
case 'Copy': { case 'Copy': {
...@@ -121,34 +110,6 @@ export class ElementNavComponent implements OnInit { ...@@ -121,34 +110,6 @@ export class ElementNavComponent implements OnInit {
window.open('https://market.aliyun.com/products/53690006/cmgj026011.html?spm=5176.730005.0.0.cY2io1'); window.open('https://market.aliyun.com/products/53690006/cmgj026011.html?spm=5176.730005.0.0.cY2io1');
break; break;
} }
case 'SetResolution': {
const dialog = this._dialog.open(
RDPSolutionDialogComponent,
{
height: '200px',
width: '300px'
});
dialog.afterClosed().subscribe(result => {
if (result) {
console.log(result);
}
});
break;
}
case 'SetFont': {
const dialog = this._dialog.open(
FontDialogComponent,
{
height: '200px',
width: '300px'
});
dialog.afterClosed().subscribe(result => {
if (result) {
console.log(result);
}
});
break;
}
case 'English': { case 'English': {
const dialog = this._dialog.open( const dialog = this._dialog.open(
ChangLanWarningDialogComponent, ChangLanWarningDialogComponent,
...@@ -189,16 +150,6 @@ export class ElementNavComponent implements OnInit { ...@@ -189,16 +150,6 @@ export class ElementNavComponent implements OnInit {
}); });
break; break;
} }
case 'LoadTreeAsync': {
this._navSvc.treeLoadAsync = !this._navSvc.treeLoadAsync;
this.refreshNav();
break;
}
case 'SkipManualPassword': {
this._navSvc.skipAllManualPassword = !this._navSvc.skipAllManualPassword;
this.refreshNav();
break;
}
default: { default: {
break; break;
} }
...@@ -212,122 +163,98 @@ export class ElementNavComponent implements OnInit { ...@@ -212,122 +163,98 @@ export class ElementNavComponent implements OnInit {
getNav() { getNav() {
return [{ return [{
'id': 'FileManager', id: 'FileManager',
'name': 'File Manager', name: 'File Manager',
'children': [ children: [
{ {
'id': 'Connect', id: 'Connect',
'click': 'ConnectSFTP', click: 'ConnectSFTP',
'name': 'Connect' name: 'Connect'
}, },
] ]
}, }, {
{ id: 'View',
'id': 'View', name: 'View',
'name': 'View', children: [
'children': [
{
'id': 'HideLeftManager',
'click': 'HideLeft',
'name': 'Hide left manager',
'hide': !DataStore.showLeftBar
},
{
'id': 'ShowLeftManager',
'click': 'ShowLeft',
'name': 'Show left manager',
'hide': DataStore.showLeftBar
},
{
'id': 'RDPResolution',
'click': 'SetResolution',
'name': 'RDP Resolution'
},
{
'id': 'Font',
'click': 'SetFont',
'name': 'Font'
},
{
'id': 'SplitVertical',
'href': '',
'name': 'Split vertical',
'disable': true
},
{ {
'id': 'CommandBar', id: 'HideLeftManager',
'href': '', click: 'HideLeft',
'name': 'Command bar', name: 'Hide left manager',
'disable': true hide: !DataStore.showLeftBar
}, },
{ {
'id': 'ShareSession', id: 'ShowLeftManager',
'href': '', click: 'ShowLeft',
'name': 'Share session (read/write)', name: 'Show left manager',
'disable': true hide: DataStore.showLeftBar
}, },
{ {
'id': 'FullScreen', id: 'SplitVertical',
'click': 'FullScreen', href: '',
'name': 'Full Screen' name: 'Split vertical',
disable: true
}, },
{ {
'id': 'LoadTreeAsync', id: 'CommandBar',
'click': 'LoadTreeAsync', href: '',
'name': 'Load Tree Async', name: 'Command bar',
'hide': this._navSvc.treeLoadAsync disable: true
}, },
{ {
'id': 'LoadTreeSync', id: 'ShareSession',
'click': 'LoadTreeAsync', href: '',
'name': 'Load Tree Sync', name: 'Share session (read/write)',
'hide': !this._navSvc.treeLoadAsync disable: true
}, },
{ {
'id': 'SkipManualPassword', id: 'FullScreen',
'click': 'SkipManualPassword', click: 'FullScreen',
'name': 'Skip manual password', name: 'Full Screen'
'hide': this._navSvc.skipAllManualPassword
}, },
{
'id': 'ShowManualPassword',
'click': 'SkipManualPassword',
'name': 'Show manual password',
'hide': !this._navSvc.skipAllManualPassword
}
] ]
}, { }, {
'id': 'Help', id: 'Help',
'name': 'Help', name: 'Help',
'children': [ children: [
{ {
'id': 'Website', id: 'Website',
'click': 'Website', click: 'Website',
'name': 'Website' name: 'Website'
}, },
{ {
'id': 'Document', id: 'Document',
'click': 'Document', click: 'Document',
'name': 'Document' name: 'Document'
}, },
{ {
'id': 'Support', id: 'Support',
'click': 'Support', click: 'Support',
'name': 'Support' name: 'Support'
}] }]
}, { }, {
'id': 'Language', id: 'Language',
'name': 'Language', name: 'Language',
'children': [ children: [
{ {
'id': 'English', id: 'English',
'click': 'English', click: 'English',
'name': 'English' name: 'English'
}, },
{ {
'id': 'Chinese', id: 'Chinese',
'click': 'Chinese', click: 'Chinese',
'name': '中文' name: '中文'
}
]
}, {
id: 'Setting',
name: 'Setting',
click: 'Setting',
children: [
{
id: 'Setting',
click: 'Setting',
name: 'Setting'
} }
] ]
} }
...@@ -356,7 +283,17 @@ export class ElementNavComponent implements OnInit { ...@@ -356,7 +283,17 @@ export class ElementNavComponent implements OnInit {
location.reload(); location.reload();
} }
Settings() { Setting() {
const dialog = this._dialog.open(
ElementSettingComponent,
{
height: '370px',
width: '400px',
});
dialog.afterClosed().subscribe(result => {
if (result) {
}
});
} }
} }
...@@ -380,71 +317,3 @@ export class ChangLanWarningDialogComponent implements OnInit { ...@@ -380,71 +317,3 @@ export class ChangLanWarningDialogComponent implements OnInit {
} }
} }
@Component({
selector: 'elements-rdp-solution-dialog',
templateUrl: 'rdpSolutionDialog.html',
styles: ['.mat-form-field { width: 100%; }']
})
export class RDPSolutionDialogComponent implements OnInit {
solutions = ['Auto', '1024x768', '1366x768', '1400x900'];
solution: string;
cacheKey = 'rdpSolution';
constructor(public dialogRef: MatDialogRef<RDPSolutionDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
}
ngOnInit() {
this.solution = localStorage.getItem(this.cacheKey) || 'Auto';
}
setSolution(value: string) {
localStorage.setItem(this.cacheKey, value);
}
onSubmit() {
this.setSolution(this.solution);
this.dialogRef.close();
}
onNoClick(): void {
this.dialogRef.close();
}
}
@Component({
selector: 'elements-font-size-dialog',
templateUrl: 'fontDialog.html',
styles: ['.mat-form-field { width: 100%; }'],
})
export class FontDialogComponent implements OnInit {
fontSize: string;
solution: string;
cacheKey = 'fontSize';
constructor(public dialogRef: MatDialogRef<FontDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
}
ngOnInit() {
this.fontSize = localStorage.getItem(this.cacheKey) || '14';
}
setFontSize(value: string) {
localStorage.setItem(this.cacheKey, value);
}
isValid() {
const size = parseInt(this.fontSize, 10);
return size > 5 && size < 60;
}
onSubmit() {
this.setFontSize(this.fontSize);
this.dialogRef.close();
}
onNoClick(): void {
this.dialogRef.close();
}
}
<h1 mat-dialog-title>{{"Set RDP solution"|trans}}</h1>
<mat-form-field>
<mat-select [(value)]="solution"
placeholder="{{'Select a solution'|trans}}" >
<mat-option *ngFor="let s of solutions" value="{{s}}">{{s}}</mat-option>
</mat-select>
</mat-form-field>
<div style="float: right">
<button mat-raised-button (click)="onNoClick()">{{"Cancel"|trans}}</button>
<button mat-raised-button color="primary" (click)="onSubmit()">{{"Confirm"|trans}}</button>
</div>
<h1 mat-dialog-title>{{"Setting"|trans}}</h1>
<mat-form-field>
<mat-select [(value)]="setting.rdpSolution"
placeholder="{{'Select a solution'|trans}}" >
<mat-option *ngFor="let s of solutionsChoices" value="{{s}}">{{s}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<input [(value)]="setting.fontSize" matInput placeholder='{{"Font size"|trans}}' name="fontSize" type="number" min="5" max="60" >
</mat-form-field>
<mat-form-field>
<mat-select [(value)]="setting.isLoadTreeAsync"
placeholder="{{'Load tree async'|trans }}" >
<mat-option *ngFor="let s of boolChoices" value="{{s.value}}">{{s.name|trans}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select [(value)]="setting.isSkipAllManualPassword"
placeholder="{{'Skip manual password'|trans }}" >
<mat-option *ngFor="let s of boolChoices" value="{{s.value}}">{{s.name|trans}}</mat-option>
</mat-select>
</mat-form-field>
<div style="float: right">
<button mat-raised-button (click)="onNoClick()">{{"Cancel"|trans}}</button>
<button mat-raised-button color="primary" (click)="onSubmit()">{{"Confirm"|trans}}</button>
</div>
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {SettingService} from '@app/services';
import {Setting} from '@app/model';
@Component({
selector: 'elements-setting',
templateUrl: './setting.component.html',
styles: ['.mat-form-field { width: 100%;}']
})
export class ElementSettingComponent implements OnInit {
solutionsChoices = ['Auto', '1024x768', '1366x768', '1400x900'];
boolChoices = [{name: 'Yes', value: '1'}, {name: 'No', value: '0'}];
setting: Setting;
constructor(public dialogRef: MatDialogRef<ElementSettingComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
private settingSrv: SettingService) {
}
ngOnInit() {
this.setting = this.settingSrv.setting;
}
onSubmit() {
this.settingSrv.save();
this.dialogRef.close();
}
onNoClick(): void {
this.dialogRef.close();
}
}
import {Component, Input, OnInit, OnDestroy } from '@angular/core'; import {Component, Input, OnInit, OnDestroy } from '@angular/core';
import {Terminal} from 'xterm'; import {Terminal} from 'xterm';
import {View} from '@app/model'; import {View} from '@app/model';
import {LogService, UUIDService} from '@app/app.service'; import {LogService, SettingService, UUIDService} from '@app/services';
import {Socket} from '@app/utils/socket'; import {Socket} from '@app/utils/socket';
import {getWsSocket, translate} from '@app/globals'; import {getWsSocket, translate} from '@app/globals';
...@@ -23,7 +23,7 @@ export class ElementSshTermComponent implements OnInit, OnDestroy { ...@@ -23,7 +23,7 @@ export class ElementSshTermComponent implements OnInit, OnDestroy {
ws: Socket; ws: Socket;
roomID: string; roomID: string;
constructor(private _uuid: UUIDService, private _logger: LogService) { constructor(private _uuid: UUIDService, private _logger: LogService, private settingSvc: SettingService) {
} }
ngOnInit() { ngOnInit() {
...@@ -37,10 +37,10 @@ export class ElementSshTermComponent implements OnInit, OnDestroy { ...@@ -37,10 +37,10 @@ export class ElementSshTermComponent implements OnInit, OnDestroy {
} }
newTerm() { newTerm() {
const fontSize = localStorage.getItem('fontSize') || '14'; const fontSize = this.settingSvc.setting.fontSize;
this.term = new Terminal({ this.term = new Terminal({
fontFamily: 'monaco, Consolas, "Lucida Console", monospace', fontFamily: 'monaco, Consolas, "Lucida Console", monospace',
fontSize: parseInt(fontSize, 10), fontSize: fontSize,
rightClickSelectsWord: true, rightClickSelectsWord: true,
theme: { theme: {
background: '#1f1b1b' background: '#1f1b1b'
......
...@@ -2,7 +2,7 @@ import {AfterViewInit, Component, Input, Output, OnInit, ViewChild, EventEmitter ...@@ -2,7 +2,7 @@ import {AfterViewInit, Component, Input, Output, OnInit, ViewChild, EventEmitter
import {ElementRef} from '@angular/core'; import {ElementRef} from '@angular/core';
import {Terminal} from 'xterm'; import {Terminal} from 'xterm';
import {fit} from 'xterm/lib/addons/fit/fit'; import {fit} from 'xterm/lib/addons/fit/fit';
import {LogService} from '@app/app.service'; import {LogService} from '@app/services';
import {Observable, fromEvent} from 'rxjs'; import {Observable, fromEvent} from 'rxjs';
import {debounceTime, distinctUntilChanged } from 'rxjs/operators'; import {debounceTime, distinctUntilChanged } from 'rxjs/operators';
import * as $ from 'jquery/dist/jquery.min.js'; import * as $ from 'jquery/dist/jquery.min.js';
......
...@@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; ...@@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms'; import {FormControl} from '@angular/forms';
import {debounceTime, distinctUntilChanged} from 'rxjs/operators'; import {debounceTime, distinctUntilChanged} from 'rxjs/operators';
import {LogService, TreeFilterService} from '@app/app.service'; import {LogService, TreeFilterService} from '@app/services';
@Component({ @Component({
......
...@@ -80,6 +80,17 @@ export class ConnectEvt { ...@@ -80,6 +80,17 @@ export class ConnectEvt {
} }
} }
export class Nav {
id: string;
name: string;
children?: Array<Nav>;
hide?: boolean = false;
click?: string;
href?: string;
disable?: boolean = false;
}
export class NavEvt { export class NavEvt {
name: string; name: string;
value: any; value: any;
...@@ -88,7 +99,6 @@ export class NavEvt { ...@@ -88,7 +99,6 @@ export class NavEvt {
this.name = name; this.name = name;
this.value = value; this.value = value;
} }
} }
export class View { export class View {
...@@ -177,3 +187,9 @@ export class Monitor { ...@@ -177,3 +187,9 @@ export class Monitor {
} }
export class Setting {
rdpSolution: string = '1024x768';
fontSize: number = 14;
isLoadTreeAsync: string = '1';
isSkipAllManualPassword: string = '0';
}
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {AppService} from '../app.service'; import {AppService} from '@app/services';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
......
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AppService, HttpService, LocalStorageService} from '@app/app.service'; import {AppService, HttpService, LocalStorageService} from '@app/services';
import {connectEvt} from '@app/globals'; import {connectEvt} from '@app/globals';
import {ConnectEvt} from '@app/model'; import {ConnectEvt} from '@app/model';
// import {DataStore} from '@app/globals'; // import {DataStore} from '@app/globals';
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @author liuzheng <liuzheng712@gmail.com> * @author liuzheng <liuzheng712@gmail.com>
*/ */
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AppService, HttpService, LogService} from '@app/app.service'; import {AppService, HttpService, LogService} from '@app/services';
import {NgForm} from '@angular/forms'; import {NgForm} from '@angular/forms';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {DataStore, User} from '@app/globals'; import {DataStore, User} from '@app/globals';
......
import {Component, HostListener, OnInit} from '@angular/core'; import {Component, HostListener, OnInit} from '@angular/core';
import {DataStore, User} from '@app/globals'; import {DataStore, User} from '@app/globals';
import {environment} from '@src/environments/environment'; import {environment} from '@src/environments/environment';
import {ViewService} from '@app/app.service'; import {ViewService} from '@app/services';
@Component({ @Component({
selector: 'pages-main', selector: 'pages-main',
......
import {Component, Input, OnInit} from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import {Terminal} from 'xterm'; import {Terminal} from 'xterm';
import {HttpService, LogService} from '@app/app.service'; import {HttpService, LogService} from '@app/services';
import {Replay} from '../replay.model'; import {Replay} from '../replay.model';
function zeroPad(num, minLength) { function zeroPad(num, minLength) {
......
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {HttpService, LogService} from '@app/app.service'; import {HttpService, LogService} from '@app/services';
import {Replay} from './replay.model'; import {Replay} from './replay.model';
@Component({ @Component({
......
import {Injectable, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {CookieService} from 'ngx-cookie-service';
import {environment} from '@src/environments/environment';
import {DataStore, i18n, User} from '@app/globals';
import {HttpService} from './http';
import {LocalStorageService, LogService} from './share';
declare function unescape(s: string): string;
@Injectable()
export class AppService implements OnInit {
// user:User = user ;
lang: string;
constructor(private _http: HttpService,
private _router: Router,
private _cookie: CookieService,
private _logger: LogService,
private _localStorage: LocalStorageService) {
this.setLogLevel();
this.setLang();
this.checklogin();
}
ngOnInit() {
}
setLogLevel() {
// 设置logger level
let logLevel = this._cookie.get('logLevel');
if (!logLevel) {
logLevel = environment.production ? '1' : '5';
}
this._logger.level = parseInt(logLevel, 10);
}
setLang() {
let lang = this._cookie.get('lang');
if (!lang) {
lang = navigator.language;
}
lang = lang.substr(0, 2);
this.lang = lang;
if (lang !== 'en') {
let url = `/luna/i18n/zh.json`;
if (!environment.production) {
url = `/assets/i18n/zh.json`;
}
this._http.get(url).subscribe(
data => {
this._localStorage.set('lang', JSON.stringify(data));
},
err => {
this._logger.error('Load i18n file error: ', err.error);
}
);
}
const l = this._localStorage.get('lang');
if (l) {
try {
const data = JSON.parse(l);
Object.keys(data).forEach((k, _) => {
i18n.set(k, data[k]);
});
} catch (e) {
this._logger.error('Parse lang json failed');
}
}
}
checklogin() {
this._logger.debug('Check user auth');
if (!DataStore.Path) {
this._router.navigate(['FOF']);
}
if (User.logined) {
if (document.location.pathname === '/login') {
this._router.navigate(['']);
} else {
this._router.navigate([document.location.pathname]);
}
return;
}
this._http.getUserProfile().subscribe(
user => {
Object.assign(User, user);
User.logined = true;
this._localStorage.set('user', user.id);
},
err => {
// this._logger.error(err);
User.logined = false;
if (document.location.pathname !== '/luna/connect') {
window.location.href = document.location.origin + '/users/login?next=' +
document.location.pathname + document.location.search;
}
// this._router.navigate(['login']);
},
);
}
browser() {
this._http.reportBrowser();
}
getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
}
import {EventEmitter, Injectable, OnInit} from '@angular/core'; import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
import {CookieService} from 'ngx-cookie-service';
import {DataStore, User, Browser, i18n} from './globals';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {NGXLogger} from 'ngx-logger'; import {Browser, DataStore} from '@app/globals';
import {SystemUser, GuacObjAddResp, TreeNode, User as _User, NavEvt, View} from './model'; import {GuacObjAddResp, SystemUser, TreeNode, User as _User} from '@app/model';
import {environment} from '../environments/environment'; import {SettingService} from './setting';
import * as UUID from 'uuid-js/lib/uuid.js';
declare function unescape(s: string): string;
@Injectable() @Injectable()
export class HttpService { export class HttpService {
headers = new HttpHeaders(); headers = new HttpHeaders();
constructor(private http: HttpClient) { constructor(private http: HttpClient, private settingSrv: SettingService) {
} }
get(url: string, options?: any) { get(url: string, options?: any) {
...@@ -126,7 +118,7 @@ export class HttpService { ...@@ -126,7 +118,7 @@ export class HttpService {
systemUserPassword = btoa(systemUserPassword); systemUserPassword = btoa(systemUserPassword);
body = body.set('username', systemUserUsername).set('password', systemUserPassword); body = body.set('username', systemUserUsername).set('password', systemUserPassword);
} }
const solution = localStorage.getItem('rdpSolution') || 'Auto'; const solution = this.settingSrv.setting.rdpSolution || 'Auto';
if (solution !== 'Auto') { if (solution !== 'Auto') {
const width = solution.split('x')[0]; const width = solution.split('x')[0];
const height = solution.split('x')[1]; const height = solution.split('x')[1];
...@@ -155,7 +147,7 @@ export class HttpService { ...@@ -155,7 +147,7 @@ export class HttpService {
systemUserPassword = btoa(systemUserPassword); systemUserPassword = btoa(systemUserPassword);
body = body.set('username', systemUserUsername).set('password', systemUserPassword); body = body.set('username', systemUserUsername).set('password', systemUserPassword);
} }
const solution = localStorage.getItem('rdpSolution') || 'Auto'; const solution = this.settingSrv.setting.rdpSolution || 'Auto';
if (solution !== 'Auto') { if (solution !== 'Auto') {
const width = solution.split('x')[0]; const width = solution.split('x')[0];
const height = solution.split('x')[1]; const height = solution.split('x')[1];
...@@ -176,7 +168,7 @@ export class HttpService { ...@@ -176,7 +168,7 @@ export class HttpService {
let params = new HttpParams() let params = new HttpParams()
.set('asset_token', assetToken) .set('asset_token', assetToken)
.set('token', token); .set('token', token);
const solution = localStorage.getItem('rdpSolution') || 'Auto'; const solution = this.settingSrv.setting.rdpSolution || 'Auto';
if (solution !== 'Auto') { if (solution !== 'Auto') {
const width = solution.split('x')[0]; const width = solution.split('x')[0];
const height = solution.split('x')[1]; const height = solution.split('x')[1];
...@@ -216,270 +208,3 @@ export class HttpService { ...@@ -216,270 +208,3 @@ export class HttpService {
} }
} }
@Injectable()
export class LogService {
level: number;
constructor(private _logger: NGXLogger) {
// 0.- Level.OFF
// 1.- Level.ERROR
// 2.- Level.WARN
// 3.- Level.INFO
// 4.- Level.DEBUG
// 5.- Level.LOG
this.level = 4;
}
log(message: any, ...additional: any[]) {
if (this.level > 4) {
this._logger.log(message, ...additional);
}
}
debug(message: any, ...additional: any[]) {
if (this.level > 3) {
this._logger.debug(message, ...additional);
}
}
info(message: any, ...additional: any[]) {
if (this.level > 2) {
this._logger.info(message, ...additional);
}
}
warn(message: any, ...additional: any[]) {
if (this.level > 1) {
this._logger.warn(message, ...additional);
}
}
error(message: any, ...additional: any[]) {
if (this.level > 0) {
this._logger.error(message, ...additional);
}
}
}
@Injectable()
export class LocalStorageService {
constructor() {
}
get(key: string): string {
return localStorage.getItem(key);
}
set(key: string, value: any) {
return localStorage.setItem(key, value);
}
delete(key: string) {
return localStorage.removeItem(key);
}
}
@Injectable()
export class AppService implements OnInit {
// user:User = user ;
lang: string;
constructor(private _http: HttpService,
private _router: Router,
private _cookie: CookieService,
private _logger: LogService,
private _localStorage: LocalStorageService) {
this.setLogLevel();
this.setLang();
this.checklogin();
}
ngOnInit() {
}
setLogLevel() {
// 设置logger level
let logLevel = this._cookie.get('logLevel');
if (!logLevel) {
logLevel = environment.production ? '1' : '5';
}
this._logger.level = parseInt(logLevel, 10);
}
setLang() {
let lang = this._cookie.get('lang');
if (!lang) {
lang = navigator.language;
}
lang = lang.substr(0, 2);
this.lang = lang;
if (lang !== 'en') {
let url = `/luna/i18n/zh.json`;
if (!environment.production) {
url = `/assets/i18n/zh.json`;
}
this._http.get(url).subscribe(
data => {
this._localStorage.set('lang', JSON.stringify(data));
},
err => {
this._logger.error('Load i18n file error: ', err.error);
}
);
}
const l = this._localStorage.get('lang');
if (l) {
try {
const data = JSON.parse(l);
Object.keys(data).forEach((k, _) => {
i18n.set(k, data[k]);
});
} catch (e) {
this._logger.error('Parse lang json failed');
}
}
}
checklogin() {
this._logger.debug('Check user auth');
if (!DataStore.Path) {
this._router.navigate(['FOF']);
}
if (User.logined) {
if (document.location.pathname === '/login') {
this._router.navigate(['']);
} else {
this._router.navigate([document.location.pathname]);
}
return;
}
this._http.getUserProfile().subscribe(
user => {
Object.assign(User, user);
User.logined = true;
this._localStorage.set('user', user.id);
},
err => {
// this._logger.error(err);
User.logined = false;
if (document.location.pathname !== '/luna/connect') {
window.location.href = document.location.origin + '/users/login?next=' +
document.location.pathname + document.location.search;
}
// this._router.navigate(['login']);
},
);
}
browser() {
this._http.reportBrowser();
}
getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
}
@Injectable()
export class UUIDService {
constructor() {
}
gen() {
return UUID.create()['hex'];
}
}
@Injectable()
export class NavService {
onNavClick: EventEmitter<NavEvt> = new EventEmitter<NavEvt>();
constructor(private store: LocalStorageService) {}
disconnectAllConnection() {
const evt = new NavEvt('disconnectAll', '');
this.onNavClick.emit(evt);
}
disconnectConnection() {
const evt = new NavEvt('disconnect', '');
this.onNavClick.emit(evt);
}
changeLang(value) {
const evt = new NavEvt('changeLang', value);
this.onNavClick.emit(evt);
}
get treeLoadAsync() {
const value = this.store.get('LoadTreeAsync');
return value === '1';
}
set treeLoadAsync(v: boolean) {
const value = v ? '1' : '0';
this.store.set('LoadTreeAsync', value);
}
get skipAllManualPassword() {
const value = this.store.get('SkipAllManualPassword');
return value === '1';
}
set skipAllManualPassword(v) {
const value = v ? '1' : '0';
this.store.set('SkipAllManualPassword', value);
}
}
@Injectable()
export class TreeFilterService {
onFilter: EventEmitter<string> = new EventEmitter<string>();
filter(q: string) {
this.onFilter.emit(q);
}
}
@Injectable()
export class ViewService {
viewList: Array<View> = [];
currentView: View;
num = 0;
addView(view: View) {
this.num += 1;
view.id = 'View_' + this.num;
this.viewList.push(view);
}
activeView(view: View) {
this.viewList.forEach((v, k) => {
v.active = v === view;
});
setTimeout(() => {
const viewEl = document.getElementById(view.id);
if (viewEl) {
viewEl.scrollIntoView();
}
}, 100);
this.currentView = view;
}
removeView(view: View) {
const index = this.viewList.indexOf(view);
this.viewList.splice(index, 1);
}
}
import {LogService, LocalStorageService, UUIDService} from './share';
export {LogService, LocalStorageService, UUIDService} from './share';
import {AppService} from './app';
export {AppService} from './app';
import {HttpService} from './http';
export {HttpService} from './http';
import {NavService} from './nav';
export {NavService} from './nav';
import {TreeFilterService} from './treeFilter';
export {TreeFilterService} from './treeFilter';
import {SettingService} from './setting';
export {SettingService} from './setting';
import {ViewService} from './view';
export {ViewService} from './view';
export const AllServices = [
LogService, LocalStorageService, UUIDService,
AppService,
HttpService,
NavService,
TreeFilterService,
SettingService,
ViewService,
];
import {EventEmitter, Injectable} from '@angular/core';
import {NavEvt} from '@app/model';
import {LocalStorageService} from './share';
@Injectable()
export class NavService {
onNavClick: EventEmitter<NavEvt> = new EventEmitter<NavEvt>();
constructor(private store: LocalStorageService) {}
disconnectAllConnection() {
const evt = new NavEvt('disconnectAll', '');
this.onNavClick.emit(evt);
}
disconnectConnection() {
const evt = new NavEvt('disconnect', '');
this.onNavClick.emit(evt);
}
changeLang(value) {
const evt = new NavEvt('changeLang', value);
this.onNavClick.emit(evt);
}
get treeLoadAsync() {
const value = this.store.get('LoadTreeAsync');
return value === '1';
}
set treeLoadAsync(v: boolean) {
const value = v ? '1' : '0';
this.store.set('LoadTreeAsync', value);
}
get skipAllManualPassword() {
const value = this.store.get('SkipAllManualPassword');
return value === '1';
}
set skipAllManualPassword(v) {
const value = v ? '1' : '0';
this.store.set('SkipAllManualPassword', value);
}
}
import {Injectable} from '@angular/core';
import {Setting} from '@app/model';
import {LocalStorageService} from './share';
@Injectable()
export class SettingService {
setting: Setting;
settingKey: 'LunaSetting';
constructor(private store: LocalStorageService) {
const settingData = this.store.get(this.settingKey);
if (settingData) {
try {
this.setting = JSON.parse(settingData) as Setting;
} catch (e) {
this.setting = new Setting();
}
} else {
this.setting = new Setting();
}
}
save() {
const settingData = JSON.stringify(this.setting);
this.store.set(this.settingKey, settingData);
}
isLoadTreeAsync(): boolean {
return this.setting.isLoadTreeAsync === '1';
}
isSkipAllManualPassword(): boolean {
return this.setting.isSkipAllManualPassword === '1';
}
}
import {Injectable} from '@angular/core';
import {NGXLogger} from 'ngx-logger';
import * as UUID from 'uuid-js/lib/uuid';
@Injectable()
export class LogService {
level: number;
constructor(private _logger: NGXLogger) {
// 0.- Level.OFF
// 1.- Level.ERROR
// 2.- Level.WARN
// 3.- Level.INFO
// 4.- Level.DEBUG
// 5.- Level.LOG
this.level = 4;
}
log(message: any, ...additional: any[]) {
if (this.level > 4) {
this._logger.log(message, ...additional);
}
}
debug(message: any, ...additional: any[]) {
if (this.level > 3) {
this._logger.debug(message, ...additional);
}
}
info(message: any, ...additional: any[]) {
if (this.level > 2) {
this._logger.info(message, ...additional);
}
}
warn(message: any, ...additional: any[]) {
if (this.level > 1) {
this._logger.warn(message, ...additional);
}
}
error(message: any, ...additional: any[]) {
if (this.level > 0) {
this._logger.error(message, ...additional);
}
}
}
@Injectable()
export class LocalStorageService {
constructor() {
}
get(key: string): string {
return localStorage.getItem(key);
}
set(key: string, value: any) {
return localStorage.setItem(key, value);
}
delete(key: string) {
return localStorage.removeItem(key);
}
}
@Injectable()
export class UUIDService {
constructor() {
}
gen() {
return UUID.create()['hex'];
}
}
import {EventEmitter, Injectable} from '@angular/core';
@Injectable()
export class TreeFilterService {
onFilter: EventEmitter<string> = new EventEmitter<string>();
filter(q: string) {
this.onFilter.emit(q);
}
}
import {Injectable} from '@angular/core';
import {View} from '@app/model';
@Injectable()
export class ViewService {
viewList: Array<View> = [];
currentView: View;
num = 0;
addView(view: View) {
this.num += 1;
view.id = 'View_' + this.num;
this.viewList.push(view);
}
activeView(view: View) {
this.viewList.forEach((v, k) => {
v.active = v === view;
});
setTimeout(() => {
const viewEl = document.getElementById(view.id);
if (viewEl) {
viewEl.scrollIntoView();
}
}, 100);
this.currentView = view;
}
removeView(view: View) {
const index = this.viewList.indexOf(view);
this.viewList.splice(index, 1);
}
}
...@@ -71,5 +71,8 @@ ...@@ -71,5 +71,8 @@
"show manual password": "显示手动密码窗", "show manual password": "显示手动密码窗",
"skip manual password": "跳过手动密码窗", "skip manual password": "跳过手动密码窗",
"tab list": "窗口列表", "tab list": "窗口列表",
"open in new window": "新窗口打开" "open in new window": "新窗口打开",
"setting": "设置",
"yes": "是",
"no": "否"
} }
...@@ -6,7 +6,7 @@ $fa-font-path: '~font-awesome/fonts'; ...@@ -6,7 +6,7 @@ $fa-font-path: '~font-awesome/fonts';
// Todo: 去掉依赖 // Todo: 去掉依赖
@import '~bootstrap/scss/bootstrap'; @import '~bootstrap/scss/bootstrap';
//@import "~@angular/material/prebuilt-themes/indigo-pink.css"; @import "~@angular/material/prebuilt-themes/indigo-pink.css";
//$FontPathOpenSans: '~npm-font-open-sans/fonts'; //$FontPathOpenSans: '~npm-font-open-sans/fonts';
//@import '~npm-font-open-sans/open-sans'; //@import '~npm-font-open-sans/open-sans';
//$roboto-font-path: '~roboto-fontface/fonts'; //$roboto-font-path: '~roboto-fontface/fonts';
......
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