mirror of https://github.com/openspug/spug
U web update
parent
6e26d56cf3
commit
6bfe26943f
|
@ -3,6 +3,9 @@ import { hasPermission } from "../libs";
|
||||||
|
|
||||||
|
|
||||||
export default function AuthDiv(props) {
|
export default function AuthDiv(props) {
|
||||||
const disabled = props.auth && !hasPermission(props.auth);
|
let disabled = props.disabled === undefined ? false : props.disabled;
|
||||||
|
if (props.auth && !hasPermission(props.auth)) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
return disabled ? null : <div {...props}>{props.children}</div>
|
return disabled ? null : <div {...props}>{props.children}</div>
|
||||||
}
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Link} from 'react-router-dom';
|
||||||
|
import { hasPermission } from 'libs';
|
||||||
|
|
||||||
|
|
||||||
|
export default function AuthLink(props) {
|
||||||
|
let disabled = props.disabled;
|
||||||
|
if (props.auth && !hasPermission(props.auth)) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
return <Link {...props} disabled={disabled}>{props.children}</Link>
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import StatisticsCard from './StatisticsCard';
|
||||||
import SearchForm from './SearchForm';
|
import SearchForm from './SearchForm';
|
||||||
import LinkButton from './LinkButton';
|
import LinkButton from './LinkButton';
|
||||||
import AuthButton from './AuthButton';
|
import AuthButton from './AuthButton';
|
||||||
|
import AuthLink from './AuthLink';
|
||||||
import AuthDiv from './AuthDiv';
|
import AuthDiv from './AuthDiv';
|
||||||
import ACEditor from './ACEditor';
|
import ACEditor from './ACEditor';
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ export {
|
||||||
SearchForm,
|
SearchForm,
|
||||||
LinkButton,
|
LinkButton,
|
||||||
AuthButton,
|
AuthButton,
|
||||||
|
AuthLink,
|
||||||
AuthDiv,
|
AuthDiv,
|
||||||
ACEditor,
|
ACEditor,
|
||||||
}
|
}
|
|
@ -2,23 +2,23 @@ export default [
|
||||||
{icon: 'desktop', title: '工作台', path: '/home'},
|
{icon: 'desktop', title: '工作台', path: '/home'},
|
||||||
{icon: 'cloud-server', title: '主机管理', auth: 'host.host.view', path: '/host'},
|
{icon: 'cloud-server', title: '主机管理', auth: 'host.host.view', path: '/host'},
|
||||||
{
|
{
|
||||||
icon: 'code', title: '批量执行', child: [
|
icon: 'code', title: '批量执行', auth: 'exec.task.do|exec.template.view', child: [
|
||||||
{title: '执行任务', path: '/exec/task'},
|
{title: '执行任务', auth: 'exec.task.do', path: '/exec/task'},
|
||||||
{title: '模板管理', path: '/exec/template'},
|
{title: '模板管理', auth: 'exec.template.view', path: '/exec/template'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'flag', title: '应用发布', child: [
|
icon: 'flag', title: '应用发布', auth: 'deploy.app.view|deploy.request.view', child: [
|
||||||
{title: '应用管理', path: '/deploy/app'},
|
{title: '应用管理', auth: 'deploy.app.view', path: '/deploy/app'},
|
||||||
{title: '发布申请', path: '/deploy/request'},
|
{title: '发布申请', auth: 'deploy.request.view', path: '/deploy/request'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{icon: 'schedule', title: '任务计划', path: '/schedule'},
|
{icon: 'schedule', title: '任务计划', auth: 'schedule.schedule.view', path: '/schedule'},
|
||||||
{
|
{
|
||||||
icon: 'deployment-unit', title: '配置中心', child: [
|
icon: 'deployment-unit', title: '配置中心', auth: 'config.env.view|config.src.view|config.app.view', child: [
|
||||||
{title: '环境管理', path: '/config/environment'},
|
{title: '环境管理', auth: 'config.env.view', path: '/config/environment'},
|
||||||
{title: '服务配置', path: '/config/service'},
|
{title: '服务配置', auth: 'config.src.view', path: '/config/service'},
|
||||||
{title: '应用配置', path: '/config/app'},
|
{title: '应用配置', auth: 'config.app.view', path: '/config/app'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{icon: 'monitor', title: '监控中心', path: '/monitor'},
|
{icon: 'monitor', title: '监控中心', path: '/monitor'},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {Modal, Form, Transfer, message, Tabs, Alert} from 'antd';
|
import {Modal, Form, Transfer, message, Tabs, Alert} from 'antd';
|
||||||
import http from 'libs/http';
|
import { http, hasPermission } from 'libs';
|
||||||
import serviceStore from '../service/store';
|
import serviceStore from '../service/store';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ class Rel extends React.Component {
|
||||||
title="配置依赖关系"
|
title="配置依赖关系"
|
||||||
onCancel={() => store.relVisible = false}
|
onCancel={() => store.relVisible = false}
|
||||||
confirmLoading={this.state.loading}
|
confirmLoading={this.state.loading}
|
||||||
|
footer={hasPermission('config.app.edit_config') ? undefined : null}
|
||||||
onOk={this.handleSubmit}>
|
onOk={this.handleSubmit}>
|
||||||
<Alert
|
<Alert
|
||||||
closable
|
closable
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {observer} from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import {Link} from 'react-router-dom';
|
import { Table, Divider, Modal, message } from 'antd';
|
||||||
import {Table, Divider, Modal, message} from 'antd';
|
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import {LinkButton} from "components";
|
import { LinkButton, AuthLink } from 'components';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class ComTable extends React.Component {
|
class ComTable extends React.Component {
|
||||||
|
@ -31,13 +30,13 @@ class ComTable extends React.Component {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
render: info => (
|
render: info => (
|
||||||
<span>
|
<span>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="config.app.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="config.app.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => store.showRel(info)}>依赖</LinkButton>
|
<LinkButton auth="config.app.view_config" onClick={() => store.showRel(info)}>依赖</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<Link to={`/config/setting/app/${info.id}`}>配置</Link>
|
<AuthLink auth="config.app.view_config" to={`/config/setting/app/${info.id}`}>配置</AuthLink>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Card, Input, Button } from 'antd';
|
import { Card, Input, Button } from 'antd';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv } from 'components';
|
||||||
import ComTable from './Table';
|
import ComTable from './Table';
|
||||||
import ComForm from './Form';
|
import ComForm from './Form';
|
||||||
import Rel from './Rel';
|
import Rel from './Rel';
|
||||||
|
@ -18,9 +18,9 @@ export default observer(function () {
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<div style={{marginBottom: 16}}>
|
<AuthDiv auth="config.app.add" style={{marginBottom: 16}}>
|
||||||
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
||||||
</div>
|
</AuthDiv>
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
{store.formVisible && <ComForm/>}
|
{store.formVisible && <ComForm/>}
|
||||||
{store.relVisible && <Rel />}
|
{store.relVisible && <Rel />}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Button, message} from 'antd';
|
import { Button, message } from 'antd';
|
||||||
import Editor from 'react-ace';
|
import Editor from 'react-ace';
|
||||||
import 'ace-builds/src-noconflict/mode-json';
|
import 'ace-builds/src-noconflict/mode-json';
|
||||||
import 'ace-builds/src-noconflict/theme-tomorrow';
|
import 'ace-builds/src-noconflict/theme-tomorrow';
|
||||||
|
import { AuthButton } from 'components';
|
||||||
import { http } from 'libs';
|
import { http } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -60,12 +61,13 @@ class JSONView extends React.Component {
|
||||||
style={{fontSize: 14}}
|
style={{fontSize: 14}}
|
||||||
value={body}
|
value={body}
|
||||||
onChange={v => this.setState({body: v})}/>
|
onChange={v => this.setState({body: v})}/>
|
||||||
{readOnly && <Button
|
{readOnly && <AuthButton
|
||||||
icon="edit"
|
icon="edit"
|
||||||
type="link"
|
type="link"
|
||||||
size="large"
|
size="large"
|
||||||
|
auth={`config.${store.type}.edit_config`}
|
||||||
style={{position: 'absolute', top: 0, right: 0}}
|
style={{position: 'absolute', top: 0, right: 0}}
|
||||||
onClick={() => this.setState({readOnly: false})}>编辑</Button>}
|
onClick={() => this.setState({readOnly: false})}>编辑</AuthButton>}
|
||||||
{readOnly || <Button
|
{readOnly || <Button
|
||||||
icon="save"
|
icon="save"
|
||||||
type="link"
|
type="link"
|
||||||
|
|
|
@ -40,9 +40,9 @@ class TableView extends React.Component {
|
||||||
width: 120,
|
width: 120,
|
||||||
render: info => (
|
render: info => (
|
||||||
<span>
|
<span>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth={`config.${store.type}.edit_config`} onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth={`config.${store.type}.edit_config`} onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -5,7 +5,8 @@ import 'ace-builds/src-noconflict/mode-space';
|
||||||
import 'ace-builds/src-noconflict/theme-tomorrow';
|
import 'ace-builds/src-noconflict/theme-tomorrow';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import { http } from "libs";
|
import { http } from "libs";
|
||||||
import { Button, message } from "antd";
|
import { Button, message } from 'antd';
|
||||||
|
import { AuthButton } from 'components';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class TextView extends React.Component {
|
class TextView extends React.Component {
|
||||||
|
@ -54,12 +55,13 @@ class TextView extends React.Component {
|
||||||
value={body}
|
value={body}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
onChange={v => this.setState({body: v})}/>
|
onChange={v => this.setState({body: v})}/>
|
||||||
{readOnly && <Button
|
{readOnly && <AuthButton
|
||||||
icon="edit"
|
icon="edit"
|
||||||
type="link"
|
type="link"
|
||||||
size="large"
|
size="large"
|
||||||
|
auth={`config.${store.type}.edit_config`}
|
||||||
style={{position: 'absolute', top: 0, right: 0}}
|
style={{position: 'absolute', top: 0, right: 0}}
|
||||||
onClick={() => this.setState({readOnly: false})}>编辑</Button>}
|
onClick={() => this.setState({readOnly: false})}>编辑</AuthButton>}
|
||||||
{readOnly || <Button
|
{readOnly || <Button
|
||||||
icon="save"
|
icon="save"
|
||||||
type="link"
|
type="link"
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Menu, Input, Button, Select, PageHeader, Icon } from 'antd';
|
||||||
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';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv, AuthButton } from 'components';
|
||||||
import DiffConfig from './DiffConfig';
|
import DiffConfig from './DiffConfig';
|
||||||
import TableView from './TableView';
|
import TableView from './TableView';
|
||||||
import TextView from './TextView';
|
import TextView from './TextView';
|
||||||
|
@ -49,7 +49,7 @@ class Index extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {view} = this.state;
|
const {view} = this.state;
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<AuthDiv auth={`config.${store.type}.view_config`} className={styles.container}>
|
||||||
<div className={styles.left}>
|
<div className={styles.left}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title="环境列表"
|
title="环境列表"
|
||||||
|
@ -86,7 +86,7 @@ class Index extends React.Component {
|
||||||
onClick={store.showRecord}>更改历史</Button>
|
onClick={store.showRecord}>更改历史</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={4} style={{textAlign: 'right'}}>
|
<SearchForm.Item span={4} style={{textAlign: 'right'}}>
|
||||||
<Button disabled={view !== '1'} type="primary" icon="plus" onClick={() => store.showForm()}>新增配置</Button>
|
<AuthButton auth="config.app.edit_config|config.service.edit_config" disabled={view !== '1'} type="primary" icon="plus" onClick={() => store.showForm()}>新增配置</AuthButton>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class Index extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
{store.recordVisible && <Record/>}
|
{store.recordVisible && <Record/>}
|
||||||
{store.diffVisible && <DiffConfig/>}
|
{store.diffVisible && <DiffConfig/>}
|
||||||
</div>
|
</AuthDiv>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,11 @@ class ComTable extends React.Component {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
render: info => (
|
render: info => (
|
||||||
<span>
|
<span>
|
||||||
<LinkButton onClick={() => store.showExtForm(info.id)}>新建发布</LinkButton>
|
<LinkButton auth="deploy.app.edit" onClick={() => store.showExtForm(info.id)}>新建发布</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="deploy.app.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="deploy.app.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}];
|
}];
|
||||||
|
@ -96,9 +96,9 @@ class ComTable extends React.Component {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
render: info => (
|
render: info => (
|
||||||
<span>
|
<span>
|
||||||
<LinkButton onClick={() => store.showExtForm(record.id, info)}>编辑</LinkButton>
|
<LinkButton auth="deploy.app.edit" onClick={() => store.showExtForm(record.id, info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDeployDelete(info)}>删除</LinkButton>
|
<LinkButton auth="deploy.app.edit" onClick={() => this.handleDeployDelete(info)}>删除</LinkButton>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Card, Input, Button } from 'antd';
|
import { Card, Input, Button } from 'antd';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv } from 'components';
|
||||||
import ComTable from './Table';
|
import ComTable from './Table';
|
||||||
import ComForm from './Form';
|
import ComForm from './Form';
|
||||||
import Ext1Form from './Ext1Form';
|
import Ext1Form from './Ext1Form';
|
||||||
|
@ -20,9 +20,9 @@ export default observer(function () {
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<div style={{marginBottom: 16}}>
|
<AuthDiv auth="deploy.app.add" style={{marginBottom: 16}}>
|
||||||
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
||||||
</div>
|
</AuthDiv>
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
{store.formVisible && <ComForm />}
|
{store.formVisible && <ComForm />}
|
||||||
{store.addVisible && <AddSelect />}
|
{store.addVisible && <AddSelect />}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Steps, Collapse, PageHeader, Spin, Tag, Button, Icon } from 'antd';
|
import { Steps, Collapse, PageHeader, Spin, Tag, Button, Icon } from 'antd';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
|
import { AuthDiv } from 'components';
|
||||||
import history from 'libs/history';
|
import history from 'libs/history';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
@ -87,49 +88,51 @@ class Ext1Index extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {app_name, env_name, status} = store.request;
|
const {app_name, env_name, status} = store.request;
|
||||||
return (
|
return (
|
||||||
<Spin spinning={this.state.fetching}>
|
<AuthDiv auth="deploy.request.do">
|
||||||
<PageHeader
|
<Spin spinning={this.state.fetching}>
|
||||||
title="应用发布"
|
<PageHeader
|
||||||
subTitle={`${app_name} - ${env_name}`}
|
title="应用发布"
|
||||||
style={{padding: 0}}
|
subTitle={`${app_name} - ${env_name}`}
|
||||||
tags={this.getStatusAlias()}
|
style={{padding: 0}}
|
||||||
extra={<Button loading={this.state.loading} type="primary" disabled={!['1', '-3'].includes(status)}
|
tags={this.getStatusAlias()}
|
||||||
onClick={this.handleDeploy}>发布</Button>}
|
extra={<Button loading={this.state.loading} type="primary" disabled={!['1', '-3'].includes(status)}
|
||||||
onBack={() => history.goBack()}/>
|
onClick={this.handleDeploy}>发布</Button>}
|
||||||
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
onBack={() => history.goBack()}/>
|
||||||
<Collapse.Panel showArrow={false} key={1} header={
|
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
||||||
<Steps>
|
<Collapse.Panel showArrow={false} key={1} header={
|
||||||
<Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
|
<Steps>
|
||||||
<Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
|
<Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
|
||||||
<Steps.Step {...this.getStatus('local', 2)} title="检出前任务"/>
|
<Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
|
||||||
<Steps.Step {...this.getStatus('local', 3)} title="执行检出"/>
|
<Steps.Step {...this.getStatus('local', 2)} title="检出前任务"/>
|
||||||
<Steps.Step {...this.getStatus('local', 4)} title="检出后任务"/>
|
<Steps.Step {...this.getStatus('local', 3)} title="执行检出"/>
|
||||||
<Steps.Step {...this.getStatus('local', 5)} title="执行打包"/>
|
<Steps.Step {...this.getStatus('local', 4)} title="检出后任务"/>
|
||||||
</Steps>}>
|
<Steps.Step {...this.getStatus('local', 5)} title="执行打包"/>
|
||||||
<pre className={styles.ext1Console}>{lds.get(store.outputs, 'local.data')}</pre>
|
</Steps>}>
|
||||||
</Collapse.Panel>
|
<pre className={styles.ext1Console}>{lds.get(store.outputs, 'local.data')}</pre>
|
||||||
</Collapse>
|
|
||||||
|
|
||||||
<Collapse
|
|
||||||
defaultActiveKey={'0'}
|
|
||||||
className={styles.collapse}
|
|
||||||
expandIcon={({isActive}) => <Icon type="caret-right" style={{fontSize: 16}} rotate={isActive ? 90 : 0}/>}>
|
|
||||||
{store.request.targets.map((item, index) => (
|
|
||||||
<Collapse.Panel key={index} header={
|
|
||||||
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
|
||||||
<b>{item.title}</b>
|
|
||||||
<Steps size="small" style={{maxWidth: 600}}>
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 2)} title="发布前任务"/>
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 3)} title="执行发布"/>
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 4)} title="发布后任务"/>
|
|
||||||
</Steps>
|
|
||||||
</div>}>
|
|
||||||
<pre className={styles.ext1Console}>{lds.get(store.outputs, `${item.id}.data`)}</pre>
|
|
||||||
</Collapse.Panel>
|
</Collapse.Panel>
|
||||||
))}
|
</Collapse>
|
||||||
</Collapse>
|
|
||||||
</Spin>
|
<Collapse
|
||||||
|
defaultActiveKey={'0'}
|
||||||
|
className={styles.collapse}
|
||||||
|
expandIcon={({isActive}) => <Icon type="caret-right" style={{fontSize: 16}} rotate={isActive ? 90 : 0}/>}>
|
||||||
|
{store.request.targets.map((item, index) => (
|
||||||
|
<Collapse.Panel key={index} header={
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<b>{item.title}</b>
|
||||||
|
<Steps size="small" style={{maxWidth: 600}}>
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 2)} title="发布前任务"/>
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 3)} title="执行发布"/>
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 4)} title="发布后任务"/>
|
||||||
|
</Steps>
|
||||||
|
</div>}>
|
||||||
|
<pre className={styles.ext1Console}>{lds.get(store.outputs, `${item.id}.data`)}</pre>
|
||||||
|
</Collapse.Panel>
|
||||||
|
))}
|
||||||
|
</Collapse>
|
||||||
|
</Spin>
|
||||||
|
</AuthDiv>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Steps, Collapse, PageHeader, Spin, Tag, Button, Icon } from 'antd';
|
import { Steps, Collapse, PageHeader, Spin, Tag, Button, Icon } from 'antd';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
|
import { AuthDiv } from 'components';
|
||||||
import history from 'libs/history';
|
import history from 'libs/history';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
@ -87,53 +88,55 @@ class Ext1Index extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {app_name, env_name, status, server_actions, host_actions} = store.request;
|
const {app_name, env_name, status, server_actions, host_actions} = store.request;
|
||||||
return (
|
return (
|
||||||
<Spin spinning={this.state.fetching}>
|
<AuthDiv auth="deploy.request.do">
|
||||||
<PageHeader
|
<Spin spinning={this.state.fetching}>
|
||||||
title="应用发布"
|
<PageHeader
|
||||||
subTitle={`${app_name} - ${env_name}`}
|
title="应用发布"
|
||||||
style={{padding: 0}}
|
subTitle={`${app_name} - ${env_name}`}
|
||||||
tags={this.getStatusAlias()}
|
style={{padding: 0}}
|
||||||
extra={<Button loading={this.state.loading} type="primary" disabled={!['1', '-3'].includes(status)}
|
tags={this.getStatusAlias()}
|
||||||
onClick={this.handleDeploy}>发布</Button>}
|
extra={<Button loading={this.state.loading} type="primary" disabled={!['1', '-3'].includes(status)}
|
||||||
onBack={() => history.goBack()}/>
|
onClick={this.handleDeploy}>发布</Button>}
|
||||||
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
onBack={() => history.goBack()}/>
|
||||||
<Collapse.Panel showArrow={false} key={1} header={
|
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
||||||
<Steps style={{maxWidth: 400 + server_actions.length * 200}}>
|
<Collapse.Panel showArrow={false} key={1} header={
|
||||||
<Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
|
<Steps style={{maxWidth: 400 + server_actions.length * 200}}>
|
||||||
<Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
|
<Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
|
||||||
{server_actions.map((item, index) => (
|
<Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
|
||||||
<Steps.Step {...this.getStatus('local', 2 + index)} key={index} title={item.title}/>
|
{server_actions.map((item, index) => (
|
||||||
))}
|
<Steps.Step {...this.getStatus('local', 2 + index)} key={index} title={item.title}/>
|
||||||
</Steps>}>
|
))}
|
||||||
<pre className={styles.ext1Console}>{lds.get(store.outputs, 'local.data')}</pre>
|
</Steps>}>
|
||||||
</Collapse.Panel>
|
<pre className={styles.ext1Console}>{lds.get(store.outputs, 'local.data')}</pre>
|
||||||
</Collapse>
|
</Collapse.Panel>
|
||||||
|
|
||||||
{host_actions.length > 0 && (
|
|
||||||
<Collapse
|
|
||||||
defaultActiveKey={'0'}
|
|
||||||
className={styles.collapse}
|
|
||||||
expandIcon={({isActive}) => <Icon type="caret-right" style={{fontSize: 16}} rotate={isActive ? 90 : 0}/>}>
|
|
||||||
{store.request.targets.map((item, index) => (
|
|
||||||
<Collapse.Panel key={index} header={
|
|
||||||
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
|
||||||
<b>{item.title}</b>
|
|
||||||
<Steps size="small" style={{maxWidth: 150 + host_actions.length * 150}}>
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
|
|
||||||
{host_actions.map((action, index) => (
|
|
||||||
<Steps.Step {...this.getStatus(item.id, 2 + index)} key={index} title={action.title}/>
|
|
||||||
))}
|
|
||||||
</Steps>
|
|
||||||
</div>}>
|
|
||||||
<pre className={styles.ext1Console}>{lds.get(store.outputs, `${item.id}.data`)}</pre>
|
|
||||||
</Collapse.Panel>
|
|
||||||
))}
|
|
||||||
</Collapse>
|
</Collapse>
|
||||||
)}
|
|
||||||
{host_actions.length === 0 && this.state.fetching === false && (
|
{host_actions.length > 0 && (
|
||||||
<div className={styles.ext2Tips}>无目标主机动作</div>
|
<Collapse
|
||||||
)}
|
defaultActiveKey={'0'}
|
||||||
</Spin>
|
className={styles.collapse}
|
||||||
|
expandIcon={({isActive}) => <Icon type="caret-right" style={{fontSize: 16}} rotate={isActive ? 90 : 0}/>}>
|
||||||
|
{store.request.targets.map((item, index) => (
|
||||||
|
<Collapse.Panel key={index} header={
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<b>{item.title}</b>
|
||||||
|
<Steps size="small" style={{maxWidth: 150 + host_actions.length * 150}}>
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
|
||||||
|
{host_actions.map((action, index) => (
|
||||||
|
<Steps.Step {...this.getStatus(item.id, 2 + index)} key={index} title={action.title}/>
|
||||||
|
))}
|
||||||
|
</Steps>
|
||||||
|
</div>}>
|
||||||
|
<pre className={styles.ext1Console}>{lds.get(store.outputs, `${item.id}.data`)}</pre>
|
||||||
|
</Collapse.Panel>
|
||||||
|
))}
|
||||||
|
</Collapse>
|
||||||
|
)}
|
||||||
|
{host_actions.length === 0 && this.state.fetching === false && (
|
||||||
|
<div className={styles.ext2Tips}>无目标主机动作</div>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
|
</AuthDiv>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Table, Divider, Modal, Icon, Popover, Tag, message } from 'antd';
|
import { Table, Divider, Modal, Icon, Popover, Tag, message } from 'antd';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import { LinkButton } from "components";
|
import { LinkButton, AuthLink } from "components";
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class ComTable extends React.Component {
|
class ComTable extends React.Component {
|
||||||
|
@ -81,37 +80,39 @@ class ComTable extends React.Component {
|
||||||
switch (info.status) {
|
switch (info.status) {
|
||||||
case '-3':
|
case '-3':
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<Link to={`/deploy/do/ext${info['app_extend']}/${info.id}`}>发布</Link>
|
<AuthLink auth="deploy.request.do" to={`/deploy/do/ext${info['app_extend']}/${info.id}`}>发布</AuthLink>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton
|
<LinkButton
|
||||||
|
auth="deploy.request.do"
|
||||||
disabled={info.type === '2'}
|
disabled={info.type === '2'}
|
||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
onClick={() => this.handleRollback(info)}>回滚</LinkButton>
|
onClick={() => this.handleRollback(info)}>回滚</LinkButton>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
case '3':
|
case '3':
|
||||||
return <LinkButton
|
return <LinkButton
|
||||||
|
auth="deploy.request.do"
|
||||||
disabled={info.type === '2'}
|
disabled={info.type === '2'}
|
||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
onClick={() => this.handleRollback(info)}>回滚</LinkButton>;
|
onClick={() => this.handleRollback(info)}>回滚</LinkButton>;
|
||||||
case '-1':
|
case '-1':
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="deploy.request.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="deploy.request.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
case '0':
|
case '0':
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<LinkButton onClick={() => store.showApprove(info)}>审核</LinkButton>
|
<LinkButton auth="deploy.request.approve" onClick={() => store.showApprove(info)}>审核</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="deploy.request.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="deploy.request.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
case '1':
|
case '1':
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<Link to={`/deploy/do/ext${info['app_extend']}/${info.id}`}>发布</Link>
|
<AuthLink auth="deploy.request.do" to={`/deploy/do/ext${info['app_extend']}/${info.id}`}>发布</AuthLink>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="deploy.request.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Card, Input, Button } from 'antd';
|
import { Card, Input, Button } from 'antd';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv } from 'components';
|
||||||
import SelectApp from './SelectApp';
|
import SelectApp from './SelectApp';
|
||||||
import Ext1Form from './Ext1Form';
|
import Ext1Form from './Ext1Form';
|
||||||
import Ext2Form from './Ext2Form';
|
import Ext2Form from './Ext2Form';
|
||||||
|
@ -23,9 +23,9 @@ export default observer(function () {
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<div style={{marginBottom: 16}}>
|
<AuthDiv auth="deploy.request.add" style={{marginBottom: 16}}>
|
||||||
<Button type="primary" icon="plus" onClick={() => store.addVisible = true}>新建发布申请</Button>
|
<Button type="primary" icon="plus" onClick={() => store.addVisible = true}>新建发布申请</Button>
|
||||||
</div>
|
</AuthDiv>
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
{store.addVisible && <SelectApp/>}
|
{store.addVisible && <SelectApp/>}
|
||||||
{store.ext1Visible && <Ext1Form/>}
|
{store.ext1Visible && <Ext1Form/>}
|
||||||
|
|
|
@ -13,11 +13,6 @@ class ComTable extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
columns = [{
|
columns = [{
|
||||||
title: '序号',
|
|
||||||
key: 'series',
|
|
||||||
render: (_, __, index) => index + 1,
|
|
||||||
width: 80,
|
|
||||||
}, {
|
|
||||||
title: '模版名称',
|
title: '模版名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
}, {
|
}, {
|
||||||
|
@ -35,9 +30,9 @@ class ComTable extends React.Component {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
render: info => (
|
render: info => (
|
||||||
<span>
|
<span>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="exec.template.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="exec.template.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Card, Input, Select, Button } from 'antd';
|
import { Card, Input, Select, Button } from 'antd';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv } from 'components';
|
||||||
import ComTable from './Table';
|
import ComTable from './Table';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ export default observer(function () {
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<div style={{marginBottom: 16}}>
|
<AuthDiv auth="exec.template.add" style={{marginBottom: 16}}>
|
||||||
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
||||||
</div>
|
</AuthDiv>
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,11 +19,11 @@ class ComTable extends React.Component {
|
||||||
moreMenus = (info) => (
|
moreMenus = (info) => (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<LinkButton onClick={() => this.handleActive(info)}>{info.is_active ? '禁用' : '激活'}</LinkButton>
|
<LinkButton auth="schedule.schedule.edit" onClick={() => this.handleActive(info)}>{info.is_active ? '禁用' : '激活'}</LinkButton>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
<LinkButton auth="schedule.schedule.del" onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
@ -67,7 +67,7 @@ class ComTable extends React.Component {
|
||||||
<span>
|
<span>
|
||||||
<LinkButton disabled={!info['latest_run_time']} onClick={() => store.showInfo(info)}>详情</LinkButton>
|
<LinkButton disabled={!info['latest_run_time']} onClick={() => store.showInfo(info)}>详情</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
<LinkButton auth="schedule.schedule.edit" onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<Dropdown overlay={() => this.moreMenus(info)} trigger={['click']}>
|
<Dropdown overlay={() => this.moreMenus(info)} trigger={['click']}>
|
||||||
<LinkButton>
|
<LinkButton>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Card, Input, Select, Button } from 'antd';
|
import { Card, Input, Select, Button } from 'antd';
|
||||||
import { SearchForm } from 'components';
|
import { SearchForm, AuthDiv } from 'components';
|
||||||
import ComTable from './Table';
|
import ComTable from './Table';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ export default observer(function () {
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<div style={{marginBottom: 16}}>
|
<AuthDiv auth="schedule.schedule.add" style={{marginBottom: 16}}>
|
||||||
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
||||||
</div>
|
</AuthDiv>
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
|
|
@ -51,6 +51,7 @@ export default [{
|
||||||
{key: 'add', label: '新建申请'},
|
{key: 'add', label: '新建申请'},
|
||||||
{key: 'edit', label: '编辑申请'},
|
{key: 'edit', label: '编辑申请'},
|
||||||
{key: 'del', label: '删除申请'},
|
{key: 'del', label: '删除申请'},
|
||||||
|
{key: 'approve', label: '审核申请'},
|
||||||
{key: 'do', label: '执行发布'}
|
{key: 'do', label: '执行发布'}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
@ -80,7 +81,7 @@ export default [{
|
||||||
{key: 'del', label: '删除环境'}
|
{key: 'del', label: '删除环境'}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
key: 'service',
|
key: 'src',
|
||||||
label: '服务管理',
|
label: '服务管理',
|
||||||
perms: [
|
perms: [
|
||||||
{key: 'view', label: '查看服务'},
|
{key: 'view', label: '查看服务'},
|
||||||
|
|
Loading…
Reference in New Issue