mirror of https://github.com/openspug/spug
U 优化web终端及文件管理器
parent
96521a5ef1
commit
045dc4281a
|
@ -39,8 +39,8 @@ class FileManager extends React.Component {
|
||||||
key: 'name',
|
key: 'name',
|
||||||
render: info => info.kind === 'd' ? (
|
render: info => info.kind === 'd' ? (
|
||||||
<div onClick={() => this.handleChdir(info.name, '1')} style={{cursor: 'pointer'}}>
|
<div onClick={() => this.handleChdir(info.name, '1')} style={{cursor: 'pointer'}}>
|
||||||
<FolderOutlined style={{color: info.is_link ? '#008b8b' : '#1890ff'}}/>
|
<FolderOutlined style={{color: info.is_link ? '#008b8b' : '#2563fc'}}/>
|
||||||
<span style={{color: info.is_link ? '#008b8b' : '#1890ff', paddingLeft: 5}}>{info.name}</span>
|
<span style={{color: info.is_link ? '#008b8b' : '#2563fc', paddingLeft: 5}}>{info.name}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -131,7 +131,7 @@ class FileManager extends React.Component {
|
||||||
this.setState({uploadStatus: 'success'});
|
this.setState({uploadStatus: 'success'});
|
||||||
this.fetchFiles()
|
this.fetchFiles()
|
||||||
}, () => this.setState({uploadStatus: 'exception'}))
|
}, () => this.setState({uploadStatus: 'exception'}))
|
||||||
.finally(() => setTimeout(() => this.setState({uploading: false}), 2000))
|
.finally(() => setTimeout(() => this.setState({uploading: false}), 2000))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ class FileManager extends React.Component {
|
||||||
if (!this.state.showDot) {
|
if (!this.state.showDot) {
|
||||||
objects = objects.filter(x => !x.name.startsWith('.'))
|
objects = objects.filter(x => !x.name.startsWith('.'))
|
||||||
}
|
}
|
||||||
const scrollY = document.body.clientHeight - 222;
|
const scrollY = document.body.clientHeight - 182;
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
title="文件管理器"
|
title="文件管理器"
|
||||||
|
@ -209,25 +209,27 @@ class FileManager extends React.Component {
|
||||||
</Breadcrumb.Item>
|
</Breadcrumb.Item>
|
||||||
))}
|
))}
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
<div style={{display: 'flex', alignItems: 'center'}}>
|
<div className={styles.action}>
|
||||||
<span>显示隐藏文件:</span>
|
<span>显示隐藏文件:</span>
|
||||||
<Switch
|
<Switch
|
||||||
checked={this.state.showDot}
|
checked={this.state.showDot}
|
||||||
checkedChildren="开启"
|
checkedChildren="开启"
|
||||||
unCheckedChildren="关闭"
|
unCheckedChildren="关闭"
|
||||||
onChange={v => this.setState({showDot: v})}/>
|
onChange={v => this.setState({showDot: v})}/>
|
||||||
<AuthButton
|
{this.state.uploading ? (
|
||||||
auth="host.console.upload"
|
<Progress className={styles.progress} strokeWidth={14} status={this.state.uploadStatus}
|
||||||
style={{marginLeft: 10}}
|
percent={this.state.percent}/>
|
||||||
size="small"
|
) : (
|
||||||
type="primary"
|
<AuthButton
|
||||||
icon={<UploadOutlined/>}
|
auth="host.console.upload"
|
||||||
onClick={this.handleUpload}>上传文件</AuthButton>
|
style={{marginLeft: 12}}
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
icon={<UploadOutlined/>}
|
||||||
|
onClick={this.handleUpload}>上传文件</AuthButton>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{this.state.uploading && (
|
|
||||||
<Progress style={{marginBottom: 15}} status={this.state.uploadStatus} percent={this.state.percent}/>
|
|
||||||
)}
|
|
||||||
<Table
|
<Table
|
||||||
size="small"
|
size="small"
|
||||||
rowKey="name"
|
rowKey="name"
|
||||||
|
|
|
@ -75,7 +75,9 @@ function WebSSH(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.terminal} ref={container}/>
|
<div className={styles.termContainer}>
|
||||||
|
<div className={styles.terminal} ref={container}/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,15 @@ import {
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
VerticalAlignBottomOutlined,
|
VerticalAlignBottomOutlined,
|
||||||
VerticalAlignMiddleOutlined,
|
VerticalAlignMiddleOutlined,
|
||||||
CloseOutlined
|
CloseOutlined,
|
||||||
|
LeftOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { NotFound, AuthButton } from 'components';
|
import { NotFound, AuthButton } from 'components';
|
||||||
import Terminal from './Terminal';
|
import Terminal from './Terminal';
|
||||||
import FileManager from './FileManager';
|
import FileManager from './FileManager';
|
||||||
import { http, hasPermission, includes } from 'libs';
|
import { http, hasPermission, includes } from 'libs';
|
||||||
import styles from './index.module.less';
|
import styles from './index.module.less';
|
||||||
import LogoSpugText from 'layout/logo-spug-txt.png';
|
import LogoSpugText from 'layout/logo-spug-white.png';
|
||||||
import lds from 'lodash';
|
import lds from 'lodash';
|
||||||
|
|
||||||
let posX = 0
|
let posX = 0
|
||||||
|
@ -241,17 +242,17 @@ function WebSSH(props) {
|
||||||
type="editable-card"
|
type="editable-card"
|
||||||
onTabClick={key => setActiveId(key)}
|
onTabClick={key => setActiveId(key)}
|
||||||
onEdit={(key, action) => action === 'remove' ? handleRemove(key, 'self') : null}
|
onEdit={(key, action) => action === 'remove' ? handleRemove(key, 'self') : null}
|
||||||
style={{width: `calc(100vw - ${width}px)`}}
|
style={{background: '#fff', width: `calc(100vw - ${width}px)`}}
|
||||||
tabBarExtraContent={hosts.length === 0 ? (
|
tabBarExtraContent={hosts.length === 0 ? (
|
||||||
<div className={styles.tips}>小提示:双击标签快速复制窗口,右击标签展开更多操作。</div>
|
<div className={styles.tips}>小提示:双击标签快速复制窗口,右击标签展开更多操作。</div>
|
||||||
) : (
|
) : (
|
||||||
<AuthButton
|
<AuthButton
|
||||||
auth="host.console.list"
|
auth="host.console.list"
|
||||||
type="primary"
|
type="link"
|
||||||
disabled={!activeId}
|
disabled={!activeId}
|
||||||
style={{marginRight: 5}}
|
style={{marginRight: 5}}
|
||||||
onClick={handleOpenFileManager}
|
onClick={handleOpenFileManager}
|
||||||
icon={<FolderOpenOutlined/>}>文件管理器</AuthButton>
|
icon={<LeftOutlined/>}>文件管理器</AuthButton>
|
||||||
)}>
|
)}>
|
||||||
{hosts.map(item => (
|
{hosts.map(item => (
|
||||||
<Tabs.TabPane key={item.vId} tab={<TabRender host={item}/>}>
|
<Tabs.TabPane key={item.vId} tab={<TabRender host={item}/>}>
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
|
|
||||||
.split {
|
.split {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 6px;
|
width: 8px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
right: -3px;
|
right: -4px;
|
||||||
cursor: ew-resize;
|
cursor: ew-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,16 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #f0f0f0;
|
background-color: #2563fc;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 30px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hosts {
|
.hosts {
|
||||||
|
box-shadow: 2px 2px 2px #e0e0e0;
|
||||||
|
|
||||||
:global(.ant-tree-node-content-wrapper) {
|
:global(.ant-tree-node-content-wrapper) {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -53,6 +55,7 @@
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: #eeeeee;
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -62,40 +65,60 @@
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fig {
|
||||||
|
flex: 1;
|
||||||
|
background-color: #2b2b2b;
|
||||||
|
color: #A9B7C6;
|
||||||
|
margin: 12px;
|
||||||
|
padding-top: 200px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
.tabRender {
|
.tabRender {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding: 8px 8px 8px 16px;
|
padding: 8px 8px 8px 16px;
|
||||||
margin: 0 -8px 0 -16px;
|
margin: 0 -8px 0 -16px;
|
||||||
|
color: #2563fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-tabs-nav) {
|
:global(.ant-tabs-nav) {
|
||||||
height: 42px;
|
height: 42px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ant-tabs-nav:before) {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ant-tabs-tab) {
|
||||||
|
border: none;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-tabs-tab-active) {
|
:global(.ant-tabs-tab-active) {
|
||||||
border-bottom: 2px solid #1890ff !important;
|
border-bottom: 2px solid #2563fc !important;
|
||||||
transition: unset;
|
transition: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.ant-tabs-content) {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.terminal {
|
.termContainer {
|
||||||
flex: 1;
|
margin: 12px;
|
||||||
display: flex;
|
border-radius: 6px;
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
padding-left: 5px;
|
padding: 10px 0 10px 10px;
|
||||||
height: calc(100vh - 42px);
|
|
||||||
|
.terminal {
|
||||||
|
height: calc(100vh - 84px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fig {
|
|
||||||
flex: 1;
|
|
||||||
background-color: #2b2b2b;
|
|
||||||
color: #A9B7C6;
|
|
||||||
padding-top: 200px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileSize {
|
.fileSize {
|
||||||
padding-right: 24px !important;
|
padding-right: 24px !important;
|
||||||
|
@ -106,6 +129,27 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
.action {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
width: 94px;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ant-breadcrumb) {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.drawerBtn {
|
.drawerBtn {
|
||||||
|
|
Loading…
Reference in New Issue