mirror of https://github.com/openspug/spug
style migrate v3
parent
a1a9792f1d
commit
97bbe7ddf0
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Modal, Card, Icon } from 'antd';
|
import { BuildOutlined, OrderedListOutlined } from '@ant-design/icons';
|
||||||
|
import { Modal, Card } from 'antd';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ class AddSelect extends React.Component {
|
||||||
bodyStyle={{display: 'flex'}}
|
bodyStyle={{display: 'flex'}}
|
||||||
onClick={this.switchExt1}>
|
onClick={this.switchExt1}>
|
||||||
<div style={{marginRight: 16}}>
|
<div style={{marginRight: 16}}>
|
||||||
<Icon type="ordered-list" style={{fontSize: 36, color: '#1890ff'}}/>
|
<OrderedListOutlined style={{fontSize: 36, color: '#1890ff'}} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.cardTitle}>常规发布</div>
|
<div className={styles.cardTitle}>常规发布</div>
|
||||||
|
@ -72,7 +73,7 @@ class AddSelect extends React.Component {
|
||||||
bodyStyle={{display: 'flex'}}
|
bodyStyle={{display: 'flex'}}
|
||||||
onClick={this.switchExt2}>
|
onClick={this.switchExt2}>
|
||||||
<div style={{marginRight: 16}}>
|
<div style={{marginRight: 16}}>
|
||||||
<Icon type="build" style={{fontSize: 36, color: '#1890ff'}}/>
|
<BuildOutlined style={{fontSize: 36, color: '#1890ff'}} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.cardTitle}>自定义发布</div>
|
<div className={styles.cardTitle}>自定义发布</div>
|
||||||
|
|
|
@ -49,7 +49,7 @@ class CloneConfirm extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const options = this.handleData(Object.values(toJS(store.records)));
|
const options = this.handleData(Object.values(toJS(store.records)));
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form layout="vertical" style={{marginTop: 24}}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
required
|
required
|
||||||
label="应用及环境"
|
label="应用及环境"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Switch, Col, Form, Input, Select, Button } from "antd";
|
import { Switch, Form, Input, Select, Button } from 'antd';
|
||||||
import envStore from 'pages/config/environment/store';
|
import envStore from 'pages/config/environment/store';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -29,17 +29,17 @@ export default observer(function Ext1Setup1() {
|
||||||
const info = store.deploy;
|
const info = store.deploy;
|
||||||
return (
|
return (
|
||||||
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
||||||
<Form.Item required label="发布环境">
|
<Form.Item required label="发布环境" style={{marginBottom: 0}}>
|
||||||
<Col span={16}>
|
<Form.Item style={{display: 'inline-block', width: '80%'}}>
|
||||||
<Select disabled={store.isReadOnly} value={info.env_id} onChange={v => info.env_id = v} placeholder="请选择发布环境">
|
<Select disabled={store.isReadOnly} value={info.env_id} onChange={v => info.env_id = v} placeholder="请选择发布环境">
|
||||||
{envStore.records.map(item => (
|
{envStore.records.map(item => (
|
||||||
<Select.Option disabled={envs.includes(item.id)} value={item.id} key={item.id}>{item.name}</Select.Option>
|
<Select.Option disabled={envs.includes(item.id)} value={item.id} key={item.id}>{item.name}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Col>
|
</Form.Item>
|
||||||
<Col span={6} offset={2}>
|
<Form.Item style={{display: 'inline-block', width: '20%', textAlign: 'right'}}>
|
||||||
<Link disabled={store.isReadOnly} to="/config/environment">新建环境</Link>
|
<Link disabled={store.isReadOnly} to="/config/environment">新建环境</Link>
|
||||||
</Col>
|
</Form.Item>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required label="Git仓库地址">
|
<Form.Item required label="Git仓库地址">
|
||||||
<Input disabled={store.isReadOnly} value={info['git_repo']} onChange={e => info['git_repo'] = e.target.value}
|
<Input disabled={store.isReadOnly} value={info['git_repo']} onChange={e => info['git_repo'] = e.target.value}
|
||||||
|
@ -58,20 +58,21 @@ export default observer(function Ext1Setup1() {
|
||||||
<a target="_blank" rel="noopener noreferrer"
|
<a target="_blank" rel="noopener noreferrer"
|
||||||
href="https://spug.dev/docs/install-error/#%E9%92%89%E9%92%89%E6%94%B6%E4%B8%8D%E5%88%B0%E9%80%9A%E7%9F%A5%EF%BC%9F">钉钉收不到通知?</a>
|
href="https://spug.dev/docs/install-error/#%E9%92%89%E9%92%89%E6%94%B6%E4%B8%8D%E5%88%B0%E9%80%9A%E7%9F%A5%EF%BC%9F">钉钉收不到通知?</a>
|
||||||
</span>}>
|
</span>}>
|
||||||
<Input addonBefore={(
|
<Input
|
||||||
<Select disabled={store.isReadOnly}
|
addonBefore={(
|
||||||
value={info['rst_notify']['mode']} style={{width: 100}}
|
<Select disabled={store.isReadOnly}
|
||||||
onChange={v => info['rst_notify']['mode'] = v}>
|
value={info['rst_notify']['mode']} style={{width: 100}}
|
||||||
<Select.Option value="0">关闭</Select.Option>
|
onChange={v => info['rst_notify']['mode'] = v}>
|
||||||
<Select.Option value="1">钉钉</Select.Option>
|
<Select.Option value="0">关闭</Select.Option>
|
||||||
<Select.Option value="3">企业微信</Select.Option>
|
<Select.Option value="1">钉钉</Select.Option>
|
||||||
<Select.Option value="2">Webhook</Select.Option>
|
<Select.Option value="3">企业微信</Select.Option>
|
||||||
</Select>
|
<Select.Option value="2">Webhook</Select.Option>
|
||||||
)}
|
</Select>
|
||||||
disabled={store.isReadOnly || info['rst_notify']['mode'] === '0'}
|
)}
|
||||||
value={info['rst_notify']['value']}
|
disabled={store.isReadOnly || info['rst_notify']['mode'] === '0'}
|
||||||
onChange={e => info['rst_notify']['value'] = e.target.value}
|
value={info['rst_notify']['value']}
|
||||||
placeholder="请输入"/>
|
onChange={e => info['rst_notify']['value'] = e.target.value}
|
||||||
|
placeholder="请输入"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Form, Input, Select, Button, Icon, message } from "antd";
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import { Form, Input, Select, Button, message } from "antd";
|
||||||
import { hasHostPermission } from 'libs';
|
import { hasHostPermission } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import hostStore from 'pages/host/store';
|
import hostStore from 'pages/host/store';
|
||||||
|
@ -55,7 +56,7 @@ class Ext1Setup2 extends React.Component {
|
||||||
showSearch
|
showSearch
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
disabled={store.isReadOnly}
|
disabled={store.isReadOnly}
|
||||||
style={{width: '80%', marginRight: 10}}
|
style={{width: '80%', marginRight: 10, marginBottom: 12}}
|
||||||
optionFilterProp="children"
|
optionFilterProp="children"
|
||||||
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||||||
onChange={v => store.editHost(index, v)}>
|
onChange={v => store.editHost(index, v)}>
|
||||||
|
@ -66,14 +67,14 @@ class Ext1Setup2 extends React.Component {
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{!store.isReadOnly && info['host_ids'].length > 1 && (
|
{!store.isReadOnly && info['host_ids'].length > 1 && (
|
||||||
<Icon className={styles.delIcon} type="minus-circle-o" onClick={() => store.delHost(index)}/>
|
<MinusCircleOutlined className={styles.delIcon} onClick={() => store.delHost(index)} />
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button disabled={store.isReadOnly} type="dashed" style={{width: '80%'}} onClick={store.addHost}>
|
<Button disabled={store.isReadOnly} type="dashed" style={{width: '80%'}} onClick={store.addHost}>
|
||||||
<Icon type="plus"/>添加目标主机
|
<PlusOutlined />添加目标主机
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Form, Row, Col, Button, Radio, Icon, Tooltip, message } from "antd";
|
import { GitlabOutlined, InfoCircleOutlined, SettingOutlined, SwapOutlined } from '@ant-design/icons';
|
||||||
|
import { Form, Row, Col, Button, Radio, Tooltip, message } from 'antd';
|
||||||
import { LinkButton } from 'components';
|
import { LinkButton } from 'components';
|
||||||
import Editor from 'react-ace';
|
import Editor from 'react-ace';
|
||||||
import 'ace-builds/src-noconflict/mode-text';
|
import 'ace-builds/src-noconflict/mode-text';
|
||||||
|
@ -51,9 +52,17 @@ class Ext1Setup3 extends React.Component {
|
||||||
}, () => this.setState({loading: false}))
|
}, () => this.setState({loading: false}))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleFullscreen = (id) => {
|
||||||
|
if (this.state.full) {
|
||||||
|
this.setState({full: ''})
|
||||||
|
} else {
|
||||||
|
this.setState({full: id})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FilterLabel = (props) => (
|
FilterLabel = (props) => (
|
||||||
<div style={{display: 'inline-block', height: 39, width: 390}}>
|
<div style={{display: 'flex', alignItems: 'center', height: 40}}>
|
||||||
<span style={{float: 'left'}}>文件过滤<span style={{margin: '0 8px 0 2px'}}>:</span></span>
|
<div>文件过滤 :</div>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
disabled={store.isReadOnly}
|
disabled={store.isReadOnly}
|
||||||
style={{marginLeft: 20, float: 'left'}}
|
style={{marginLeft: 20, float: 'left'}}
|
||||||
|
@ -61,36 +70,30 @@ class Ext1Setup3 extends React.Component {
|
||||||
onChange={e => store.deploy['filter_rule']['type'] = e.target.value}>
|
onChange={e => store.deploy['filter_rule']['type'] = e.target.value}>
|
||||||
<Radio value="contain">包含
|
<Radio value="contain">包含
|
||||||
<Tooltip title="请输入相对于项目根目录的文件路径,仅将匹配到文件传输至要发布的目标主机。">
|
<Tooltip title="请输入相对于项目根目录的文件路径,仅将匹配到文件传输至要发布的目标主机。">
|
||||||
<Icon type="info-circle" style={{color: '#515151', marginLeft: 8}}/>
|
<InfoCircleOutlined style={{color: '#515151', marginLeft: 8}}/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Radio>
|
</Radio>
|
||||||
<Radio value="exclude">排除
|
<Radio value="exclude">排除
|
||||||
<Tooltip title="支持模糊匹配,如果路径以 / 开头则基于项目根目录匹配,匹配到文件将不会被传输。">
|
<Tooltip title="支持模糊匹配,如果路径以 / 开头则基于项目根目录匹配,匹配到文件将不会被传输。">
|
||||||
<Icon type="info-circle" style={{color: '#515151', marginLeft: 8}}/>
|
<InfoCircleOutlined style={{color: '#515151', marginLeft: 8}}/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Radio>
|
</Radio>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
{this.state.full === '1' ? (
|
<div style={{flex: 1, textAlign: 'right'}}>
|
||||||
<LinkButton onClick={() => this.setState({full: ''})}>退出全屏</LinkButton>
|
<LinkButton onClick={() => this.handleFullscreen('1')}>{this.state.full ? '退出全屏' : '全屏'}</LinkButton>
|
||||||
) : (
|
</div>
|
||||||
<LinkButton onClick={() => this.setState({full: '1'})}>全屏</LinkButton>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
NormalLabel = (props) => (
|
NormalLabel = (props) => (
|
||||||
<div style={{display: 'inline-block', height: 39, width: 390}}>
|
<div style={{display: 'flex', alignItems: 'center', height: 40}}>
|
||||||
<span style={{float: 'left'}}>
|
<div style={{marginRight: 8}}>{props.title} :</div>
|
||||||
{props.title}<span style={{margin: '0 8px 0 2px'}}>:</span>
|
<Tooltip title={this.helpMap[props.id]}>
|
||||||
<Tooltip title={this.helpMap[props.id]}>
|
<InfoCircleOutlined style={{color: '#515151'}}/>
|
||||||
<Icon type="info-circle" style={{color: '#515151'}}/>
|
</Tooltip>
|
||||||
</Tooltip>
|
<div style={{flex: 1, textAlign: 'right'}}>
|
||||||
</span>
|
<LinkButton onClick={() => this.handleFullscreen(props.id)}>{this.state.full ? '退出全屏' : '全屏'}</LinkButton>
|
||||||
{this.state.full ? (
|
</div>
|
||||||
<span style={{color: '#1890ff', cursor: 'pointer'}} onClick={() => this.setState({full: ''})}>退出全屏</span>
|
|
||||||
) : (
|
|
||||||
<span style={{color: '#1890ff', cursor: 'pointer'}} onClick={() => this.setState({full: props.id})}>全屏</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -101,10 +104,8 @@ class Ext1Setup3 extends React.Component {
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={11}>
|
<Col span={11}>
|
||||||
<Form.Item
|
<div className={full === '1' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.FilterLabel type={info['filter_rule']['type']}/>
|
||||||
className={full === '1' ? styles.fullScreen : null}
|
|
||||||
label={<this.FilterLabel type={info['filter_rule']['type']}/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="text"
|
mode="text"
|
||||||
|
@ -115,11 +116,9 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['filter_rule']['data']}
|
value={info['filter_rule']['data']}
|
||||||
onChange={v => info['filter_rule']['data'] = cleanCommand(v)}
|
onChange={v => info['filter_rule']['data'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
<Form.Item
|
<div className={full === '3' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.NormalLabel title="代码检出前执行" id="3"/>
|
||||||
className={full === '3' ? styles.fullScreen : null}
|
|
||||||
label={<this.NormalLabel title="代码检出前执行" id="3"/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="sh"
|
mode="sh"
|
||||||
|
@ -130,11 +129,9 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['hook_pre_server']}
|
value={info['hook_pre_server']}
|
||||||
onChange={v => info['hook_pre_server'] = cleanCommand(v)}
|
onChange={v => info['hook_pre_server'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
<Form.Item
|
<div className={full === '5' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.NormalLabel title="应用发布前执行" id="5"/>
|
||||||
className={full === '5' ? styles.fullScreen : null}
|
|
||||||
label={<this.NormalLabel title="应用发布前执行" id="5"/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="sh"
|
mode="sh"
|
||||||
|
@ -145,27 +142,25 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['hook_pre_host']}
|
value={info['hook_pre_host']}
|
||||||
onChange={v => info['hook_pre_host'] = cleanCommand(v)}
|
onChange={v => info['hook_pre_host'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={2}>
|
<Col span={2}>
|
||||||
<div className={styles.deployBlock} style={{marginTop: 39}}>
|
<div className={styles.deployBlock} style={{marginTop: 39}}>
|
||||||
<Icon type="setting" style={{fontSize: 32}}/>
|
<SettingOutlined style={{fontSize: 32}}/>
|
||||||
<span style={{fontSize: 12, marginTop: 5}}>基础设置</span>
|
<span style={{fontSize: 12, marginTop: 5}}>基础设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.deployBlock}>
|
<div className={styles.deployBlock}>
|
||||||
<Icon type="gitlab" style={{fontSize: 32}}/>
|
<GitlabOutlined style={{fontSize: 32}}/>
|
||||||
<span style={{fontSize: 12, marginTop: 5}}>检出代码</span>
|
<span style={{fontSize: 12, marginTop: 5}}>检出代码</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.deployBlock}>
|
<div className={styles.deployBlock}>
|
||||||
<Icon type="swap" style={{fontSize: 32}}/>
|
<SwapOutlined style={{fontSize: 32}}/>
|
||||||
<span style={{fontSize: 12, marginTop: 5}}>版本切换</span>
|
<span style={{fontSize: 12, marginTop: 5}}>版本切换</span>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={11}>
|
<Col span={11}>
|
||||||
<Form.Item
|
<div className={full === '2' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.NormalLabel title="自定义全局变量" id="2"/>
|
||||||
className={full === '2' ? styles.fullScreen : null}
|
|
||||||
label={<this.NormalLabel title="自定义全局变量" id="2"/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="text"
|
mode="text"
|
||||||
|
@ -176,11 +171,9 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['custom_envs']}
|
value={info['custom_envs']}
|
||||||
onChange={v => info['custom_envs'] = cleanCommand(v)}
|
onChange={v => info['custom_envs'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
<Form.Item
|
<div className={full === '4' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.NormalLabel title="代码检出后执行" id="4"/>
|
||||||
className={full === '4' ? styles.fullScreen : null}
|
|
||||||
label={<this.NormalLabel title="代码检出后执行" id="4"/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="sh"
|
mode="sh"
|
||||||
|
@ -191,11 +184,9 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['hook_post_server']}
|
value={info['hook_post_server']}
|
||||||
onChange={v => info['hook_post_server'] = cleanCommand(v)}
|
onChange={v => info['hook_post_server'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
<Form.Item
|
<div className={full === '6' ? styles.fullScreen : null} style={{marginBottom: 24}}>
|
||||||
colon={false}
|
<this.NormalLabel title="应用发布后执行" id="6"/>
|
||||||
className={full === '6' ? styles.fullScreen : null}
|
|
||||||
label={<this.NormalLabel title="应用发布后执行" id="6"/>}>
|
|
||||||
<Editor
|
<Editor
|
||||||
readOnly={store.isReadOnly}
|
readOnly={store.isReadOnly}
|
||||||
mode="sh"
|
mode="sh"
|
||||||
|
@ -206,7 +197,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
value={info['hook_post_host']}
|
value={info['hook_post_host']}
|
||||||
onChange={v => info['hook_post_host'] = cleanCommand(v)}
|
onChange={v => info['hook_post_host'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Switch, Col, Form, Select, Button, Input } from "antd";
|
import { Form, Switch, Select, Button, Input } from "antd";
|
||||||
import envStore from 'pages/config/environment/store';
|
import envStore from 'pages/config/environment/store';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -29,17 +29,17 @@ export default observer(function Ext2Setup1() {
|
||||||
const info = store.deploy;
|
const info = store.deploy;
|
||||||
return (
|
return (
|
||||||
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
||||||
<Form.Item required label="发布环境">
|
<Form.Item required label="发布环境" style={{marginBottom: 0}}>
|
||||||
<Col span={16}>
|
<Form.Item style={{display: 'inline-block', width: '80%'}}>
|
||||||
<Select disabled={store.isReadOnly} value={info.env_id} onChange={v => info.env_id = v} placeholder="请选择发布环境">
|
<Select disabled={store.isReadOnly} value={info.env_id} onChange={v => info.env_id = v} placeholder="请选择发布环境">
|
||||||
{envStore.records.map(item => (
|
{envStore.records.map(item => (
|
||||||
<Select.Option disabled={envs.includes(item.id)} value={item.id} key={item.id}>{item.name}</Select.Option>
|
<Select.Option disabled={envs.includes(item.id)} value={item.id} key={item.id}>{item.name}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Col>
|
</Form.Item>
|
||||||
<Col span={6} offset={2}>
|
<Form.Item style={{display: 'inline-block', width: '20%', textAlign: 'right'}}>
|
||||||
<Link disabled={store.isReadOnly} to="/config/environment">新建环境</Link>
|
<Link disabled={store.isReadOnly} to="/config/environment">新建环境</Link>
|
||||||
</Col>
|
</Form.Item>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="发布审核">
|
<Form.Item label="发布审核">
|
||||||
<Switch
|
<Switch
|
||||||
|
@ -54,20 +54,21 @@ export default observer(function Ext2Setup1() {
|
||||||
<a target="_blank" rel="noopener noreferrer"
|
<a target="_blank" rel="noopener noreferrer"
|
||||||
href="https://spug.dev/docs/install-error/#%E9%92%89%E9%92%89%E6%94%B6%E4%B8%8D%E5%88%B0%E9%80%9A%E7%9F%A5%EF%BC%9F">钉钉收不到通知?</a>
|
href="https://spug.dev/docs/install-error/#%E9%92%89%E9%92%89%E6%94%B6%E4%B8%8D%E5%88%B0%E9%80%9A%E7%9F%A5%EF%BC%9F">钉钉收不到通知?</a>
|
||||||
</span>}>
|
</span>}>
|
||||||
<Input addonBefore={(
|
<Input
|
||||||
<Select disabled={store.isReadOnly}
|
addonBefore={(
|
||||||
value={info['rst_notify']['mode']} style={{width: 100}}
|
<Select disabled={store.isReadOnly}
|
||||||
onChange={v => info['rst_notify']['mode'] = v}>
|
value={info['rst_notify']['mode']} style={{width: 100}}
|
||||||
<Select.Option value="0">关闭</Select.Option>
|
onChange={v => info['rst_notify']['mode'] = v}>
|
||||||
<Select.Option value="1">钉钉</Select.Option>
|
<Select.Option value="0">关闭</Select.Option>
|
||||||
<Select.Option value="3">企业微信</Select.Option>
|
<Select.Option value="1">钉钉</Select.Option>
|
||||||
<Select.Option value="2">Webhook</Select.Option>
|
<Select.Option value="3">企业微信</Select.Option>
|
||||||
</Select>
|
<Select.Option value="2">Webhook</Select.Option>
|
||||||
)}
|
</Select>
|
||||||
disabled={store.isReadOnly || info['rst_notify']['mode'] === '0'}
|
)}
|
||||||
value={info['rst_notify']['value']}
|
disabled={store.isReadOnly || info['rst_notify']['mode'] === '0'}
|
||||||
onChange={e => info['rst_notify']['value'] = e.target.value}
|
value={info['rst_notify']['value']}
|
||||||
placeholder="请输入"/>
|
onChange={e => info['rst_notify']['value'] = e.target.value}
|
||||||
|
placeholder="请输入"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Form, Select, Button, Icon } from "antd";
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import { Form, Select, Button } from 'antd';
|
||||||
import { hasHostPermission } from 'libs';
|
import { hasHostPermission } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import hostStore from 'pages/host/store';
|
import hostStore from 'pages/host/store';
|
||||||
|
@ -32,7 +33,7 @@ class Ext2Setup2 extends React.Component {
|
||||||
disabled={store.isReadOnly}
|
disabled={store.isReadOnly}
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
optionFilterProp="children"
|
optionFilterProp="children"
|
||||||
style={{width: '80%', marginRight: 10}}
|
style={{width: '80%', marginRight: 10, marginBottom: 12}}
|
||||||
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||||||
onChange={v => store.editHost(index, v)}>
|
onChange={v => store.editHost(index, v)}>
|
||||||
{hostStore.records.filter(x => hasHostPermission(x.id)).map(item => (
|
{hostStore.records.filter(x => hasHostPermission(x.id)).map(item => (
|
||||||
|
@ -42,14 +43,14 @@ class Ext2Setup2 extends React.Component {
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{!store.isReadOnly && info['host_ids'].length > 1 && (
|
{!store.isReadOnly && info['host_ids'].length > 1 && (
|
||||||
<Icon className={styles.delIcon} type="minus-circle-o" onClick={() => store.delHost(index)}/>
|
<MinusCircleOutlined className={styles.delIcon} onClick={() => store.delHost(index)} />
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button disabled={store.isReadOnly} type="dashed" style={{width: '80%'}} onClick={store.addHost}>
|
<Button disabled={store.isReadOnly} type="dashed" style={{width: '80%'}} onClick={store.addHost}>
|
||||||
<Icon type="plus"/>添加目标主机
|
<PlusOutlined />添加目标主机
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Form, Input, Button, message, Divider, Alert, Icon, Select } from 'antd';
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import { Form, Input, Button, message, Divider, Alert, Select } from 'antd';
|
||||||
import Editor from 'react-ace';
|
import Editor from 'react-ace';
|
||||||
import 'ace-builds/src-noconflict/mode-sh';
|
import 'ace-builds/src-noconflict/mode-sh';
|
||||||
import 'ace-builds/src-noconflict/theme-tomorrow';
|
import 'ace-builds/src-noconflict/theme-tomorrow';
|
||||||
|
@ -81,7 +82,7 @@ class Ext2Setup3 extends React.Component {
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{!store.isReadOnly && (
|
{!store.isReadOnly && (
|
||||||
<div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}>
|
<div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}>
|
||||||
<Icon type="minus-circle"/>移除
|
<MinusCircleOutlined />移除
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -89,7 +90,7 @@ class Ext2Setup3 extends React.Component {
|
||||||
{!store.isReadOnly && (
|
{!store.isReadOnly && (
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button type="dashed" block onClick={() => server_actions.push({})}>
|
<Button type="dashed" block onClick={() => server_actions.push({})}>
|
||||||
<Icon type="plus"/>添加本地执行动作(在服务端本地执行)
|
<PlusOutlined />添加本地执行动作(在服务端本地执行)
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
|
@ -159,7 +160,7 @@ class Ext2Setup3 extends React.Component {
|
||||||
)}
|
)}
|
||||||
{!store.isReadOnly && (
|
{!store.isReadOnly && (
|
||||||
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>
|
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>
|
||||||
<Icon type="minus-circle"/>移除
|
<MinusCircleOutlined />移除
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -167,14 +168,15 @@ class Ext2Setup3 extends React.Component {
|
||||||
{!store.isReadOnly && (
|
{!store.isReadOnly && (
|
||||||
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
<Form.Item wrapperCol={{span: 14, offset: 6}}>
|
||||||
<Button disabled={store.isReadOnly} type="dashed" block onClick={() => host_actions.push({})}>
|
<Button disabled={store.isReadOnly} type="dashed" block onClick={() => host_actions.push({})}>
|
||||||
<Icon type="plus"/>添加目标主机执行动作(在部署目标主机执行)
|
<PlusOutlined />添加目标主机执行动作(在部署目标主机执行)
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
block
|
block
|
||||||
type="dashed"
|
type="dashed"
|
||||||
|
style={{marginTop: 8}}
|
||||||
disabled={store.isReadOnly || lds.findIndex(host_actions, x => x.type === 'transfer') !== -1}
|
disabled={store.isReadOnly || lds.findIndex(host_actions, x => x.type === 'transfer') !== -1}
|
||||||
onClick={() => host_actions.push({type: 'transfer', title: '数据传输', mode: '0', src_mode: '0'})}>
|
onClick={() => host_actions.push({type: 'transfer', title: '数据传输', mode: '0', src_mode: '0'})}>
|
||||||
<Icon type="plus"/>添加数据传输动作(仅能添加一个)
|
<PlusOutlined />添加数据传输动作(仅能添加一个)
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -3,65 +3,48 @@
|
||||||
* Copyright (c) <spug.dev@gmail.com>
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Modal, Form, Input, message } from 'antd';
|
import { Modal, Form, Input, message } from 'antd';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
@observer
|
export default observer(function () {
|
||||||
class ComForm extends React.Component {
|
const [form] = Form.useForm();
|
||||||
constructor(props) {
|
const [loading, setLoading] = useState(false);
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
loading: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit = () => {
|
function handleSubmit() {
|
||||||
this.setState({loading: true});
|
setLoading(true);
|
||||||
const formData = this.props.form.getFieldsValue();
|
const formData = form.getFieldsValue();
|
||||||
formData['id'] = store.record.id;
|
formData['id'] = store.record.id;
|
||||||
http.post('/api/app/', formData)
|
http.post('/api/app/', formData)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
message.success('操作成功');
|
message.success('操作成功');
|
||||||
store.formVisible = false;
|
store.formVisible = false;
|
||||||
store.fetchRecords()
|
store.fetchRecords()
|
||||||
}, () => this.setState({loading: false}))
|
}, () => setLoading(false))
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const info = store.record;
|
|
||||||
const {getFieldDecorator} = this.props.form;
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
visible
|
|
||||||
width={800}
|
|
||||||
maskClosable={false}
|
|
||||||
title={store.record.id ? '编辑应用' : '新建应用'}
|
|
||||||
onCancel={() => store.formVisible = false}
|
|
||||||
confirmLoading={this.state.loading}
|
|
||||||
onOk={this.handleSubmit}>
|
|
||||||
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
|
||||||
<Form.Item required label="应用名称">
|
|
||||||
{getFieldDecorator('name', {initialValue: info['name']})(
|
|
||||||
<Input placeholder="请输入应用名称,例如:订单服务"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item required label="唯一标识符">
|
|
||||||
{getFieldDecorator('key', {initialValue: info['key']})(
|
|
||||||
<Input placeholder="请输入唯一标识符,例如:api_order"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="备注信息">
|
|
||||||
{getFieldDecorator('desc', {initialValue: info['desc']})(
|
|
||||||
<Input.TextArea placeholder="请输入备注信息"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export default Form.create()(ComForm)
|
return (
|
||||||
|
<Modal
|
||||||
|
visible
|
||||||
|
width={800}
|
||||||
|
maskClosable={false}
|
||||||
|
title={store.record.id ? '编辑应用' : '新建应用'}
|
||||||
|
onCancel={() => store.formVisible = false}
|
||||||
|
confirmLoading={loading}
|
||||||
|
onOk={handleSubmit}>
|
||||||
|
<Form form={form} initialValues={store.record} labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
||||||
|
<Form.Item required name="name" label="应用名称">
|
||||||
|
<Input placeholder="请输入应用名称,例如:订单服务"/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item required name="key" label="唯一标识符">
|
||||||
|
<Input placeholder="请输入唯一标识符,例如:api_order"/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item name="desc" label="备注信息">
|
||||||
|
<Input.TextArea placeholder="请输入备注信息"/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
})
|
|
@ -4,12 +4,19 @@
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { toJS } from 'mobx';
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Table, Modal, Tag, Icon, Divider, message } from 'antd';
|
import {
|
||||||
|
BuildOutlined,
|
||||||
|
DownSquareOutlined,
|
||||||
|
ExclamationCircleOutlined,
|
||||||
|
OrderedListOutlined,
|
||||||
|
UpSquareOutlined,
|
||||||
|
PlusOutlined
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import { Table, Modal, Tag, Divider, message } from 'antd';
|
||||||
import { http, hasPermission } from 'libs';
|
import { http, hasPermission } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import { Action } from "components";
|
import { Action, TableCard, AuthButton } from "components";
|
||||||
import CloneConfirm from './CloneConfirm';
|
import CloneConfirm from './CloneConfirm';
|
||||||
import envStore from 'pages/config/environment/store';
|
import envStore from 'pages/config/environment/store';
|
||||||
import lds from 'lodash';
|
import lds from 'lodash';
|
||||||
|
@ -32,7 +39,7 @@ class ComTable extends React.Component {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.cloneObj = null;
|
this.cloneObj = null;
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
icon: 'exclamation-circle',
|
icon: <ExclamationCircleOutlined/>,
|
||||||
title: '选择克隆对象',
|
title: '选择克隆对象',
|
||||||
content: <CloneConfirm onChange={v => this.cloneObj = v[1]}/>,
|
content: <CloneConfirm onChange={v => this.cloneObj = v[1]}/>,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
|
@ -88,49 +95,51 @@ class ComTable extends React.Component {
|
||||||
store.loadDeploys(record.id)
|
store.loadDeploys(record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Table
|
|
||||||
rowKey="id"
|
|
||||||
loading={record['deploys'] === undefined}
|
|
||||||
dataSource={record['deploys']}
|
|
||||||
pagination={false}>
|
|
||||||
<Table.Column width={80} title="模式" dataIndex="extend" render={value => value === '1' ?
|
|
||||||
<Icon style={{fontSize: 20, color: '#1890ff'}} type="ordered-list"/> :
|
|
||||||
<Icon style={{fontSize: 20, color: '#1890ff'}} type="build"/>}/>
|
|
||||||
<Table.Column title="发布环境" dataIndex="env_id" render={value => lds.get(envStore.idMap, `${value}.name`)}/>
|
|
||||||
<Table.Column title="关联主机" dataIndex="host_ids" render={value => `${value.length} 台`}/>
|
|
||||||
<Table.Column title="发布审核" dataIndex="is_audit"
|
|
||||||
render={value => value ? <Tag color="green">开启</Tag> : <Tag color="red">关闭</Tag>}/>
|
|
||||||
{hasPermission('deploy.app.config|deploy.app.edit') && (
|
|
||||||
<Table.Column title="操作" render={info => (
|
|
||||||
<Action>
|
|
||||||
<Action.Button
|
|
||||||
auth="deploy.app.config"
|
|
||||||
onClick={e => store.showExtForm(e, record.id, info, false, true)}>查看</Action.Button>
|
|
||||||
<Action.Button auth="deploy.app.edit"
|
|
||||||
onClick={e => store.showExtForm(e, record.id, info)}>编辑</Action.Button>
|
|
||||||
<Action.Button auth="deploy.app.edit" onClick={() => this.handleDeployDelete(info)}>删除</Action.Button>
|
|
||||||
</Action>
|
|
||||||
)}/>
|
|
||||||
)}
|
|
||||||
</Table>
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let data = Object.values(toJS(store.records));
|
|
||||||
if (store.f_name) {
|
|
||||||
data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase()))
|
|
||||||
}
|
|
||||||
if (store.f_desc) {
|
|
||||||
data = data.filter(item => item['desc'] && item['desc'].toLowerCase().includes(store.f_desc.toLowerCase()))
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
expandRowByClick
|
loading={record['deploys'] === undefined}
|
||||||
|
dataSource={record['deploys']}
|
||||||
|
pagination={false}>
|
||||||
|
<Table.Column width={80} title="模式" dataIndex="extend" render={value => value === '1' ?
|
||||||
|
<OrderedListOutlined style={{fontSize: 20, color: '#1890ff'}}/> :
|
||||||
|
<BuildOutlined style={{fontSize: 20, color: '#1890ff'}}/>}/>
|
||||||
|
<Table.Column title="发布环境" dataIndex="env_id" render={value => lds.get(envStore.idMap, `${value}.name`)}/>
|
||||||
|
<Table.Column title="关联主机" dataIndex="host_ids" render={value => `${value.length} 台`}/>
|
||||||
|
<Table.Column title="发布审核" dataIndex="is_audit"
|
||||||
|
render={value => value ? <Tag color="green">开启</Tag> : <Tag color="red">关闭</Tag>}/>
|
||||||
|
{hasPermission('deploy.app.config|deploy.app.edit') && (
|
||||||
|
<Table.Column title="操作" render={info => (
|
||||||
|
<Action>
|
||||||
|
<Action.Button
|
||||||
|
auth="deploy.app.config"
|
||||||
|
onClick={e => store.showExtForm(e, record.id, info, false, true)}>查看</Action.Button>
|
||||||
|
<Action.Button auth="deploy.app.edit"
|
||||||
|
onClick={e => store.showExtForm(e, record.id, info)}>编辑</Action.Button>
|
||||||
|
<Action.Button auth="deploy.app.edit" onClick={() => this.handleDeployDelete(info)}>删除</Action.Button>
|
||||||
|
</Action>
|
||||||
|
)}/>
|
||||||
|
)}
|
||||||
|
</Table>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<TableCard
|
||||||
|
title="应用列表"
|
||||||
|
rowKey="id"
|
||||||
loading={store.isFetching}
|
loading={store.isFetching}
|
||||||
dataSource={data}
|
dataSource={store.dataSource}
|
||||||
expandedRowRender={this.expandedRowRender}
|
expandable={{expandRowByClick: true, expandedRowRender: this.expandedRowRender}}
|
||||||
|
onReload={store.fetchRecords}
|
||||||
|
actions={[
|
||||||
|
<AuthButton
|
||||||
|
auth="deploy.app.add"
|
||||||
|
type="primary"
|
||||||
|
icon={<PlusOutlined/>}
|
||||||
|
onClick={() => store.showForm()}>新建</AuthButton>
|
||||||
|
]}
|
||||||
pagination={{
|
pagination={{
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
showLessItems: true,
|
showLessItems: true,
|
||||||
|
@ -140,11 +149,13 @@ class ComTable extends React.Component {
|
||||||
}}>
|
}}>
|
||||||
<Table.Column width={80} title="排序" key="series" render={(info) => (
|
<Table.Column width={80} title="排序" key="series" render={(info) => (
|
||||||
<div>
|
<div>
|
||||||
<Icon onClick={e => this.handleSort(e, info, 'up')} type="up-square"
|
<UpSquareOutlined
|
||||||
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
onClick={e => this.handleSort(e, info, 'up')}
|
||||||
|
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<Icon onClick={e => this.handleSort(e, info, 'down')} type="down-square"
|
<DownSquareOutlined
|
||||||
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
onClick={e => this.handleSort(e, info, 'down')}
|
||||||
|
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
||||||
</div>
|
</div>
|
||||||
)}/>
|
)}/>
|
||||||
<Table.Column title="应用名称" dataIndex="name"/>
|
<Table.Column title="应用名称" dataIndex="name"/>
|
||||||
|
@ -160,7 +171,7 @@ class ComTable extends React.Component {
|
||||||
</Action>
|
</Action>
|
||||||
)}/>
|
)}/>
|
||||||
)}
|
)}
|
||||||
</Table>
|
</TableCard>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Input, Button } from 'antd';
|
import { Input } from 'antd';
|
||||||
import { SearchForm, AuthDiv, AuthCard } from 'components';
|
import { SearchForm, AuthDiv, Breadcrumb } 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';
|
||||||
|
@ -16,26 +16,25 @@ import store from './store';
|
||||||
|
|
||||||
export default observer(function () {
|
export default observer(function () {
|
||||||
return (
|
return (
|
||||||
<AuthCard auth="deploy.app.view">
|
<AuthDiv auth="deploy.app.view">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item>首页</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>应用发布</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>应用管理</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
<SearchForm>
|
<SearchForm>
|
||||||
<SearchForm.Item span={6} title="应用名称">
|
<SearchForm.Item span={7} title="应用名称">
|
||||||
<Input allowClear value={store.f_name} onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
<Input allowClear value={store.f_name} onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={6} title="描述信息">
|
<SearchForm.Item span={7} title="描述信息">
|
||||||
<Input allowClear value={store.f_desc} onChange={e => store.f_desc = e.target.value} placeholder="请输入"/>
|
<Input allowClear value={store.f_desc} onChange={e => store.f_desc = e.target.value} placeholder="请输入"/>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={8}>
|
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
|
||||||
</SearchForm.Item>
|
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
<AuthDiv auth="deploy.app.add" style={{marginBottom: 16}}>
|
|
||||||
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
|
||||||
</AuthDiv>
|
|
||||||
<ComTable/>
|
<ComTable/>
|
||||||
{store.formVisible && <ComForm />}
|
{store.formVisible && <ComForm />}
|
||||||
{store.addVisible && <AddSelect />}
|
{store.addVisible && <AddSelect />}
|
||||||
{store.ext1Visible && <Ext1Form />}
|
{store.ext1Visible && <Ext1Form />}
|
||||||
{store.ext2Visible && <Ext2Form />}
|
{store.ext2Visible && <Ext2Form />}
|
||||||
</AuthCard>
|
</AuthDiv>
|
||||||
)
|
);
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) <spug.dev@gmail.com>
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import { observable, computed } from "mobx";
|
import { observable, computed, toJS } from 'mobx';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
|
|
||||||
class Store {
|
class Store {
|
||||||
|
@ -22,6 +22,13 @@ class Store {
|
||||||
@observable f_name;
|
@observable f_name;
|
||||||
@observable f_desc;
|
@observable f_desc;
|
||||||
|
|
||||||
|
@computed get dataSource() {
|
||||||
|
let records = Object.values(toJS(this.records));
|
||||||
|
if (this.f_name) records = records.filter(x => x.name.toLowerCase().includes(this.f_name.toLowerCase()));
|
||||||
|
if (this.f_desc) records = records.filter(x => x.desc && x.desc.toLowerCase().includes(this.f_desc.toLowerCase()));
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
@computed get currentRecord() {
|
@computed get currentRecord() {
|
||||||
return this.records[`a${this.app_id}`]
|
return this.records[`a${this.app_id}`]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue