mirror of https://github.com/openspug/spug
A web update
parent
19356ff94a
commit
1a039f212a
|
@ -35,7 +35,7 @@ class AppView(View):
|
||||||
).parse(request.GET)
|
).parse(request.GET)
|
||||||
if error is None:
|
if error is None:
|
||||||
if Deploy.objects.filter(app_id=form.id).exists():
|
if Deploy.objects.filter(app_id=form.id).exists():
|
||||||
return json_response(error='该应用已存在关联的发布配置,请删除相关配置后再尝试删除')
|
return json_response(error='该应用在应用发布中已存在关联的发布配置,请删除相关发布配置后再尝试删除')
|
||||||
if Config.objects.filter(type='app', o_id=form.id).exists():
|
if Config.objects.filter(type='app', o_id=form.id).exists():
|
||||||
return json_response(error='该应用在配置中心已存在关联的配置信息,请删除相关配置后再尝试删除')
|
return json_response(error='该应用在配置中心已存在关联的配置信息,请删除相关配置后再尝试删除')
|
||||||
App.objects.filter(pk=form.id).delete()
|
App.objects.filter(pk=form.id).delete()
|
||||||
|
|
|
@ -17,7 +17,8 @@ export default [
|
||||||
{
|
{
|
||||||
icon: 'deployment-unit', title: '配置中心', child: [
|
icon: 'deployment-unit', title: '配置中心', child: [
|
||||||
{title: '环境管理', path: '/config/environment'},
|
{title: '环境管理', path: '/config/environment'},
|
||||||
{title: '服务管理', path: '/config/service'},
|
{title: '服务配置', path: '/config/service'},
|
||||||
|
{title: '应用配置', path: '/config/app'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{icon: 'monitor', title: '监控中心', path: '/monitor'},
|
{icon: 'monitor', title: '监控中心', path: '/monitor'},
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Modal, Form, Input, message } from 'antd';
|
||||||
|
import http from 'libs/http';
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
class ComForm extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = () => {
|
||||||
|
this.setState({loading: true});
|
||||||
|
const formData = this.props.form.getFieldsValue();
|
||||||
|
formData['id'] = store.record.id;
|
||||||
|
http.post('/api/app/', formData)
|
||||||
|
.then(res => {
|
||||||
|
message.success('操作成功');
|
||||||
|
store.formVisible = false;
|
||||||
|
store.fetchRecords()
|
||||||
|
}, () => this.setState({loading: 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)
|
|
@ -0,0 +1,72 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { Table, Divider, Modal, message } from 'antd';
|
||||||
|
import ComForm from './Form';
|
||||||
|
import http from 'libs/http';
|
||||||
|
import store from './store';
|
||||||
|
import { LinkButton } from "components";
|
||||||
|
|
||||||
|
@observer
|
||||||
|
class ComTable extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
store.fetchRecords()
|
||||||
|
}
|
||||||
|
|
||||||
|
columns = [{
|
||||||
|
title: '序号',
|
||||||
|
key: 'series',
|
||||||
|
render: (_, __, index) => index + 1,
|
||||||
|
width: 80,
|
||||||
|
}, {
|
||||||
|
title: '应用名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
}, {
|
||||||
|
title: '标识符',
|
||||||
|
dataIndex: 'key',
|
||||||
|
}, {
|
||||||
|
title: '描述信息',
|
||||||
|
dataIndex: 'desc',
|
||||||
|
ellipsis: true
|
||||||
|
}, {
|
||||||
|
title: '操作',
|
||||||
|
render: info => (
|
||||||
|
<span>
|
||||||
|
<LinkButton onClick={() => store.showForm(info)}>编辑</LinkButton>
|
||||||
|
<Divider type="vertical"/>
|
||||||
|
<LinkButton onClick={() => this.handleDelete(info)}>删除</LinkButton>
|
||||||
|
<Divider type="vertical"/>
|
||||||
|
<Link to={`/config/setting/app/${info.id}`}>配置</Link>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}];
|
||||||
|
|
||||||
|
handleDelete = (text) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '删除确认',
|
||||||
|
content: `确定要删除【${text['name']}】?`,
|
||||||
|
onOk: () => {
|
||||||
|
return http.delete('/api/app/', {params: {id: text.id}})
|
||||||
|
.then(() => {
|
||||||
|
message.success('删除成功');
|
||||||
|
store.fetchRecords()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let data = store.records;
|
||||||
|
if (store.f_name) {
|
||||||
|
data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase()))
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Table rowKey="id" loading={store.isFetching} dataSource={data} columns={this.columns}/>
|
||||||
|
{store.formVisible && <ComForm/>}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ComTable
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Card, Input, Button } from 'antd';
|
||||||
|
import { SearchForm } from 'components';
|
||||||
|
import ComTable from './Table';
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
export default observer(function () {
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<SearchForm>
|
||||||
|
<SearchForm.Item span={8} title="应用名称">
|
||||||
|
<Input allowClear onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
||||||
|
</SearchForm.Item>
|
||||||
|
<SearchForm.Item span={8}>
|
||||||
|
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
||||||
|
</SearchForm.Item>
|
||||||
|
</SearchForm>
|
||||||
|
<div style={{marginBottom: 16}}>
|
||||||
|
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
|
||||||
|
</div>
|
||||||
|
<ComTable/>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { observable } from "mobx";
|
||||||
|
import http from 'libs/http';
|
||||||
|
|
||||||
|
class Store {
|
||||||
|
@observable records = [];
|
||||||
|
@observable record = {};
|
||||||
|
@observable isFetching = false;
|
||||||
|
@observable formVisible = false;
|
||||||
|
|
||||||
|
@observable f_name;
|
||||||
|
|
||||||
|
fetchRecords = () => {
|
||||||
|
this.isFetching = true;
|
||||||
|
http.get('/api/app/')
|
||||||
|
.then(res => this.records = res)
|
||||||
|
.finally(() => this.isFetching = false)
|
||||||
|
};
|
||||||
|
|
||||||
|
showForm = (info = {}) => {
|
||||||
|
this.formVisible = true;
|
||||||
|
this.record = info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Store()
|
|
@ -1,11 +1,13 @@
|
||||||
import { makeRoute } from 'libs/router';
|
import { makeRoute } from 'libs/router';
|
||||||
import Environment from './environment';
|
import Environment from './environment';
|
||||||
import Service from './service';
|
import Service from './service';
|
||||||
|
import App from './app';
|
||||||
import Setting from './setting';
|
import Setting from './setting';
|
||||||
|
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
makeRoute('/environment', Environment),
|
makeRoute('/environment', Environment),
|
||||||
makeRoute('/service', Service),
|
makeRoute('/service', Service),
|
||||||
|
makeRoute('/app', App),
|
||||||
makeRoute('/setting/:type/:id', Setting),
|
makeRoute('/setting/:type/:id', Setting),
|
||||||
]
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Modal, Form, Input, Checkbox, Row, Col, message } from 'antd';
|
import { Modal, Form, Input, Checkbox, Switch, Row, Col, message } from 'antd';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import envStore from '../environment/store'
|
import envStore from '../environment/store'
|
||||||
|
@ -27,7 +27,7 @@ class ComForm extends React.Component {
|
||||||
formData['type'] = store.type;
|
formData['type'] = store.type;
|
||||||
formData['o_id'] = store.id;
|
formData['o_id'] = store.id;
|
||||||
formData['envs'] = this.state.envs;
|
formData['envs'] = this.state.envs;
|
||||||
formData['is_public'] = true;
|
formData['is_public'] = store.type === 'src' ? true : formData['is_public'];
|
||||||
request = http.post('/api/config/', formData)
|
request = http.post('/api/config/', formData)
|
||||||
}
|
}
|
||||||
request.then(res => {
|
request.then(res => {
|
||||||
|
@ -78,6 +78,13 @@ class ComForm extends React.Component {
|
||||||
<Input.TextArea placeholder="请输入备注信息"/>
|
<Input.TextArea placeholder="请输入备注信息"/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{store.type === 'app' && (
|
||||||
|
<Form.Item label="类型">
|
||||||
|
{getFieldDecorator('is_public', {initialValue: info['is_public'] || true, valuePropName: 'checked'})(
|
||||||
|
<Switch checkedChildren="公共" unCheckedChildren="私有"/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
<Form.Item label="选择环境">
|
<Form.Item label="选择环境">
|
||||||
{envStore.records.map((item, index) => (
|
{envStore.records.map((item, index) => (
|
||||||
<Row
|
<Row
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Table, Divider, Modal, Tooltip, message } from 'antd';
|
import { Table, Divider, Modal, Tooltip, Tag, Icon, message } from 'antd';
|
||||||
import { LinkButton } from 'components';
|
import { LinkButton } from 'components';
|
||||||
import ComForm from './Form';
|
import ComForm from './Form';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
|
@ -8,10 +8,21 @@ import store from './store';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class TableView extends React.Component {
|
class TableView extends React.Component {
|
||||||
|
lockIcon = <Tooltip title="私有配置应用专用,不会被其他应用获取到">
|
||||||
|
<Icon style={{marginRight: 5}} type="lock"/>
|
||||||
|
</Tooltip>;
|
||||||
|
|
||||||
columns = [{
|
columns = [{
|
||||||
title: 'Key',
|
title: 'Key',
|
||||||
key: 'key',
|
key: 'key',
|
||||||
render: info => <Tooltip title={info.desc}>{info.key}</Tooltip>
|
render: info => {
|
||||||
|
let prefix = (store.type === 'app' && info.is_public === false) ? this.lockIcon : null;
|
||||||
|
let content = info.desc ? <span style={{color: '#1890ff'}}>{info.key}</span> : info.key;
|
||||||
|
return <React.Fragment>
|
||||||
|
{prefix}
|
||||||
|
<Tooltip title={info.desc}>{content}</Tooltip>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
title: 'Value',
|
title: 'Value',
|
||||||
dataIndex: 'value',
|
dataIndex: 'value',
|
||||||
|
|
|
@ -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 type="primary" icon="plus" onClick={() => store.showForm()}>新增配置</Button>
|
<Button disabled={view !== '1'} type="primary" icon="plus" onClick={() => store.showForm()}>新增配置</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue