mirror of https://github.com/openspug/spug
ant migrate v4
parent
f21ce3f241
commit
f13efa91cc
|
@ -3,13 +3,9 @@
|
||||||
* Copyright (c) <spug.dev@gmail.com>
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
const {override, fixBabelImports, addDecoratorsLegacy} = require('customize-cra');
|
const {override, addDecoratorsLegacy, addLessLoader} = require('customize-cra');
|
||||||
|
|
||||||
module.exports = override(
|
module.exports = override(
|
||||||
addDecoratorsLegacy(),
|
addDecoratorsLegacy(),
|
||||||
fixBabelImports('import', {
|
addLessLoader(),
|
||||||
libraryName: 'antd',
|
|
||||||
libraryDirectory: 'es',
|
|
||||||
style: true,
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
{
|
{
|
||||||
"name": "spug_web",
|
"name": "spug_web",
|
||||||
"version": "0.1.0",
|
"version": "3.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@antv/data-set": "^0.10.2",
|
"@ant-design/icons": "^4.3.0",
|
||||||
"ace-builds": "^1.4.7",
|
"ace-builds": "^1.4.7",
|
||||||
"antd": "^3.25.0",
|
"antd": "^4.8.5",
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.20.0",
|
||||||
"bizcharts": "^3.5.6",
|
"bizcharts": "^3.5.6",
|
||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
"http-proxy-middleware": "^0.20.0",
|
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"mobx": "^5.15.0",
|
"mobx": "^5.15.6",
|
||||||
"mobx-react": "^6.1.4",
|
"mobx-react": "^6.3.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"react": "^16.11.0",
|
"react": "^16.13.1",
|
||||||
"react-ace": "^8.0.0",
|
"react-ace": "^8.0.0",
|
||||||
"react-dom": "^16.11.0",
|
"react-dom": "^16.13.1",
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "3.2.0",
|
"react-scripts": "3.4.3",
|
||||||
"xterm": "^4.6.0",
|
"xterm": "^4.6.0",
|
||||||
"xterm-addon-fit": "^0.4.0"
|
"xterm-addon-fit": "^0.4.0"
|
||||||
},
|
},
|
||||||
|
@ -44,9 +43,10 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-decorators": "^7.7.0",
|
"@babel/plugin-proposal-decorators": "^7.10.5",
|
||||||
"babel-plugin-import": "^1.12.2",
|
"customize-cra": "^1.0.0",
|
||||||
"customize-cra": "^0.8.0",
|
"less": "^3.12.2",
|
||||||
"react-app-rewired": "^2.1.5"
|
"less-loader": "^7.1.0",
|
||||||
|
"react-app-rewired": "^2.1.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Layout, Icon } from 'antd';
|
import { Layout } from 'antd';
|
||||||
import styles from './layout.module.css';
|
import { CopyrightOutlined, GithubOutlined } from '@ant-design/icons';
|
||||||
|
import styles from './layout.module.less';
|
||||||
|
|
||||||
|
|
||||||
export default class extends React.Component {
|
export default class extends React.Component {
|
||||||
|
@ -17,12 +18,12 @@ export default class extends React.Component {
|
||||||
<a className={styles.links} title="官网" href="https://www.spug.dev" target="_blank"
|
<a className={styles.links} title="官网" href="https://www.spug.dev" target="_blank"
|
||||||
rel="noopener noreferrer">官网</a>
|
rel="noopener noreferrer">官网</a>
|
||||||
<a className={styles.links} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
<a className={styles.links} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
||||||
rel="noopener noreferrer"><Icon type="github" /></a>
|
rel="noopener noreferrer"><GithubOutlined/></a>
|
||||||
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
||||||
rel="noopener noreferrer">文档</a>
|
rel="noopener noreferrer">文档</a>
|
||||||
</div>
|
</div>
|
||||||
<div style={{color: 'rgba(0, 0, 0, .45)'}}>
|
<div style={{color: 'rgba(0, 0, 0, .45)'}}>
|
||||||
Copyright <Icon type="copyright"/> 2020 By OpenSpug
|
Copyright <CopyrightOutlined/> 2020 By OpenSpug
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout.Footer>
|
</Layout.Footer>
|
||||||
|
|
|
@ -5,8 +5,16 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Layout, Dropdown, Menu, List, Icon, Badge, Avatar } from 'antd';
|
import { Layout, Dropdown, Menu, List, Badge, Avatar } from 'antd';
|
||||||
import styles from './layout.module.css';
|
import {
|
||||||
|
CheckOutlined,
|
||||||
|
MenuFoldOutlined,
|
||||||
|
MenuUnfoldOutlined,
|
||||||
|
UserOutlined,
|
||||||
|
LogoutOutlined,
|
||||||
|
NotificationOutlined
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import styles from './layout.module.less';
|
||||||
import http from '../libs/http';
|
import http from '../libs/http';
|
||||||
import history from '../libs/history';
|
import history from '../libs/history';
|
||||||
import avatar from './avatar.png';
|
import avatar from './avatar.png';
|
||||||
|
@ -62,12 +70,12 @@ export default class extends React.Component {
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<Link to="/welcome/info">
|
<Link to="/welcome/info">
|
||||||
<Icon type="user" style={{marginRight: 10}}/>个人中心
|
<UserOutlined style={{marginRight: 10}}/>个人中心
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Divider/>
|
<Menu.Divider/>
|
||||||
<Menu.Item onClick={this.handleLogout}>
|
<Menu.Item onClick={this.handleLogout}>
|
||||||
<Icon type="logout" style={{marginRight: 10}}/>退出登录
|
<LogoutOutlined style={{marginRight: 10}}/>退出登录
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
@ -84,7 +92,7 @@ export default class extends React.Component {
|
||||||
<List.Item className={styles.notifyItem} onClick={e => this.handleRead(e, item)}>
|
<List.Item className={styles.notifyItem} onClick={e => this.handleRead(e, item)}>
|
||||||
<List.Item.Meta
|
<List.Item.Meta
|
||||||
style={{opacity: this.state.read.includes(item.id) ? 0.4 : 1}}
|
style={{opacity: this.state.read.includes(item.id) ? 0.4 : 1}}
|
||||||
avatar={<Icon type={item.source} style={{fontSize: 24, color: '#1890ff'}}/>}
|
avatar={<CheckOutlined type={item.source} style={{fontSize: 24, color: '#1890ff'}}/>}
|
||||||
title={<span style={{fontWeight: 400, color: '#404040'}}>{item.title}</span>}
|
title={<span style={{fontWeight: 400, color: '#404040'}}>{item.title}</span>}
|
||||||
description={[
|
description={[
|
||||||
<div key="1" style={{fontSize: 12}}>{item.content}</div>,
|
<div key="1" style={{fontSize: 12}}>{item.content}</div>,
|
||||||
|
@ -105,7 +113,7 @@ export default class extends React.Component {
|
||||||
<Layout.Header style={{padding: 0}}>
|
<Layout.Header style={{padding: 0}}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.trigger} onClick={this.props.toggle}>
|
<div className={styles.trigger} onClick={this.props.toggle}>
|
||||||
<Icon type={this.props.collapsed ? 'menu-unfold' : 'menu-fold'}/>
|
{this.props.collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.right}>
|
<div className={styles.right}>
|
||||||
<Dropdown overlay={this.menu}>
|
<Dropdown overlay={this.menu}>
|
||||||
|
@ -119,7 +127,7 @@ export default class extends React.Component {
|
||||||
<Dropdown overlay={this.notify} trigger={['click']}>
|
<Dropdown overlay={this.notify} trigger={['click']}>
|
||||||
<span className={styles.trigger}>
|
<span className={styles.trigger}>
|
||||||
<Badge count={notifies.length - read.length}>
|
<Badge count={notifies.length - read.length}>
|
||||||
<Icon type="notification" style={{fontSize: 16}}/>
|
<NotificationOutlined style={{fontSize: 16}}/>
|
||||||
</Badge>
|
</Badge>
|
||||||
</span>
|
</span>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
|
@ -1,98 +1,64 @@
|
||||||
/**
|
|
||||||
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
|
||||||
* Copyright (c) <spug.dev@gmail.com>
|
|
||||||
* Released under the AGPL-3.0 License.
|
|
||||||
*/
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { Layout, Menu } from 'antd';
|
||||||
import { Layout, Menu, Icon } from 'antd';
|
import { hasPermission, history } from 'libs';
|
||||||
import { hasPermission } from "../libs/functools";
|
|
||||||
import history from '../libs/history';
|
|
||||||
import styles from './layout.module.css';
|
import styles from './layout.module.css';
|
||||||
import lodash from 'lodash';
|
import menus from '../routes';
|
||||||
import menus from '../menus';
|
|
||||||
import logo from './logo-spug.png';
|
import logo from './logo-spug.png';
|
||||||
import logoText from './logo-text.png';
|
import logoText from './logo-text.png';
|
||||||
|
|
||||||
|
const initPath = window.location.pathname;
|
||||||
class Sider extends React.Component {
|
let openKeys = [];
|
||||||
constructor(props) {
|
loop:
|
||||||
super(props);
|
|
||||||
this._init(props);
|
|
||||||
this.state = {
|
|
||||||
selectedKeys: [],
|
|
||||||
openKeys: [lodash.get(this.keysMap, props.location.pathname)],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_init() {
|
|
||||||
this.keysMap = {};
|
|
||||||
for (let item of menus.filter(x => x.child)) {
|
for (let item of menus.filter(x => x.child)) {
|
||||||
for (let m of item.child) {
|
for (let sub of item.child) {
|
||||||
this.keysMap[m.path] = item.title
|
if (sub.path === initPath) {
|
||||||
|
openKeys = [item.title]
|
||||||
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
|
export default function Sider(props) {
|
||||||
if (nextProps.collapsed && !this.props.collapsed) {
|
function makeMenu(menu) {
|
||||||
this.setState({openKeys: []})
|
if (menu.auth && !hasPermission(menu.auth)) return null;
|
||||||
}
|
if (!menu.title) return null;
|
||||||
|
return menu.child ? _makeSubMenu(menu) : _makeItem(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
makeMenu = (menu) => {
|
function _makeSubMenu(menu) {
|
||||||
if (menu.auth !== undefined && !hasPermission(menu.auth)) return null;
|
return (
|
||||||
return (menu.child) ? this.makeSubMenu(menu) : this.makeItem(menu)
|
<Menu.SubMenu key={menu.title} title={<span>{menu.icon}<span>{menu.title}</span></span>}>
|
||||||
};
|
{menu.child.map(menu => makeMenu(menu))}
|
||||||
|
</Menu.SubMenu>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
makeItem = (menu) => {
|
function _makeItem(menu) {
|
||||||
return (
|
return (
|
||||||
<Menu.Item key={menu.path}>
|
<Menu.Item key={menu.path}>
|
||||||
{menu.icon && <Icon type={menu.icon}/>}
|
{menu.icon}
|
||||||
<span>{menu.title}</span>
|
<span>{menu.title}</span>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
)
|
)
|
||||||
};
|
|
||||||
|
|
||||||
makeSubMenu = (subMenu) => {
|
|
||||||
return (
|
|
||||||
<Menu.SubMenu key={subMenu.title} title={<span><Icon type={subMenu.icon}/><span>{subMenu.title}</span></span>}>
|
|
||||||
{subMenu.child.map(menu => this.makeMenu(menu))}
|
|
||||||
</Menu.SubMenu>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSelect = ({key}) => {
|
|
||||||
history.push(key)
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClick = ({key}) => {
|
|
||||||
if (key === this.state.selectedKeys[0] && key !== this.props.location.pathname) {
|
|
||||||
this.props.history.push(key)
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<Layout.Sider collapsed={this.props.collapsed} style={{height: '100vh', overflow: 'scroll'}}>
|
<Layout.Sider width={208} collapsed={props.collapsed} className={styles.sider}>
|
||||||
<div className={styles.logo}>
|
<div className={styles.logo}>
|
||||||
<img src={logo} alt="Logo"/>
|
<img src={logo} alt="Logo"/>
|
||||||
<img src={logoText} alt="logo-text" style={{marginLeft: 25, width: 70}}/>
|
<img src={logoText} alt="logo-text" style={{marginLeft: 25, width: 70}}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={styles.menus} style={{height: `${document.body.clientHeight - 64}px`}}>
|
||||||
<Menu
|
<Menu
|
||||||
theme="dark"
|
theme="dark"
|
||||||
mode="inline"
|
mode="inline"
|
||||||
selectedKeys={[this.props.location.pathname]}
|
className={styles.menus}
|
||||||
openKeys={this.state.openKeys}
|
defaultSelectedKeys={[initPath]}
|
||||||
onSelect={this.handleSelect}
|
defaultOpenKeys={openKeys}
|
||||||
onClick={this.handleClick}
|
onSelect={menu => history.push(menu.key)}>
|
||||||
onOpenChange={openKeys => this.setState({openKeys})}
|
{menus.map(menu => makeMenu(menu))}
|
||||||
>
|
|
||||||
{menus.map(menu => this.makeMenu(menu))}
|
|
||||||
</Menu>
|
</Menu>
|
||||||
|
</div>
|
||||||
</Layout.Sider>
|
</Layout.Sider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export default withRouter(Sider)
|
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
.header {
|
|
||||||
height: 64px;
|
|
||||||
padding: 0 12px 0 0;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 2px 2px 2px rgba(0, 21, 41, 0.08);
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header .icon {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 24px 24px 0;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trigger {
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 64px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s, padding 0s;
|
|
||||||
padding: 0 24px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trigger:hover {
|
|
||||||
background: rgb(233, 247, 254);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: 64px;
|
|
||||||
line-height: 64px;
|
|
||||||
padding-left: 15px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo h1 {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
color: #ffffff;
|
|
||||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
|
||||||
font-size: 20px;
|
|
||||||
margin: 0 0 0 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo img {
|
|
||||||
width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0 12px;
|
|
||||||
display: inline-block;
|
|
||||||
transition: all 0.3s;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action:hover {
|
|
||||||
background: rgb(233, 247, 254);
|
|
||||||
}
|
|
||||||
.notify {
|
|
||||||
width: 350px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.notify :global(.ant-dropdown-menu-item:hover) {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.notifyItem {
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 12px 24px;
|
|
||||||
}
|
|
||||||
.notifyItem:hover {
|
|
||||||
background-color: rgb(233, 247, 254);
|
|
||||||
}
|
|
||||||
.notifyFooter {
|
|
||||||
line-height: 46px;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
border-top: 1px solid #e8e8e8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footerZone {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footerZone .linksZone {
|
|
||||||
margin-bottom: 7px;
|
|
||||||
}
|
|
||||||
.footerZone .links{
|
|
||||||
margin-right: 40px;
|
|
||||||
}
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 0 12px 0 0;;
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.trigger {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 48px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s, padding 0s;
|
||||||
|
padding: 0 24px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trigger:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.action {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 12px;
|
||||||
|
display: inline-block;
|
||||||
|
transition: all 0.3s;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 24px 24px 0;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sider {
|
||||||
|
height: 100%;
|
||||||
|
width: 208px;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.menus {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 64px;
|
||||||
|
line-height: 64px;
|
||||||
|
padding-left: 24px;
|
||||||
|
background-color: #002140;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo h1 {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 0 0 0 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin: 48px 0 24px;
|
||||||
|
text-align: center;
|
||||||
|
color: rgba(0, 0, 0, .45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.router {
|
||||||
|
display: flex;
|
||||||
|
height: 80%;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.imgBlock {
|
||||||
|
flex: 0 0 62.5%;
|
||||||
|
width: 62.5%;
|
||||||
|
zoom: 1;
|
||||||
|
padding-right: 88px;
|
||||||
|
|
||||||
|
.img {
|
||||||
|
float: right;
|
||||||
|
height: 360px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 430px;
|
||||||
|
background-size: contain;
|
||||||
|
background: url('./404.svg') no-repeat 50% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #434e59;
|
||||||
|
font-size: 72px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 72px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
color: rgba(0, 0, 0, .45);
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Menu, Input, Button, Select, PageHeader, Icon, Modal } from 'antd';
|
import { Menu, Input, Button, Select, PageHeader, Modal } from 'antd';
|
||||||
|
import { TableOutlined, UnorderedListOutlined, NumberOutlined } from '@ant-design/icons';
|
||||||
import envStore from '../environment/store';
|
import envStore from '../environment/store';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
import history from 'libs/history';
|
import history from 'libs/history';
|
||||||
|
@ -84,9 +85,9 @@ class Index extends React.Component {
|
||||||
<SearchForm>
|
<SearchForm>
|
||||||
<SearchForm.Item span={6} title="视图">
|
<SearchForm.Item span={6} title="视图">
|
||||||
<Select value={view} style={{width: '100%'}} onChange={v => this.setState({view: v})}>
|
<Select value={view} style={{width: '100%'}} onChange={v => this.setState({view: v})}>
|
||||||
<Select.Option value="1"><Icon type="table" style={{marginRight: 10}}/>表格</Select.Option>
|
<Select.Option value="1"><TableOutlined style={{marginRight: 10}}/>表格</Select.Option>
|
||||||
<Select.Option value="2"><Icon type="unordered-list" style={{marginRight: 10}}/>文本</Select.Option>
|
<Select.Option value="2"><UnorderedListOutlined style={{marginRight: 10}}/>文本</Select.Option>
|
||||||
<Select.Option value="3"><Icon type="number" style={{marginRight: 10}}/>JSON</Select.Option>
|
<Select.Option value="3"><NumberOutlined style={{marginRight: 10}}/>JSON</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={7} title="Key">
|
<SearchForm.Item span={7} title="Key">
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Form, Input, Icon, Button, Tabs, Modal } from 'antd';
|
import { Form, Input, Button, Tabs, Modal } from 'antd';
|
||||||
|
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||||
import styles from './login.module.css';
|
import styles from './login.module.css';
|
||||||
import history from 'libs/history';
|
import history from 'libs/history';
|
||||||
import { http, updatePermissions } from 'libs';
|
import { http, updatePermissions } from 'libs';
|
||||||
|
@ -94,7 +95,7 @@ class LoginIndex extends React.Component {
|
||||||
size="large"
|
size="large"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
placeholder="请输入账户"
|
placeholder="请输入账户"
|
||||||
prefix={<Icon type="user" className={styles.icon}/>}/>
|
prefix={<UserOutlined className={styles.icon}/>}/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item className={styles.formItem}>
|
<Form.Item className={styles.formItem}>
|
||||||
|
@ -105,7 +106,7 @@ class LoginIndex extends React.Component {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
placeholder="请输入密码"
|
placeholder="请输入密码"
|
||||||
onPressEnter={this.handleSubmit}
|
onPressEnter={this.handleSubmit}
|
||||||
prefix={<Icon type="lock" className={styles.icon}/>}/>
|
prefix={<LockOutlined className={styles.icon}/>}/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Drawer, Breadcrumb, Table, Icon, Divider, Switch, Button, Progress, Modal, message } from 'antd';
|
import { Drawer, Breadcrumb, Table, Divider, Switch, Button, Progress, Modal, message } from 'antd';
|
||||||
|
import { DownloadOutlined, FileOutlined, FolderOutlined, DeleteOutlined, HomeOutlined } from '@ant-design/icons';
|
||||||
import { http, uniqueId, X_TOKEN } from 'libs';
|
import { http, uniqueId, X_TOKEN } from 'libs';
|
||||||
import lds from 'lodash';
|
import lds from 'lodash';
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
@ -31,12 +32,12 @@ 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'}}>
|
||||||
<Icon type="folder" style={{color: '#1890ff'}}/>
|
<FolderOutlined style={{color: '#1890ff'}}/>
|
||||||
<span style={{color: '#1890ff', paddingLeft: 5}}>{info.name}</span>
|
<span style={{color: '#1890ff', paddingLeft: 5}}>{info.name}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Icon type="file"/>
|
<FileOutlined/>
|
||||||
<span style={{paddingLeft: 5}}>{info.name}</span>
|
<span style={{paddingLeft: 5}}>{info.name}</span>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
),
|
),
|
||||||
|
@ -63,9 +64,9 @@ class FileManager extends React.Component {
|
||||||
key: 'action',
|
key: 'action',
|
||||||
render: info => info.kind === '-' ? (
|
render: info => info.kind === '-' ? (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Icon style={{color: '#1890ff'}} type="download" onClick={() => this.handleDownload(info.name)}/>
|
<DownloadOutlined style={{color: '#1890ff'}} onClick={() => this.handleDownload(info.name)}/>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<Icon style={{color: 'red'}} type="delete" onClick={() => this.handleDelete(info.name)}/>
|
<DeleteOutlined style={{color: 'red'}} onClick={() => this.handleDelete(info.name)}/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : null
|
) : null
|
||||||
}];
|
}];
|
||||||
|
@ -188,7 +189,7 @@ class FileManager extends React.Component {
|
||||||
<div className={styles.drawerHeader}>
|
<div className={styles.drawerHeader}>
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<Breadcrumb.Item href="#" onClick={() => this.handleChdir('', '0')}>
|
<Breadcrumb.Item href="#" onClick={() => this.handleChdir('', '0')}>
|
||||||
<Icon type="home"/>
|
<HomeOutlined/>
|
||||||
</Breadcrumb.Item>
|
</Breadcrumb.Item>
|
||||||
{this.state.pwd.map(item => (
|
{this.state.pwd.map(item => (
|
||||||
<Breadcrumb.Item key={item} href="#" onClick={() => this.handleChdir(item, '2')}>
|
<Breadcrumb.Item key={item} href="#" onClick={() => this.handleChdir(item, '2')}>
|
||||||
|
|
Loading…
Reference in New Issue