Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
L
luna
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
luna
Commits
f0abd8f7
Commit
f0abd8f7
authored
Aug 29, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改代码结构
parent
65ccd3dd
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
1141 additions
and
770 deletions
+1141
-770
app.module.ts
src/app/app.module.ts
+1
-1
asset-tree.component.ts
src/app/elements/asset-tree/asset-tree.component.ts
+8
-194
connect.component.html
src/app/elements/connect/connect.component.html
+0
-0
connect.component.ts
src/app/elements/connect/connect.component.ts
+249
-0
dialog.html
src/app/elements/connect/dialog.html
+0
-0
manual-password-dialog.html
src/app/elements/connect/manual-password-dialog.html
+0
-0
content-tab.component.css
src/app/elements/content-tab/content-tab.component.css
+79
-0
content-tab.component.html
src/app/elements/content-tab/content-tab.component.html
+8
-0
content-tab.component.ts
src/app/elements/content-tab/content-tab.component.ts
+27
-0
content-window.component.css
src/app/elements/content-window/content-window.component.css
+22
-0
content-window.component.html
...app/elements/content-window/content-window.component.html
+17
-0
content-window.component.ts
src/app/elements/content-window/content-window.component.ts
+47
-0
content.component.css
src/app/elements/content/content.component.css
+62
-0
content.component.html
src/app/elements/content/content.component.html
+24
-0
content.component.ts
src/app/elements/content/content.component.ts
+91
-0
model.ts
src/app/elements/content/model.ts
+26
-0
elements.component.ts
src/app/elements/elements.component.ts
+16
-4
left-bar.component.html
src/app/elements/left-bar/left-bar.component.html
+12
-0
left-bar.component.scss
src/app/elements/left-bar/left-bar.component.scss
+71
-0
left-bar.component.ts
src/app/elements/left-bar/left-bar.component.ts
+94
-0
leftbar.component.html
src/app/elements/leftbar/leftbar.component.html
+0
-33
leftbar.component.scss
src/app/elements/leftbar/leftbar.component.scss
+0
-107
leftbar.component.spec.ts
src/app/elements/leftbar/leftbar.component.spec.ts
+0
-25
leftbar.component.ts
src/app/elements/leftbar/leftbar.component.ts
+0
-125
nav.component.css
src/app/elements/nav/nav.component.css
+2
-1
ssh-term.component.ts
src/app/elements/ssh-term/ssh-term.component.ts
+8
-13
term.component.ts
src/app/elements/term/term.component.ts
+16
-5
tree-filter.component.css
src/app/elements/tree-filter/tree-filter.component.css
+20
-0
tree-filter.component.html
src/app/elements/tree-filter/tree-filter.component.html
+8
-0
tree-filter.component.ts
src/app/elements/tree-filter/tree-filter.component.ts
+60
-0
globals.ts
src/app/globals.ts
+11
-117
model.ts
src/app/model.ts
+95
-0
control.component.ts
src/app/pages/control/control.component.ts
+2
-2
nav.component.css
src/app/pages/control/control/controlnav/nav.component.css
+1
-1
index.component.html
src/app/pages/index/index.component.html
+0
-79
index.component.spec.ts
src/app/pages/index/index.component.spec.ts
+0
-25
index.component.ts
src/app/pages/index/index.component.ts
+0
-26
main.component.css
src/app/pages/main/main.component.css
+17
-0
main.component.html
src/app/pages/main/main.component.html
+10
-0
main.component.ts
src/app/pages/main/main.component.ts
+24
-0
pages.component.ts
src/app/pages/pages.component.ts
+11
-11
router.module.ts
src/app/router/router.module.ts
+2
-1
No files found.
src/app/app.module.ts
View file @
f0abd8f7
...
...
@@ -30,7 +30,7 @@ import {ChangLanWarningDialogComponent, RDPSolutionDialogComponent, FontDialogCo
import
{
DialogService
,
ElementDialogAlertComponent
}
from
'./elements/dialog/dialog.service'
;
import
{
PluginModules
}
from
'./plugins/plugins'
;
import
{
TestPageComponent
}
from
'./test-page/test-page.component'
;
import
{
AssetTreeDialogComponent
,
ManualPasswordDialogComponent
}
from
'./elements/
asset-tree/asset-tree
.component'
;
import
{
AssetTreeDialogComponent
,
ManualPasswordDialogComponent
}
from
'./elements/
connect/connect
.component'
;
import
{
SftpComponent
}
from
'./elements/sftp/sftp.component'
;
...
...
src/app/elements/asset-tree/asset-tree.component.ts
View file @
f0abd8f7
import
{
Component
,
Input
,
OnInit
,
Inject
,
SimpleChanges
,
OnChanges
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
import
{
NavList
,
View
}
from
'../../pages/control/control/control.component'
;
import
{
AppService
,
HttpService
,
LogService
,
NavService
}
from
'../../app.service'
;
import
{
MAT_DIALOG_DATA
,
MatDialog
,
MatDialogRef
}
from
'@angular/material
'
;
import
{
FormControl
,
Validators
}
from
'@angular/forms
'
;
import
{
connectEvt
}
from
'../../globals
'
;
import
{
MatDialog
}
from
'@angular/material
'
;
import
{
BehaviorSubject
}
from
'rxjs/BehaviorSubject'
;
import
{
ActivatedRoute
}
from
'@angular/router'
;
import
{
SystemUser
,
TreeNode
,
Asset
,
Node
}
from
'../../model'
;
import
{
TreeNode
,
ConnectEvt
}
from
'../../model'
;
import
*
as
jQuery
from
'jquery/dist/jquery.min'
;
declare
var
$
:
any
;
...
...
@@ -34,7 +34,6 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
title
:
'title'
}
},
};
pos
=
{
left
:
'100px'
,
top
:
'200px'
};
hiddenNodes
:
any
;
...
...
@@ -153,6 +152,11 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
});
}
Connect
(
node
:
TreeNode
)
{
const
evt
=
new
ConnectEvt
(
node
,
'asset'
);
connectEvt
.
next
(
evt
);
}
rootNodeAddDom
(
ztree
,
callback
)
{
const
tId
=
ztree
.
setting
.
treeId
+
'_tree_refresh'
;
const
refreshIcon
=
'<a id='
+
tId
+
' class="tree-refresh">'
+
...
...
@@ -210,76 +214,6 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
}
Connect
(
node
:
TreeNode
)
{
switch
(
node
.
meta
.
type
)
{
case
'asset'
:
this
.
connectAsset
(
node
);
break
;
case
'remote_app'
:
this
.
connectRemoteApp
(
node
);
break
;
default
:
alert
(
'Unknown type: '
+
node
.
meta
.
type
);
}
}
connectAsset
(
node
:
TreeNode
)
{
const
host
=
node
.
meta
.
asset
as
Asset
;
this
.
_http
.
getMyAssetSystemUsers
(
host
.
id
).
subscribe
(
systemUsers
=>
{
let
user
:
SystemUser
;
if
(
systemUsers
.
length
>
1
)
{
// 检查系统用户优先级,获取最高优先级的
user
=
this
.
checkPriority
(
systemUsers
);
if
(
user
)
{
return
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
);
}
const
dialogRef
=
this
.
_dialog
.
open
(
AssetTreeDialogComponent
,
{
height
:
'200px'
,
width
:
'300px'
,
data
:
{
users
:
systemUsers
}
});
dialogRef
.
afterClosed
().
subscribe
(
result
=>
{
if
(
result
)
{
for
(
const
i
of
systemUsers
)
{
if
(
i
.
id
.
toString
()
===
result
.
toString
())
{
user
=
i
;
break
;
}
}
return
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
);
}
});
}
else
if
(
systemUsers
.
length
===
1
)
{
user
=
systemUsers
[
0
];
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
);
}
else
{
alert
(
'该主机没有授权登录用户'
);
}
});
}
connectRemoteApp
(
node
:
TreeNode
)
{
const
user
=
node
.
meta
.
user
as
SystemUser
;
return
this
.
manualSetUserAuthLoginIfNeed
(
node
,
user
,
this
.
loginRemoteApp
);
}
loginRemoteApp
(
node
:
TreeNode
,
user
:
SystemUser
)
{
const
id
=
NavList
.
List
.
length
-
1
;
if
(
node
)
{
NavList
.
List
[
id
].
nick
=
node
.
name
;
NavList
.
List
[
id
].
connected
=
true
;
NavList
.
List
[
id
].
edit
=
false
;
NavList
.
List
[
id
].
closed
=
false
;
NavList
.
List
[
id
].
remoteApp
=
node
.
id
;
NavList
.
List
[
id
].
user
=
user
;
NavList
.
List
[
id
].
type
=
'rdp'
;
NavList
.
List
.
push
(
new
View
());
NavList
.
Active
=
id
;
jQuery
(
'.tabs'
).
animate
({
'scrollLeft'
:
150
*
id
},
400
);
}
}
connectFileManager
()
{
const
host
=
this
.
rightClickSelectNode
.
meta
.
asset
;
const
id
=
NavList
.
List
.
length
-
1
;
...
...
@@ -301,64 +235,6 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
this
.
Connect
(
host
);
}
manualSetUserAuthLoginIfNeed
(
host
:
Asset
,
user
:
SystemUser
,
callback
)
{
if
(
user
.
login_mode
!==
'manual'
||
user
.
protocol
!==
'rdp'
)
{
return
callback
(
host
,
user
);
}
user
=
Object
.
assign
({},
user
);
const
dialogRef
=
this
.
_dialog
.
open
(
ManualPasswordDialogComponent
,
{
height
:
'250px'
,
width
:
'500px'
,
data
:
{
username
:
user
.
username
}
});
dialogRef
.
afterClosed
().
subscribe
(
result
=>
{
if
(
!
result
)
{
return
;
}
if
(
result
.
skip
)
{
return
callback
(
host
,
user
);
}
user
.
username
=
result
.
username
;
user
.
password
=
result
.
password
;
return
callback
(
host
,
user
);
});
}
loginAsset
(
host
:
Asset
,
user
:
SystemUser
)
{
const
id
=
NavList
.
List
.
length
-
1
;
if
(
user
)
{
NavList
.
List
[
id
].
nick
=
host
.
hostname
;
NavList
.
List
[
id
].
connected
=
true
;
NavList
.
List
[
id
].
edit
=
false
;
NavList
.
List
[
id
].
closed
=
false
;
NavList
.
List
[
id
].
host
=
host
;
NavList
.
List
[
id
].
user
=
user
;
if
(
user
.
protocol
===
'ssh'
||
user
.
protocol
===
'telnet'
)
{
NavList
.
List
[
id
].
type
=
'ssh'
;
}
else
if
(
user
.
protocol
===
'rdp'
||
user
.
protocol
===
'vnc'
)
{
NavList
.
List
[
id
].
type
=
'rdp'
;
}
NavList
.
List
.
push
(
new
View
());
NavList
.
Active
=
id
;
jQuery
(
'.tabs'
).
animate
({
'scrollLeft'
:
150
*
id
},
400
);
}
}
checkPriority
(
sysUsers
:
Array
<
SystemUser
>
)
{
let
priority
=
-
1
;
let
user
:
any
;
for
(
const
u
of
sysUsers
)
{
if
(
u
.
priority
>
priority
)
{
user
=
u
;
priority
=
u
.
priority
;
}
else
if
(
u
.
priority
===
priority
)
{
return
null
;
}
}
return
user
;
}
recurseParent
(
node
)
{
const
parentNode
=
node
.
getParentNode
();
if
(
parentNode
&&
parentNode
.
pId
)
{
...
...
@@ -435,65 +311,3 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
}
@
Component
({
selector
:
'elements-asset-tree-dialog'
,
templateUrl
:
'dialog.html'
,
})
export
class
AssetTreeDialogComponent
implements
OnInit
{
UserSelectControl
=
new
FormControl
(
''
,
[
Validators
.
required
]);
selected
:
any
;
constructor
(
public
dialogRef
:
MatDialogRef
<
AssetTreeDialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
private
_logger
:
LogService
)
{
}
ngOnInit
()
{
this
.
selected
=
this
.
data
.
users
[
0
].
id
;
this
.
UserSelectControl
.
setValue
(
this
.
selected
);
// this._logger.debug(this.UserSelectControl);
}
onNoClick
():
void
{
this
.
dialogRef
.
close
();
}
compareFn
:
((
f1
:
any
,
f2
:
any
)
=>
boolean
)
|
null
=
this
.
compareByValue
;
compareByValue
(
f1
:
any
,
f2
:
any
)
{
return
f1
&&
f2
&&
f1
.
value
===
f2
.
value
;
}
}
@
Component
({
selector
:
'elements-manual-password-dialog'
,
templateUrl
:
'manual-password-dialog.html'
,
})
export
class
ManualPasswordDialogComponent
implements
OnInit
{
PasswordControl
=
new
FormControl
(
''
,
[
Validators
.
required
]);
constructor
(@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
public
dialogRef
:
MatDialogRef
<
ManualPasswordDialogComponent
>
)
{
}
onSkip
()
{
this
.
data
.
skip
=
true
;
this
.
dialogRef
.
close
(
this
.
data
);
}
onSkipAll
()
{
this
.
data
.
skipAll
=
true
;
this
.
dialogRef
.
close
(
this
.
data
);
}
onNoClick
()
{
this
.
dialogRef
.
close
();
}
onEnter
()
{
this
.
dialogRef
.
close
(
this
.
data
);
}
ngOnInit
():
void
{
}
}
src/app/
pages/index/index.component.css
→
src/app/
elements/connect/connect.component.html
View file @
f0abd8f7
File moved
src/app/elements/connect/connect.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
Input
,
OnInit
,
Output
,
Inject
,
OnDestroy
,
EventEmitter
}
from
'@angular/core'
;
import
{
connectEvt
}
from
'../../globals'
;
import
{
AppService
,
HttpService
,
LogService
,
NavService
}
from
'../../app.service'
;
import
{
MAT_DIALOG_DATA
,
MatDialog
,
MatDialogRef
}
from
'@angular/material'
;
import
{
FormControl
,
Validators
}
from
'@angular/forms'
;
import
{
ActivatedRoute
}
from
'@angular/router'
;
import
{
SystemUser
,
TreeNode
,
Asset
}
from
'../../model'
;
import
{
View
}
from
'../content/model'
;
import
*
as
jQuery
from
'jquery/dist/jquery.min'
;
declare
var
$
:
any
;
@
Component
({
selector
:
'elements-connect'
,
templateUrl
:
'./connect.component.html'
,
})
export
class
ElementConnectComponent
implements
OnInit
,
OnDestroy
{
@
Output
()
onNewView
:
EventEmitter
<
View
>
=
new
EventEmitter
<
View
>
();
pos
=
{
left
:
'100px'
,
top
:
'200px'
};
hasLoginTo
=
false
;
constructor
(
private
_appSvc
:
AppService
,
public
_dialog
:
MatDialog
,
public
_logger
:
LogService
,
private
activatedRoute
:
ActivatedRoute
,
private
_http
:
HttpService
,
)
{
}
ngOnInit
():
void
{
connectEvt
.
asObservable
().
subscribe
(
evt
=>
{
switch
(
evt
.
action
)
{
case
'asset'
:
{
this
.
connectAsset
(
evt
.
node
);
break
;
}
}
});
}
ngOnDestroy
():
void
{
connectEvt
.
unsubscribe
();
}
Connect
(
node
:
TreeNode
)
{
switch
(
node
.
meta
.
type
)
{
case
'asset'
:
this
.
connectAsset
(
node
);
break
;
case
'remote_app'
:
this
.
connectRemoteApp
(
node
);
break
;
default
:
alert
(
'Unknown type: '
+
node
.
meta
.
type
);
}
}
connectAsset
(
node
:
TreeNode
)
{
const
host
=
node
.
meta
.
asset
as
Asset
;
this
.
_http
.
getMyAssetSystemUsers
(
host
.
id
).
subscribe
(
systemUsers
=>
{
let
user
:
SystemUser
;
if
(
systemUsers
.
length
>
1
)
{
// 检查系统用户优先级,获取最高优先级的
user
=
this
.
checkPriority
(
systemUsers
);
if
(
user
)
{
return
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
.
bind
(
this
));
}
const
dialogRef
=
this
.
_dialog
.
open
(
AssetTreeDialogComponent
,
{
height
:
'200px'
,
width
:
'300px'
,
data
:
{
users
:
systemUsers
}
});
dialogRef
.
afterClosed
().
subscribe
(
result
=>
{
if
(
result
)
{
for
(
const
i
of
systemUsers
)
{
if
(
i
.
id
.
toString
()
===
result
.
toString
())
{
user
=
i
;
break
;
}
}
return
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
.
bind
(
this
));
}
});
}
else
if
(
systemUsers
.
length
===
1
)
{
user
=
systemUsers
[
0
];
this
.
manualSetUserAuthLoginIfNeed
(
host
,
user
,
this
.
loginAsset
.
bind
(
this
));
}
else
{
alert
(
'该主机没有授权登录用户'
);
}
});
}
connectRemoteApp
(
node
:
TreeNode
)
{
const
user
=
node
.
meta
.
user
as
SystemUser
;
return
this
.
manualSetUserAuthLoginIfNeed
(
node
,
user
,
this
.
loginRemoteApp
.
bind
(
this
));
}
loginRemoteApp
(
node
:
TreeNode
,
user
:
SystemUser
)
{
if
(
node
)
{
const
view
=
new
View
();
view
.
nick
=
node
.
name
;
view
.
connected
=
true
;
view
.
editable
=
false
;
view
.
closed
=
false
;
view
.
remoteApp
=
node
.
id
;
view
.
user
=
user
;
view
.
type
=
'rdp'
;
this
.
onNewView
.
emit
(
view
);
}
}
connectFileManager
(
node
:
TreeNode
)
{
const
host
=
node
.
meta
.
asset
as
Asset
;
if
(
host
)
{
const
view
=
new
View
();
view
.
nick
=
'[FILE]'
+
host
.
hostname
;
view
.
connected
=
true
;
view
.
editable
=
false
;
view
.
closed
=
false
;
view
.
host
=
host
;
view
.
type
=
'sftp'
;
this
.
onNewView
.
emit
(
view
);
// jQuery('.tabs').animate({'scrollLeft': 150 * id}, 400);
}
}
connectTerminal
(
node
:
TreeNode
)
{
this
.
Connect
(
node
);
}
manualSetUserAuthLoginIfNeed
(
node
:
any
,
user
:
SystemUser
,
callback
)
{
if
(
user
.
login_mode
!==
'manual'
||
user
.
protocol
!==
'rdp'
)
{
return
callback
(
node
,
user
);
}
user
=
Object
.
assign
({},
user
);
const
dialogRef
=
this
.
_dialog
.
open
(
ManualPasswordDialogComponent
,
{
height
:
'250px'
,
width
:
'500px'
,
data
:
{
username
:
user
.
username
}
});
dialogRef
.
afterClosed
().
subscribe
(
result
=>
{
if
(
!
result
)
{
return
;
}
if
(
result
.
skip
)
{
return
callback
(
node
,
user
);
}
user
.
username
=
result
.
username
;
user
.
password
=
result
.
password
;
return
callback
(
node
,
user
);
});
}
loginAsset
(
host
:
Asset
,
user
:
SystemUser
)
{
if
(
user
)
{
const
view
=
new
View
();
view
.
nick
=
host
.
hostname
;
view
.
connected
=
true
;
view
.
editable
=
false
;
view
.
closed
=
false
;
view
.
host
=
host
;
view
.
user
=
user
;
if
(
user
.
protocol
===
'ssh'
||
user
.
protocol
===
'telnet'
)
{
view
.
type
=
'ssh'
;
}
else
if
(
user
.
protocol
===
'rdp'
||
user
.
protocol
===
'vnc'
)
{
view
.
type
=
'rdp'
;
}
this
.
onNewView
.
emit
(
view
);
}
}
checkPriority
(
sysUsers
:
Array
<
SystemUser
>
)
{
let
priority
=
-
1
;
let
user
:
any
;
for
(
const
u
of
sysUsers
)
{
if
(
u
.
priority
>
priority
)
{
user
=
u
;
priority
=
u
.
priority
;
}
else
if
(
u
.
priority
===
priority
)
{
return
null
;
}
}
return
user
;
}
}
@
Component
({
selector
:
'elements-asset-tree-dialog'
,
templateUrl
:
'dialog.html'
,
})
export
class
AssetTreeDialogComponent
implements
OnInit
{
UserSelectControl
=
new
FormControl
(
''
,
[
Validators
.
required
]);
selected
:
any
;
constructor
(
public
dialogRef
:
MatDialogRef
<
AssetTreeDialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
private
_logger
:
LogService
)
{
}
ngOnInit
()
{
this
.
selected
=
this
.
data
.
users
[
0
].
id
;
this
.
UserSelectControl
.
setValue
(
this
.
selected
);
// this._logger.debug(this.UserSelectControl);
}
onNoClick
():
void
{
this
.
dialogRef
.
close
();
}
compareFn
:
((
f1
:
any
,
f2
:
any
)
=>
boolean
)
|
null
=
this
.
compareByValue
;
compareByValue
(
f1
:
any
,
f2
:
any
)
{
return
f1
&&
f2
&&
f1
.
value
===
f2
.
value
;
}
}
@
Component
({
selector
:
'elements-manual-password-dialog'
,
templateUrl
:
'manual-password-dialog.html'
,
})
export
class
ManualPasswordDialogComponent
implements
OnInit
{
PasswordControl
=
new
FormControl
(
''
,
[
Validators
.
required
]);
constructor
(@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
public
dialogRef
:
MatDialogRef
<
ManualPasswordDialogComponent
>
)
{
}
onSkip
()
{
this
.
data
.
skip
=
true
;
this
.
dialogRef
.
close
(
this
.
data
);
}
onSkipAll
()
{
this
.
data
.
skipAll
=
true
;
this
.
dialogRef
.
close
(
this
.
data
);
}
onNoClick
()
{
this
.
dialogRef
.
close
();
}
onEnter
()
{
this
.
dialogRef
.
close
(
this
.
data
);
}
ngOnInit
():
void
{
}
}
src/app/elements/
asset-tree
/dialog.html
→
src/app/elements/
connect
/dialog.html
View file @
f0abd8f7
File moved
src/app/elements/
asset-tree
/manual-password-dialog.html
→
src/app/elements/
connect
/manual-password-dialog.html
View file @
f0abd8f7
File moved
src/app/elements/content-tab/content-tab.component.css
0 → 100644
View file @
f0abd8f7
.window
{
display
:
none
;
/*padding: 15px;*/
}
li
.disconnected
{
background-color
:
darkgray
;
}
li
.hidden
{
display
:
none
;
}
li
{
display
:
inline-table
;
width
:
150px
;
height
:
30px
;
position
:
relative
;
box-sizing
:
content-box
;
float
:
left
;
;
background-color
:
#463a3a66
;
border-right
:
1px
solid
#3a3333
c2
;
}
li
.active
{
box-sizing
:
border-box
;
border-bottom
:
3px
solid
#19aa8d
;
}
li
span
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
color
:
#f1f0f0
;
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
;
}
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
;
}
li
.active
a
{
color
:
white
;
}
li
.active
span
{
padding-left
:
12px
;
line-height
:
26px
;
color
:
white
;
height
:
18px
;
}
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
;
}
src/app/elements/content-tab/content-tab.component.html
0 → 100644
View file @
f0abd8f7
<li
[
ngClass
]="{'
active
'
:
view
.
active
,'
disconnected
'
:
!
view
.
connected
,
'
hidden
'
:
view
.
closed
!=
false
}"
[
id
]="
view
.
id
"
(
click
)="
setActive
()"
(
dblclick
)="
view
.
editable=
true;setActive()"
>
<span
*
ngIf=
"view.nick"
>
{{view.nick | truncatechars:25 }}
</span>
<input
*
ngIf=
"view.editable"
[(
ngModel
)]="
view
.
nick
"
(
blur
)="
view
.
editable=
false"
(
keyup
.
enter
)="
view
.
editable=
false"
autofocus=
"true"
/>
<a
class=
"close"
(
click
)="
close
()"
>
×
</a>
</li>
src/app/elements/content-tab/content-tab.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
OnInit
,
Input
,
Output
,
EventEmitter
}
from
'@angular/core'
;
import
{
View
,
ViewAction
}
from
'../content/model'
;
@
Component
({
selector
:
'elements-content-tab'
,
templateUrl
:
'./content-tab.component.html'
,
styleUrls
:
[
'./content-tab.component.css'
],
})
export
class
ElementContentTabComponent
implements
OnInit
{
@
Input
()
view
:
View
;
@
Output
()
onAction
:
EventEmitter
<
ViewAction
>
=
new
EventEmitter
<
ViewAction
>
();
ngOnInit
():
void
{
}
close
()
{
const
action
=
new
ViewAction
(
this
.
view
,
'close'
);
this
.
onAction
.
emit
(
action
);
}
setActive
()
{
const
action
=
new
ViewAction
(
this
.
view
,
'active'
);
this
.
onAction
.
emit
(
action
);
}
}
src/app/elements/content-window/content-window.component.css
0 → 100644
View file @
f0abd8f7
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
;
}
src/app/elements/content-window/content-window.component.html
0 → 100644
View file @
f0abd8f7
<div
class=
"window"
[
ngClass
]="{'
active
'
:view
.
active
}"
style=
"height: 100%"
>
<elements-ssh-term
[
view
]="
view
"
[
host
]="
view
.
host
"
[
sysUser
]="
view
.
user
"
*
ngIf=
"view.type=='ssh'"
>
</elements-ssh-term>
<elements-guacamole
[
host
]="
view
.
host
"
[
sysUser
]="
view
.
user
"
[
remoteAppId
]="
view
.
remoteApp
"
*
ngIf=
"view.type=='rdp'"
>
</elements-guacamole>
<app-sftp
*
ngIf=
"view.type=='sftp'"
[
host
]="
view
.
host
"
></app-sftp>
</div>
src/app/elements/content-window/content-window.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
OnInit
,
Input
}
from
'@angular/core'
;
import
{
View
}
from
'../content/model'
;
@
Component
({
selector
:
'elements-content-window'
,
templateUrl
:
'./content-window.component.html'
,
styleUrls
:
[
'./content-window.component.css'
]
})
export
class
ElementContentViewComponent
implements
OnInit
{
@
Input
()
view
:
View
;
static
active
()
{
// viewList.List.forEach((v, k) => {
// v.hide = id.toString() !== k;
// });
// viewList.Active = id;
}
static
TerminalDisconnect
(
id
)
{
// if (viewList.List[id].connected) {
// viewList.List[id].connected = false;
// viewList.List[id].Term.write('\r\n\x1b[31mBye Bye!\x1b[m\r\n');
// TermWS.emit('logout', viewList.List[id].room);
// }
}
static
RdpDisconnect
(
id
)
{
// viewList.List[id].connected = false;
}
static
DisconnectAll
()
{
// for (let i = 0; i < viewList.List.length; i++) {
// Todo:
// ContentComponent.TerminalDisconnect(i);
// }
}
constructor
()
{
}
ngOnInit
()
{
}
// trackByFn(index: number, item: View) {
// return item.id;
// }
}
src/app/elements/content/content.component.css
0 → 100644
View file @
f0abd8f7
/*.right-side {*/
/*height: 100%;*/
/*width: 100%;*/
/*background-color: gray;*/
/*}*/
/*div {*/
/*height: 100%;*/
/*width: 100%;*/
/*padding: 0;*/
/*background-color: #1f1b1b;*/
/*margin: 0;*/
/*position: initial;*/
/*}*/
/*#content {*/
/*padding-top: 0;*/
/*}*/
/*.container-fluid {*/
/*padding-top: 30px;*/
/*}*/
.tabs
{
height
:
30px
;
overflow-y
:
hidden
;
overflow-x
:
hidden
;
position
:
relative
;
}
.tabs
ul
{
list-style-type
:
none
;
height
:
30px
;
background-color
:
#3a3333
;
display
:
block
;
min-width
:
100%
;
padding-left
:
0
;
}
/*
* 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
}
src/app/elements/content/content.component.html
0 → 100644
View file @
f0abd8f7
<div
id=
"content"
fxLayout=
"column"
ngxSplit=
"column"
style=
"width: 100%;height: 100%;"
>
<div
fxFlex=
"0 0 30px"
>
<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>
<!--<ul [ngStyle]="{'width':150*viewList.length+'px'}">-->
<elements-content-tab
*
ngFor=
"let view of viewList"
[
view
]="
view
"
(
onAction
)="
onViewAction
($
event
)"
>
</elements-content-tab>
</ul>
</div>
</div>
<div
fxFlex=
"0 0 calc(100%-35px)"
id=
"winContainer"
>
<div
class=
"window"
*
ngFor=
"let view of viewList; let i=index"
>
<elements-content-window
[
view
]="
view
"
></elements-content-window>
</div>
</div>
</div>
<elements-connect
(
onNewView
)="
onNewView
($
event
)"
></elements-connect>
src/app/elements/content/content.component.ts
0 → 100644
View file @
f0abd8f7
/**
* 控制页面
*
* 主管已连接的主机标签卡,各连接方式的web展现(WebTerminal、RDP、VNC等)
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
TermWS
}
from
'../../globals'
;
import
{
View
,
ViewAction
}
from
'./model'
;
import
jQuery
from
'jquery/dist/jquery.min'
;
@
Component
({
selector
:
'elements-content'
,
templateUrl
:
'./content.component.html'
,
styleUrls
:
[
'./content.component.css'
]
})
export
class
ElementContentComponent
implements
OnInit
{
viewList
:
Array
<
View
>
=
[];
static
RdpDisconnect
(
id
)
{
// viewList.List[id].connected = false;
}
static
DisconnectAll
()
{
// for (let i = 0; i < viewList.List.length; i++) {
// // Todo:
// // ContentComponent.TerminalDisconnect(i);
// }
}
constructor
()
{
}
ngOnInit
()
{
}
onNewView
(
view
)
{
this
.
viewList
.
push
(
view
);
this
.
setViewActive
(
view
);
}
onViewAction
(
action
:
ViewAction
)
{
switch
(
action
.
name
)
{
case
'active'
:
{
this
.
setViewActive
(
action
.
view
);
break
;
}
case
'close'
:
{
this
.
closeView
(
action
.
view
);
break
;
}
}
}
setViewActive
(
view
)
{
this
.
viewList
.
forEach
((
v
,
k
)
=>
{
v
.
active
=
v
===
view
;
});
}
closeView
(
view
)
{
let
nextActiveView
=
null
;
const
index
=
this
.
viewList
.
indexOf
(
view
);
if
(
view
.
active
)
{
// 如果关掉的是最后一个, 存在上一个
if
(
index
===
this
.
viewList
.
length
-
1
&&
index
!==
0
)
{
nextActiveView
=
this
.
viewList
[
index
-
1
];
}
else
if
(
index
<
this
.
viewList
.
length
)
{
nextActiveView
=
this
.
viewList
[
index
+
1
];
}
}
this
.
viewList
.
splice
(
index
,
1
);
if
(
nextActiveView
)
{
this
.
setViewActive
(
nextActiveView
);
}
}
scrollLeft
()
{
const
tabRef
=
jQuery
(
'.tabs'
);
tabRef
.
scrollLeft
(
tabRef
.
scrollLeft
()
-
100
);
}
scrollRight
()
{
const
tabRef
=
jQuery
(
'.tabs'
);
tabRef
.
scrollLeft
(
tabRef
.
scrollLeft
()
+
100
);
}
}
src/app/elements/content/model.ts
0 → 100644
View file @
f0abd8f7
export
class
View
{
id
:
string
;
nick
:
string
;
type
:
string
;
editable
:
boolean
;
active
:
boolean
;
connected
:
boolean
;
hide
:
boolean
;
closed
:
boolean
;
host
:
any
;
user
:
any
;
remoteApp
:
string
;
room
:
string
;
Rdp
:
any
;
Term
:
any
;
}
export
class
ViewAction
{
view
:
View
;
name
:
string
;
constructor
(
view
:
View
,
name
:
string
)
{
this
.
view
=
view
;
this
.
name
=
name
;
}
}
src/app/elements/elements.component.ts
View file @
f0abd8f7
// Elements
import
{
ElementTableComponent
}
from
'./table/table.component'
;
import
{
ElementLeftbarComponent
}
from
'./leftbar/leftbar.component'
;
import
{
ElementLeftBarComponent
}
from
'./left-bar/left-bar.component'
;
import
{
ElementContentComponent
}
from
'./content/content.component'
;
import
{
ElementContentViewComponent
}
from
'./content-window/content-window.component'
;
import
{
ElementContentTabComponent
}
from
'./content-tab/content-tab.component'
;
import
{
ElementAssetTreeComponent
}
from
'./asset-tree/asset-tree.component'
;
import
{
ElementTreeFilterComponent
}
from
'./tree-filter/tree-filter.component'
;
import
{
ElementOfooterComponent
}
from
'./ofooter/ofooter.component'
;
import
{
ElementFooterComponent
}
from
'./footer/footer.component'
;
import
{
ElementTermComponent
}
from
'./term/term.component'
;
...
...
@@ -13,17 +18,23 @@ 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
{
Element
AssetTreeComponent
,
AssetTreeDialogComponent
,
ManualPasswordDialogComponent
}
from
'./asset-tree/asset-tree
.component'
;
import
{
Element
ConnectComponent
,
AssetTreeDialogComponent
,
ManualPasswordDialogComponent
}
from
'./connect/connect
.component'
;
import
{
RDPSolutionDialogComponent
,
FontDialogComponent
}
from
'./nav/nav.component'
;
export
const
ElementComponents
=
[
ElementLeftbarComponent
,
ElementLeftBarComponent
,
ElementContentComponent
,
ElementContentTabComponent
,
ElementContentViewComponent
,
ElementConnectComponent
,
ElementTreeFilterComponent
,
ElementOfooterComponent
,
ElementTableComponent
,
ElementFooterComponent
,
ElementTermComponent
,
ElementInteractiveComponent
,
ElementNavComponent
,
ChangLanWarningDialogComponent
,
ElementNavComponent
,
ChangLanWarningDialogComponent
,
ElementPopupComponent
,
ElementRdpComponent
,
ElementServerMenuComponent
,
...
...
@@ -32,6 +43,7 @@ export const ElementComponents = [
ElementGuacamoleComponent
,
ElementAssetTreeComponent
,
ElementSshTermComponent
,
ElementConnectComponent
,
AssetTreeDialogComponent
,
ManualPasswordDialogComponent
,
RDPSolutionDialogComponent
,
...
...
src/app/elements/left-bar/left-bar.component.html
0 → 100644
View file @
f0abd8f7
<div
class=
"sidebar"
fxLayout=
"column"
ngxSplit=
"column"
>
<div
fxflex=
"1 1 30px"
class=
"tree-filter"
>
<elements-tree-filter></elements-tree-filter>
</div>
<div
class=
"overflow ngx-scroll-overlay"
fxflex=
"1 1 calc(90%-60px)"
>
<elements-asset-tree
[
query
]="
q
"
></elements-asset-tree>
</div>
<div
class=
"footer-version"
fxflex=
"1 1 30px"
>
<p>
Version
<strong>
{{version}}
</strong></p>
</div>
</div>
src/app/elements/left-bar/left-bar.component.scss
0 → 100644
View file @
f0abd8f7
.sidebar
{
height
:
100%
;
width
:
100%
;
overflow
:
auto
;
}
//
//:root {
// font-family: "Hiragino Kaku Gothic ProN", Meiryo, sans-serif;
//}
label
{
margin-bottom
:
0
;
}
.fa.fa-undefined
:before
{
content
:
"\f26c"
;
}
.tree-filter
{
height
:
30px
;
}
.overflow
{
height
:
90%
;
display
:
flex
;
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
:
60px
;
}
.footer-version
>
p
{
height
:
8px
;
font-size
:
13px
;
padding-top
:
2px
;
padding-bottom
:
2px
;
color
:
#d6cbcb
;
}
//@import "~@swimlane/ngx-ui/release/styles/components/scrollbars";
.ngx-scroll-overlay
{
overflow
:
auto
;
// for FF
}
//.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;
//}
src/app/elements/left-bar/left-bar.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
Inject
,
OnInit
,
ViewChild
,
ElementRef
}
from
'@angular/core'
;
import
{
AppService
,
HttpService
,
LogService
}
from
'../../app.service'
;
// import {ElementTreeFilterComponent} from '../tree-filter/tree-filter.component';
import
{
DataStore
}
from
'../../globals'
;
import
{
version
}
from
'../../../environments/environment'
;
import
{
MAT_DIALOG_DATA
,
MatDialog
,
MatDialogRef
}
from
'@angular/material'
;
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
:
'elements-left-bar'
,
templateUrl
:
'./left-bar.component.html'
,
styleUrls
:
[
'./left-bar.component.scss'
],
// providers: [ElementTreeFilterComponent]
})
export
class
ElementLeftBarComponent
{
DataStore
=
DataStore
;
version
=
version
;
q
:
string
;
event
:
MouseEvent
;
clientX
=
0
;
clientY
=
0
;
TooltipPosition
=
'above'
;
static
Reload
()
{
}
static
Hide
()
{
DataStore
.
leftbarshow
=
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
.
leftbarshow
=
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
_logger
:
LogService
,
public
_dialog
:
MatDialog
,
)
{
this
.
_logger
.
log
(
'nav.ts:NavComponent'
);
}
Search
(
q
)
{
// Todo:
// this._search.Search(q);
}
onRightClick
(
event
:
MouseEvent
):
void
{
this
.
clientX
=
event
.
clientX
;
this
.
clientY
=
event
.
clientY
;
}
}
src/app/elements/leftbar/leftbar.component.html
deleted
100644 → 0
View file @
65ccd3dd
<mat-sidenav-container>
<mat-sidenav
#
sidenav
mode=
"side"
opened=
"true"
class=
"example-sidenav"
[
fixedInViewport
]="
options
.
value
.
fixed
"
[
fixedTopGap
]="
options
.
value
.
top
"
[
fixedBottomGap
]="
options
.
value
.
bottom
"
>
<nav>
<div
class=
"header"
>
<a
href=
"http://www.jumpserver.org"
target=
"_blank"
>
<img
alt=
"image"
height=
"55"
src=
"/static/imgs/logo-text.png"
style=
"margin-left: 10px"
>
</a>
</div>
<div
class=
"body"
>
<ul
class=
"nav metismenu nav-frist-level"
>
<li
*
ngFor=
"let bar of leftbar;let i = index"
[
ngClass
]="{'
active
'
:i=
=active}"
>
<a
(
click
)="
gotoLink
(
bar
.
link
,
i
,
-1
)"
>
<i
class=
"{{bar.class}}"
></i>
<span
class=
"nav-label"
>
{{bar.name|trans}}
</span>
<span
class=
"{{bar.label}}"
></span>
</a>
<ul
class=
"nav nav-second-level collapse"
>
<li
*
ngFor=
"let child of bar.child;let ii = index"
[
ngClass
]="{'
active
'
:ii=
=active2}"
>
<a
(
click
)="
gotoLink
(
child
.
link
,
i
,
ii
)"
>
{{child.name|trans}}
</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</mat-sidenav>
<div
class=
"navbar-header"
>
<button
class=
"navbar-minimalize minimalize-styl-2 btn btn-primary "
(
click
)="
sidenav
.
toggle
()"
><i
class=
"fa fa-bars"
></i></button>
</div>
</mat-sidenav-container>
src/app/elements/leftbar/leftbar.component.scss
deleted
100644 → 0
View file @
65ccd3dd
li
a
{
background-color
:
rgba
(
0
,
0
,
0
,
0
);
box-sizing
:
border-box
;
color
:
rgb
(
167
,
177
,
194
);
cursor
:
pointer
;
display
:
block
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
font-weight
:
600
;
height
:
46px
;
line-height
:
18
.5714px
;
list-style-image
:
none
;
list-style-position
:
outside
;
list-style-type
:
none
;
padding-bottom
:
14px
;
padding-left
:
25px
;
padding-right
:
20px
;
padding-top
:
14px
;
position
:
relative
;
text-align
:
left
;
text-decoration-color
:
rgb
(
167
,
177
,
194
);
text-decoration-line
:
none
;
text-decoration-style
:
solid
;
text-size-adjust
:
100%
;
width
:
220px
;
-webkit-tap-highlight-color
:
rgba
(
0
,
0
,
0
,
0
);
}
li
.active
>
a
{
width
:
216px
;
color
:
white
;
}
li
.active
ul
.nav.nav-second-level
li
{;
border-bottom-style
:
none
;
border-bottom-width
:
0px
;
box-sizing
:
border-box
;
color
:
rgb
(
103
,
106
,
108
);
display
:
block
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
height
:
32px
;
line-height
:
18
.5714px
;
list-style-image
:
none
;
list-style-position
:
outside
;
list-style-type
:
none
;
position
:
relative
;
text-align
:
left
;
text-size-adjust
:
100%
;
visibility
:
visible
;
width
:
216px
;
-webkit-tap-highlight-color
:
rgba
(
0
,
0
,
0
,
0
);
}
li
.active
ul
.nav.nav-second-level
{
box-sizing
:
border-box
;
color
:
rgb
(
103
,
106
,
108
);
display
:
block
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
line-height
:
18
.5714px
;
list-style-image
:
none
;
list-style-position
:
outside
;
list-style-type
:
none
;
margin-bottom
:
0px
;
margin-top
:
0px
;
padding-left
:
0px
;
text-align
:
left
;
text-size-adjust
:
100%
;
visibility
:
visible
;
width
:
216px
;
-webkit-margin-after
:
0px
;
-webkit-margin-before
:
0px
;
-webkit-margin-end
:
0px
;
-webkit-margin-start
:
0px
;
-webkit-padding-start
:
0px
;
-webkit-tap-highlight-color
:
rgba
(
0
,
0
,
0
,
0
);
}
mat-sidenav
{
background-color
:
#2f4050
;
}
nav
{
width
:
220px
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
}
div
.header
{
background-color
:
#202c37
;
}
div
.body
{
background-color
:
#2f4050
;
height
:
100%
;
}
li
:hover
{
color
:
white
!
important
;
}
.nav-second-level
li
a
{
padding
:
7px
10px
7px
52px
;
}
src/app/elements/leftbar/leftbar.component.spec.ts
deleted
100644 → 0
View file @
65ccd3dd
import
{
async
,
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
ElementLeftbarComponent
}
from
'./leftbar.component'
;
describe
(
'ElementLeftbarComponent'
,
()
=>
{
let
component
:
ElementLeftbarComponent
;
let
fixture
:
ComponentFixture
<
ElementLeftbarComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
ElementLeftbarComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
ElementLeftbarComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should create'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/elements/leftbar/leftbar.component.ts
deleted
100644 → 0
View file @
65ccd3dd
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
FormBuilder
,
FormGroup
}
from
'@angular/forms'
;
import
{
Router
}
from
'@angular/router'
;
@
Component
({
selector
:
'elements-leftbar'
,
templateUrl
:
'./leftbar.component.html'
,
styleUrls
:
[
'./leftbar.component.scss'
]
})
export
class
ElementLeftbarComponent
implements
OnInit
{
leftbar
=
[
{
'name'
:
'Dashboard'
,
'class'
:
'fa fa-dashboard'
,
'label'
:
''
,
'link'
:
'/'
},
{
'name'
:
'Users'
,
'class'
:
'fa fa-group'
,
'label'
:
'fa arrow'
,
'child'
:
[
{
'name'
:
'User'
,
},
{
'name'
:
'User group'
,
},
{
'name'
:
'Login logs'
,
}
]
},
{
'name'
:
'Assets'
,
'class'
:
'fa fa-inbox'
,
'label'
:
'fa arrow'
,
'child'
:
[
{
'name'
:
'Asset'
,
},
{
'name'
:
'Asset group'
,
},
{
'name'
:
'Cluster'
,
},
{
'name'
:
'Admin user'
,
},
{
'name'
:
'System user'
,
},
{
'name'
:
'Labels'
,
}
]
},
{
'name'
:
'Perms'
,
'class'
:
'fa fa-edit'
,
'label'
:
'fa arrow'
,
'child'
:
[{
'name'
:
'Asset permission'
}]
},
{
'name'
:
'Sessions'
,
'class'
:
'fa fa-rocket'
,
'label'
:
'fa arrow'
,
'child'
:
[
{
'name'
:
'Session online'
},
{
'name'
:
'Session offline'
},
{
'name'
:
'Commands'
},
{
'name'
:
'Terminal'
},
]
},
{
'name'
:
'Job Center'
,
'class'
:
'fa fa-coffee'
,
'label'
:
'fa arrow'
,
'child'
:
[
{
'name'
:
'Task'
,
'link'
:
'/task'
},
]
},
{
'name'
:
'Settings'
,
'class'
:
'fa fa-gears'
,
'label'
:
''
,
'link'
:
'/luna/setting'
},
];
options
:
FormGroup
;
active
:
number
;
active2
:
number
;
constructor
(
fb
:
FormBuilder
,
private
_router
:
Router
)
{
this
.
options
=
fb
.
group
({
'fixed'
:
true
,
'top'
:
0
,
'bottom'
:
0
,
});
}
ngOnInit
()
{
this
.
active
=
6
;
this
.
active2
=
0
;
}
gotoLink
(
link
:
string
,
index
:
number
,
index2
:
number
)
{
if
(
link
)
{
if
(
link
===
'/luna/setting'
)
{
this
.
_router
.
navigate
([
'setting'
]);
}
else
{
window
.
location
.
href
=
link
;
}
}
this
.
active
=
index
;
this
.
active2
=
index2
;
}
}
src/app/elements/nav/nav.component.css
View file @
f0abd8f7
.nav
{
display
:
block
;
margin-top
:
2px
;
height
:
30px
height
:
31px
;
background-color
:
#463e3e
;
}
.nav
ul
{
...
...
src/app/elements/ssh-term/ssh-term.component.ts
View file @
f0abd8f7
import
{
AfterViewInit
,
Component
,
Input
,
OnInit
,
OnDestroy
}
from
'@angular/core'
;
import
{
Terminal
}
from
'xterm'
;
import
{
NavList
,
View
}
from
'../../pages/control/control/control.component
'
;
import
{
View
}
from
'../content/model
'
;
import
{
UUIDService
}
from
'../../app.service'
;
import
{
CookieService
}
from
'ngx-cookie-service'
;
import
{
Socket
}
from
'../../utils/socket'
;
...
...
@@ -14,6 +14,7 @@ import {getWsSocket} from '../../globals';
})
export
class
ElementSshTermComponent
implements
OnInit
,
AfterViewInit
,
OnDestroy
{
@
Input
()
host
:
any
;
@
Input
()
view
:
View
;
@
Input
()
sysUser
:
any
;
@
Input
()
index
:
number
;
@
Input
()
token
:
string
;
...
...
@@ -22,13 +23,11 @@ export class ElementSshTermComponent implements OnInit, AfterViewInit, OnDestroy
secret
:
string
;
ws
:
Socket
;
roomID
:
string
;
view
:
View
;
constructor
(
private
_uuid
:
UUIDService
,
private
_cookie
:
CookieService
)
{
}
ngOnInit
()
{
this
.
view
=
NavList
.
List
[
this
.
index
];
this
.
secret
=
this
.
_uuid
.
gen
();
this
.
newTerm
();
getWsSocket
().
then
(
sock
=>
{
...
...
@@ -92,7 +91,7 @@ export class ElementSshTermComponent implements OnInit, AfterViewInit, OnDestroy
// 服务器主动断开
this
.
ws
.
on
(
'disconnect'
,
()
=>
{
console
.
log
(
'On disconnect event trigger'
);
this
.
close
()
;
this
.
view
.
connected
=
false
;
});
this
.
ws
.
on
(
'logout'
,
data
=>
{
...
...
@@ -111,19 +110,15 @@ export class ElementSshTermComponent implements OnInit, AfterViewInit, OnDestroy
});
}
// 客户端主动关闭
close
()
{
if
(
this
.
view
&&
(
this
.
view
.
room
===
this
.
roomID
))
{
this
.
view
.
connected
=
false
;
this
.
ws
.
emit
(
'logout'
,
this
.
roomID
);
}
}
active
()
{
this
.
term
.
focus
();
}
ngOnDestroy
():
void
{
this
.
close
();
console
.
log
(
'Close view'
);
if
(
this
.
view
&&
(
this
.
view
.
room
===
this
.
roomID
))
{
this
.
view
.
connected
=
false
;
this
.
ws
.
emit
(
'logout'
,
this
.
roomID
);
}
}
}
src/app/elements/term/term.component.ts
View file @
f0abd8f7
...
...
@@ -24,9 +24,6 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
@
Output
()
winSizeChangeTrigger
=
new
EventEmitter
<
Array
<
number
>>
();
winSizeChange$
:
Observable
<
any
>
;
constructor
(
private
_cookie
:
CookieService
)
{
}
ngOnInit
()
{
this
.
winSizeChange$
=
Observable
.
fromEvent
(
window
,
'resize'
)
.
debounceTime
(
500
)
...
...
@@ -66,21 +63,35 @@ export class ElementTermComponent implements OnInit, AfterViewInit {
availableWidth
=
activeEle
.
width
()
-
elementPaddingHor
-
(
<
any
>
this
.
term
).
viewport
.
scrollBarWidth
;
}
const
dimensions
=
(
<
any
>
this
.
term
).
renderer
.
dimensions
;
const
geometry
=
[
Math
.
floor
(
availableWidth
/
(
<
any
>
this
.
term
).
renderer
.
dimensions
.
actualCellWidth
)
-
1
,
Math
.
floor
(
availableHeight
/
(
<
any
>
this
.
term
).
renderer
.
dimensions
.
actualCellHeight
)
-
1
Math
.
floor
(
availableWidth
/
dimensions
.
actualCellWidth
)
-
1
,
Math
.
floor
(
availableHeight
/
dimensions
.
actualCellHeight
)
-
2
];
console
.
log
(
availableWidth
,
dimensions
.
actualCellWidth
);
console
.
log
(
availableHeight
,
dimensions
.
actualCellHeight
);
console
.
log
(
'with: '
,
geometry
[
0
],
'height: '
,
geometry
[
1
]);
if
(
!
isFinite
(
geometry
[
0
]))
{
geometry
[
0
]
=
80
;
}
if
(
!
isFinite
(
geometry
[
1
]))
{
geometry
[
1
]
=
24
;
}
return
geometry
;
}
resizeTerm
()
{
const
size
=
this
.
getWinSize
();
// Todo: 修改大小
console
.
log
(
'get size is: '
,
size
);
if
(
isNaN
(
size
[
0
])
||
isNaN
(
size
[
1
]))
{
fit
(
this
.
term
);
}
else
{
(
<
any
>
this
.
term
).
renderer
.
clear
();
this
.
term
.
resize
(
size
[
0
],
size
[
1
]);
}
console
.
log
(
size
);
this
.
winSizeChangeTrigger
.
emit
([
this
.
term
.
cols
,
this
.
term
.
rows
]);
}
...
...
src/app/elements/tree-filter/tree-filter.component.css
0 → 100644
View file @
f0abd8f7
/*.left-search {*/
/*padding-left: 14px;*/
/*width: 100%;*/
/*border: none;*/
/*}*/
.search
{
border
:
none
;
border-left-width
:
0
;
border-bottom
:
#19aa8d
1px
inset
;
width
:
100%
;
background
:
#2f2a2a
;
color
:
#d6cbcb
;
height
:
30px
;
padding-left
:
10px
;
/* padding-top: 30px;
//position: fixed;
//height: 28px;
*/
}
src/app/elements/tree-filter/tree-filter.component.html
0 → 100644
View file @
f0abd8f7
<input
#
keyword
id=
"search"
class=
"search"
placeholder=
" {{'Search'| trans }} ..."
maxlength=
"2048"
name=
"q"
autocomplete=
"off"
title=
"Search"
type=
"text"
tabindex=
"1"
spellcheck=
"false"
[(
ngModel
)]="
q
"
>
src/app/elements/tree-filter/tree-filter.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
OnChanges
,
Input
,
Pipe
,
PipeTransform
}
from
'@angular/core'
;
import
{
AppService
,
HttpService
,
LogService
}
from
'../../app.service'
;
@
Component
({
selector
:
'elements-tree-filter'
,
templateUrl
:
'./tree-filter.component.html'
,
styleUrls
:
[
'./tree-filter.component.css'
]
})
export
class
ElementTreeFilterComponent
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
)
{
this
.
q
=
changes
.
input
.
currentValue
;
}
modelChange
(
$event
)
{
this
.
Search
(
this
.
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
;
}
}
src/app/globals.ts
View file @
f0abd8f7
'use strict'
;
import
{
EventEmitter
}
from
'events/events'
;
import
*
as
io
from
'socket.io-client'
;
import
*
as
neffos
from
'neffos.js'
;
import
{
Terminal
}
from
'xterm'
;
// const abc = io.connect('/ssh');
import
{
Socket
}
from
'./utils/socket'
;
import
{
BehaviorSubject
}
from
'rxjs/BehaviorSubject'
;
import
{
ConnectEvt
,
User
as
_User
}
from
'./model'
;
import
{
DataStore
as
_DataStore
,
Browser
as
_Browser
,
Video
as
_Video
,
Monitor
as
_Monitor
}
from
'./model'
;
const
scheme
=
document
.
location
.
protocol
===
'https:'
?
'wss'
:
'ws'
;
const
port
=
document
.
location
.
port
?
':'
+
document
.
location
.
port
:
''
;
const
wsURL
=
scheme
+
'://'
+
document
.
location
.
hostname
+
port
+
'/socket.io/'
;
const
hostname
=
document
.
location
.
hostname
;
const
wsURL
=
`
${
scheme
}
://
${
hostname
}${
port
}
/socket.io/`
;
export
let
TermWS
=
null
;
export
const
emitter
=
new
(
EventEmitter
);
export
const
sep
=
'/'
;
export
let
Video
:
{
id
:
string
,
src
:
string
,
type
:
string
,
height
:
number
,
width
:
number
,
json
:
object
;
timelist
:
Array
<
number
>
;
totalTime
:
number
;
}
=
{
id
:
''
,
src
:
''
,
type
:
''
,
width
:
0
,
height
:
0
,
json
:
{},
timelist
:
[],
totalTime
:
0
,
};
export
let
Monitor
:
{
token
:
string
,
room
:
string
,
type
:
string
,
}
=
{
token
:
''
,
room
:
''
,
type
:
'term'
,
};
export
class
Group
{
id
:
string
;
name
:
string
;
membercount
:
number
;
comment
:
string
;
}
export
let
User
:
{
id
:
string
;
name
:
string
;
username
:
string
;
password
:
string
;
phone
:
string
;
avatar
:
string
;
role
:
string
;
email
:
string
;
wechat
:
string
;
comment
:
string
;
is_active
:
boolean
;
is_superuser
:
boolean
;
date_joined
:
string
;
last_login
:
string
;
date_expired
:
string
;
groups
:
Array
<
Group
>
;
logined
:
boolean
;
}
=
{
id
:
''
,
name
:
'nobody'
,
username
:
''
,
password
:
''
,
phone
:
''
,
avatar
:
''
,
role
:
''
,
email
:
''
,
wechat
:
''
,
comment
:
''
,
is_active
:
false
,
is_superuser
:
false
,
date_joined
:
''
,
last_login
:
''
,
date_expired
:
''
,
groups
:
[],
logined
:
false
,
};
export
let
DataStore
:
{
socket
:
any
;
Nav
:
Array
<
object
>
;
NavShow
:
boolean
;
Path
:
{};
error
:
{};
msg
:
{};
loglevel
:
number
;
leftbarshow
:
boolean
;
windowsize
:
Array
<
number
>
;
autologin
:
boolean
;
guacamole_token
:
string
;
guacamole_token_time
:
number
;
}
=
{
export
let
Video
=
new
_Video
();
export
let
Monitor
=
new
_Monitor
();
export
let
User
=
new
_User
();
export
const
DataStore
:
_DataStore
=
{
socket
:
TermWS
,
Nav
:
[{}],
NavShow
:
true
,
...
...
@@ -115,30 +31,8 @@ export let DataStore: {
guacamole_token
:
''
,
guacamole_token_time
:
0
};
export
let
CSRF
=
''
;
export
let
Browser
:
{
userAgent
:
string
;
appCodeName
:
string
;
appName
:
string
;
appVersion
:
string
;
language
:
string
;
platform
:
string
;
product
:
string
;
productSub
:
string
;
vendor
:
string
;
}
=
{
userAgent
:
navigator
.
userAgent
,
appCodeName
:
navigator
.
appCodeName
,
appName
:
navigator
.
appName
,
appVersion
:
navigator
.
appVersion
,
language
:
navigator
.
language
,
platform
:
navigator
.
platform
,
product
:
navigator
.
product
,
productSub
:
navigator
.
productSub
,
vendor
:
navigator
.
vendor
,
};
export
let
Browser
=
new
_Browser
();
export
const
i18n
=
new
Map
();
export
async
function
getWsSocket
()
{
...
...
@@ -155,4 +49,4 @@ export async function getWsSocket() {
return
TermWS
;
}
export
const
connectEvt
=
new
BehaviorSubject
<
ConnectEvt
>
(
new
ConnectEvt
(
null
,
null
));
src/app/model.ts
View file @
f0abd8f7
export
class
UserGroup
{
id
:
string
;
name
:
string
;
comment
:
string
;
}
export
class
User
{
id
:
string
;
name
:
string
;
username
:
string
;
password
:
string
;
phone
:
string
;
avatar
:
string
;
role
:
string
;
email
:
string
;
wechat
:
string
;
comment
:
string
;
is_active
:
boolean
;
is_superuser
:
boolean
;
date_joined
:
string
;
last_login
:
string
;
date_expired
:
string
;
groups
:
Array
<
UserGroup
>
;
logined
:
boolean
;
}
export
class
SystemUser
{
id
:
string
;
name
:
string
;
...
...
@@ -43,3 +69,72 @@ export class GuacObjAddResp {
code
:
number
;
result
:
string
;
}
export
class
ConnectEvt
{
node
:
TreeNode
;
action
:
string
;
constructor
(
node
:
TreeNode
,
action
:
string
)
{
this
.
node
=
node
;
this
.
action
=
action
;
}
}
export
class
DataStore
{
socket
:
any
;
Nav
:
Array
<
object
>
;
NavShow
=
true
;
Path
:
{};
error
:
{};
msg
:
{};
loglevel
:
number
;
leftbarshow
=
true
;
windowsize
:
Array
<
number
>
;
autologin
:
boolean
;
guacamole_token
:
string
;
guacamole_token_time
:
number
;
}
export
class
Browser
{
userAgent
:
string
;
appCodeName
:
string
;
appName
:
string
;
appVersion
:
string
;
language
:
string
;
platform
:
string
;
product
:
string
;
productSub
:
string
;
vendor
:
string
;
constructor
()
{
this
.
userAgent
=
navigator
.
userAgent
;
this
.
appCodeName
=
navigator
.
appCodeName
;
this
.
appName
=
navigator
.
appName
;
this
.
appVersion
=
navigator
.
appVersion
;
this
.
language
=
navigator
.
language
;
this
.
platform
=
navigator
.
platform
;
this
.
product
=
navigator
.
product
;
this
.
productSub
=
navigator
.
productSub
;
this
.
vendor
=
navigator
.
vendor
;
}
}
export
class
Video
{
id
:
string
;
src
:
string
;
type
:
string
;
height
:
number
;
width
:
number
;
json
:
object
;
timelist
:
Array
<
number
>
;
totalTime
:
number
;
}
export
class
Monitor
{
token
:
string
;
room
:
string
;
type
:
string
;
}
src/app/pages/control/control.component.ts
View file @
f0abd8f7
...
...
@@ -15,8 +15,8 @@ import {NavList} from './control/control.component';
styleUrls
:
[
'./control.component.css'
],
})
export
class
PagesControlComponent
implements
OnInit
{
D
ataStore
=
DataStore
;
U
ser
=
User
;
d
ataStore
=
DataStore
;
u
ser
=
User
;
constructor
()
{
}
...
...
src/app/pages/control/control/controlnav/nav.component.css
View file @
f0abd8f7
...
...
@@ -33,7 +33,7 @@
.tabs
ul
li
.active
{
box-sizing
:
border-box
;
border-bottom
:
3px
solid
#19aa8d
!important
;
/*border-bottom: 3px solid #19aa8d !important;*/
}
.tabs
ul
li
span
{
...
...
src/app/pages/index/index.component.html
deleted
100644 → 0
View file @
65ccd3dd
<div
class=
"container"
*
ngIf=
"User.logined"
>
<div
class=
"row row-offcanvas row-offcanvas-right"
>
<div
class=
"col-12 col-md-9"
>
<p
class=
"float-right hidden-md-up"
>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
data-toggle=
"offcanvas"
>
Toggle nav
</button>
</p>
<div
class=
"jumbotron"
>
<h1>
Hello, world! {{User.username}}
</h1>
<p>
This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some
responsive-range viewport sizes to see it in action.
</p>
</div>
<div
class=
"row"
>
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
<div
class=
"col-6 col-lg-4"
>
<h2>
Heading
</h2>
<p>
Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.
</p>
<p><a
class=
"btn btn-secondary"
href=
"#"
role=
"button"
>
View details »
</a></p>
</div>
<!--/span-->
</div>
<!--/row-->
</div>
<!--/span-->
<div
class=
"col-6 col-md-3 sidebar-offcanvas"
id=
"sidebar"
>
<div
class=
"list-group"
>
<a
href=
"#"
class=
"list-group-item active"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
<a
href=
"#"
class=
"list-group-item"
>
Link
</a>
</div>
</div>
<!--/span-->
</div>
<!--/row-->
<hr>
</div>
src/app/pages/index/index.component.spec.ts
deleted
100644 → 0
View file @
65ccd3dd
import
{
async
,
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
PagesIndexComponent
}
from
'./index.component'
;
describe
(
'PagesIndexComponent'
,
()
=>
{
let
component
:
PagesIndexComponent
;
let
fixture
:
ComponentFixture
<
PagesIndexComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
PagesIndexComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
PagesIndexComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should be created'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/pages/index/index.component.ts
deleted
100644 → 0
View file @
65ccd3dd
/**
* 主页
*
*
* @date 2017-11-07
* @author liuzheng <liuzheng712@gmail.com>
*/
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
AppService
}
from
'../../app.service'
;
import
{
User
}
from
'../../globals'
;
@
Component
({
selector
:
'pages-index'
,
templateUrl
:
'./index.component.html'
,
styleUrls
:
[
'./index.component.css'
],
})
export
class
PagesIndexComponent
implements
OnInit
{
User
=
User
;
constructor
()
{
}
ngOnInit
()
{
}
}
src/app/pages/main/main.component.css
0 → 100644
View file @
f0abd8f7
div
{
height
:
100%
;
width
:
100%
;
padding
:
0
;
background-color
:
#1f1b1b
;
margin
:
0
;
position
:
initial
;
}
#container
{
padding-top
:
0
;
}
.container-fluid
{
padding-top
:
30px
;
}
src/app/pages/main/main.component.html
0 → 100644
View file @
f0abd8f7
<elements-nav></elements-nav>
<div
id=
"container"
class=
"container-fluid row"
fxLayout=
"row"
ngxSplit=
"row"
>
<div
fxFlex=
"1 1 20%"
minBasis=
"100px"
maxBasis=
"800px"
fxFlexFill
ngxSplitArea
*
ngIf=
"DataStore.leftbarshow"
>
<elements-left-bar></elements-left-bar>
</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"
>
<elements-content></elements-content>
</div>
</div>
src/app/pages/main/main.component.ts
0 → 100644
View file @
f0abd8f7
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
DataStore
,
User
}
from
'../../globals'
;
import
{
NavList
}
from
'../control/control/control.component'
;
@
Component
({
selector
:
'pages-main'
,
templateUrl
:
'./main.component.html'
,
styleUrls
:
[
'./main.component.css'
],
})
export
class
PageMainComponent
implements
OnInit
{
User
=
User
;
DataStore
=
DataStore
;
ngOnInit
():
void
{
}
activeViewIsRdp
()
{
return
NavList
.
List
[
NavList
.
Active
].
type
===
'rdp'
;
}
dragSplitBtn
(
evt
)
{
window
.
dispatchEvent
(
new
Event
(
'resize'
));
}
}
src/app/pages/pages.component.ts
View file @
f0abd8f7
import
{
PageMainComponent
}
from
'./main/main.component'
;
import
{
PagesBlankComponent
}
from
'./blank/blank.component'
;
import
{
PagesConnectComponent
}
from
'./connect/connect.component'
;
import
{
PagesControlComponent
}
from
'./control/control.component'
;
import
{
PagesIndexComponent
}
from
'./index/index.component'
;
// import {PagesControlComponent} from './control/control.component';
import
{
PagesMonitorComponent
}
from
'./monitor/monitor.component'
;
import
{
PagesReplayComponent
}
from
'./replay/replay.component'
;
// import {PagesSettingComponent} from './setting/setting.component';
import
{
PagesNotFoundComponent
}
from
'./not-found/not-found.component'
;
import
{
PagesLoginComponent
}
from
'./login/login.component'
;
import
{
CleftbarComponent
}
from
'./control/cleftbar/cleftbar.component'
;
//
import {CleftbarComponent} from './control/cleftbar/cleftbar.component';
import
{
JsonComponent
}
from
'./replay/json/json.component'
;
import
{
ControlComponent
}
from
'./control/control/control.component'
;
import
{
PagesControlNavComponent
}
from
'./control/control/controlnav/nav.component'
;
import
{
SearchComponent
,
SearchFilter
}
from
'./control/search/search.component'
;
//
import {ControlComponent} from './control/control/control.component';
//
import {PagesControlNavComponent} from './control/control/controlnav/nav.component';
//
import {SearchComponent, SearchFilter} from './control/search/search.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
,
PagesControlComponent
,
ControlComponent
,
PagesControlNavComponent
,
CleftbarComponent
,
PagesIndexComponent
,
// PagesControlComponent, ControlComponent, PagesControlNavComponent,
// CleftbarComponent,
PagesMonitorComponent
,
PagesReplayComponent
,
JsonComponent
,
// PagesSettingComponent,
PagesNotFoundComponent
,
PagesLoginComponent
,
SearchComponent
,
SearchFilter
,
//
SearchComponent,
//
SearchFilter,
PagesMonitorLinuxComponent
,
PagesMonitorWindowsComponent
,
ReplayGuacamoleComponent
...
...
src/app/router/router.module.ts
View file @
f0abd8f7
...
...
@@ -12,6 +12,7 @@ import {PagesBlankComponent} from '../pages/blank/blank.component';
import
{
TestPageComponent
}
from
'../test-page/test-page.component'
;
import
{
PagesConnectComponent
}
from
'../pages/connect/connect.component'
;
import
{
PagesReplayComponent
}
from
'../pages/replay/replay.component'
;
import
{
PageMainComponent
}
from
'../pages/main/main.component'
;
import
{
PagesControlComponent
}
from
'../pages/control/control.component'
;
import
{
PagesNotFoundComponent
}
from
'../pages/not-found/not-found.component'
;
import
{
PagesMonitorComponent
}
from
'../pages/monitor/monitor.component'
;
...
...
@@ -25,7 +26,7 @@ const appRoutes: Routes = [
{
path
:
'connect'
,
component
:
PagesConnectComponent
},
{
path
:
'sftp'
,
component
:
SftpComponent
},
{
path
:
'undefined'
,
component
:
PagesBlankComponent
},
{
path
:
''
,
component
:
Page
sControl
Component
},
{
path
:
''
,
component
:
Page
Main
Component
},
{
path
:
'**'
,
component
:
PagesNotFoundComponent
}
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment