mirror of https://github.com/openspug/spug
				
				
				
			fix issue
							parent
							
								
									0dd2ef3df8
								
							
						
					
					
						commit
						083452dd90
					
				| 
						 | 
				
			
			@ -1,182 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
 | 
			
		||||
 * Copyright (c) <spug.dev@gmail.com>
 | 
			
		||||
 * Released under the AGPL-3.0 License.
 | 
			
		||||
 */
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { observer } from 'mobx-react';
 | 
			
		||||
import { CaretRightOutlined, LoadingOutlined, PlayCircleOutlined, SyncOutlined } from '@ant-design/icons';
 | 
			
		||||
import { Steps, Collapse, PageHeader, Spin, Tag, Button } from 'antd';
 | 
			
		||||
import { http, history, X_TOKEN } from 'libs';
 | 
			
		||||
import { AuthDiv } from 'components';
 | 
			
		||||
import OutView from './OutView';
 | 
			
		||||
import styles from './index.module.css';
 | 
			
		||||
import store from './store';
 | 
			
		||||
import lds from 'lodash';
 | 
			
		||||
 | 
			
		||||
@observer
 | 
			
		||||
class Ext1Index extends React.Component {
 | 
			
		||||
  constructor(props) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.timer = null;
 | 
			
		||||
    this.id = props.match.params.id;
 | 
			
		||||
    this.log = props.match.params.log;
 | 
			
		||||
    this.state = {
 | 
			
		||||
      fetching: true,
 | 
			
		||||
      loading: false,
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentDidMount() {
 | 
			
		||||
    this.fetch()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillUnmount() {
 | 
			
		||||
    if (this.socket) this.socket.close();
 | 
			
		||||
    if (this.timer) clearTimeout(this.timer);
 | 
			
		||||
    store.request = {targets: [], host_actions: [], server_actions: []};
 | 
			
		||||
    store.outputs = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fetch = () => {
 | 
			
		||||
    if (!this.timer) this.setState({fetching: true});
 | 
			
		||||
    http.get(`/api/deploy/request/${this.id}/`, {params: {log: this.log}})
 | 
			
		||||
      .then(res => {
 | 
			
		||||
        store.request = res;
 | 
			
		||||
        const outputs = {}
 | 
			
		||||
        while (res.outputs.length) {
 | 
			
		||||
          const msg = JSON.parse(res.outputs.pop());
 | 
			
		||||
          if (!outputs.hasOwnProperty(msg.key)) {
 | 
			
		||||
            const data = msg.key === 'local' ? ['读取数据...        '] : [];
 | 
			
		||||
            outputs[msg.key] = {data}
 | 
			
		||||
          }
 | 
			
		||||
          this._parse_message(msg, outputs)
 | 
			
		||||
        }
 | 
			
		||||
        store.outputs = outputs;
 | 
			
		||||
        if (store.request.status === '2') {
 | 
			
		||||
          this.timer = setTimeout(this.fetch, 2000)
 | 
			
		||||
        } else {
 | 
			
		||||
          this.timer = null
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => this.setState({fetching: false}))
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  _parse_message = (message, outputs) => {
 | 
			
		||||
    outputs = outputs || store.outputs;
 | 
			
		||||
    const {key, data, step, status} = message;
 | 
			
		||||
    if (data !== undefined) {
 | 
			
		||||
      outputs[key]['data'].push(data);
 | 
			
		||||
    }
 | 
			
		||||
    if (step !== undefined) outputs[key]['step'] = step;
 | 
			
		||||
    if (status !== undefined) outputs[key]['status'] = status;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleDeploy = () => {
 | 
			
		||||
    this.setState({loading: true});
 | 
			
		||||
    http.post(`/api/deploy/request/${this.id}/`)
 | 
			
		||||
      .then(({token, outputs}) => {
 | 
			
		||||
        store.request.status = '2';
 | 
			
		||||
        store.outputs = outputs;
 | 
			
		||||
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
 | 
			
		||||
        this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/?x-token=${X_TOKEN}`);
 | 
			
		||||
        this.socket.onopen = () => {
 | 
			
		||||
          this.socket.send('ok');
 | 
			
		||||
        };
 | 
			
		||||
        this.socket.onmessage = e => {
 | 
			
		||||
          if (e.data === 'pong') {
 | 
			
		||||
            this.socket.send('ping')
 | 
			
		||||
          } else {
 | 
			
		||||
            this._parse_message(JSON.parse(e.data))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .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 = <LoadingOutlined />;
 | 
			
		||||
    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 <Tag color="red">发布异常</Tag>
 | 
			
		||||
        } else if (lds.get(store.outputs, `${item.id}.step`, -1) < 5) {
 | 
			
		||||
          return <Tag color="orange">发布中</Tag>
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return <Tag color="green">发布成功</Tag>
 | 
			
		||||
    } else {
 | 
			
		||||
      return <Tag color="blue">{store.request['status_alias'] || '...'}</Tag>
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const {app_name, env_name, status} = store.request;
 | 
			
		||||
    return (
 | 
			
		||||
      <AuthDiv auth="deploy.request.do">
 | 
			
		||||
        <Spin spinning={this.state.fetching}>
 | 
			
		||||
          <PageHeader
 | 
			
		||||
            title="应用发布"
 | 
			
		||||
            subTitle={`${app_name} - ${env_name}`}
 | 
			
		||||
            style={{padding: 0}}
 | 
			
		||||
            tags={this.getStatusAlias()}
 | 
			
		||||
            extra={this.log ? (
 | 
			
		||||
              <Button icon={<SyncOutlined />} type="primary" onClick={this.fetch}>刷新</Button>
 | 
			
		||||
            ) : (
 | 
			
		||||
              <Button icon={<PlayCircleOutlined />} loading={this.state.loading} type="primary"
 | 
			
		||||
                      disabled={!['1', '-3'].includes(status)}
 | 
			
		||||
                      onClick={this.handleDeploy}>发布</Button>
 | 
			
		||||
            )}
 | 
			
		||||
            onBack={() => history.goBack()}/>
 | 
			
		||||
          <Collapse defaultActiveKey={1} className={styles.collapse}>
 | 
			
		||||
            <Collapse.Panel showArrow={false} key={1} header={
 | 
			
		||||
              <Steps>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 2)} title="检出前任务"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 3)} title="执行检出"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 4)} title="检出后任务"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 5)} title="执行打包"/>
 | 
			
		||||
              </Steps>}>
 | 
			
		||||
              <OutView id="local"/>
 | 
			
		||||
            </Collapse.Panel>
 | 
			
		||||
          </Collapse>
 | 
			
		||||
 | 
			
		||||
          <Collapse
 | 
			
		||||
            defaultActiveKey={'0'}
 | 
			
		||||
            className={styles.collapse}
 | 
			
		||||
            expandIcon={({isActive}) => <CaretRightOutlined style={{fontSize: 16}} rotate={isActive ? 90 : 0} />}>
 | 
			
		||||
            {store.request.targets.map((item, index) => (
 | 
			
		||||
              <Collapse.Panel key={index} header={
 | 
			
		||||
                <div style={{display: 'flex', justifyContent: 'space-between'}}>
 | 
			
		||||
                  <b>{item.title}</b>
 | 
			
		||||
                  <Steps size="small" style={{maxWidth: 600}}>
 | 
			
		||||
                    <Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
 | 
			
		||||
                    <Steps.Step {...this.getStatus(item.id, 2)} title="发布前任务"/>
 | 
			
		||||
                    <Steps.Step {...this.getStatus(item.id, 3)} title="执行发布"/>
 | 
			
		||||
                    <Steps.Step {...this.getStatus(item.id, 4)} title="发布后任务"/>
 | 
			
		||||
                  </Steps>
 | 
			
		||||
                </div>}>
 | 
			
		||||
                <OutView id={item.id}/>
 | 
			
		||||
              </Collapse.Panel>
 | 
			
		||||
            ))}
 | 
			
		||||
          </Collapse>
 | 
			
		||||
        </Spin>
 | 
			
		||||
      </AuthDiv>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Ext1Index
 | 
			
		||||
| 
						 | 
				
			
			@ -1,188 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
 | 
			
		||||
 * Copyright (c) <spug.dev@gmail.com>
 | 
			
		||||
 * Released under the AGPL-3.0 License.
 | 
			
		||||
 */
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { observer } from 'mobx-react';
 | 
			
		||||
import { CaretRightOutlined, LoadingOutlined, PlayCircleOutlined, SyncOutlined } from '@ant-design/icons';
 | 
			
		||||
import { Steps, Collapse, PageHeader, Spin, Tag, Button } from 'antd';
 | 
			
		||||
import { http, history, X_TOKEN } from 'libs';
 | 
			
		||||
import { AuthDiv } from 'components';
 | 
			
		||||
import OutView from './OutView';
 | 
			
		||||
import styles from './index.module.css';
 | 
			
		||||
import store from './store';
 | 
			
		||||
import lds from 'lodash';
 | 
			
		||||
 | 
			
		||||
@observer
 | 
			
		||||
class Ext1Index extends React.Component {
 | 
			
		||||
  constructor(props) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.timer = null;
 | 
			
		||||
    this.id = props.match.params.id;
 | 
			
		||||
    this.log = props.match.params.log;
 | 
			
		||||
    this.state = {
 | 
			
		||||
      fetching: true,
 | 
			
		||||
      loading: false,
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentDidMount() {
 | 
			
		||||
    this.fetch()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillUnmount() {
 | 
			
		||||
    if (this.socket) this.socket.close();
 | 
			
		||||
    if (this.timer) clearTimeout(this.timer);
 | 
			
		||||
    store.request = {targets: [], server_actions: [], host_actions: []};
 | 
			
		||||
    store.outputs = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  fetch = () => {
 | 
			
		||||
    if (!this.timer) this.setState({fetching: true});
 | 
			
		||||
    http.get(`/api/deploy/request/${this.id}/`, {params: {log: this.log}})
 | 
			
		||||
      .then(res => {
 | 
			
		||||
        store.request = res;
 | 
			
		||||
        const outputs = {};
 | 
			
		||||
        while (res.outputs.length) {
 | 
			
		||||
          const msg = JSON.parse(res.outputs.pop());
 | 
			
		||||
          if (!outputs.hasOwnProperty(msg.key)) {
 | 
			
		||||
            const data = msg.key === 'local' ? ['读取数据...        '] : [];
 | 
			
		||||
            outputs[msg.key] = {data}
 | 
			
		||||
          }
 | 
			
		||||
          this._parse_message(msg, outputs)
 | 
			
		||||
        }
 | 
			
		||||
        store.outputs = outputs;
 | 
			
		||||
        if (store.request.status === '2') {
 | 
			
		||||
          this.timer = setTimeout(this.fetch, 2000)
 | 
			
		||||
        } else {
 | 
			
		||||
          this.timer = null
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .finally(() => this.setState({fetching: false}))
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  _parse_message = (message, outputs) => {
 | 
			
		||||
    outputs = outputs || store.outputs;
 | 
			
		||||
    const {key, data, step, status} = message;
 | 
			
		||||
    if (data !== undefined) {
 | 
			
		||||
      outputs[key]['data'].push(data);
 | 
			
		||||
    }
 | 
			
		||||
    if (step !== undefined) outputs[key]['step'] = step;
 | 
			
		||||
    if (status !== undefined) outputs[key]['status'] = status;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleDeploy = () => {
 | 
			
		||||
    this.setState({loading: true});
 | 
			
		||||
    http.post(`/api/deploy/request/${this.id}/`)
 | 
			
		||||
      .then(({token, outputs}) => {
 | 
			
		||||
        store.request.status = '2';
 | 
			
		||||
        store.outputs = outputs;
 | 
			
		||||
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
 | 
			
		||||
        this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/?x-token=${X_TOKEN}`);
 | 
			
		||||
        this.socket.onopen = () => {
 | 
			
		||||
          this.socket.send('ok');
 | 
			
		||||
        };
 | 
			
		||||
        this.socket.onmessage = e => {
 | 
			
		||||
          if (e.data === 'pong') {
 | 
			
		||||
            this.socket.send('ping')
 | 
			
		||||
          } else {
 | 
			
		||||
            this._parse_message(JSON.parse(e.data))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .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 = <LoadingOutlined />;
 | 
			
		||||
    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) {
 | 
			
		||||
      const {targets, host_actions} = store.request;
 | 
			
		||||
      for (let item of [{id: 'local'}, ...(host_actions.length > 0 ? targets : [])]) {
 | 
			
		||||
        if (lds.get(store.outputs, `${item.id}.status`) === 'error') {
 | 
			
		||||
          return <Tag color="red">发布异常</Tag>
 | 
			
		||||
        } else if (lds.get(store.outputs, `${item.id}.step`, -1) < 100) {
 | 
			
		||||
          return <Tag color="orange">发布中</Tag>
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return <Tag color="green">发布成功</Tag>
 | 
			
		||||
    } else {
 | 
			
		||||
      return <Tag color="blue">{store.request['status_alias'] || '...'}</Tag>
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const {app_name, env_name, status, server_actions, host_actions} = store.request;
 | 
			
		||||
    return (
 | 
			
		||||
      <AuthDiv auth="deploy.request.do">
 | 
			
		||||
        <Spin spinning={this.state.fetching}>
 | 
			
		||||
          <PageHeader
 | 
			
		||||
            title="应用发布"
 | 
			
		||||
            subTitle={`${app_name} - ${env_name}`}
 | 
			
		||||
            style={{padding: 0}}
 | 
			
		||||
            tags={this.getStatusAlias()}
 | 
			
		||||
            extra={this.log ? (
 | 
			
		||||
              <Button icon={<SyncOutlined />} type="primary" onClick={this.fetch}>刷新</Button>
 | 
			
		||||
            ) : (
 | 
			
		||||
              <Button icon={<PlayCircleOutlined />} loading={this.state.loading} type="primary"
 | 
			
		||||
                      disabled={!['1', '-3'].includes(status)}
 | 
			
		||||
                      onClick={this.handleDeploy}>发布</Button>
 | 
			
		||||
            )}
 | 
			
		||||
            onBack={() => history.goBack()}/>
 | 
			
		||||
          <Collapse defaultActiveKey={1} className={styles.collapse}>
 | 
			
		||||
            <Collapse.Panel showArrow={false} key={1} header={
 | 
			
		||||
              <Steps style={{maxWidth: 400 + server_actions.length * 200}}>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 0)} title="建立连接"/>
 | 
			
		||||
                <Steps.Step {...this.getStatus('local', 1)} title="发布准备"/>
 | 
			
		||||
                {server_actions.map((item, index) => (
 | 
			
		||||
                  <Steps.Step {...this.getStatus('local', 2 + index)} key={index} title={item.title}/>
 | 
			
		||||
                ))}
 | 
			
		||||
              </Steps>}>
 | 
			
		||||
              <OutView id="local"/>
 | 
			
		||||
            </Collapse.Panel>
 | 
			
		||||
          </Collapse>
 | 
			
		||||
 | 
			
		||||
          {host_actions.length > 0 && (
 | 
			
		||||
            <Collapse
 | 
			
		||||
              defaultActiveKey={'0'}
 | 
			
		||||
              className={styles.collapse}
 | 
			
		||||
              expandIcon={({isActive}) => <CaretRightOutlined style={{fontSize: 16}} rotate={isActive ? 90 : 0} />}>
 | 
			
		||||
              {store.request.targets.map((item, index) => (
 | 
			
		||||
                <Collapse.Panel key={index} header={
 | 
			
		||||
                  <div style={{display: 'flex', justifyContent: 'space-between'}}>
 | 
			
		||||
                    <b>{item.title}</b>
 | 
			
		||||
                    <Steps size="small" style={{maxWidth: 150 + host_actions.length * 150}}>
 | 
			
		||||
                      <Steps.Step {...this.getStatus(item.id, 1)} title="数据准备"/>
 | 
			
		||||
                      {host_actions.map((action, index) => (
 | 
			
		||||
                        <Steps.Step {...this.getStatus(item.id, 2 + index)} key={index} title={action.title}/>
 | 
			
		||||
                      ))}
 | 
			
		||||
                    </Steps>
 | 
			
		||||
                  </div>}>
 | 
			
		||||
                  <OutView id={item.id}/>
 | 
			
		||||
                </Collapse.Panel>
 | 
			
		||||
              ))}
 | 
			
		||||
            </Collapse>
 | 
			
		||||
          )}
 | 
			
		||||
          {host_actions.length === 0 && this.state.fetching === false && (
 | 
			
		||||
            <div className={styles.ext2Tips}>无目标主机动作</div>
 | 
			
		||||
          )}
 | 
			
		||||
        </Spin>
 | 
			
		||||
      </AuthDiv>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Ext1Index
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
 | 
			
		||||
 * Copyright (c) <spug.dev@gmail.com>
 | 
			
		||||
 * Released under the AGPL-3.0 License.
 | 
			
		||||
 */
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { toJS } from 'mobx';
 | 
			
		||||
import { observer } from 'mobx-react';
 | 
			
		||||
import styles from './index.module.css';
 | 
			
		||||
import store from './store';
 | 
			
		||||
import lds from 'lodash';
 | 
			
		||||
 | 
			
		||||
@observer
 | 
			
		||||
class OutView extends React.Component {
 | 
			
		||||
  constructor(props) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.el = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentDidUpdate(prevProps, prevState, snapshot) {
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      if (this.el) this.el.scrollTop = this.el.scrollHeight
 | 
			
		||||
    }, 100)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const outputs = lds.get(store.outputs, `${this.props.id}.data`, []);
 | 
			
		||||
    return (
 | 
			
		||||
      <pre ref={el => this.el = el} className={styles.ext1Console}>
 | 
			
		||||
        {toJS(outputs)}
 | 
			
		||||
      </pre>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default OutView
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
.header {
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapse {
 | 
			
		||||
    margin-top: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapse :global(.ant-collapse-content-box) {
 | 
			
		||||
    padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ext2Tips {
 | 
			
		||||
    color: #888;
 | 
			
		||||
    margin-top: 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pre {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,17 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
 | 
			
		||||
 * Copyright (c) <spug.dev@gmail.com>
 | 
			
		||||
 * Released under the AGPL-3.0 License.
 | 
			
		||||
 */
 | 
			
		||||
import { observable } from "mobx";
 | 
			
		||||
 | 
			
		||||
class Store {
 | 
			
		||||
  @observable outputs = {};
 | 
			
		||||
  @observable request = {
 | 
			
		||||
    targets: [],
 | 
			
		||||
    host_actions: [],
 | 
			
		||||
    server_actions: []
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new Store()
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +25,6 @@ import ExecTemplate from './pages/exec/template';
 | 
			
		|||
import DeployApp from './pages/deploy/app';
 | 
			
		||||
import DeployRepository from './pages/deploy/repository';
 | 
			
		||||
import DeployRequest from './pages/deploy/request';
 | 
			
		||||
import DoExt1Index from './pages/deploy/do/Ext1Index';
 | 
			
		||||
import DoExt2Index from './pages/deploy/do/Ext2Index';
 | 
			
		||||
import ScheduleIndex from './pages/schedule';
 | 
			
		||||
import ConfigEnvironment from './pages/config/environment';
 | 
			
		||||
import ConfigService from './pages/config/service';
 | 
			
		||||
| 
						 | 
				
			
			@ -63,10 +61,6 @@ export default [
 | 
			
		|||
      {title: '应用管理', auth: 'deploy.app.view', path: '/deploy/app', component: DeployApp},
 | 
			
		||||
      {title: '构建仓库', auth: 'deploy.repository.view', path: '/deploy/repository', component: DeployRepository},
 | 
			
		||||
      {title: '发布申请', auth: 'deploy.request.view', path: '/deploy/request', component: DeployRequest},
 | 
			
		||||
      {path: '/deploy/do/ext1/:id', component: DoExt1Index},
 | 
			
		||||
      {path: '/deploy/do/ext2/:id', component: DoExt2Index},
 | 
			
		||||
      {path: '/deploy/do/ext1/:id/:log', component: DoExt1Index},
 | 
			
		||||
      {path: '/deploy/do/ext2/:id/:log', component: DoExt2Index},
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue