From dd06dfe5fcacf180f0ee2fa057c74254036d6ce4 Mon Sep 17 00:00:00 2001 From: suxiaoxin Date: Wed, 16 Aug 2017 18:04:16 +0800 Subject: [PATCH] feat: add interface and col route --- .../containers/Project/Interface/Interface.js | 44 ++++++--- .../InterfaceList/InterfaceContent.js | 93 ++++++++++++++++--- .../Interface/InterfaceList/InterfaceMenu.js | 36 ++++--- .../Project/Interface/interface.scss | 3 + client/containers/Project/Project.js | 4 +- .../reducer/middleware/messageMiddleware.js | 1 + client/reducer/modules/interface.js | 29 ++---- 7 files changed, 139 insertions(+), 71 deletions(-) diff --git a/client/containers/Project/Interface/Interface.js b/client/containers/Project/Interface/Interface.js index f6c4b114..a8a3a193 100644 --- a/client/containers/Project/Interface/Interface.js +++ b/client/containers/Project/Interface/Interface.js @@ -1,6 +1,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { Row, Col, Tabs } from 'antd'; +import { Route } from 'react-router-dom'; + import './interface.scss' import InterfaceMenu from './InterfaceList/InterfaceMenu.js' @@ -9,37 +11,50 @@ import InterfaceContent from './InterfaceList/InterfaceContent.js' import InterfaceColMenu from './InterfaceCol/InterfaceColMenu.js' import InterfaceColContent from './InterfaceCol/InterfaceColContent.js' +class InterfaceRoute extends Component { + static propTypes = { + match: PropTypes.object + } + constructor(props){ + super(props) + } + render() { + let C, props = this.props; + if (props.match.params.action === 'api') { + C = InterfaceContent; + } else if (props.match.params.action === 'col') { + C = InterfaceColContent; + } + return + } +} + + class Interface extends Component { static propTypes = { match: PropTypes.object } constructor(props) { - super(props) + super(props) this.state = { - contentView: 'list' + curkey: this.props.match.params.action } } - handleTab = (key) => { + onChange = (key)=>{ this.setState({ - contentView: key + curkey: key }) } render() { - const {contentView} = this.state; - let content; - content = contentView === 'list' ? - - : - return
- - + + @@ -48,10 +63,11 @@ class Interface extends Component {
+
- {content} +
@@ -59,4 +75,6 @@ class Interface extends Component { } } + + export default Interface \ No newline at end of file diff --git a/client/containers/Project/Interface/InterfaceList/InterfaceContent.js b/client/containers/Project/Interface/InterfaceList/InterfaceContent.js index bb9cb3b8..2eb414af 100644 --- a/client/containers/Project/Interface/InterfaceList/InterfaceContent.js +++ b/client/containers/Project/Interface/InterfaceList/InterfaceContent.js @@ -1,25 +1,92 @@ -import React from 'react' +import React, { Component } from 'react' +import { connect } from 'react-redux'; +import PropTypes from 'prop-types' import { Tabs } from 'antd'; import Edit from './Edit.js' import View from './View.js' import Run from './Run.js' +import { fetchInterfaceData } from '../../../../reducer/modules/interface.js'; +import { withRouter } from 'react-router-dom'; const TabPane = Tabs.TabPane; +@connect( + state => { + return { + curdata: state.inter.curdata, + list: state.inter.list + } + }, + { + fetchInterfaceData + } +) +class Content extends Component { + static propTypes = { + match: PropTypes.object, + list: PropTypes.array, + curdata: PropTypes.object, + fetchInterfaceData: PropTypes.func + } + constructor(props) { + super(props) + this.state = { + curtab: 'view' + } + this._actionId = 0; + } -const Content = () => { - return
- - - + componentWillReceiveProps(nextProps){ + this.handleRequest(nextProps) + } + + handleRequest(nextProps){ + let matchParams = nextProps.match.params; + let _actionId; + _actionId = matchParams.actionId; + _actionId = parseInt(matchParams.actionId, 10); + if(!nextProps.curdata)return; + if(this._actionId !== _actionId){ + this._actionId = _actionId; + this.props.fetchInterfaceData(_actionId) + } + this.setState({ + curtab: 'view' + }) + } + + onChange = (key)=>{ + this.setState({ + curtab: key + }) + } + + render() { + const tabs = + + {/* */} - - + + - - + + {/* */} - -
+ ; + let tabContent; + if (this.state.curtab === 'view') { + tabContent = ; + } else if (this.state.curtab === 'edit') { + tabContent = + } else if (this.state.curtab === 'run') { + tabContent = + } + + return
+ {tabs} + {tabContent} +
+ } } -export default Content \ No newline at end of file + +export default withRouter(Content) \ No newline at end of file diff --git a/client/containers/Project/Interface/InterfaceList/InterfaceMenu.js b/client/containers/Project/Interface/InterfaceList/InterfaceMenu.js index d1926bee..aaca6ccd 100644 --- a/client/containers/Project/Interface/InterfaceList/InterfaceMenu.js +++ b/client/containers/Project/Interface/InterfaceList/InterfaceMenu.js @@ -1,10 +1,11 @@ import React, { Component } from 'react' import { connect } from 'react-redux'; import PropTypes from 'prop-types' -import { fetchInterfaceList, fetchInterfaceData, changeInterfaceId, addInterfaceData, deleteInterfaceData } from '../../../../reducer/modules/interface.js'; +import { fetchInterfaceList, fetchInterfaceData, addInterfaceData, deleteInterfaceData } from '../../../../reducer/modules/interface.js'; import { Menu, Input, Icon, Tag, Modal, message } from 'antd'; import AddInterfaceForm from './AddInterfaceForm'; import axios from 'axios' +import { Link,withRouter } from 'react-router-dom'; const confirm = Modal.confirm; @@ -14,29 +15,27 @@ const confirm = Modal.confirm; state => { return { list: state.inter.list, - curProject: state.project.curProject, - interfaceId: state.inter.interfaceId + curProject: state.project.curProject } }, { fetchInterfaceList, fetchInterfaceData, - changeInterfaceId, addInterfaceData, deleteInterfaceData } ) class InterfaceMenu extends Component { static propTypes = { + match: PropTypes.object, projectId: PropTypes.string, - interfaceId: PropTypes.number, list: PropTypes.array, fetchInterfaceList: PropTypes.func, curProject: PropTypes.object, fetchInterfaceData: PropTypes.func, - changeInterfaceId: PropTypes.func, addInterfaceData: PropTypes.func, - deleteInterfaceData: PropTypes.func + deleteInterfaceData: PropTypes.func, + history: PropTypes.object } showModal = () => { @@ -59,26 +58,21 @@ class InterfaceMenu extends Component { delIcon: null, filter: '' } + } async handleRequest() { let result = await this.props.fetchInterfaceList(this.props.projectId); - let interfaces = result.payload.data; - if (interfaces.length > 0) { - this.props.changeInterfaceId(interfaces[0]._id) - await this.props.fetchInterfaceData(interfaces[0]._id) + let params = this.props.match.params; + if(!params.actionId){ + this.props.history.replace('/project/'+params.id + '/interface/api/' + result.payload.data[0]._id) } } componentWillMount() { this.handleRequest() } - - onSelect = (item) => { - this.props.changeInterfaceId(parseInt(item.key, 10)) - this.props.fetchInterfaceData(parseInt(item.key, 10)) - } - + handleAddInterface = (data) => { data.project_id = this.props.projectId; axios.post('/api/interface/add', data).then((res) => { @@ -127,6 +121,7 @@ class InterfaceMenu extends Component { render() { const items = []; + const matchParams = this.props.match.params; this.props.list.forEach((item) => { let color, filter = this.state.filter; if(filter && item.title.indexOf(filter) === -1 && item.path.indexOf(filter) === -1){ @@ -141,9 +136,10 @@ class InterfaceMenu extends Component { } items.push( + {item.method} - {item.title} + {item.title} {this.showConfirm(item._id)}} style={{ display: this.state.delIcon == item._id ? 'block' : 'none' }} className="interface-delete-icon" /> ) @@ -163,7 +159,7 @@ class InterfaceMenu extends Component {
- + {items} @@ -171,4 +167,4 @@ class InterfaceMenu extends Component { } } -export default InterfaceMenu \ No newline at end of file +export default withRouter(InterfaceMenu) \ No newline at end of file diff --git a/client/containers/Project/Interface/interface.scss b/client/containers/Project/Interface/interface.scss index 760e4052..ebe76ec3 100644 --- a/client/containers/Project/Interface/interface.scss +++ b/client/containers/Project/Interface/interface.scss @@ -45,6 +45,9 @@ padding: 0 5px; width: 40px; } + .interface-item{ + display: inline + } .interface-delete-icon{ position: absolute; diff --git a/client/containers/Project/Project.js b/client/containers/Project/Project.js index 67ae1ffc..dc7903c9 100644 --- a/client/containers/Project/Project.js +++ b/client/containers/Project/Project.js @@ -43,7 +43,7 @@ export default class Project extends Component { default={'动态'} data={[{ name: '接口', - path: `/project/${match.params.id}/interface` + path: `/project/${match.params.id}/interface/api` }, { name: '设置', path: `/project/${match.params.id}/setting` @@ -54,7 +54,7 @@ export default class Project extends Component { - + diff --git a/client/reducer/middleware/messageMiddleware.js b/client/reducer/middleware/messageMiddleware.js index 5c16bde7..f2ce0cf0 100644 --- a/client/reducer/middleware/messageMiddleware.js +++ b/client/reducer/middleware/messageMiddleware.js @@ -1,6 +1,7 @@ import { message } from 'antd'; export default () => next => action => { + if(!action) return; if (action.error) { message.error((action.payload && action.payload.message) || '服务器错误'); } else if (action.payload && action.payload.data && action.payload.data.errcode && action.payload.data.errcode !== 40011) { diff --git a/client/reducer/modules/interface.js b/client/reducer/modules/interface.js index 1aa3c799..fec2591a 100644 --- a/client/reducer/modules/interface.js +++ b/client/reducer/modules/interface.js @@ -2,7 +2,6 @@ import axios from 'axios' // Actions const FETCH_INTERFACE_DATA = 'yapi/interface/FETCH_INTERFACE_DATA'; const FETCH_INTERFACE_LIST = 'yapi/interface/FETCH_INTERFACE_LIST'; -const CHANGE_INTERFACE_ID = 'yapi/interface/CHANGE_INTERFACE_ID'; const ADD_INTERFACE_DATA = 'yapi/interface/ADD_INTERFACE_DATA'; const DELETE_INTERFACE_DATA = 'yapi/interface/DELETE_INTERFACE_DATA'; const UPDATE_INTERFACE_DATA = 'yapi/interface/UPDATE_INTERFACE_DATA'; @@ -11,7 +10,6 @@ const UPDATE_INTERFACE_DATA = 'yapi/interface/UPDATE_INTERFACE_DATA'; // Reducer const initialState = { - interfaceId: 0, curdata: {}, list: [] } @@ -26,20 +24,17 @@ export default (state = initialState, action) => { case DELETE_INTERFACE_DATA: return (() => { - let newlist = state.list.filter(data => data._id !== action.payload), newid, curdata; + let newlist = state.list.filter(data => data._id !== action.payload), curdata; - if (state.interfaceId === action.payload && state.list.length > 0) { - newid = state.list[0]._id + if (state.list.length > 0) { curdata = state.list[0] } else if (state.list.length == 0) { - newid = 0; curdata = {} } return { ...state, curdata: curdata, - interfaceId: newid, list: newlist } })() @@ -48,13 +43,7 @@ export default (state = initialState, action) => { return { ...state, curdata: action.payload, - list: [].concat(state.list, action.payload), - interfaceId: action.payload._id - } - case CHANGE_INTERFACE_ID: - return { - ...state, - interfaceId: action.payload + list: [].concat(state.list, action.payload) } case FETCH_INTERFACE_DATA: return { @@ -65,20 +54,13 @@ export default (state = initialState, action) => { return { ...state, list: action.payload.data, - curdata: action.payload.data.length > 0 ? action.payload.data[0] : {} + curdata: {} } default: return state } } -export function changeInterfaceId(id) { - return { - type: CHANGE_INTERFACE_ID, - payload: id - } -} - export function updateInterfaceData(updata) { return { @@ -94,13 +76,14 @@ export async function deleteInterfaceData(id) { await axios.post('/api/interface/del', { id: id }) return { type: DELETE_INTERFACE_DATA, - payload: id + payload: true } } // Action Creators export async function fetchInterfaceData(interfaceId) { let result = await axios.get('/api/interface/get?id=' + interfaceId); + return { type: FETCH_INTERFACE_DATA, payload: result.data