mirror of https://github.com/openspug/spug
ant migrate v4
parent
cbbcbb71fe
commit
d97570b338
|
@ -9,24 +9,22 @@ import { CopyrightOutlined, GithubOutlined } from '@ant-design/icons';
|
|||
import styles from './layout.module.less';
|
||||
|
||||
|
||||
export default class extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Layout.Footer style={{padding: 0}}>
|
||||
<div className={styles.footerZone}>
|
||||
<div className={styles.linksZone}>
|
||||
<a className={styles.links} title="官网" href="https://www.spug.dev" target="_blank"
|
||||
rel="noopener noreferrer">官网</a>
|
||||
<a className={styles.links} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
||||
rel="noopener noreferrer"><GithubOutlined/></a>
|
||||
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
||||
rel="noopener noreferrer">文档</a>
|
||||
</div>
|
||||
<div style={{color: 'rgba(0, 0, 0, .45)'}}>
|
||||
Copyright <CopyrightOutlined/> 2020 By OpenSpug
|
||||
</div>
|
||||
export default function () {
|
||||
return (
|
||||
<Layout.Footer style={{padding: 0}}>
|
||||
<div className={styles.footer}>
|
||||
<div className={styles.links}>
|
||||
<a className={styles.item} title="官网" href="https://www.spug.dev" target="_blank"
|
||||
rel="noopener noreferrer">官网</a>
|
||||
<a className={styles.item} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
||||
rel="noopener noreferrer"><GithubOutlined/></a>
|
||||
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
||||
rel="noopener noreferrer">文档</a>
|
||||
</div>
|
||||
</Layout.Footer>
|
||||
)
|
||||
}
|
||||
<div style={{color: 'rgba(0, 0, 0, .45)'}}>
|
||||
Copyright <CopyrightOutlined/> 2020 By OpenSpug
|
||||
</div>
|
||||
</div>
|
||||
</Layout.Footer>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,68 +5,22 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Layout, Dropdown, Menu, List, Badge, Avatar } from 'antd';
|
||||
import {
|
||||
CheckOutlined,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
UserOutlined,
|
||||
LogoutOutlined,
|
||||
NotificationOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { Layout, Dropdown, Menu, Avatar } from 'antd';
|
||||
import { MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined } from '@ant-design/icons';
|
||||
import Notification from './Notification';
|
||||
import styles from './layout.module.less';
|
||||
import http from '../libs/http';
|
||||
import history from '../libs/history';
|
||||
import avatar from './avatar.png';
|
||||
import moment from 'moment';
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.inerval = null;
|
||||
this.state = {
|
||||
loading: true,
|
||||
notifies: [],
|
||||
read: []
|
||||
}
|
||||
}
|
||||
export default function (props) {
|
||||
|
||||
componentDidMount() {
|
||||
this.fetch();
|
||||
this.interval = setInterval(this.fetch, 60000)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.interval && clearInterval(this.interval)
|
||||
}
|
||||
|
||||
fetch = () => {
|
||||
this.setState({loading: true});
|
||||
http.get('/api/notify/')
|
||||
.then(res => this.setState({notifies: res, read: []}))
|
||||
.finally(() => this.setState({loading: false}))
|
||||
};
|
||||
|
||||
handleLogout = () => {
|
||||
function handleLogout() {
|
||||
history.push('/');
|
||||
http.get('/api/account/logout/')
|
||||
};
|
||||
}
|
||||
|
||||
handleRead = (e, item) => {
|
||||
e.stopPropagation();
|
||||
if (this.state.read.indexOf(item.id) === -1) {
|
||||
this.state.read.push(item.id);
|
||||
this.setState({read: this.state.read});
|
||||
http.patch('/api/notify/', {ids: [item.id]})
|
||||
}
|
||||
};
|
||||
|
||||
handleReadAll = () => {
|
||||
const ids = this.state.notifies.map(x => x.id);
|
||||
this.setState({read: ids});
|
||||
http.patch('/api/notify/', {ids})
|
||||
};
|
||||
menu = (
|
||||
const UserMenu = (
|
||||
<Menu>
|
||||
<Menu.Item>
|
||||
<Link to="/welcome/info">
|
||||
|
@ -74,66 +28,28 @@ export default class extends React.Component {
|
|||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Divider/>
|
||||
<Menu.Item onClick={this.handleLogout}>
|
||||
<Menu.Item onClick={handleLogout}>
|
||||
<LogoutOutlined style={{marginRight: 10}}/>退出登录
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
notify = () => (
|
||||
<Menu className={styles.notify}>
|
||||
<Menu.Item style={{padding: 0, whiteSpace: 'unset'}}>
|
||||
<List
|
||||
loading={this.state.loading}
|
||||
style={{maxHeight: 500, overflow: 'scroll'}}
|
||||
itemLayout="horizontal"
|
||||
dataSource={this.state.notifies}
|
||||
renderItem={item => (
|
||||
<List.Item className={styles.notifyItem} onClick={e => this.handleRead(e, item)}>
|
||||
<List.Item.Meta
|
||||
style={{opacity: this.state.read.includes(item.id) ? 0.4 : 1}}
|
||||
avatar={<CheckOutlined type={item.source} style={{fontSize: 24, color: '#1890ff'}}/>}
|
||||
title={<span style={{fontWeight: 400, color: '#404040'}}>{item.title}</span>}
|
||||
description={[
|
||||
<div key="1" style={{fontSize: 12}}>{item.content}</div>,
|
||||
<div key="2" style={{fontSize: 12}}>{moment(item['created_at']).fromNow()}</div>
|
||||
]}/>
|
||||
</List.Item>
|
||||
)}/>
|
||||
{this.state.notifies.length !== 0 && (
|
||||
<div className={styles.notifyFooter} onClick={() => this.handleReadAll()}>全部 已读</div>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
render() {
|
||||
const {notifies, read} = this.state;
|
||||
return (
|
||||
<Layout.Header style={{padding: 0}}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.trigger} onClick={this.props.toggle}>
|
||||
{this.props.collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<Dropdown overlay={this.menu}>
|
||||
<span className={styles.action}>
|
||||
<Avatar size="small" src={avatar} style={{marginRight: 8}}/>
|
||||
{localStorage.getItem('nickname')}
|
||||
</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<Dropdown overlay={this.notify} trigger={['click']}>
|
||||
<span className={styles.trigger}>
|
||||
<Badge count={notifies.length - read.length}>
|
||||
<NotificationOutlined style={{fontSize: 16}}/>
|
||||
</Badge>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
return (
|
||||
<Layout.Header className={styles.header}>
|
||||
<div className={styles.left}>
|
||||
<div className={styles.trigger} onClick={props.toggle}>
|
||||
{props.collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
|
||||
</div>
|
||||
</Layout.Header>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<Notification/>
|
||||
<div className={styles.right}>
|
||||
<Dropdown overlay={UserMenu} style={{background: '#000'}}>
|
||||
<span className={styles.action}>
|
||||
<Avatar size="small" src={avatar} style={{marginRight: 8}}/>
|
||||
{localStorage.getItem('nickname')}
|
||||
</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</Layout.Header>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Menu, List, Dropdown, Badge } from 'antd';
|
||||
import { CheckOutlined, NotificationOutlined } from '@ant-design/icons';
|
||||
import { http } from 'libs';
|
||||
import moment from 'moment';
|
||||
import styles from './layout.module.less';
|
||||
|
||||
let interval;
|
||||
|
||||
export default function () {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [notifies, setNotifies] = useState([]);
|
||||
const [reads, setReads] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch();
|
||||
interval = setInterval(fetch, 60000);
|
||||
return () => {
|
||||
if (interval) clearInterval(interval)
|
||||
}
|
||||
}, [])
|
||||
|
||||
function fetch() {
|
||||
setLoading(true);
|
||||
http.get('/api/notify/')
|
||||
.then(res => {
|
||||
setNotifies(res);
|
||||
setReads([])
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}
|
||||
|
||||
function handleRead(e, item) {
|
||||
e.stopPropagation();
|
||||
if (reads.indexOf(item.id) === -1) {
|
||||
reads.push(item.id);
|
||||
setReads(reads)
|
||||
http.patch('/api/notify/', {ids: [item.id]})
|
||||
}
|
||||
}
|
||||
|
||||
function handleReadAll() {
|
||||
const ids = notifies.map(x => x.id);
|
||||
setReads(ids);
|
||||
http.patch('/api/notify/', {ids})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.right}>
|
||||
<Dropdown trigger={['click']} overlay={(
|
||||
<Menu className={styles.notify}>
|
||||
<Menu.Item style={{padding: 0, whiteSpace: 'unset'}}>
|
||||
<List
|
||||
loading={loading}
|
||||
style={{maxHeight: 500, overflow: 'scroll'}}
|
||||
itemLayout="horizontal"
|
||||
dataSource={notifies}
|
||||
renderItem={item => (
|
||||
<List.Item className={styles.item} onClick={e => handleRead(e, item)}>
|
||||
<List.Item.Meta
|
||||
style={{opacity: reads.includes(item.id) ? 0.4 : 1}}
|
||||
avatar={<CheckOutlined type={item.source} style={{fontSize: 24, color: '#1890ff'}}/>}
|
||||
title={<span style={{fontWeight: 400, color: '#404040'}}>{item.title}</span>}
|
||||
description={[
|
||||
<div key="1" style={{fontSize: 12}}>{item.content}</div>,
|
||||
<div key="2" style={{fontSize: 12}}>{moment(item['created_at']).fromNow()}</div>
|
||||
]}/>
|
||||
</List.Item>
|
||||
)}/>
|
||||
{notifies.length !== 0 && (
|
||||
<div className={styles.footer} onClick={handleReadAll}>全部 已读</div>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)}>
|
||||
<span className={styles.trigger}>
|
||||
<Badge count={notifies.length - reads.length}>
|
||||
<NotificationOutlined style={{fontSize: 16}}/>
|
||||
</Badge>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Layout, Menu } from 'antd';
|
||||
import { hasPermission, history } from 'libs';
|
||||
import styles from './layout.module.css';
|
||||
import styles from './layout.module.less';
|
||||
import menus from '../routes';
|
||||
import logo from './logo-spug.png';
|
||||
import logoText from './logo-text.png';
|
||||
|
|
|
@ -3,47 +3,64 @@
|
|||
* Copyright (c) <spug.dev@gmail.com>
|
||||
* Released under the AGPL-3.0 License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { Layout } from 'antd';
|
||||
import Sider from './Sider';
|
||||
import Header from './Header';
|
||||
import Footer from './Footer'
|
||||
import { Router } from '../libs/router';
|
||||
import { updatePermissions} from '../libs';
|
||||
import styles from './layout.module.css';
|
||||
import routes from '../routes';
|
||||
import { updatePermissions, hasPermission } from 'libs';
|
||||
import styles from './layout.module.less';
|
||||
|
||||
const Routes = [];
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.initPermissions();
|
||||
this.state = {
|
||||
collapsed: false
|
||||
function initRoutes(routes) {
|
||||
for (let route of routes) {
|
||||
if (route.component) {
|
||||
if (!route.auth || hasPermission(route.auth)) {
|
||||
Routes.push(<Route exact key={route.path} path={route.path} component={route.component}/>)
|
||||
}
|
||||
} else if (route.child) {
|
||||
initRoutes(route.child)
|
||||
}
|
||||
}
|
||||
|
||||
initPermissions() {
|
||||
const data = localStorage.getItem('permissions');
|
||||
const hostPerms = localStorage.getItem('host_perms');
|
||||
const isSuper = localStorage.getItem('is_supper') === 'true';
|
||||
data && updatePermissions(isSuper, JSON.parse(hostPerms), JSON.parse(data))
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Layout>
|
||||
<Sider collapsed={this.state.collapsed} />
|
||||
<Layout>
|
||||
<Header
|
||||
collapsed={this.state.collapsed}
|
||||
toggle={() => this.setState({collapsed: !this.state.collapsed})}
|
||||
/>
|
||||
<Layout.Content className={styles.content} style={{height: `${document.body.clientHeight - 64}px`}}>
|
||||
<Router/>
|
||||
<Footer/>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
initRoutes(routes)
|
||||
updatePermissions()
|
||||
|
||||
// 404
|
||||
function NotFound() {
|
||||
return (
|
||||
<div className={styles.router}>
|
||||
<div className={styles.imgBlock}>
|
||||
<div className={styles.img}/>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className={styles.title}>404</h1>
|
||||
<div className={styles.desc}>抱歉,你访问的页面不存在</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function () {
|
||||
const [collapsed, setCollapsed] = useState(false)
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Sider collapsed={collapsed}/>
|
||||
<Layout style={{height: '100vh'}}>
|
||||
<Header collapsed={collapsed} toggle={() => setCollapsed(!collapsed)}/>
|
||||
<Layout.Content className={styles.content}>
|
||||
<Switch>
|
||||
{Routes}
|
||||
<Route component={NotFound}/>
|
||||
</Switch>
|
||||
<Footer/>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,19 +10,6 @@
|
|||
|
||||
.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 {
|
||||
|
@ -38,9 +25,51 @@
|
|||
background: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
.notify {
|
||||
width: 350px;
|
||||
padding: 0;
|
||||
|
||||
.item {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background-color: rgb(233, 247, 254);
|
||||
}
|
||||
|
||||
.footer {
|
||||
line-height: 46px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
}
|
||||
|
||||
.notify :global(.ant-dropdown-menu-item:hover) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 24px 24px 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
@ -60,32 +89,15 @@
|
|||
.logo {
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
padding-left: 24px;
|
||||
background-color: #002140;
|
||||
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 {
|
||||
height: 32px;
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
}
|
||||
|
||||
.router {
|
||||
display: flex;
|
||||
height: 80%;
|
||||
|
@ -121,4 +133,21 @@
|
|||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.links {
|
||||
margin-bottom: 7px;
|
||||
|
||||
.item {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||
* Copyright (c) <spug.dev@gmail.com>
|
||||
* Released under the AGPL-3.0 License.
|
||||
*/
|
||||
export default [
|
||||
{icon: 'desktop', title: '工作台', auth: 'home.home.view', path: '/home'},
|
||||
{icon: 'cloud-server', title: '主机管理', auth: 'host.host.view', path: '/host'},
|
||||
{
|
||||
icon: 'code', title: '批量执行', auth: 'exec.task.do|exec.template.view', child: [
|
||||
{title: '执行任务', auth: 'exec.task.do', path: '/exec/task'},
|
||||
{title: '模板管理', auth: 'exec.template.view', path: '/exec/template'},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'flag', title: '应用发布', auth: 'deploy.app.view|deploy.request.view', child: [
|
||||
{title: '应用管理', auth: 'deploy.app.view', path: '/deploy/app'},
|
||||
{title: '发布申请', auth: 'deploy.request.view', path: '/deploy/request'},
|
||||
]
|
||||
},
|
||||
{icon: 'schedule', title: '任务计划', auth: 'schedule.schedule.view', path: '/schedule'},
|
||||
{
|
||||
icon: 'deployment-unit', title: '配置中心', auth: 'config.env.view|config.src.view|config.app.view', child: [
|
||||
{title: '环境管理', auth: 'config.env.view', path: '/config/environment'},
|
||||
{title: '服务配置', auth: 'config.src.view', path: '/config/service'},
|
||||
{title: '应用配置', auth: 'config.app.view', path: '/config/app'},
|
||||
]
|
||||
},
|
||||
{icon: 'monitor', title: '监控中心', auth: 'monitor.monitor.view', path: '/monitor'},
|
||||
{
|
||||
icon: 'alert', title: '报警中心', auth: 'alarm.alarm.view|alarm.contact.view|alarm.group.view', child: [
|
||||
{title: '报警历史', auth: 'alarm.alarm.view', path: '/alarm/alarm'},
|
||||
{title: '报警联系人', auth: 'alarm.contact.view', path: '/alarm/contact'},
|
||||
{title: '报警联系组', auth: 'alarm.group.view', path: '/alarm/group'},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'setting', title: '系统管理', auth: "system.account.view|system.role.view|system.setting.view", child: [
|
||||
{title: '账户管理', auth: 'system.account.view', path: '/system/account'},
|
||||
{title: '角色管理', auth: 'system.role.view', path: '/system/role'},
|
||||
{title: '系统设置', auth: 'system.setting.view', path: '/system/setting'},
|
||||
]
|
||||
},
|
||||
]
|
|
@ -3,29 +3,83 @@
|
|||
* Copyright (c) <spug.dev@gmail.com>
|
||||
* Released under the AGPL-3.0 License.
|
||||
*/
|
||||
import { makeModuleRoute } from "./libs/router";
|
||||
|
||||
import welcomeRoues from './pages/welcome/routes';
|
||||
import homeRoutes from './pages/home/routes';
|
||||
import hostRoutes from './pages/host/routes';
|
||||
import systemRoutes from './pages/system/routes';
|
||||
import execRoutes from './pages/exec/routes';
|
||||
import scheduleRoutes from './pages/schedule/routes';
|
||||
import monitorRoutes from './pages/monitor/routes';
|
||||
import alarmRoutes from './pages/alarm/routes';
|
||||
import configRoutes from './pages/config/routes';
|
||||
import deployRoutes from './pages/deploy/routes';
|
||||
import React from 'react';
|
||||
import {
|
||||
DesktopOutlined,
|
||||
CloudServerOutlined,
|
||||
CodeOutlined,
|
||||
FlagOutlined,
|
||||
ScheduleOutlined,
|
||||
DeploymentUnitOutlined,
|
||||
MonitorOutlined,
|
||||
AlertOutlined,
|
||||
SettingOutlined
|
||||
} from '@ant-design/icons';
|
||||
import HomeIndex from './pages/home';
|
||||
import HostIndex from './pages/host';
|
||||
import ExecTask from './pages/exec/task';
|
||||
import ExecTemplate from './pages/exec/template';
|
||||
import DeployApp from './pages/deploy/app';
|
||||
import DeployRequest from './pages/deploy/request';
|
||||
import ScheduleIndex from './pages/schedule';
|
||||
import ConfigEnvironment from './pages/config/environment';
|
||||
import ConfigService from './pages/config/service';
|
||||
import ConfigApp from './pages/config/app';
|
||||
import MonitorIndex from './pages/monitor';
|
||||
import AlarmIndex from './pages/alarm/alarm';
|
||||
import AlarmGroup from './pages/alarm/group';
|
||||
import AlarmContact from './pages/alarm/contact';
|
||||
import SystemAccount from './pages/system/account';
|
||||
import SystemRole from './pages/system/role';
|
||||
import SystemSetting from './pages/system/setting';
|
||||
|
||||
import WelcomeIndex from './pages/welcome/index';
|
||||
import WelcomeInfo from './pages/welcome/info';
|
||||
|
||||
export default [
|
||||
makeModuleRoute('/welcome', welcomeRoues),
|
||||
makeModuleRoute('/home', homeRoutes),
|
||||
makeModuleRoute('/host', hostRoutes),
|
||||
makeModuleRoute('/system', systemRoutes),
|
||||
makeModuleRoute('/exec', execRoutes),
|
||||
makeModuleRoute('/schedule', scheduleRoutes),
|
||||
makeModuleRoute('/monitor', monitorRoutes),
|
||||
makeModuleRoute('/alarm', alarmRoutes),
|
||||
makeModuleRoute('/config', configRoutes),
|
||||
makeModuleRoute('/deploy', deployRoutes),
|
||||
{icon: <DesktopOutlined/>, title: '工作台', auth: 'home.home.view', path: '/home', component: HomeIndex},
|
||||
{icon: <CloudServerOutlined/>, title: '主机管理', auth: 'host.host.view', path: '/host', component: HostIndex},
|
||||
{
|
||||
icon: <CodeOutlined/>, title: '批量执行', auth: 'exec.task.do|exec.template.view', child: [
|
||||
{title: '执行任务', auth: 'exec.task.do', path: '/exec/task', component: ExecTask},
|
||||
{title: '模板管理', auth: 'exec.template.view', path: '/exec/template', component: ExecTemplate},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: <FlagOutlined/>, title: '应用发布', auth: 'deploy.app.view|deploy.request.view', child: [
|
||||
{title: '应用管理', auth: 'deploy.app.view', path: '/deploy/app', component: DeployApp},
|
||||
{title: '发布申请', auth: 'deploy.request.view', path: '/deploy/request', component: DeployRequest},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: <ScheduleOutlined/>,
|
||||
title: '任务计划',
|
||||
auth: 'schedule.schedule.view',
|
||||
path: '/schedule',
|
||||
component: ScheduleIndex
|
||||
},
|
||||
{
|
||||
icon: <DeploymentUnitOutlined/>, title: '配置中心', auth: 'config.env.view|config.src.view|config.app.view', child: [
|
||||
{title: '环境管理', auth: 'config.env.view', path: '/config/environment', component: ConfigEnvironment},
|
||||
{title: '服务配置', auth: 'config.src.view', path: '/config/service', component: ConfigService},
|
||||
{title: '应用配置', auth: 'config.app.view', path: '/config/app', component: ConfigApp},
|
||||
]
|
||||
},
|
||||
{icon: <MonitorOutlined/>, title: '监控中心', auth: 'monitor.monitor.view', path: '/monitor', component: MonitorIndex},
|
||||
{
|
||||
icon: <AlertOutlined/>, title: '报警中心', auth: 'alarm.alarm.view|alarm.contact.view|alarm.group.view', child: [
|
||||
{title: '报警历史', auth: 'alarm.alarm.view', path: '/alarm/alarm', component: AlarmIndex},
|
||||
{title: '报警联系人', auth: 'alarm.contact.view', path: '/alarm/contact', component: AlarmContact},
|
||||
{title: '报警联系组', auth: 'alarm.group.view', path: '/alarm/group', component: AlarmGroup},
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: <SettingOutlined/>, title: '系统管理', auth: "system.account.view|system.role.view|system.setting.view", child: [
|
||||
{title: '账户管理', auth: 'system.account.view', path: '/system/account', component: SystemAccount},
|
||||
{title: '角色管理', auth: 'system.role.view', path: '/system/role', component: SystemRole},
|
||||
{title: '系统设置', auth: 'system.setting.view', path: '/system/setting', component: SystemSetting},
|
||||
]
|
||||
},
|
||||
{path: '/welcome/index', component: WelcomeIndex},
|
||||
{path: '/welcome/info', component: WelcomeInfo},
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue