mirror of https://github.com/openspug/spug
A web update
parent
70913eacf4
commit
5ec88738d0
|
@ -1,8 +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 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 { http } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
|
@ -10,31 +12,63 @@ class JSONView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
readOnly: true,
|
||||||
body: ''
|
body: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.updateValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateValue = () => {
|
||||||
const body = {};
|
const body = {};
|
||||||
for (let item of store.records) {
|
for (let item of store.records) {
|
||||||
body[item.key] = item.value
|
body[item.key] = item.value
|
||||||
}
|
}
|
||||||
this.setState({body: JSON.stringify(body, null, 2)})
|
this.setState({readOnly: true, body: JSON.stringify(body, null, 2)})
|
||||||
}
|
};
|
||||||
|
|
||||||
|
handleSubmit = () => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(this.state.body);
|
||||||
|
this.setState({loading: true});
|
||||||
|
const formData = {type: store.type, o_id: store.id, env_id: store.env.id, data};
|
||||||
|
http.post('/api/config/parse/json/', formData)
|
||||||
|
.then(res => {
|
||||||
|
message.success('保存成功')
|
||||||
|
})
|
||||||
|
.finally(() => this.setState({loading: false}))
|
||||||
|
} catch (err) {
|
||||||
|
message.error('解析JSON失败,请检查输入内容')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {body, readOnly, loading} = this.state;
|
||||||
return (
|
return (
|
||||||
<Editor
|
<div style={{position: 'relative'}}>
|
||||||
mode="json"
|
<Editor
|
||||||
theme="tomorrow"
|
mode="json"
|
||||||
height="500px"
|
theme="tomorrow"
|
||||||
width="100%"
|
height="500px"
|
||||||
readOnly={true}
|
width="100%"
|
||||||
setOptions={{useWorker: false}}
|
readOnly={readOnly}
|
||||||
style={{fontSize: 14}}
|
setOptions={{useWorker: false}}
|
||||||
value={this.state.body}
|
style={{fontSize: 14}}
|
||||||
onChange={v => this.setState({body: v})}
|
value={body}
|
||||||
/>
|
onChange={v => this.setState({body: v})}/>
|
||||||
|
{readOnly && <Button
|
||||||
|
icon="edit"
|
||||||
|
style={{position: 'absolute', top: 20, right: 0}}
|
||||||
|
onClick={() => this.setState({readOnly: false})}>编辑</Button>}
|
||||||
|
{readOnly || <Button
|
||||||
|
icon="save"
|
||||||
|
loading={loading}
|
||||||
|
style={{position: 'absolute', top: 20, right: 0}}
|
||||||
|
onClick={this.handleSubmit}>保存</Button>}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,27 +4,65 @@ import Editor from 'react-ace';
|
||||||
import 'ace-builds/src-noconflict/mode-space';
|
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 { Button, message } from "antd";
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class TextView extends React.Component {
|
class TextView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
readOnly: true,
|
||||||
body: ''
|
body: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.updateValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateValue = () => {
|
||||||
let body = '';
|
let body = '';
|
||||||
for (let item of store.records) {
|
for (let item of store.records) {
|
||||||
body += `${item.key} = ${item.value}\n`
|
body += `${item.key} = ${item.value}\n`
|
||||||
}
|
}
|
||||||
this.setState({body})
|
this.setState({readOnly: true, body})
|
||||||
}
|
};
|
||||||
|
|
||||||
|
handleSubmit = () => {
|
||||||
|
this.setState({loading: true});
|
||||||
|
const formData = {type: store.type, o_id: store.id, env_id: store.env.id, data: this.state.body};
|
||||||
|
http.post('/api/config/parse/text/', formData)
|
||||||
|
.then(res => {
|
||||||
|
message.success('保存成功')
|
||||||
|
})
|
||||||
|
.finally(() => this.setState({loading: false}))
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {body, loading, readOnly} = this.state;
|
||||||
return (
|
return (
|
||||||
<Editor style={{fontSize: 14}} value={this.state.body} mode="space" theme="tomorrow" height="500px" width="100%"/>
|
<div style={{position: 'relative'}}>
|
||||||
|
<Editor
|
||||||
|
mode="space"
|
||||||
|
width="100%"
|
||||||
|
height="500px"
|
||||||
|
theme="tomorrow"
|
||||||
|
style={{fontSize: 14}}
|
||||||
|
value={body}
|
||||||
|
readOnly={readOnly}
|
||||||
|
onChange={v => this.setState({body: v})}/>
|
||||||
|
{readOnly && <Button
|
||||||
|
icon="edit"
|
||||||
|
style={{position: 'absolute', top: 20, right: 10}}
|
||||||
|
onClick={() => this.setState({readOnly: false})}>编辑</Button>}
|
||||||
|
{readOnly || <Button
|
||||||
|
icon="save"
|
||||||
|
loading={loading}
|
||||||
|
style={{position: 'absolute', top: 20, right: 10}}
|
||||||
|
onClick={this.handleSubmit}>保存</Button>}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import store from './store';
|
||||||
class Index extends React.Component {
|
class Index extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.textView = null;
|
||||||
|
this.JSONView = null;
|
||||||
this.state = {
|
this.state = {
|
||||||
view: '1'
|
view: '1'
|
||||||
}
|
}
|
||||||
|
@ -32,7 +34,14 @@ class Index extends React.Component {
|
||||||
|
|
||||||
updateEnv = (env) => {
|
updateEnv = (env) => {
|
||||||
store.env = env || envStore.records[0];
|
store.env = env || envStore.records[0];
|
||||||
store.fetchRecords()
|
this.handleRefresh()
|
||||||
|
};
|
||||||
|
|
||||||
|
handleRefresh = () => {
|
||||||
|
store.fetchRecords().then(() => {
|
||||||
|
if (this.textView) this.textView.updateValue();
|
||||||
|
if (this.JSONView) this.JSONView.updateValue();
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -63,7 +72,7 @@ class Index extends React.Component {
|
||||||
<Input allowClear onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
<Input allowClear onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={4}>
|
<SearchForm.Item span={4}>
|
||||||
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
|
<Button type="primary" icon="sync" onClick={this.handleRefresh}>刷新</Button>
|
||||||
</SearchForm.Item>
|
</SearchForm.Item>
|
||||||
<SearchForm.Item span={4}>
|
<SearchForm.Item span={4}>
|
||||||
<Button type="primary" style={{backgroundColor: 'orange', borderColor: 'orange'}} icon="history"
|
<Button type="primary" style={{backgroundColor: 'orange', borderColor: 'orange'}} icon="history"
|
||||||
|
@ -75,8 +84,8 @@ class Index extends React.Component {
|
||||||
</SearchForm>
|
</SearchForm>
|
||||||
|
|
||||||
{view === '1' && <TableView />}
|
{view === '1' && <TableView />}
|
||||||
{view === '2' && <TextView />}
|
{view === '2' && <TextView ref={ref => this.textView = ref} />}
|
||||||
{view === '3' && <JSONView />}
|
{view === '3' && <JSONView ref={ref => this.JSONView = ref} />}
|
||||||
</div>
|
</div>
|
||||||
{store.recordVisible && <Record />}
|
{store.recordVisible && <Record />}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Store {
|
||||||
fetchRecords = () => {
|
fetchRecords = () => {
|
||||||
const params = {type: this.type, id: this.id, env_id: this.env.id};
|
const params = {type: this.type, id: this.id, env_id: this.env.id};
|
||||||
this.isFetching = true;
|
this.isFetching = true;
|
||||||
http.get('/api/config/', {params})
|
return http.get('/api/config/', {params})
|
||||||
.then(res => this.records = res)
|
.then(res => this.records = res)
|
||||||
.finally(() => this.isFetching = false)
|
.finally(() => this.isFetching = false)
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue