From 0e57c71896681111e569e70a86b3ac8d0ff2707b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E4=BA=8C=E7=8C=9B?= Date: Tue, 24 Dec 2019 23:50:34 +0800 Subject: [PATCH] A web update --- spug_web/src/pages/deploy/app/AddSelect.js | 3 +- spug_web/src/pages/deploy/app/Ext2Setup3.js | 69 +++++++---- .../deploy/do/{index.js => Ext1Index.js} | 8 +- spug_web/src/pages/deploy/do/Ext2Index.js | 110 ++++++++++++++++++ spug_web/src/pages/deploy/do/index.module.css | 25 +++- spug_web/src/pages/deploy/request/Ext2Form.js | 21 +++- .../src/pages/deploy/request/SelectApp.js | 6 +- spug_web/src/pages/deploy/request/Table.js | 8 +- .../src/pages/deploy/request/index.module.css | 5 + spug_web/src/pages/deploy/routes.js | 6 +- 10 files changed, 219 insertions(+), 42 deletions(-) rename spug_web/src/pages/deploy/do/{index.js => Ext1Index.js} (94%) create mode 100644 spug_web/src/pages/deploy/do/Ext2Index.js diff --git a/spug_web/src/pages/deploy/app/AddSelect.js b/spug_web/src/pages/deploy/app/AddSelect.js index c007f83..3233860 100644 --- a/spug_web/src/pages/deploy/app/AddSelect.js +++ b/spug_web/src/pages/deploy/app/AddSelect.js @@ -24,7 +24,8 @@ class AddSelect extends React.Component { store.record = { is_audit: false, host_ids: [undefined], - actions: [{target: 'server'}] + host_actions: [], + server_actions: [] } }; diff --git a/spug_web/src/pages/deploy/app/Ext2Setup3.js b/spug_web/src/pages/deploy/app/Ext2Setup3.js index a7ad3c9..5f80982 100644 --- a/spug_web/src/pages/deploy/app/Ext2Setup3.js +++ b/spug_web/src/pages/deploy/app/Ext2Setup3.js @@ -1,6 +1,6 @@ import React from 'react'; import { observer } from 'mobx-react'; -import { Form, Input, Button, message, Col, Radio, Icon } from 'antd'; +import { Form, Input, Button, message, Divider, Icon } from 'antd'; import Editor from 'react-ace'; import 'ace-builds/src-noconflict/mode-sh'; import 'ace-builds/src-noconflict/theme-tomorrow'; @@ -19,9 +19,11 @@ class Ext2Setup3 extends React.Component { handleSubmit = () => { this.setState({loading: true}); - store.record['extend'] = '2'; - store.record['actions'] = store.record['actions'].filter(x => x.title && x.data); - http.post('/api/app/', store.record) + const info = store.record; + info['extend'] = '2'; + info['host_actions'] = info['host_actions'].filter(x => x.title && x.data); + info['server_actions'] = info['server_actions'].filter(x => x.title && x.data); + http.post('/api/app/', info) .then(res => { message.success('保存成功'); store.ext2Visible = false; @@ -30,23 +32,14 @@ class Ext2Setup3 extends React.Component { }; render() { - const actions = store.record['actions']; + const server_actions = store.record['server_actions']; + const host_actions = store.record['host_actions']; return (
- {actions.map((item, index) => ( + {server_actions.map((item, index) => (
- - - item['title'] = e.target.value} placeholder="请输入"/> - - - - item['target'] = e.target.value}> - 服务本机 - 目标主机 - - - + + item['title'] = e.target.value} placeholder="请输入"/> @@ -59,21 +52,47 @@ class Ext2Setup3 extends React.Component { onChange={v => item['data'] = v} placeholder="请输入要执行的动作"/> - {actions.length > 1 && ( -
actions.splice(index, 1)}>移除
- )} +
server_actions.splice(index, 1)}> + 移除 +
))} - + + {host_actions.map((item, index) => ( +
+ + item['title'] = e.target.value} placeholder="请输入"/> + + + + item['data'] = v} + placeholder="请输入要执行的动作"/> + +
host_actions.splice(index, 1)}> + 移除 +
+
+ ))} + + + diff --git a/spug_web/src/pages/deploy/do/index.js b/spug_web/src/pages/deploy/do/Ext1Index.js similarity index 94% rename from spug_web/src/pages/deploy/do/index.js rename to spug_web/src/pages/deploy/do/Ext1Index.js index dd87fab..5efda14 100644 --- a/spug_web/src/pages/deploy/do/index.js +++ b/spug_web/src/pages/deploy/do/Ext1Index.js @@ -8,7 +8,7 @@ import store from './store'; import lds from 'lodash'; @observer -class Index extends React.Component { +class Ext1Index extends React.Component { constructor(props) { super(props); this.state = { @@ -105,7 +105,7 @@ class Index extends React.Component { }> -
{lds.get(store.outputs, 'local.data')}
+
{lds.get(store.outputs, 'local.data')}
@@ -124,7 +124,7 @@ class Index extends React.Component { }> -
{lds.get(store.outputs, `${item.id}.data`)}
+
{lds.get(store.outputs, `${item.id}.data`)}
))} @@ -133,4 +133,4 @@ class Index extends React.Component { } } -export default Index \ No newline at end of file +export default Ext1Index \ No newline at end of file diff --git a/spug_web/src/pages/deploy/do/Ext2Index.js b/spug_web/src/pages/deploy/do/Ext2Index.js new file mode 100644 index 0000000..0d3a812 --- /dev/null +++ b/spug_web/src/pages/deploy/do/Ext2Index.js @@ -0,0 +1,110 @@ +import React from 'react'; +import { observer } from 'mobx-react'; +import { Steps, PageHeader, Spin, Tag, Button, Icon } from 'antd'; +import http from 'libs/http'; +import history from 'libs/history'; +import styles from './index.module.css'; +import store from './store'; +import lds from 'lodash'; + +@observer +class Ext2Index extends React.Component { + constructor(props) { + super(props); + this.state = { + fetching: true, + loading: false, + request: {}, + } + } + + componentDidMount() { + this.id = this.props.match.params.id; + http.get(`/api/deploy/request/${this.id}/`) + .then(res => store.request = res) + .finally(() => this.setState({fetching: false})) + } + + componentWillUnmount() { + if (this.socket) this.socket.close(); + store.request = {targets: []}; + store.outputs = {}; + } + + handleDeploy = () => { + this.setState({loading: true}); + http.post(`/api/deploy/request/${this.id}/`) + .then(({token, outputs}) => { + store.request.status = '2'; + store.outputs = outputs; + this.socket = new WebSocket(`ws://localhost:8000/ws/exec/${token}/`); + this.socket.onopen = () => { + this.socket.send('ok'); + }; + this.socket.onmessage = e => { + if (e.data === 'pong') { + this.socket.send('ping') + } else { + const {key, data, step, status} = JSON.parse(e.data); + if (data !== undefined) store.outputs[key]['data'] += data; + if (step !== undefined) store.outputs[key]['step'] = step; + if (status !== undefined) store.outputs[key]['status'] = status; + } + } + }) + .finally(() => this.setState({loading: false})) + }; + + getStatus = (key, n) => { + const step = lds.get(store.outputs, `${key}.step`, -1); + const isError = lds.get(store.outputs, `${key}.status`) === 'error'; + const icon = ; + if (n > step) { + return {key: n, status: 'wait'} + } else if (n === step) { + return isError ? {key: n, status: 'error'} : {key: n, status: 'process', icon} + } else { + return {key: n, status: 'finish'} + } + }; + + getStatusAlias = () => { + if (Object.keys(store.outputs).length !== 0) { + for (let item of [{id: 'local'}, ...store.request.targets]) { + if (lds.get(store.outputs, `${item.id}.status`) === 'error') { + return 发布异常 + } else if (lds.get(store.outputs, `${item.id}.step`, -1) < 5) { + return 发布中 + } + } + return 发布成功 + } else { + return {store.request['status_alias'] || '...'} + } + }; + + render() { + const {app_name, env_name, status} = store.request; + return ( + + 发布} + onBack={() => history.goBack()}/> +
+ + + + +
{lds.get(store.outputs, 'local.data')}
+
+
+ ) + } +} + +export default Ext2Index \ No newline at end of file diff --git a/spug_web/src/pages/deploy/do/index.module.css b/spug_web/src/pages/deploy/do/index.module.css index 9173a06..96cecb3 100644 --- a/spug_web/src/pages/deploy/do/index.module.css +++ b/spug_web/src/pages/deploy/do/index.module.css @@ -10,12 +10,35 @@ padding: 0; } -.console { +.ext1Console { min-height: 40px; max-height: 300px; padding: 10px 15px; } +.ext2Block { + display: flex; + background-color: #fff; + margin-top: 16px; + border-radius: 4px; + border: 1px solid #d9d9d9; +} + +.ext2Console { + flex: 1; + padding: 30px; +} + +.ext2Step { + padding: 24px; + width: 220px; + border-right: 1px solid #e8e8e8; +} + +.ext2Step :global(.ant-steps-item) { + height: 100px; +} + pre { margin: 0; } \ No newline at end of file diff --git a/spug_web/src/pages/deploy/request/Ext2Form.js b/spug_web/src/pages/deploy/request/Ext2Form.js index 4c3698d..bf7aea2 100644 --- a/spug_web/src/pages/deploy/request/Ext2Form.js +++ b/spug_web/src/pages/deploy/request/Ext2Form.js @@ -17,6 +17,12 @@ class Ext2Form extends React.Component { } } + componentDidMount() { + if (hostStore.records.length === 0) { + hostStore.fetchRecords() + } + } + handleSubmit = () => { if (this.state.host_ids.length === 0) { return message.error('请至少选择一个要发布的目标主机') @@ -24,11 +30,13 @@ class Ext2Form extends React.Component { this.setState({loading: true}); const formData = this.props.form.getFieldsValue(); formData['id'] = store.record.id; - formData['body'] = this.state.body; - http.post('/api/exec/template/', formData) + formData['app_id'] = store.record.app_id; + formData['extra'] = [formData['extra']]; + formData['host_ids'] = this.state.host_ids; + http.post('/api/deploy/request/', formData) .then(res => { message.success('操作成功'); - store.formVisible = false; + store.ext2Visible = false; store.fetchRecords() }, () => this.setState({loading: false})) }; @@ -63,13 +71,18 @@ class Ext2Form extends React.Component { )}
+ + {getFieldDecorator('extra', {initialValue: info['extra']})( + + )} + {getFieldDecorator('desc', {initialValue: info['desc']})( )} - {info['host_ids'].map(id => ( + {info['app_host_ids'].map(id => ( this.handleChange(id, v)}> {lds.get(hostStore.idMap, `${id}.name`)}({lds.get(hostStore.idMap, `${id}.hostname`)}:{lds.get(hostStore.idMap, `${id}.port`)}) diff --git a/spug_web/src/pages/deploy/request/SelectApp.js b/spug_web/src/pages/deploy/request/SelectApp.js index 14897e4..a70ba5c 100644 --- a/spug_web/src/pages/deploy/request/SelectApp.js +++ b/spug_web/src/pages/deploy/request/SelectApp.js @@ -1,4 +1,5 @@ import React from 'react'; +import { Link } from 'react-router-dom'; import { observer } from 'mobx-react'; import { Modal, Button, Menu, Icon } from 'antd'; import store from './store'; @@ -45,6 +46,7 @@ class SelectApp extends React.Component { render() { const {env_id} = this.state; + const records = appStore.records.filter(x => String(x.env_id) === env_id); return (
{lds.get(envStore.idMap, `${env_id}.name`)}
- {appStore.records.map(item => ( + {records.map(item => ( ))} + {records.length === 0 && +
该环境下还没有可发布的应用哦,快去应用管理创建应用吧。
}
diff --git a/spug_web/src/pages/deploy/request/Table.js b/spug_web/src/pages/deploy/request/Table.js index 40ce1fd..3da5ce9 100644 --- a/spug_web/src/pages/deploy/request/Table.js +++ b/spug_web/src/pages/deploy/request/Table.js @@ -44,7 +44,7 @@ class ComTable extends React.Component { } } else { return - xxx + {info.extra[0]} } } @@ -81,7 +81,7 @@ class ComTable extends React.Component { switch (info.status) { case '-3': return - 发布 + 发布 store.showForm(info)}>编辑 this.handleDelete(info)}>删除 - + ; case '1': return - 发布 + 发布 this.handleDelete(info)}>删除 ; diff --git a/spug_web/src/pages/deploy/request/index.module.css b/spug_web/src/pages/deploy/request/index.module.css index e243228..7bc5463 100644 --- a/spug_web/src/pages/deploy/request/index.module.css +++ b/spug_web/src/pages/deploy/request/index.module.css @@ -27,4 +27,9 @@ height: 60px; font-size: 18px; margin-right: 20px; +} + +.tips { + margin-top: 32px; + color: #888; } \ No newline at end of file diff --git a/spug_web/src/pages/deploy/routes.js b/spug_web/src/pages/deploy/routes.js index 170b799..fec1355 100644 --- a/spug_web/src/pages/deploy/routes.js +++ b/spug_web/src/pages/deploy/routes.js @@ -1,11 +1,13 @@ import { makeRoute } from "../../libs/router"; import app from './app'; import request from './request'; -import doIndex from './do'; +import doExt1Index from './do/Ext1Index'; +import doExt2Index from './do/Ext2Index'; export default [ makeRoute('/app', app), makeRoute('/request', request), - makeRoute('/do/:id', doIndex), + makeRoute('/do/ext1/:id', doExt1Index), + makeRoute('/do/ext2/:id', doExt2Index), ] \ No newline at end of file