postman export V2 & request body huge update!!!

pull/71/head
Bosn 7 years ago
parent 64b5da7c93
commit e1d97c8d5d

@ -22,36 +22,38 @@
"author": "mozhi.gyy@alibaba-inc.com", "author": "mozhi.gyy@alibaba-inc.com",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"animate.css": "3.5.2", "animate.css": "3.6.1",
"bootstrap": "^4.1.1", "bootstrap": "^4.1.1",
"chart.js": "^2.6.0", "chart.js": "^2.6.0",
"codemirror": "5.27.2", "codemirror": "5.39.0",
"graceful": "1.0.1", "graceful": "1.0.1",
"koa": "2.3.0", "jquery": "^3.3.1",
"koa-router": "7.2.1", "koa": "2.5.1",
"koa-session": "5.3.0", "koa-router": "7.4.0",
"koa-static": "3.0.0", "koa-session": "5.8.1",
"lodash": "4.17.4", "koa-static": "5.0.0",
"lodash": "4.17.10",
"mockjs": "1.0.1-beta3", "mockjs": "1.0.1-beta3",
"moment": "2.22.1", "moment": "2.22.2",
"node-fetch": "1.7.1", "node-fetch": "2.1.2",
"normalizr": "^3.2.4", "normalizr": "^3.2.4",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"parsleyjs": "^2.7.2", "parsleyjs": "^2.7.2",
"prop-types": "15.5.10", "popper.js": "^1.14.3",
"react": "15.6.1", "prop-types": "15.6.2",
"react-dom": "15.6.1", "react": "16.4.1",
"react-icons": "2.2.5", "react-dom": "16.4.1",
"react-modal": "2.1.0", "react-icons": "2.2.7",
"react-redux": "5.0.5", "react-modal": "3.4.5",
"react-router": "4.1.1", "react-redux": "5.0.7",
"react-router-config": "1.0.0-beta.3", "react-router": "4.3.1",
"react-router-dom": "4.1.1", "react-router-config": "1.0.0-beta.4",
"react-router-dom": "4.3.1",
"react-router-redux": "5.0.0-alpha.6", "react-router-redux": "5.0.0-alpha.6",
"redux": "3.7.1", "redux": "4.0.0",
"redux-saga": "0.15.4", "redux-saga": "0.16.0",
"sortablejs": "1.6.0", "sortablejs": "1.7.0",
"urijs": "1.18.10" "urijs": "1.19.1"
}, },
"standard": { "standard": {
"parser": "babel-eslint", "parser": "babel-eslint",
@ -63,10 +65,10 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "7.2.3", "babel-eslint": "8.2.5",
"node-sass": "4.5.3", "node-sass": "4.9.0",
"npm-run-all": "4.0.2", "npm-run-all": "4.1.3",
"react-scripts": "0.9.5", "react-scripts": "1.1.4",
"standard": "10.0.2" "standard": "11.0.1"
} }
} }

@ -6,7 +6,7 @@ export const updateProperty = (property, onResolved) => ({ type: 'PROPERTY_UPDAT
export const updatePropertySucceeded = (property) => ({ type: 'PROPERTY_UPDATE_SUCCEEDED', property }) export const updatePropertySucceeded = (property) => ({ type: 'PROPERTY_UPDATE_SUCCEEDED', property })
export const updatePropertyFailed = (message) => ({ type: 'PROPERTY_UPDATE_FAILED', message }) export const updatePropertyFailed = (message) => ({ type: 'PROPERTY_UPDATE_FAILED', message })
export const updateProperties = (itf, properties, onResolved) => ({ type: 'PROPERTIES_UPDATE', itf, properties, onResolved }) export const updateProperties = (itf, properties, summary, onResolved) => ({ type: 'PROPERTIES_UPDATE', itf, properties, summary, onResolved })
export const updatePropertiesSucceeded = (properties) => ({ type: 'PROPERTIES_UPDATE_SUCCEEDED', properties }) export const updatePropertiesSucceeded = (properties) => ({ type: 'PROPERTIES_UPDATE_SUCCEEDED', properties })
export const updatePropertiesFailed = (message) => ({ type: 'PROPERTIES_UPDATE_FAILED', message }) export const updatePropertiesFailed = (message) => ({ type: 'PROPERTIES_UPDATE_FAILED', message })

@ -1,12 +1,12 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { PropTypes, connect, replace, StoreStateRouterLocationURI, _ } from '../../family' import { PropTypes, connect, replace, StoreStateRouterLocationURI, _ } from '../../family'
import InterfaceEditorToolbar from './InterfaceEditorToolbar' import InterfaceEditorToolbar from './InterfaceEditorToolbar'
import InterfaceSummary from './InterfaceSummary' import InterfaceSummary, { BODY_OPTION, REQUEST_PARAMS_TYPE, rptFromStr2Num } from './InterfaceSummary'
import PropertyList from './PropertyList' import PropertyList from './PropertyList'
export const RequestPropertyList = (props) => ( export const RequestPropertyList = (props) => {
<PropertyList scope='request' title='请求参数' label='请求' {...props} /> return <PropertyList scope='request' title='请求参数' label='请求' {...props} />
) }
export const ResponsePropertyList = (props) => ( export const ResponsePropertyList = (props) => (
<PropertyList scope='response' title='响应内容' label='响应' {...props} /> <PropertyList scope='response' title='响应内容' label='响应' {...props} />
) )
@ -36,53 +36,65 @@ class InterfaceEditor extends Component {
handleDeleteMemoryProperty: PropTypes.func.isRequired, handleDeleteMemoryProperty: PropTypes.func.isRequired,
handleChangeProperty: PropTypes.func.isRequired handleChangeProperty: PropTypes.func.isRequired
} }
constructor (props) {
super(props)
this.state = {
...InterfaceEditor.mapPropsToState(props),
summaryState: {
bodyOption: BODY_OPTION.FORM_DATA,
requestParamsType: REQUEST_PARAMS_TYPE.QUERY_PARAMS
}
}
this.summaryStateChange = this.summaryStateChange.bind(this)
// { itf: {}, properties: [] }
}
getChildContext () { getChildContext () {
return _.pick(this, Object.keys(InterfaceEditor.childContextTypes)) return _.pick(this, Object.keys(InterfaceEditor.childContextTypes))
// return { }
// handleLockInterface: this.handleLockInterface, static mapPropsToState (prevProps, prevStates) {
// handleUnlockInterface: this.handleUnlockInterface, let { auth, itf, properties } = prevProps
// handleSaveInterface: this.handleSaveInterface,
// handleAddMemoryProperty: this.handleAddMemoryProperty,
// handleAddMemoryProperties: this.handleAddMemoryProperties,
// handleDeleteMemoryProperty: this.handleDeleteMemoryProperty,
// handleChangeProperty: this.handleChangeProperty
// }
}
static mapPropsToState (props) {
let { auth, itf, properties } = props
return { return {
itf: { ...itf }, ...prevStates,
itf,
properties: properties.map(property => ({ ...property })), properties: properties.map(property => ({ ...property })),
editable: !!(itf.locker && (itf.locker.id === auth.id)) editable: !!(itf.locker && (itf.locker.id === auth.id))
} }
} }
componentDidMount () { } componentDidMount () { }
summaryStateChange (summaryState) {
this.setState({ summaryState })
}
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if ( if (
nextProps.itf.id === this.state.itf.id && nextProps.itf.id === this.state.itf.id &&
nextProps.itf.updatedAt === this.state.itf.updatedAt nextProps.itf.updatedAt === this.state.itf.updatedAt
) return ) return
this.setState(InterfaceEditor.mapPropsToState(nextProps)) const prevStates = this.state
this.setState(InterfaceEditor.mapPropsToState(nextProps, prevStates))
} }
// Use shouldComponentUpdate() to let React know if a component's output is not affected by the current change in state or props. // Use shouldComponentUpdate() to let React know if a component's output is not affected by the current change in state or props.
// TODO 2.2 // TODO 2.2
// shouldComponentUpdate (nextProps, nextState) {} // shouldComponentUpdate (nextProps, nextState) {}
constructor (props) {
super(props)
this.state = InterfaceEditor.mapPropsToState(props)
// { itf: {}, properties: [] }
}
render () { render () {
let { auth, repository, mod, itf } = this.props const { auth, repository, mod, itf } = this.props
let { id, locker } = this.state.itf const { editable } = this.state
const { id, locker } = this.state.itf
if (!id) return null if (!id) return null
return ( return (
<article className='InterfaceEditor'> <article className='InterfaceEditor'>
<InterfaceEditorToolbar locker={locker} auth={auth} repository={repository} editable={this.state.editable} /> <InterfaceEditorToolbar locker={locker} auth={auth} repository={repository} editable={editable} />
<InterfaceSummary repository={repository} mod={mod} itf={itf} active /> <InterfaceSummary repository={repository} mod={mod} itf={itf} active editable={editable} stateChangeHandler={this.summaryStateChange} />
<RequestPropertyList properties={this.state.properties} editable={this.state.editable} <RequestPropertyList
repository={repository} mod={mod} itf={this.state.itf} /> properties={this.state.properties}
<ResponsePropertyList properties={this.state.properties} editable={this.state.editable} editable={editable}
repository={repository}
mod={mod}
itf={this.state.itf}
bodyOption={this.state.summaryState.bodyOption}
requestParamsType={this.state.summaryState.requestParamsType}
/>
<ResponsePropertyList properties={this.state.properties} editable={editable}
repository={repository} mod={mod} itf={this.state.itf} /> repository={repository} mod={mod} itf={this.state.itf} />
</article> </article>
) )
@ -91,9 +103,13 @@ class InterfaceEditor extends Component {
this.handleAddMemoryProperties([property], cb) this.handleAddMemoryProperties([property], cb)
} }
handleAddMemoryProperties = (properties, cb) => { handleAddMemoryProperties = (properties, cb) => {
const requestParamsType = this.state.summaryState.requestParamsType
const rpt = rptFromStr2Num(requestParamsType)
properties.forEach(item => { properties.forEach(item => {
if (item.memory === undefined) item.memory = true if (item.memory === undefined) item.memory = true
if (item.id === undefined) item.id = _.uniqueId('memory-') if (item.id === undefined) item.id = _.uniqueId('memory-')
item.pos = rpt
}) })
let nextState = { properties: [...this.state.properties, ...properties] } let nextState = { properties: [...this.state.properties, ...properties] }
this.setState(nextState, () => { this.setState(nextState, () => {
@ -131,8 +147,8 @@ class InterfaceEditor extends Component {
} }
handleSaveInterface = (e) => { handleSaveInterface = (e) => {
e.preventDefault() e.preventDefault()
let { onUpdateProperties } = this.context const { onUpdateProperties } = this.context
onUpdateProperties(this.state.itf.id, this.state.properties, () => { onUpdateProperties(this.state.itf.id, this.state.properties, this.state.summaryState, () => {
this.handleUnlockInterface() this.handleUnlockInterface()
}) })
} }

@ -2,7 +2,7 @@ import React, { Component } from 'react'
import { PropTypes, connect, Link, Mock } from '../../family' import { PropTypes, connect, Link, Mock } from '../../family'
import { SmartTextarea } from '../utils' import { SmartTextarea } from '../utils'
export const METHODS = ['GET', 'POST', 'PUT', 'DELETE'] export const METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH', 'HEAD']
// //
const mockInterface = process.env.NODE_ENV === 'development' const mockInterface = process.env.NODE_ENV === 'development'

@ -2,10 +2,49 @@ import React, { Component } from 'react'
import { PropTypes, Link, replace, StoreStateRouterLocationURI } from '../../family' import { PropTypes, Link, replace, StoreStateRouterLocationURI } from '../../family'
import { DialogController } from '../utils' import { DialogController } from '../utils'
import { serve } from '../../relatives/services/constant' import { serve } from '../../relatives/services/constant'
import InterfaceForm from './InterfaceForm' import InterfaceForm, { METHODS } from './InterfaceForm'
import { getRelativeUrl } from '../../utils/URLUtils' import { getRelativeUrl } from '../../utils/URLUtils'
import './InterfaceSummary.css'
export const BODY_OPTION = {
FORM_DATA: 'FORM_DATA',
FORM_URLENCODED: 'FORM_URLENCODED',
RAW: 'RAW',
BINARY: 'BINARY'
}
export const REQUEST_PARAMS_TYPE = {
HEADERS: 'HEADERS',
QUERY_PARAMS: 'QUERY_PARAMS',
BODY_PARAMS: 'BODY_PARAMS'
}
export function rptFromStr2Num (rpt) {
let pos = 2
if (rpt === 'HEADERS') {
pos = 1
} else if (rpt === 'BODY_PARAMS') {
pos = 3
}
return pos
}
class InterfaceSummary extends Component { class InterfaceSummary extends Component {
constructor (props) {
super(props)
this.state = {
name: props.itf.name,
method: props.itf.method,
url: props.itf.url,
description: props.itf.description,
bodyOption: BODY_OPTION.FORM_DATA,
requestParamsType: props.method === 'POST' ? REQUEST_PARAMS_TYPE.BODY_PARAMS : REQUEST_PARAMS_TYPE.QUERY_PARAMS
}
this.changeMethod = this.changeMethod.bind(this)
this.changeHandler = this.changeHandler.bind(this)
this.switchBodyOptions = this.switchBodyOption.bind(this)
this.switchRequestParamsType = this.switchRequestParamsType.bind(this)
}
static contextTypes = { static contextTypes = {
store: PropTypes.object.isRequired, store: PropTypes.object.isRequired,
onDeleteInterface: PropTypes.func.isRequired onDeleteInterface: PropTypes.func.isRequired
@ -14,17 +53,50 @@ class InterfaceSummary extends Component {
repository: PropTypes.object.isRequired, repository: PropTypes.object.isRequired,
mod: PropTypes.object.isRequired, mod: PropTypes.object.isRequired,
itf: PropTypes.object.isRequired, itf: PropTypes.object.isRequired,
active: PropTypes.bool.isRequired active: PropTypes.bool.isRequired,
editable: PropTypes.bool.isRequired,
stateChangeHandler: PropTypes.func.isRequired
}
componentDidUpdate () {
}
switchBodyOption (val) {
return () => {
this.setState({
bodyOption: val
}, () => {
this.props.stateChangeHandler(this.state)
})
}
}
switchRequestParamsType (val) {
return () => {
this.setState({
requestParamsType: val
}, () => {
this.props.stateChangeHandler(this.state)
})
} }
}
changeMethod (method) {
this.setState({ method })
}
changeHandler (e) {
this.setState({
[e.target.name]: e.target.value
})
}
render () { render () {
let { repository = {}, mod = {}, itf = {} } = this.props const { repository = {}, mod = {}, itf = {}, editable } = this.props
const { method, name, url, description, bodyOption, requestParamsType } = this.state
if (!itf.id) return null if (!itf.id) return null
return (
return !editable ? (
<div className='InterfaceSummary'> <div className='InterfaceSummary'>
<div className='header'> <div className='header'>
<span className='title'> <span className='title'>
{mod.name}
<span className='slash'> / </span>
{itf.name} {itf.name}
</span> </span>
{/* TODO 2.2 √模板接口、√数据接口、JSONSchema 接口 */} {/* TODO 2.2 √模板接口、√数据接口、JSONSchema 接口 */}
@ -42,13 +114,104 @@ class InterfaceSummary extends Component {
<span className='label'>地址</span> <span className='label'>地址</span>
<Link to={`${serve}/app/mock/${repository.id}${getRelativeUrl(itf.url)}`} target='_blank'>{itf.url}</Link> <Link to={`${serve}/app/mock/${repository.id}${getRelativeUrl(itf.url)}`} target='_blank'>{itf.url}</Link>
</li> </li>
<li><span className='label'>类型</span>{itf.method}</li> <li><span className='label'>类型</span>
{itf.method}
</li>
{itf.description && {itf.description &&
<li><span className='label'>简介</span>{itf.description}</li> <li><span className='label'>简介</span>{itf.description}</li>
} }
</ul> </ul>
</div> </div>
) )
: (
<div className='InterfaceSummary'>
<div className='head'>
<div className='form-group row'>
<label className='col-sm-1 col-form-label'>接口名</label>
<div className='col-sm-10'>
<input type='text' className='form-control' name='name' value={name || ''} onChange={this.changeHandler} />
</div>
</div>
{/* TODO 2.2 √模板接口、√数据接口、JSONSchema 接口 */}
{/* TODO 2.2 权限控制,被别人锁定时不能编辑和删除 */}
{/* TODO 2.2 这里的接口编辑和右侧的编辑容易引起歧义,很难受 */}
<span className='hide'>
<DialogController content={<InterfaceForm title='修改接口' repository={repository} mod={mod} itf={itf} />} onResolved={this.handleUpdate}>
<Link to='' onClick={e => e.preventDefault()} title='修改接口' className='edit'>编辑</Link>
</DialogController>
<Link to='' onClick={e => this.handleDelete(e, itf)} className='delete'>删除</Link>
</span>
</div>
<div className='body'>
<div className='form-group row'>
<label className='col-sm-1 col-form-label'>地址</label>
<div className='col-sm-10'>
<input type='text' className='form-control' name='url' value={url || ''} onChange={this.changeHandler} />
</div>
</div>
<div className='form-group row'>
<label className='col-sm-1 col-form-label'>类型</label>
<div className='dropdown col-sm-10'>
<button
className='btn btn-secondary dropdown-toggle'
style={{ width: 160, display: 'block' }}
type='button'
id='btnDropdownMethods'
data-toggle='dropdown'
aria-haspopup='true'
aria-expanded='false'
>
{method}
</button>
<div className='dropdown-menu' aria-labelledby='btnDropdownMethods'>
{METHODS.map(method =>
<button className='dropdown-item' key={method} onClick={() => { this.changeMethod(method); return false }}>{method}</button>
)}
</div>
</div>
</div>
<div className='form-group row'>
<label className='col-sm-1 col-form-label'>简介</label>
<div className='col-sm-10'>
<textarea className='form-control' name='description' onChange={this.changeHandler} value={description || ''} />
</div>
</div>
<ul className='nav nav-tabs' role='tablist'>
<li className='nav-item' onClick={this.switchRequestParamsType(REQUEST_PARAMS_TYPE.HEADERS)}>
<a className={`nav-link ${requestParamsType === REQUEST_PARAMS_TYPE.HEADERS ? 'active' : ''}`} href='#' role='tab' data-toggle='tab'>headers</a>
</li>
<li className='nav-item' onClick={this.switchRequestParamsType(REQUEST_PARAMS_TYPE.QUERY_PARAMS)}>
<a className={`nav-link ${requestParamsType === REQUEST_PARAMS_TYPE.QUERY_PARAMS ? 'active' : ''}`} href='#' role='tab' data-toggle='tab'>Query Params</a>
</li>
<li className='nav-item' onClick={this.switchRequestParamsType(REQUEST_PARAMS_TYPE.BODY_PARAMS)}>
<a className={`nav-link ${requestParamsType === REQUEST_PARAMS_TYPE.BODY_PARAMS ? 'active' : ''}`} href='#' role='tab' data-toggle='tab'>Body Params</a>
</li>
</ul>
</div>
{requestParamsType === REQUEST_PARAMS_TYPE.BODY_PARAMS
? <div className='body-options'>
<div className='form-check form-check-inline' onClick={this.switchBodyOption(BODY_OPTION.FORM_DATA)}>
<input className='form-check-input' type='radio' name='inlineRadioOptions' id='inlineRadio1' value='option1' />
<label className='form-check-label' htmlFor='inlineRadio1'>form-data</label>
</div>
<div className='form-check form-check-inline' onClick={this.switchBodyOption(BODY_OPTION.FORM_URLENCODED)}>
<input className='form-check-input' type='radio' name='inlineRadioOptions' id='inlineRadio2' value='option2' />
<label className='form-check-label' htmlFor='inlineRadio2'>x-www-form-urlencoded</label>
</div>
<div className='form-check form-check-inline' onClick={this.switchBodyOption(BODY_OPTION.RAW)}>
<input className='form-check-input' type='radio' name='inlineRadioOptions' id='inlineRadio3' value='option3' />
<label className='form-check-label' htmlFor='inlineRadio3'>raw</label>
</div>
<div className='form-check form-check-inline' onClick={this.switchBodyOption(BODY_OPTION.BINARY)}>
<input className='form-check-input' type='radio' name='inlineRadioOptions' id='inlineRadio4' value='option4' />
<label className='form-check-label' htmlFor='inlineRadio4'>binary</label>
</div>
</div> : null
}
</div>
)
} }
handleDelete = (e, itf) => { handleDelete = (e, itf) => {
e.preventDefault() e.preventDefault()

@ -0,0 +1,7 @@
.InterfaceSummary
.dropdown
display: inline-block
.form-control
max-width: 500px
.body-options
margin: 8px

@ -121,8 +121,6 @@ class PropertyForm extends Component {
parentId: parent.id parentId: parent.id
}) })
handleAddMemoryProperty(property, () => { handleAddMemoryProperty(property, () => {
console.log('cb:')
console.log(arguments)
let { rmodal } = this.context let { rmodal } = this.context
if (rmodal) rmodal.resolve() if (rmodal) rmodal.resolve()
}) })

@ -5,6 +5,7 @@ import PropertyForm from './PropertyForm'
import Importer from './Importer' import Importer from './Importer'
import Previewer from './InterfacePreviewer' import Previewer from './InterfacePreviewer'
import { GoMention, GoFileCode, GoEye, GoPlus, GoTrashcan, GoQuestion } from 'react-icons/lib/go' import { GoMention, GoFileCode, GoEye, GoPlus, GoTrashcan, GoQuestion } from 'react-icons/lib/go'
import { rptFromStr2Num } from './InterfaceSummary'
export const RequestPropertyListPreviewer = (props) => ( export const RequestPropertyListPreviewer = (props) => (
<Previewer {...props} /> <Previewer {...props} />
@ -44,6 +45,17 @@ class SortableTreeTableHeader extends Component {
} }
} }
const PropertyLabel = (props) => {
const { pos } = props
if (pos === 1) {
return <label className='ml5 badge badge-danger'>HEAD</label>
} else if (pos === 3) {
return <label className='ml5 badge badge-primary'>BODY</label>
} else {
return <label className='ml5 badge badge-secondary'>QUERY</label>
}
}
class SortableTreeTableRow extends Component { class SortableTreeTableRow extends Component {
render () { render () {
let { property, editable } = this.props let { property, editable } = this.props
@ -64,7 +76,7 @@ class SortableTreeTableRow extends Component {
} }
<div className={`td payload name depth-${item.depth} nowrap`}> <div className={`td payload name depth-${item.depth} nowrap`}>
{!editable {!editable
? <span className='nowrap'>{item.name}</span> ? <span className='nowrap'>{item.name}{item.scope === 'request' && item.depth === 0 ? <PropertyLabel pos={item.pos} /> : null}</span>
: <input value={item.name} onChange={e => handleChangePropertyField(item.id, 'name', e.target.value)} className='form-control editable' spellCheck='false' placeholder='' /> : <input value={item.name} onChange={e => handleChangePropertyField(item.id, 'name', e.target.value)} className='form-control editable' spellCheck='false' placeholder='' />
} }
</div> </div>
@ -134,7 +146,11 @@ class PropertyList extends Component {
repository: PropTypes.object.isRequired, repository: PropTypes.object.isRequired,
mod: PropTypes.object.isRequired, mod: PropTypes.object.isRequired,
itf: PropTypes.object.isRequired, itf: PropTypes.object.isRequired,
editable: PropTypes.bool.isRequired editable: PropTypes.bool.isRequired,
/** optional */
bodyOption: PropTypes.string,
requestParamsType: PropTypes.string
} }
constructor (props) { constructor (props) {
super(props) super(props)
@ -148,9 +164,12 @@ class PropertyList extends Component {
render () { render () {
let { title, label, scope, properties = [], repository = {}, mod = {}, itf = {} } = this.props let { title, label, scope, properties = [], repository = {}, mod = {}, itf = {} } = this.props
if (!itf.id) return null if (!itf.id) return null
let { editable, bodyOption, requestParamsType } = this.props // itf.locker && (itf.locker.id === auth.id)
const pos = rptFromStr2Num(requestParamsType)
let scopedProperties = properties.map(property => ({ ...property })).filter(property => property.scope === scope) let scopedProperties = properties.map(property => ({ ...property })).filter(property => property.scope === scope)
let { editable } = this.props // itf.locker && (itf.locker.id === auth.id) if (scope === 'request' && editable) {
scopedProperties = scopedProperties.filter(s => s.pos === pos)
}
return ( return (
<section className='PropertyList'> <section className='PropertyList'>
@ -216,9 +235,9 @@ class PropertyList extends Component {
handleChangeProperty({ ...property, [key]: value }) handleChangeProperty({ ...property, [key]: value })
} }
handleCreatePropertySucceeded = () => { handleCreatePropertySucceeded = () => {
let { store } = this.context // let { store } = this.context
let uri = StoreStateRouterLocationURI(store) // let uri = StoreStateRouterLocationURI(store)
store.dispatch(replace(uri.href())) // store.dispatch(replace(uri.href()))
} }
handleDeleteMemoryProperty = (e, property) => { handleDeleteMemoryProperty = (e, property) => {
e.preventDefault() e.preventDefault()

@ -105,7 +105,7 @@ class RepositoryEditor extends Component {
<Link to={`${serve}/repository/get?id=${repository.id}`} target='_blank' className='api'><GoDatabase /> 数据</Link> <Link to={`${serve}/repository/get?id=${repository.id}`} target='_blank' className='api'><GoDatabase /> 数据</Link>
<Link to={`${serve}/test/test.plugin.jquery.html?id=${repository.id}`} target='_blank' className='api'><GoJersey /> 测试</Link> <Link to={`${serve}/test/test.plugin.jquery.html?id=${repository.id}`} target='_blank' className='api'><GoJersey /> 测试</Link>
<span className='fake-link edit' onClick={e => this.setState({ exportPostman: true })}><GoLinkExternal /> 导出Postman Collection</span> <span className='fake-link edit' onClick={e => this.setState({ exportPostman: true })}><GoLinkExternal /> 导出Postman Collection</span>
<RModal when={this.state.exportPostman} onClose={e => this.setState({ exportPostman: false })}> <RModal when={this.state.exportPostman} onClose={e => this.setState({ exportPostman: false })} onResolve={e => this.setState({ exportPostman: false })}>
<ExportPostmanForm title='导出到Postman' repoId={repository.id} /> <ExportPostmanForm title='导出到Postman' repoId={repository.id} />
</RModal> </RModal>
</div> </div>

@ -38,7 +38,6 @@ class Example extends Component {
}) })
} }
handleChange = (value) => { handleChange = (value) => {
console.log(value)
this.setState({ members: value, options: [] }) this.setState({ members: value, options: [] })
} }
} }

@ -1,4 +1,5 @@
import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'
import './assets/index.css' import './assets/index.css'
import 'animate.css' import 'animate.css'

@ -36,7 +36,7 @@ export function * updateProperty (action) {
} }
export function * updateProperties (action) { export function * updateProperties (action) {
try { try {
const properties = yield call(EditorService.updateProperties, action.itf, action.properties) const properties = yield call(EditorService.updateProperties, action.itf, action.properties, action.summary)
yield put(PropertyAction.updatePropertiesSucceeded(properties)) yield put(PropertyAction.updatePropertiesSucceeded(properties))
if (action.onResolved) action.onResolved() if (action.onResolved) action.onResolved()
} catch (e) { } catch (e) {

@ -190,11 +190,11 @@ export default {
.then(res => res.json()) .then(res => res.json())
.then(json => json.data) .then(json => json.data)
}, },
updateProperties (itf, properties) { updateProperties (itf, properties, summary) {
return fetch(`${serve}/properties/update?itf=${itf}`, { return fetch(`${serve}/properties/update?itf=${itf}`, {
...CREDENTIALS, ...CREDENTIALS,
method: 'POST', method: 'POST',
body: JSON.stringify(properties), body: JSON.stringify({ properties, summary }),
headers: { 'Content-Type': 'application/json' } headers: { 'Content-Type': 'application/json' }
}) })
.then(res => res.json()) .then(res => res.json())

Loading…
Cancel
Save