Merge branch 'master' into uri-encoded-scopes-fix
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
"brace": "0.7.0",
|
"brace": "0.7.0",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"commonmark": "^0.28.1",
|
"commonmark": "^0.28.1",
|
||||||
|
"core-js": "^2.5.1",
|
||||||
"css.escape": "1.5.1",
|
"css.escape": "1.5.1",
|
||||||
"deep-extend": "0.4.1",
|
"deep-extend": "0.4.1",
|
||||||
"expect": "1.20.2",
|
"expect": "1.20.2",
|
||||||
@@ -70,7 +71,7 @@
|
|||||||
"react-motion": "^0.5.2",
|
"react-motion": "^0.5.2",
|
||||||
"react-object-inspector": "0.2.1",
|
"react-object-inspector": "0.2.1",
|
||||||
"react-redux": "^4.x.x",
|
"react-redux": "^4.x.x",
|
||||||
"react-split-pane": "0.1.57",
|
"react-split-pane": "0.1.70",
|
||||||
"redux": "^3.x.x",
|
"redux": "^3.x.x",
|
||||||
"redux-immutable": "3.0.8",
|
"redux-immutable": "3.0.8",
|
||||||
"redux-logger": "*",
|
"redux-logger": "*",
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ export default class ApiKeyAuth extends React.Component {
|
|||||||
<Row>
|
<Row>
|
||||||
<Markdown source={ schema.get("description") } />
|
<Markdown source={ schema.get("description") } />
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<p>Name: <code>{ schema.get("name") }</code></p>
|
||||||
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<p>In: <code>{ schema.get("in") }</code></p>
|
<p>In: <code>{ schema.get("in") }</code></p>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ export default class ContentType extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if(!nextProps.contentTypes || !nextProps.contentTypes.size) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!nextProps.contentTypes.includes(nextProps.value)) {
|
||||||
|
nextProps.onChange(nextProps.contentTypes.first())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onChangeWrapper = e => this.props.onChange(e.target.value)
|
onChangeWrapper = e => this.props.onChange(e.target.value)
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ export default class Execute extends Component {
|
|||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
operation: PropTypes.object.isRequired,
|
operation: PropTypes.object.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
method: PropTypes.string.isRequired,
|
method: PropTypes.string.isRequired,
|
||||||
onExecute: PropTypes.func
|
onExecute: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
import { Iterable } from "immutable"
|
||||||
|
|
||||||
const Headers = ( { headers } )=>{
|
const Headers = ( { headers } )=>{
|
||||||
return (
|
return (
|
||||||
@@ -28,19 +29,29 @@ Duration.propTypes = {
|
|||||||
|
|
||||||
export default class LiveResponse extends React.Component {
|
export default class LiveResponse extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
response: PropTypes.object.isRequired,
|
response: PropTypes.instanceOf(Iterable).isRequired,
|
||||||
specSelectors: PropTypes.object.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
pathMethod: PropTypes.object.isRequired,
|
method: PropTypes.string.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
displayRequestDuration: PropTypes.bool.isRequired,
|
displayRequestDuration: PropTypes.bool.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired
|
getConfigs: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps) {
|
||||||
|
// BUG: props.response is always coming back as a new Immutable instance
|
||||||
|
// same issue as responses.jsx (tryItOutResponse)
|
||||||
|
return this.props.response !== nextProps.response
|
||||||
|
|| this.props.path !== nextProps.path
|
||||||
|
|| this.props.method !== nextProps.method
|
||||||
|
|| this.props.displayRequestDuration !== nextProps.displayRequestDuration
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { response, getComponent, getConfigs, displayRequestDuration, specSelectors, pathMethod } = this.props
|
const { response, getComponent, getConfigs, displayRequestDuration, specSelectors, path, method } = this.props
|
||||||
const { showMutatedRequest } = getConfigs()
|
const { showMutatedRequest } = getConfigs()
|
||||||
|
|
||||||
const curlRequest = showMutatedRequest ? specSelectors.mutatedRequestFor(pathMethod[0], pathMethod[1]) : specSelectors.requestFor(pathMethod[0], pathMethod[1])
|
const curlRequest = showMutatedRequest ? specSelectors.mutatedRequestFor(path, method) : specSelectors.requestFor(path, method)
|
||||||
const status = response.get("status")
|
const status = response.get("status")
|
||||||
const url = response.get("url")
|
const url = response.get("url")
|
||||||
const headers = response.get("headers").toJS()
|
const headers = response.get("headers").toJS()
|
||||||
@@ -118,7 +129,6 @@ export default class LiveResponse extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
request: ImPropTypes.map,
|
|
||||||
response: ImPropTypes.map
|
response: ImPropTypes.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,13 +76,14 @@ export default class ObjectModel extends Component {
|
|||||||
{
|
{
|
||||||
!(properties && properties.size) ? null : properties.entrySeq().map(
|
!(properties && properties.size) ? null : properties.entrySeq().map(
|
||||||
([key, value]) => {
|
([key, value]) => {
|
||||||
|
let isDeprecated = isOAS3() && value.get("deprecated")
|
||||||
let isRequired = List.isList(requiredProperties) && requiredProperties.contains(key)
|
let isRequired = List.isList(requiredProperties) && requiredProperties.contains(key)
|
||||||
let propertyStyle = { verticalAlign: "top", paddingRight: "0.2em" }
|
let propertyStyle = { verticalAlign: "top", paddingRight: "0.2em" }
|
||||||
if ( isRequired ) {
|
if ( isRequired ) {
|
||||||
propertyStyle.fontWeight = "bold"
|
propertyStyle.fontWeight = "bold"
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<tr key={key}>
|
return (<tr key={key} className={isDeprecated && "deprecated"}>
|
||||||
<td style={ propertyStyle }>
|
<td style={ propertyStyle }>
|
||||||
{ key }{ isRequired && <span style={{ color: "red" }}>*</span> }
|
{ key }{ isRequired && <span style={{ color: "red" }}>*</span> }
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -1,32 +1,22 @@
|
|||||||
import React, { PureComponent } from "react"
|
import React, { PureComponent } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { getList } from "core/utils"
|
import { getList } from "core/utils"
|
||||||
import * as CustomPropTypes from "core/proptypes"
|
|
||||||
import { sanitizeUrl } from "core/utils"
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
import { Iterable } from "immutable"
|
||||||
//import "less/opblock"
|
|
||||||
|
|
||||||
export default class Operation extends PureComponent {
|
export default class Operation extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
operation: PropTypes.instanceOf(Iterable).isRequired,
|
||||||
method: PropTypes.string.isRequired,
|
response: PropTypes.instanceOf(Iterable),
|
||||||
operation: PropTypes.object.isRequired,
|
request: PropTypes.instanceOf(Iterable),
|
||||||
showSummary: PropTypes.bool,
|
|
||||||
isShown: PropTypes.bool.isRequired,
|
|
||||||
|
|
||||||
tagKey: PropTypes.string,
|
toggleShown: PropTypes.func.isRequired,
|
||||||
operationKey: PropTypes.string,
|
onTryoutClick: PropTypes.func.isRequired,
|
||||||
jumpToKey: CustomPropTypes.arrayOrString.isRequired,
|
onCancelClick: PropTypes.func.isRequired,
|
||||||
|
onExecute: PropTypes.func.isRequired,
|
||||||
allowTryItOut: PropTypes.bool,
|
|
||||||
|
|
||||||
displayOperationId: PropTypes.bool,
|
|
||||||
displayRequestDuration: PropTypes.bool,
|
|
||||||
|
|
||||||
response: PropTypes.object,
|
|
||||||
request: PropTypes.object,
|
|
||||||
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
getConfigs: PropTypes.func.isRequired,
|
||||||
authActions: PropTypes.object,
|
authActions: PropTypes.object,
|
||||||
authSelectors: PropTypes.object,
|
authSelectors: PropTypes.object,
|
||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
@@ -34,88 +24,66 @@ export default class Operation extends PureComponent {
|
|||||||
oas3Actions: PropTypes.object.isRequired,
|
oas3Actions: PropTypes.object.isRequired,
|
||||||
layoutActions: PropTypes.object.isRequired,
|
layoutActions: PropTypes.object.isRequired,
|
||||||
layoutSelectors: PropTypes.object.isRequired,
|
layoutSelectors: PropTypes.object.isRequired,
|
||||||
fn: PropTypes.object.isRequired,
|
fn: PropTypes.object.isRequired
|
||||||
getConfigs: PropTypes.func.isRequired
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
showSummary: true,
|
operation: null,
|
||||||
response: null,
|
response: null,
|
||||||
allowTryItOut: true,
|
request: null
|
||||||
displayOperationId: false,
|
|
||||||
displayRequestDuration: false
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context)
|
|
||||||
this.state = {
|
|
||||||
tryItOutEnabled: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if(nextProps.response !== this.props.response) {
|
|
||||||
this.setState({ executeInProgress: false })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleShown =() => {
|
|
||||||
let { layoutActions, tagKey, operationKey, isShown } = this.props
|
|
||||||
const isShownKey = ["operations", tagKey, operationKey]
|
|
||||||
|
|
||||||
layoutActions.show(isShownKey, !isShown)
|
|
||||||
}
|
|
||||||
|
|
||||||
onTryoutClick =() => {
|
|
||||||
this.setState({tryItOutEnabled: !this.state.tryItOutEnabled})
|
|
||||||
}
|
|
||||||
|
|
||||||
onCancelClick =() => {
|
|
||||||
let { specActions, path, method } = this.props
|
|
||||||
this.setState({tryItOutEnabled: !this.state.tryItOutEnabled})
|
|
||||||
specActions.clearValidateParams([path, method])
|
|
||||||
}
|
|
||||||
|
|
||||||
onExecute = () => {
|
|
||||||
this.setState({ executeInProgress: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {
|
let {
|
||||||
operationKey,
|
|
||||||
tagKey,
|
|
||||||
isShown,
|
|
||||||
jumpToKey,
|
|
||||||
path,
|
|
||||||
method,
|
|
||||||
operation,
|
|
||||||
showSummary,
|
|
||||||
response,
|
response,
|
||||||
request,
|
request,
|
||||||
allowTryItOut,
|
toggleShown,
|
||||||
displayOperationId,
|
onTryoutClick,
|
||||||
displayRequestDuration,
|
onCancelClick,
|
||||||
|
onExecute,
|
||||||
fn,
|
fn,
|
||||||
getComponent,
|
getComponent,
|
||||||
|
getConfigs,
|
||||||
specActions,
|
specActions,
|
||||||
specSelectors,
|
specSelectors,
|
||||||
authActions,
|
authActions,
|
||||||
authSelectors,
|
authSelectors,
|
||||||
getConfigs,
|
|
||||||
oas3Actions
|
oas3Actions
|
||||||
} = this.props
|
} = this.props
|
||||||
|
let operationProps = this.props.operation
|
||||||
|
|
||||||
let summary = operation.get("summary")
|
let {
|
||||||
let description = operation.get("description")
|
isShown,
|
||||||
let deprecated = operation.get("deprecated")
|
jumpToKey,
|
||||||
let externalDocs = operation.get("externalDocs")
|
path,
|
||||||
|
method,
|
||||||
|
op,
|
||||||
|
tag,
|
||||||
|
showSummary,
|
||||||
|
operationId,
|
||||||
|
allowTryItOut,
|
||||||
|
displayOperationId,
|
||||||
|
displayRequestDuration,
|
||||||
|
isDeepLinkingEnabled,
|
||||||
|
tryItOutEnabled,
|
||||||
|
executeInProgress
|
||||||
|
} = operationProps.toJS()
|
||||||
|
|
||||||
|
let {
|
||||||
|
summary,
|
||||||
|
description,
|
||||||
|
deprecated,
|
||||||
|
externalDocs,
|
||||||
|
schemes
|
||||||
|
} = op.operation
|
||||||
|
|
||||||
|
let operation = operationProps.getIn(["op", "operation"])
|
||||||
let responses = operation.get("responses")
|
let responses = operation.get("responses")
|
||||||
let security = operation.get("security") || specSelectors.security()
|
|
||||||
let produces = operation.get("produces")
|
let produces = operation.get("produces")
|
||||||
let schemes = operation.get("schemes")
|
let security = operation.get("security") || specSelectors.security()
|
||||||
let parameters = getList(operation, ["parameters"])
|
let parameters = getList(operation, ["parameters"])
|
||||||
let operationId = operation.get("__originalOperationId")
|
|
||||||
let operationScheme = specSelectors.operationScheme(path, method)
|
let operationScheme = specSelectors.operationScheme(path, method)
|
||||||
|
let isShownKey = ["operations", tag, operationId]
|
||||||
|
|
||||||
const Responses = getComponent("responses")
|
const Responses = getComponent("responses")
|
||||||
const Parameters = getComponent( "parameters" )
|
const Parameters = getComponent( "parameters" )
|
||||||
@@ -127,28 +95,23 @@ export default class Operation extends PureComponent {
|
|||||||
const Markdown = getComponent( "Markdown" )
|
const Markdown = getComponent( "Markdown" )
|
||||||
const Schemes = getComponent( "schemes" )
|
const Schemes = getComponent( "schemes" )
|
||||||
|
|
||||||
const { deepLinking } = getConfigs()
|
|
||||||
|
|
||||||
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
|
|
||||||
|
|
||||||
// Merge in Live Response
|
// Merge in Live Response
|
||||||
if(responses && response && response.size > 0) {
|
if(responses && response && response.size > 0) {
|
||||||
let notDocumented = !responses.get(String(response.get("status")))
|
let notDocumented = !responses.get(String(response.get("status")))
|
||||||
response = response.set("notDocumented", notDocumented)
|
response = response.set("notDocumented", notDocumented)
|
||||||
}
|
}
|
||||||
|
|
||||||
let { tryItOutEnabled } = this.state
|
|
||||||
let onChangeKey = [ path, method ] // Used to add values to _this_ operation ( indexed by path and method )
|
let onChangeKey = [ path, method ] // Used to add values to _this_ operation ( indexed by path and method )
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={deprecated ? "opblock opblock-deprecated" : isShown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={`operations-${tagKey}-${operationKey}`} >
|
<div className={deprecated ? "opblock opblock-deprecated" : isShown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={isShownKey.join("-")} >
|
||||||
<div className={`opblock-summary opblock-summary-${method}`} onClick={this.toggleShown} >
|
<div className={`opblock-summary opblock-summary-${method}`} onClick={toggleShown} >
|
||||||
<span className="opblock-summary-method">{method.toUpperCase()}</span>
|
<span className="opblock-summary-method">{method.toUpperCase()}</span>
|
||||||
<span className={ deprecated ? "opblock-summary-path__deprecated" : "opblock-summary-path" } >
|
<span className={ deprecated ? "opblock-summary-path__deprecated" : "opblock-summary-path" } >
|
||||||
<a
|
<a
|
||||||
className="nostyle"
|
className="nostyle"
|
||||||
onClick={isDeepLinkingEnabled ? (e) => e.preventDefault() : null}
|
onClick={isDeepLinkingEnabled ? (e) => e.preventDefault() : null}
|
||||||
href={isDeepLinkingEnabled ? `#/${tagKey}/${operationKey}` : null}>
|
href={isDeepLinkingEnabled ? `#/${isShownKey.join("/")}` : null}>
|
||||||
<span>{path}</span>
|
<span>{path}</span>
|
||||||
</a>
|
</a>
|
||||||
<JumpToPath path={jumpToKey} />
|
<JumpToPath path={jumpToKey} />
|
||||||
@@ -200,8 +163,8 @@ export default class Operation extends PureComponent {
|
|||||||
parameters={parameters}
|
parameters={parameters}
|
||||||
operation={operation}
|
operation={operation}
|
||||||
onChangeKey={onChangeKey}
|
onChangeKey={onChangeKey}
|
||||||
onTryoutClick = { this.onTryoutClick }
|
onTryoutClick = { onTryoutClick }
|
||||||
onCancelClick = { this.onCancelClick }
|
onCancelClick = { onCancelClick }
|
||||||
tryItOutEnabled = { tryItOutEnabled }
|
tryItOutEnabled = { tryItOutEnabled }
|
||||||
allowTryItOut={allowTryItOut}
|
allowTryItOut={allowTryItOut}
|
||||||
|
|
||||||
@@ -226,25 +189,23 @@ export default class Operation extends PureComponent {
|
|||||||
{ !tryItOutEnabled || !allowTryItOut ? null :
|
{ !tryItOutEnabled || !allowTryItOut ? null :
|
||||||
|
|
||||||
<Execute
|
<Execute
|
||||||
getComponent={getComponent}
|
|
||||||
operation={ operation }
|
operation={ operation }
|
||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
path={ path }
|
path={ path }
|
||||||
method={ method }
|
method={ method }
|
||||||
onExecute={ this.onExecute } />
|
onExecute={ onExecute } />
|
||||||
}
|
}
|
||||||
|
|
||||||
{ (!tryItOutEnabled || !response || !allowTryItOut) ? null :
|
{ (!tryItOutEnabled || !response || !allowTryItOut) ? null :
|
||||||
<Clear
|
<Clear
|
||||||
onClick={ this.onClearClick }
|
|
||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
path={ path }
|
path={ path }
|
||||||
method={ method }/>
|
method={ method }/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{this.state.executeInProgress ? <div className="loading-container"><div className="loading"></div></div> : null}
|
{executeInProgress ? <div className="loading-container"><div className="loading"></div></div> : null}
|
||||||
|
|
||||||
{ !responses ? null :
|
{ !responses ? null :
|
||||||
<Responses
|
<Responses
|
||||||
@@ -258,7 +219,8 @@ export default class Operation extends PureComponent {
|
|||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
produces={ produces }
|
produces={ produces }
|
||||||
producesValue={ operation.get("produces_value") }
|
producesValue={ operation.get("produces_value") }
|
||||||
pathMethod={ [path, method] }
|
path={ path }
|
||||||
|
method={ method }
|
||||||
displayRequestDuration={ displayRequestDuration }
|
displayRequestDuration={ displayRequestDuration }
|
||||||
fn={fn} />
|
fn={fn} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { helpers } from "swagger-client"
|
|
||||||
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
||||||
const { opId } = helpers
|
|
||||||
|
|
||||||
export default class Operations extends React.Component {
|
export default class Operations extends React.Component {
|
||||||
|
|
||||||
@@ -21,28 +19,20 @@ export default class Operations extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
let {
|
let {
|
||||||
specSelectors,
|
specSelectors,
|
||||||
specActions,
|
|
||||||
oas3Actions,
|
|
||||||
getComponent,
|
getComponent,
|
||||||
layoutSelectors,
|
layoutSelectors,
|
||||||
layoutActions,
|
layoutActions,
|
||||||
authActions,
|
getConfigs
|
||||||
authSelectors,
|
|
||||||
getConfigs,
|
|
||||||
fn
|
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
let taggedOps = specSelectors.taggedOperations()
|
let taggedOps = specSelectors.taggedOperations()
|
||||||
|
|
||||||
const Operation = getComponent("operation")
|
const OperationContainer = getComponent("OperationContainer", true)
|
||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
const Markdown = getComponent("Markdown")
|
const Markdown = getComponent("Markdown")
|
||||||
|
|
||||||
let showSummary = layoutSelectors.showSummary()
|
|
||||||
let {
|
let {
|
||||||
docExpansion,
|
docExpansion,
|
||||||
displayOperationId,
|
|
||||||
displayRequestDuration,
|
|
||||||
maxDisplayedTags,
|
maxDisplayedTags,
|
||||||
deepLinking
|
deepLinking
|
||||||
} = getConfigs()
|
} = getConfigs()
|
||||||
@@ -120,49 +110,15 @@ export default class Operations extends React.Component {
|
|||||||
<Collapse isOpened={showTag}>
|
<Collapse isOpened={showTag}>
|
||||||
{
|
{
|
||||||
operations.map( op => {
|
operations.map( op => {
|
||||||
|
const path = op.get("path")
|
||||||
|
const method = op.get("method")
|
||||||
|
|
||||||
const path = op.get("path", "")
|
return <OperationContainer
|
||||||
const method = op.get("method", "")
|
key={`${path}-${method}`}
|
||||||
const jumpToKey = `paths.${path}.${method}`
|
op={op}
|
||||||
|
path={path}
|
||||||
const operationId =
|
method={method}
|
||||||
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id")
|
tag={tag}
|
||||||
const tagKey = createDeepLinkPath(tag)
|
|
||||||
const operationKey = createDeepLinkPath(operationId)
|
|
||||||
|
|
||||||
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method"))
|
|
||||||
const response = specSelectors.responseFor(op.get("path"), op.get("method"))
|
|
||||||
const request = specSelectors.requestFor(op.get("path"), op.get("method"))
|
|
||||||
|
|
||||||
return <Operation
|
|
||||||
{...op.toObject()}
|
|
||||||
tagKey={tagKey}
|
|
||||||
operationKey={operationKey}
|
|
||||||
isShown={layoutSelectors.isShown(["operations", tagKey, operationKey], docExpansion === "full")}
|
|
||||||
jumpToKey={jumpToKey}
|
|
||||||
showSummary={showSummary}
|
|
||||||
key={tagKey + operationKey}
|
|
||||||
response={ response }
|
|
||||||
request={ request }
|
|
||||||
allowTryItOut={allowTryItOut}
|
|
||||||
|
|
||||||
displayOperationId={displayOperationId}
|
|
||||||
displayRequestDuration={displayRequestDuration}
|
|
||||||
|
|
||||||
specActions={ specActions }
|
|
||||||
specSelectors={ specSelectors }
|
|
||||||
|
|
||||||
oas3Actions={oas3Actions}
|
|
||||||
|
|
||||||
layoutActions={ layoutActions }
|
|
||||||
layoutSelectors={ layoutSelectors }
|
|
||||||
|
|
||||||
authActions={ authActions }
|
|
||||||
authSelectors={ authSelectors }
|
|
||||||
|
|
||||||
getComponent={ getComponent }
|
|
||||||
fn={fn}
|
|
||||||
getConfigs={ getConfigs }
|
|
||||||
/>
|
/>
|
||||||
}).toArray()
|
}).toArray()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import { fromJS, Seq } from "immutable"
|
import { fromJS, Seq, Iterable } from "immutable"
|
||||||
import { getSampleSchema, fromJSOrdered } from "core/utils"
|
import { getSampleSchema, fromJSOrdered } from "core/utils"
|
||||||
|
|
||||||
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
|
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
|
||||||
@@ -42,7 +42,7 @@ export default class Response extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
code: PropTypes.string.isRequired,
|
code: PropTypes.string.isRequired,
|
||||||
response: PropTypes.object,
|
response: PropTypes.instanceOf(Iterable),
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -1,41 +1,52 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS, Iterable } from "immutable"
|
||||||
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
|
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
|
||||||
|
|
||||||
export default class Responses extends React.Component {
|
export default class Responses extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
request: PropTypes.object,
|
tryItOutResponse: PropTypes.instanceOf(Iterable),
|
||||||
tryItOutResponse: PropTypes.object,
|
responses: PropTypes.instanceOf(Iterable).isRequired,
|
||||||
responses: PropTypes.object.isRequired,
|
produces: PropTypes.instanceOf(Iterable),
|
||||||
produces: PropTypes.object,
|
|
||||||
producesValue: PropTypes.any,
|
producesValue: PropTypes.any,
|
||||||
|
displayRequestDuration: PropTypes.bool.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
method: PropTypes.string.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
oas3Actions: PropTypes.object.isRequired,
|
oas3Actions: PropTypes.object.isRequired,
|
||||||
pathMethod: PropTypes.array.isRequired,
|
|
||||||
displayRequestDuration: PropTypes.bool.isRequired,
|
|
||||||
fn: PropTypes.object.isRequired
|
fn: PropTypes.object.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
request: null,
|
|
||||||
tryItOutResponse: null,
|
tryItOutResponse: null,
|
||||||
produces: fromJS(["application/json"]),
|
produces: fromJS(["application/json"]),
|
||||||
displayRequestDuration: false
|
displayRequestDuration: false
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
|
shouldComponentUpdate(nextProps) {
|
||||||
|
// BUG: props.tryItOutResponse is always coming back as a new Immutable instance
|
||||||
|
let render = this.props.tryItOutResponse !== nextProps.tryItOutResponse
|
||||||
|
|| this.props.responses !== nextProps.responses
|
||||||
|
|| this.props.produces !== nextProps.produces
|
||||||
|
|| this.props.producesValue !== nextProps.producesValue
|
||||||
|
|| this.props.displayRequestDuration !== nextProps.displayRequestDuration
|
||||||
|
|| this.props.path !== nextProps.path
|
||||||
|
|| this.props.method !== nextProps.method
|
||||||
|
return render
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue([this.props.path, this.props.method], val)
|
||||||
|
|
||||||
onResponseContentTypeChange = ({ controlsAcceptHeader, value }) => {
|
onResponseContentTypeChange = ({ controlsAcceptHeader, value }) => {
|
||||||
const { oas3Actions, pathMethod } = this.props
|
const { oas3Actions, path, method } = this.props
|
||||||
if(controlsAcceptHeader) {
|
if(controlsAcceptHeader) {
|
||||||
oas3Actions.setResponseContentType({
|
oas3Actions.setResponseContentType({
|
||||||
value,
|
value,
|
||||||
pathMethod
|
path,
|
||||||
|
method
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +54,6 @@ export default class Responses extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
let {
|
let {
|
||||||
responses,
|
responses,
|
||||||
request,
|
|
||||||
tryItOutResponse,
|
tryItOutResponse,
|
||||||
getComponent,
|
getComponent,
|
||||||
getConfigs,
|
getConfigs,
|
||||||
@@ -81,12 +91,12 @@ export default class Responses extends React.Component {
|
|||||||
{
|
{
|
||||||
!tryItOutResponse ? null
|
!tryItOutResponse ? null
|
||||||
: <div>
|
: <div>
|
||||||
<LiveResponse request={ request }
|
<LiveResponse response={ tryItOutResponse }
|
||||||
response={ tryItOutResponse }
|
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
pathMethod={ this.props.pathMethod }
|
path={ this.props.path }
|
||||||
|
method={ this.props.method }
|
||||||
displayRequestDuration={ displayRequestDuration } />
|
displayRequestDuration={ displayRequestDuration } />
|
||||||
<h4>Responses</h4>
|
<h4>Responses</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
194
src/core/containers/OperationContainer.jsx
Normal file
194
src/core/containers/OperationContainer.jsx
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
import React, { PureComponent } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import { helpers } from "swagger-client"
|
||||||
|
import { Iterable, fromJS } from "immutable"
|
||||||
|
|
||||||
|
const { opId } = helpers
|
||||||
|
|
||||||
|
export default class OperationContainer extends PureComponent {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
this.state = {
|
||||||
|
tryItOutEnabled: false,
|
||||||
|
executeInProgress: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
op: PropTypes.instanceOf(Iterable).isRequired,
|
||||||
|
tag: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
method: PropTypes.string.isRequired,
|
||||||
|
operationId: PropTypes.string.isRequired,
|
||||||
|
showSummary: PropTypes.bool.isRequired,
|
||||||
|
isShown: PropTypes.bool.isRequired,
|
||||||
|
jumpToKey: PropTypes.string.isRequired,
|
||||||
|
allowTryItOut: PropTypes.bool,
|
||||||
|
displayOperationId: PropTypes.bool,
|
||||||
|
displayRequestDuration: PropTypes.bool,
|
||||||
|
response: PropTypes.instanceOf(Iterable),
|
||||||
|
request: PropTypes.instanceOf(Iterable),
|
||||||
|
isDeepLinkingEnabled: PropTypes.bool.isRequired,
|
||||||
|
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
authActions: PropTypes.object,
|
||||||
|
oas3Actions: PropTypes.object,
|
||||||
|
authSelectors: PropTypes.object,
|
||||||
|
specActions: PropTypes.object.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
layoutActions: PropTypes.object.isRequired,
|
||||||
|
layoutSelectors: PropTypes.object.isRequired,
|
||||||
|
fn: PropTypes.object.isRequired,
|
||||||
|
getConfigs: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
showSummary: true,
|
||||||
|
response: null,
|
||||||
|
allowTryItOut: true,
|
||||||
|
displayOperationId: false,
|
||||||
|
displayRequestDuration: false
|
||||||
|
}
|
||||||
|
|
||||||
|
mapStateToProps(nextState, props) {
|
||||||
|
const { op, layoutSelectors, getConfigs } = props
|
||||||
|
const { docExpansion, deepLinking, displayOperationId, displayRequestDuration } = getConfigs()
|
||||||
|
const showSummary = layoutSelectors.showSummary()
|
||||||
|
const operationId = op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id")
|
||||||
|
const isShownKey = ["operations", props.tag, operationId]
|
||||||
|
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
|
||||||
|
const allowTryItOut = typeof props.allowTryItOut === "undefined" ?
|
||||||
|
props.specSelectors.allowTryItOutFor(props.path, props.method) : props.allowTryItOut
|
||||||
|
|
||||||
|
return {
|
||||||
|
operationId,
|
||||||
|
isDeepLinkingEnabled,
|
||||||
|
showSummary,
|
||||||
|
displayOperationId,
|
||||||
|
displayRequestDuration,
|
||||||
|
allowTryItOut,
|
||||||
|
isShown: layoutSelectors.isShown(isShownKey, docExpansion === "full" ),
|
||||||
|
jumpToKey: `paths.${props.path}.${props.method}`,
|
||||||
|
response: props.specSelectors.responseFor(props.path, props.method),
|
||||||
|
request: props.specSelectors.requestFor(props.path, props.method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
const defaultContentType = "application/json"
|
||||||
|
let { specActions, path, method, op } = nextProps
|
||||||
|
let operation = op.get("operation")
|
||||||
|
let producesValue = operation.get("produces_value")
|
||||||
|
let produces = operation.get("produces")
|
||||||
|
let consumes = operation.get("consumes")
|
||||||
|
let consumesValue = operation.get("consumes_value")
|
||||||
|
|
||||||
|
if(nextProps.response !== this.props.response) {
|
||||||
|
this.setState({ executeInProgress: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (producesValue === undefined) {
|
||||||
|
producesValue = produces && produces.size ? produces.first() : defaultContentType
|
||||||
|
specActions.changeProducesValue([path, method], producesValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consumesValue === undefined) {
|
||||||
|
consumesValue = consumes && consumes.size ? consumes.first() : defaultContentType
|
||||||
|
specActions.changeConsumesValue([path, method], consumesValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleShown =() => {
|
||||||
|
let { layoutActions, tag, operationId, isShown } = this.props
|
||||||
|
layoutActions.show(["operations", tag, operationId], !isShown)
|
||||||
|
}
|
||||||
|
|
||||||
|
onTryoutClick =() => {
|
||||||
|
this.setState({tryItOutEnabled: !this.state.tryItOutEnabled})
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancelClick =() => {
|
||||||
|
let { specActions, path, method } = this.props
|
||||||
|
this.setState({tryItOutEnabled: !this.state.tryItOutEnabled})
|
||||||
|
specActions.clearValidateParams([path, method])
|
||||||
|
}
|
||||||
|
|
||||||
|
onExecute = () => {
|
||||||
|
this.setState({ executeInProgress: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {
|
||||||
|
op,
|
||||||
|
tag,
|
||||||
|
path,
|
||||||
|
method,
|
||||||
|
operationId,
|
||||||
|
showSummary,
|
||||||
|
isShown,
|
||||||
|
jumpToKey,
|
||||||
|
allowTryItOut,
|
||||||
|
response,
|
||||||
|
request,
|
||||||
|
displayOperationId,
|
||||||
|
displayRequestDuration,
|
||||||
|
isDeepLinkingEnabled,
|
||||||
|
specSelectors,
|
||||||
|
specActions,
|
||||||
|
getComponent,
|
||||||
|
getConfigs,
|
||||||
|
layoutSelectors,
|
||||||
|
layoutActions,
|
||||||
|
authActions,
|
||||||
|
authSelectors,
|
||||||
|
oas3Actions,
|
||||||
|
fn
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const Operation = getComponent( "operation" )
|
||||||
|
|
||||||
|
const operationProps = fromJS({
|
||||||
|
op,
|
||||||
|
tag,
|
||||||
|
path,
|
||||||
|
method,
|
||||||
|
operationId,
|
||||||
|
showSummary,
|
||||||
|
isShown,
|
||||||
|
jumpToKey,
|
||||||
|
allowTryItOut,
|
||||||
|
request,
|
||||||
|
displayOperationId,
|
||||||
|
displayRequestDuration,
|
||||||
|
isDeepLinkingEnabled,
|
||||||
|
executeInProgress: this.state.executeInProgress,
|
||||||
|
tryItOutEnabled: this.state.tryItOutEnabled
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Operation
|
||||||
|
operation={operationProps}
|
||||||
|
response={response}
|
||||||
|
request={request}
|
||||||
|
isShown={isShown}
|
||||||
|
|
||||||
|
toggleShown={this.toggleShown}
|
||||||
|
onTryoutClick={this.onTryoutClick}
|
||||||
|
onCancelClick={this.onCancelClick}
|
||||||
|
onExecute={this.onExecute}
|
||||||
|
|
||||||
|
specActions={ specActions }
|
||||||
|
specSelectors={ specSelectors }
|
||||||
|
oas3Actions={oas3Actions}
|
||||||
|
layoutActions={ layoutActions }
|
||||||
|
layoutSelectors={ layoutSelectors }
|
||||||
|
authActions={ authActions }
|
||||||
|
authSelectors={ authSelectors }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
getConfigs={ getConfigs }
|
||||||
|
fn={fn}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,8 +7,7 @@ import * as AllPlugins from "core/plugins/all"
|
|||||||
import { parseSearch } from "core/utils"
|
import { parseSearch } from "core/utils"
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "production") {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
const Perf = require("react-addons-perf")
|
window.Perf = require("react-addons-perf")
|
||||||
window.Perf = Perf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ export function setRequestContentType ({ value, pathMethod }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setResponseContentType ({ value, pathMethod }) {
|
export function setResponseContentType ({ value, path, method }) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_RESPONSE_CONTENT_TYPE,
|
type: UPDATE_RESPONSE_CONTENT_TYPE,
|
||||||
payload: { value, pathMethod }
|
payload: { value, path, method }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
import { fromJS } from "immutable"
|
||||||
|
|
||||||
const Callbacks = (props) => {
|
const Callbacks = (props) => {
|
||||||
let { callbacks, getComponent } = props
|
let { callbacks, getComponent } = props
|
||||||
// const Markdown = getComponent("Markdown")
|
// const Markdown = getComponent("Markdown")
|
||||||
const Operation = getComponent("operation", true)
|
const OperationContainer = getComponent("OperationContainer", true)
|
||||||
|
|
||||||
if(!callbacks) {
|
if(!callbacks) {
|
||||||
return <span>No callbacks</span>
|
return <span>No callbacks</span>
|
||||||
@@ -16,24 +18,22 @@ const Callbacks = (props) => {
|
|||||||
{ callback.map((pathItem, pathItemName) => {
|
{ callback.map((pathItem, pathItemName) => {
|
||||||
return <div key={pathItemName}>
|
return <div key={pathItemName}>
|
||||||
{ pathItem.map((operation, method) => {
|
{ pathItem.map((operation, method) => {
|
||||||
return <Operation
|
let op = fromJS({
|
||||||
operation={operation}
|
operation
|
||||||
|
})
|
||||||
|
return <OperationContainer
|
||||||
|
{...props}
|
||||||
|
op={op}
|
||||||
key={method}
|
key={method}
|
||||||
|
tag={""}
|
||||||
method={method}
|
method={method}
|
||||||
isShownKey={["callbacks", operation.get("id"), callbackName]}
|
|
||||||
path={pathItemName}
|
path={pathItemName}
|
||||||
allowTryItOut={false}
|
allowTryItOut={false}
|
||||||
{...props}></Operation>
|
/>
|
||||||
// return <pre>{JSON.stringify(operation)}</pre>
|
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
// return <div>
|
|
||||||
// <h2>{name}</h2>
|
|
||||||
// {callback.description && <Markdown source={callback.description}/>}
|
|
||||||
// <pre>{JSON.stringify(callback)}</pre>
|
|
||||||
// </div>
|
|
||||||
})
|
})
|
||||||
return <div>
|
return <div>
|
||||||
{callbackElements}
|
{callbackElements}
|
||||||
@@ -42,7 +42,7 @@ const Callbacks = (props) => {
|
|||||||
|
|
||||||
Callbacks.propTypes = {
|
Callbacks.propTypes = {
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
callbacks: PropTypes.array.isRequired
|
callbacks: ImPropTypes.iterable.isRequired
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ export default class RequestBodyEditor extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if(this.props.requestBody !== prevProps.requestBody) {
|
||||||
|
// force recalc of value if the request body definition has changed
|
||||||
|
this.setValueToSample(this.props.mediaType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setValueToSample = (explicitMediaType) => {
|
setValueToSample = (explicitMediaType) => {
|
||||||
this.onChange(this.sample(explicitMediaType))
|
this.onChange(this.sample(explicitMediaType))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ const RequestBody = ({
|
|||||||
|
|
||||||
const mediaTypeValue = requestBodyContent.get(contentType)
|
const mediaTypeValue = requestBodyContent.get(contentType)
|
||||||
|
|
||||||
|
if(!mediaTypeValue) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{ requestBodyDescription &&
|
{ requestBodyDescription &&
|
||||||
<Markdown source={requestBodyDescription} />
|
<Markdown source={requestBodyDescription} />
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ export default {
|
|||||||
let [path, method] = pathMethod
|
let [path, method] = pathMethod
|
||||||
return state.setIn( [ "requestData", path, method, "requestContentType" ], value)
|
return state.setIn( [ "requestData", path, method, "requestContentType" ], value)
|
||||||
},
|
},
|
||||||
[UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, pathMethod } } ) =>{
|
[UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, path, method } } ) =>{
|
||||||
let [path, method] = pathMethod
|
|
||||||
return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
|
return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
|
||||||
},
|
},
|
||||||
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{
|
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{
|
||||||
|
|||||||
@@ -20,8 +20,14 @@ const RootWrapper = (reduxStore, ComponentToWrap) => class extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const makeContainer = (getSystem, component, reduxStore) => {
|
const makeContainer = (getSystem, component, reduxStore) => {
|
||||||
|
const mapStateToProps = function(state, ownProps) {
|
||||||
|
const propsForContainerComponent = Object.assign({}, ownProps, getSystem())
|
||||||
|
const ori = component.prototype.mapStateToProps || (state => { return {state} })
|
||||||
|
return ori(state, propsForContainerComponent)
|
||||||
|
}
|
||||||
|
|
||||||
let wrappedWithSystem = SystemWrapper(getSystem, component, reduxStore)
|
let wrappedWithSystem = SystemWrapper(getSystem, component, reduxStore)
|
||||||
let connected = connect(state => ({state}))(wrappedWithSystem)
|
let connected = connect( mapStateToProps )(wrappedWithSystem)
|
||||||
if(reduxStore)
|
if(reduxStore)
|
||||||
return RootWrapper(reduxStore, connected)
|
return RootWrapper(reduxStore, connected)
|
||||||
return connected
|
return connected
|
||||||
@@ -114,5 +120,5 @@ export const getComponent = (getSystem, getStore, getComponents, componentName,
|
|||||||
return makeContainer(getSystem, component, getStore())
|
return makeContainer(getSystem, component, getStore())
|
||||||
|
|
||||||
// container == truthy
|
// container == truthy
|
||||||
return makeContainer(getSystem, component)
|
return makeContainer(getSystem, wrapRender(component))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import downloadUrlPlugin from "core/plugins/download-url"
|
|||||||
import configsPlugin from "plugins/configs"
|
import configsPlugin from "plugins/configs"
|
||||||
import deepLinkingPlugin from "core/plugins/deep-linking"
|
import deepLinkingPlugin from "core/plugins/deep-linking"
|
||||||
|
|
||||||
|
import OperationContainer from "core/containers/OperationContainer"
|
||||||
|
|
||||||
import App from "core/components/app"
|
import App from "core/components/app"
|
||||||
import AuthorizationPopup from "core/components/auth/authorization-popup"
|
import AuthorizationPopup from "core/components/auth/authorization-popup"
|
||||||
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
||||||
@@ -112,7 +114,8 @@ export default function() {
|
|||||||
TryItOutButton,
|
TryItOutButton,
|
||||||
Markdown,
|
Markdown,
|
||||||
BaseLayout,
|
BaseLayout,
|
||||||
VersionStamp
|
VersionStamp,
|
||||||
|
OperationContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -289,8 +289,7 @@ export default class Store {
|
|||||||
|
|
||||||
getMapStateToProps() {
|
getMapStateToProps() {
|
||||||
return () => {
|
return () => {
|
||||||
let obj = Object.assign({}, this.getSystem())
|
return Object.assign({}, this.getSystem())
|
||||||
return obj
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -575,6 +575,12 @@
|
|||||||
color: $response-col-description-inner-markdown-link-font-color-hover;
|
color: $response-col-description-inner-markdown-link-font-color-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th
|
||||||
|
{
|
||||||
|
@include text_code($response-col-description-inner-markdown-font-color);
|
||||||
|
border-bottom: 1px solid $response-col-description-inner-markdown-font-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
{
|
{
|
||||||
color: $model-deprecated-font-color !important;
|
color: $model-deprecated-font-color !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> td:first-of-type {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&-toggle
|
&-toggle
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
/* eslint-env mocha */
|
/* eslint-env mocha */
|
||||||
|
import React, { PureComponent } from "react"
|
||||||
import expect from "expect"
|
import expect from "expect"
|
||||||
import System from "core/system"
|
import System from "core/system"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS } from "immutable"
|
||||||
|
import { render } from "enzyme"
|
||||||
|
import ViewPlugin from "core/plugins/view/index.js"
|
||||||
|
import { connect, Provider } from "react-redux"
|
||||||
|
|
||||||
describe("bound system", function(){
|
describe("bound system", function(){
|
||||||
|
|
||||||
@@ -444,4 +448,239 @@ describe("bound system", function(){
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("getComponent", function() {
|
||||||
|
it("returns a component from the system", function() {
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
test: ({ name }) => <div>{name} component</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("test")
|
||||||
|
const renderedComponent = render(<Component name="Test" />)
|
||||||
|
expect(renderedComponent.text()).toEqual("Test component")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("allows container components to provide their own `mapStateToProps` function", function() {
|
||||||
|
// Given
|
||||||
|
class ContainerComponent extends PureComponent {
|
||||||
|
mapStateToProps(nextState, props) {
|
||||||
|
return {
|
||||||
|
"fromMapState": "This came from mapStateToProps"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
"fromMapState" : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { exampleSelectors, fromMapState, fromOwnProps } = this.props
|
||||||
|
return (
|
||||||
|
<div>{ fromMapState } {exampleSelectors.foo()} {fromOwnProps}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
ContainerComponent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statePlugins: {
|
||||||
|
example: {
|
||||||
|
selectors: {
|
||||||
|
foo() { return "and this came from the system" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("ContainerComponent", true)
|
||||||
|
const renderedComponent = render(
|
||||||
|
<Provider store={system.getStore()}>
|
||||||
|
<Component fromOwnProps="and this came from my own props" />
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("gives the system and own props as props to a container's `mapStateToProps` function", function() {
|
||||||
|
// Given
|
||||||
|
class ContainerComponent extends PureComponent {
|
||||||
|
mapStateToProps(nextState, props) {
|
||||||
|
const { exampleSelectors, fromMapState, fromOwnProps } = props
|
||||||
|
return {
|
||||||
|
"fromMapState": `This came from mapStateToProps ${exampleSelectors.foo()} ${fromOwnProps}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
"fromMapState" : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { fromMapState } = this.props
|
||||||
|
return (
|
||||||
|
<div>{ fromMapState }</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
ContainerComponent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statePlugins: {
|
||||||
|
example: {
|
||||||
|
selectors: {
|
||||||
|
foo() { return "and this came from the system" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("ContainerComponent", true)
|
||||||
|
const renderedComponent = render(
|
||||||
|
<Provider store={system.getStore()}>
|
||||||
|
<Component fromOwnProps="and this came from my own props" />
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of React Component Class render methods", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of pure component render methods", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends PureComponent {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of stateless component functions", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
let BrokenComponent = function BrokenComponent() { throw new Error("This component is broken") }
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text().startsWith("😱 Could not render")).toEqual(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of container components", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent", true)
|
||||||
|
const renderedComponent = render(
|
||||||
|
<Provider store={system.getStore()}>
|
||||||
|
<Component />
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user