A web update

This commit is contained in:
雷二猛 2019-12-19 23:45:52 +08:00
parent 0cd3b99b85
commit e4b7df5ab6
3 changed files with 70 additions and 33 deletions

View File

@ -1,15 +1,19 @@
import React from 'react'; import React from 'react';
import { observer } from 'mobx-react';
import { Steps, Collapse, Icon } from 'antd'; import { Steps, Collapse, Icon } from 'antd';
import http from 'libs/http'; import http from 'libs/http';
import styles from './index.module.css'; import styles from './index.module.css';
import store from './store'; import store from './store';
import lds from 'lodash';
@observer
class Index extends React.Component { class Index extends React.Component {
componentDidMount() { componentDidMount() {
const {id} = this.props.match.params; const {id} = this.props.match.params;
http.post(`/api/deploy/request/${id}/`) http.post(`/api/deploy/request/${id}/`)
.then(token => { .then(({token, outputs, targets}) => {
store.outputs = outputs;
store.targets = targets;
this.socket = new WebSocket(`ws://localhost:8000/ws/exec/${token}/`); this.socket = new WebSocket(`ws://localhost:8000/ws/exec/${token}/`);
this.socket.onopen = () => { this.socket.onopen = () => {
this.socket.send('ok'); this.socket.send('ok');
@ -18,17 +22,13 @@ class Index extends React.Component {
if (e.data === 'pong') { if (e.data === 'pong') {
this.socket.send('ping') this.socket.send('ping')
} else { } else {
console.log(JSON.parse(e.data)); const {key, data, step, status} = JSON.parse(e.data);
// const {key, data, type, status} = JSON.parse(e.data); if (data !== undefined) store.outputs[key]['data'] += data;
// if (status !== undefined) { if (step !== undefined) store.outputs[key]['step'] = step;
// store.outputs[key]['status'] = status if (status !== undefined) store.outputs[key]['status'] = status;
// } else if (data) {
// store.outputs[key][type] += data;
// store.outputs[key]['latest'] = data;
// if (this.elements[key]) { // if (this.elements[key]) {
// this.elements[key].scrollIntoView({behavior: 'smooth'}) // this.elements[key].scrollIntoView({behavior: 'smooth'})
// } // }
// }
} }
} }
}) })
@ -38,32 +38,54 @@ class Index extends React.Component {
if (this.socket) this.socket.close() if (this.socket) this.socket.close()
} }
getStatus = (key, n) => {
const step = lds.get(store.outputs, `${key}.step`, 0);
const isError = lds.get(store.outputs, `${key}.status`) === 'error';
const icon = <Icon type="loading"/>;
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'}
}
};
render() { render() {
return ( return (
<div> <div>
<div style={{fontSize: 16, marginBottom: 10}}>服务端执行 :</div> <div style={{fontSize: 16, marginBottom: 10}}>服务端执行 :</div>
<Collapse defaultActiveKey={1}> <Collapse defaultActiveKey={1} className={styles.collapse}>
<Collapse.Panel showArrow={false} key={1} header={ <Collapse.Panel showArrow={false} key={1} header={
<Steps style={{maxWidth: 800}}> <Steps>
<Steps.Step status="finish" title="检出前任务"/> <Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
<Steps.Step status="finish" title="执行检出"/> <Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
<Steps.Step status="finish" title="检出后任务" icon={<Icon type="loading"/>}/> <Steps.Step {...this.getStatus('local', 2)} title="检出前任务"/>
</Steps> <Steps.Step {...this.getStatus('local', 3)} title="执行检出"/>
}>web -01</Collapse.Panel> <Steps.Step {...this.getStatus('local', 4)} title="检出后任务"/>
</Steps>}>
<pre className={styles.console}>{lds.get(store.outputs, 'local.data')}</pre>
</Collapse.Panel>
</Collapse> </Collapse>
<div style={{fontSize: 16, margin: '30px 0 10px 0'}}>目标主机执行 :</div> <div style={{fontSize: 16, margin: '30px 0 10px 0'}}>目标主机执行 :</div>
<Collapse> <Collapse
<Collapse.Panel key={1} header={ defaultActiveKey={'0'}
className={styles.collapse}
expandIcon={({isActive}) => <Icon type="caret-right" style={{fontSize: 16}} rotate={isActive ? 90 : 0}/>}>
{store.targets.map((item, index) => (
<Collapse.Panel key={index} header={
<div style={{display: 'flex', justifyContent: 'space-between'}}> <div style={{display: 'flex', justifyContent: 'space-between'}}>
<div>web-01</div> <b>{item.title}</b>
<Steps size="small" style={{maxWidth: 500}}> <Steps size="small" style={{maxWidth: 600}}>
<Steps.Step status="finish" title="发布前任务"/> <Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
<Steps.Step status="finish" title="执行发布"/> <Steps.Step {...this.getStatus(item.id, 2)} title="发布前任务"/>
<Steps.Step status="finish" title="发布后任务" icon={<Icon type="loading"/>}/> <Steps.Step {...this.getStatus(item.id, 3)} title="执行发布"/>
<Steps.Step {...this.getStatus(item.id, 4)} title="发布后任务"/>
</Steps> </Steps>
</div> </div>}>
}>web -01</Collapse.Panel> <pre className={styles.console}>{lds.get(store.outputs, `${item.id}.data`)}</pre>
<Collapse.Panel key={2} header="web-02">web -02</Collapse.Panel> </Collapse.Panel>
))}
</Collapse> </Collapse>
</div> </div>
) )

View File

@ -1,3 +1,17 @@
.header { .header {
display: flex; display: flex;
} }
.collapse :global(.ant-collapse-content-box) {
padding: 0;
}
.console {
min-height: 40px;
max-height: 300px;
padding: 10px 15px;
}
pre {
margin: 0;
}

View File

@ -1,7 +1,8 @@
import { observable } from "mobx"; import { observable } from "mobx";
class Store { class Store {
@observable outputs = []; @observable outputs = {};
@observable targets = [];
} }
export default new Store() export default new Store()