Refactor Operation component to not trigger its own re-render

This commit is contained in:
Kyle Shockey
2017-11-09 16:28:53 -08:00
parent 076f32b1f0
commit e33de3049f
3 changed files with 23 additions and 35 deletions

View File

@@ -21,6 +21,10 @@ export default class ObjectModel extends Component {
let { specSelectors } = otherProps let { specSelectors } = otherProps
let { isOAS3 } = specSelectors let { isOAS3 } = specSelectors
if(!schema) {
return null
}
let description = schema.get("description") let description = schema.get("description")
let properties = schema.get("properties") let properties = schema.get("properties")
let additionalProperties = schema.get("additionalProperties") let additionalProperties = schema.get("additionalProperties")

View File

@@ -12,8 +12,10 @@ export default class Operation extends PureComponent {
method: PropTypes.string.isRequired, method: PropTypes.string.isRequired,
operation: PropTypes.object.isRequired, operation: PropTypes.object.isRequired,
showSummary: PropTypes.bool, showSummary: PropTypes.bool,
isShown: PropTypes.bool.isRequired,
isShownKey: CustomPropTypes.arrayOrString.isRequired, tagKey: PropTypes.string,
operationKey: PropTypes.string,
jumpToKey: CustomPropTypes.arrayOrString.isRequired, jumpToKey: CustomPropTypes.arrayOrString.isRequired,
allowTryItOut: PropTypes.bool, allowTryItOut: PropTypes.bool,
@@ -52,38 +54,16 @@ export default class Operation extends PureComponent {
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const defaultContentType = "application/json"
let { specActions, path, method, operation } = nextProps
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) { if(nextProps.response !== this.props.response) {
this.setState({ executeInProgress: false }) 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 =() => { toggleShown =() => {
let { layoutActions, isShownKey } = this.props let { layoutActions, tagKey, operationKey, isShown } = this.props
layoutActions.show(isShownKey, !this.isShown()) const isShownKey = ["operations", tagKey, operationKey]
}
isShown =() => { layoutActions.show(isShownKey, !isShown)
let { layoutSelectors, isShownKey, getConfigs } = this.props
let { docExpansion } = getConfigs()
return layoutSelectors.isShown(isShownKey, docExpansion === "full" ) // Here is where we set the default
} }
onTryoutClick =() => { onTryoutClick =() => {
@@ -102,7 +82,9 @@ export default class Operation extends PureComponent {
render() { render() {
let { let {
isShownKey, operationKey,
tagKey,
isShown,
jumpToKey, jumpToKey,
path, path,
method, method,
@@ -156,18 +138,17 @@ export default class Operation extends PureComponent {
} }
let { tryItOutEnabled } = this.state let { tryItOutEnabled } = this.state
let shown = this.isShown()
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" : shown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={isShownKey.join("-")} > <div className={deprecated ? "opblock opblock-deprecated" : isShown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={`operations-${tagKey}-${operationKey}`} >
<div className={`opblock-summary opblock-summary-${method}`} onClick={this.toggleShown} > <div className={`opblock-summary opblock-summary-${method}`} onClick={this.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 ? `#/${isShownKey[1]}/${isShownKey[2]}` : null}> href={isDeepLinkingEnabled ? `#/${tagKey}/${operationKey}` : null}>
<span>{path}</span> <span>{path}</span>
</a> </a>
<JumpToPath path={jumpToKey} /> <JumpToPath path={jumpToKey} />
@@ -193,7 +174,7 @@ export default class Operation extends PureComponent {
} }
</div> </div>
<Collapse isOpened={shown}> <Collapse isOpened={isShown}>
<div className="opblock-body"> <div className="opblock-body">
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>} { deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
{ description && { description &&

View File

@@ -1,4 +1,5 @@
import React from "react" import React from "react"
import { List } from "immutable"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import { helpers } from "swagger-client" import { helpers } from "swagger-client"
import { createDeepLinkPath, sanitizeUrl } from "core/utils" import { createDeepLinkPath, sanitizeUrl } from "core/utils"
@@ -127,7 +128,8 @@ export default class Operations extends React.Component {
const operationId = const operationId =
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id") op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id")
const isShownKey = ["operations", createDeepLinkPath(tag), createDeepLinkPath(operationId)] const tagKey = createDeepLinkPath(tag)
const operationKey = createDeepLinkPath(operationId)
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method")) const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method"))
const response = specSelectors.responseFor(op.get("path"), op.get("method")) const response = specSelectors.responseFor(op.get("path"), op.get("method"))
@@ -135,11 +137,12 @@ export default class Operations extends React.Component {
return <Operation return <Operation
{...op.toObject()} {...op.toObject()}
tagKey={tagKey}
isShownKey={isShownKey} operationKey={operationKey}
isShown={layoutSelectors.isShown(["operations", tagKey, operationKey])}
jumpToKey={jumpToKey} jumpToKey={jumpToKey}
showSummary={showSummary} showSummary={showSummary}
key={isShownKey} key={tagKey + operationKey}
response={ response } response={ response }
request={ request } request={ request }
allowTryItOut={allowTryItOut} allowTryItOut={allowTryItOut}