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