Merge pull request #4060 from shockey/master
Refactor `specPath` to Immutable.js data structures to avoid waste renders
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
"react-height": "^2.0.0",
|
||||
"react-hot-loader": "1.3.1",
|
||||
"react-immutable-proptypes": "2.1.0",
|
||||
"react-immutable-pure-component": "^1.1.1",
|
||||
"react-markdown": "^2.5.0",
|
||||
"react-motion": "^0.5.2",
|
||||
"react-object-inspector": "0.2.1",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||
|
||||
@@ -12,7 +13,7 @@ export default class ArrayModel extends Component {
|
||||
name: PropTypes.string,
|
||||
required: PropTypes.bool,
|
||||
expandDepth: PropTypes.number,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
depth: PropTypes.number
|
||||
}
|
||||
|
||||
@@ -48,7 +49,17 @@ export default class ArrayModel extends Component {
|
||||
!description ? null :
|
||||
<Markdown source={ description } />
|
||||
}
|
||||
<span><Model { ...this.props } getConfigs={ getConfigs } specPath={[...specPath, "items"]} name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
|
||||
<span>
|
||||
<Model
|
||||
{ ...this.props }
|
||||
getConfigs={ getConfigs }
|
||||
specPath={specPath.push("items")}
|
||||
name={null}
|
||||
schema={ items }
|
||||
required={ false }
|
||||
depth={ depth + 1 }
|
||||
/>
|
||||
</span>
|
||||
]
|
||||
</ModelCollapse>
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export default class ModelExample extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -9,7 +10,7 @@ export default class ModelExample extends React.Component {
|
||||
example: PropTypes.any.isRequired,
|
||||
isExecute: PropTypes.bool,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
constructor(props, context) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, { PureComponent } from "react"
|
||||
import React from "react"
|
||||
import ImmutablePureComponent from "react-immutable-pure-component"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class Model extends PureComponent {
|
||||
export default class Model extends ImmutablePureComponent {
|
||||
static propTypes = {
|
||||
schema: ImPropTypes.orderedMap.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
@@ -13,7 +14,7 @@ export default class Model extends PureComponent {
|
||||
required: PropTypes.bool,
|
||||
expandDepth: PropTypes.number,
|
||||
depth: PropTypes.number,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
getModelName =( ref )=> {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { Component } from "react"
|
||||
import Im from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class Models extends Component {
|
||||
@@ -20,7 +21,7 @@ export default class Models extends Component {
|
||||
const specPathBase = specSelectors.isOAS3() ? ["components", "schemas"] : ["definitions"]
|
||||
|
||||
const ModelWrapper = getComponent("ModelWrapper")
|
||||
const Collapse = getComponent("Collapse")
|
||||
const Collapse = getComponent("Collapse")
|
||||
|
||||
return <section className={ showModels ? "models is-open" : "models"}>
|
||||
<h4 onClick={() => layoutActions.show("models", !showModels)}>
|
||||
@@ -37,7 +38,7 @@ export default class Models extends Component {
|
||||
<ModelWrapper name={ name }
|
||||
expandDepth={ defaultModelsExpandDepth }
|
||||
schema={ model }
|
||||
specPath={[...specPathBase, name]}
|
||||
specPath={Im.List([...specPathBase, name])}
|
||||
getComponent={ getComponent }
|
||||
specSelectors={ specSelectors }
|
||||
getConfigs = {getConfigs}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component, } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { List } from "immutable"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
const braceOpen = "{"
|
||||
const braceClose = "}"
|
||||
@@ -17,7 +18,7 @@ export default class ObjectModel extends Component {
|
||||
isRef: PropTypes.bool,
|
||||
expandDepth: PropTypes.number,
|
||||
depth: PropTypes.number,
|
||||
specPath: PropTypes.object.isRequired
|
||||
specPath: ImPropTypes.list.isRequired
|
||||
}
|
||||
|
||||
render(){
|
||||
@@ -102,7 +103,7 @@ export default class ObjectModel extends Component {
|
||||
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
|
||||
required={ isRequired }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, "properties", key]}
|
||||
specPath={specPath.push("properties", key)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ value }
|
||||
depth={ depth + 1 } />
|
||||
@@ -141,7 +142,7 @@ export default class ObjectModel extends Component {
|
||||
<td>
|
||||
<Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, "additionalProperties"]}
|
||||
specPath={specPath.push("additionalProperties")}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ additionalProperties }
|
||||
depth={ depth + 1 } />
|
||||
@@ -156,7 +157,7 @@ export default class ObjectModel extends Component {
|
||||
{anyOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, "anyOf", k]}
|
||||
specPath={specPath.push("anyOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
@@ -172,7 +173,7 @@ export default class ObjectModel extends Component {
|
||||
{oneOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, "oneOf", k]}
|
||||
specPath={specPath.push("oneOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
@@ -189,7 +190,7 @@ export default class ObjectModel extends Component {
|
||||
<Model { ...otherProps }
|
||||
required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, "not"]}
|
||||
specPath={specPath.push("not")}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ not }
|
||||
depth={ depth + 1 } />
|
||||
|
||||
@@ -2,11 +2,12 @@ import React, { PureComponent } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { getList } from "core/utils"
|
||||
import { getExtensions, sanitizeUrl } from "core/utils"
|
||||
import { Iterable } from "immutable"
|
||||
import { Iterable, List } from "immutable"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export default class Operation extends PureComponent {
|
||||
static propTypes = {
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
operation: PropTypes.instanceOf(Iterable).isRequired,
|
||||
response: PropTypes.instanceOf(Iterable),
|
||||
request: PropTypes.instanceOf(Iterable),
|
||||
@@ -33,7 +34,7 @@ export default class Operation extends PureComponent {
|
||||
operation: null,
|
||||
response: null,
|
||||
request: null,
|
||||
specPath: []
|
||||
specPath: List()
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -174,7 +175,7 @@ export default class Operation extends PureComponent {
|
||||
|
||||
<Parameters
|
||||
parameters={parameters}
|
||||
specPath={[...specPath, "parameters"]}
|
||||
specPath={specPath.push("parameters")}
|
||||
operation={operation}
|
||||
onChangeKey={onChangeKey}
|
||||
onTryoutClick = { onTryoutClick }
|
||||
@@ -248,7 +249,7 @@ export default class Operation extends PureComponent {
|
||||
specActions={ specActions }
|
||||
produces={ produces }
|
||||
producesValue={ operation.get("produces_value") }
|
||||
specPath={[...specPath, "responses"]}
|
||||
specPath={specPath.push("responses")}
|
||||
path={ path }
|
||||
method={ method }
|
||||
displayRequestDuration={ displayRequestDuration }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Im from "immutable"
|
||||
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
||||
|
||||
const SWAGGER2_OPERATION_METHODS = [
|
||||
@@ -119,7 +120,7 @@ export default class Operations extends React.Component {
|
||||
operations.map( op => {
|
||||
const path = op.get("path")
|
||||
const method = op.get("method")
|
||||
const specPath = ["paths", path, method]
|
||||
const specPath = Im.List(["paths", path, method])
|
||||
|
||||
|
||||
// FIXME: (someday) this logic should probably be in a selector,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component } from "react"
|
||||
import { Map } from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import win from "core/window"
|
||||
import { getExtensions } from "core/utils"
|
||||
|
||||
@@ -15,7 +16,7 @@ export default class ParameterRow extends Component {
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
pathMethod: PropTypes.array.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired
|
||||
}
|
||||
|
||||
constructor(props, context) {
|
||||
@@ -139,7 +140,7 @@ export default class ParameterRow extends Component {
|
||||
|
||||
{
|
||||
bodyParam && schema ? <ModelExample getComponent={ getComponent }
|
||||
specPath={[...specPath, "schema"]}
|
||||
specPath={specPath.push("schema")}
|
||||
getConfigs={ getConfigs }
|
||||
isExecute={ isExecute }
|
||||
specSelectors={ specSelectors }
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class Parameters extends Component {
|
||||
onChangeKey: PropTypes.array,
|
||||
pathMethod: PropTypes.array.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ export default class Parameters extends Component {
|
||||
eachMap(parameters, (parameter, i) => (
|
||||
<ParameterRow
|
||||
fn={ fn }
|
||||
specPath={[...specPath, i]}
|
||||
specPath={specPath.push(i.toString())}
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
param={ parameter }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import cx from "classnames"
|
||||
import { fromJS, Seq, Iterable } from "immutable"
|
||||
import { fromJS, Seq, Iterable, List } from "immutable"
|
||||
import { getSampleSchema, fromJSOrdered } from "core/utils"
|
||||
|
||||
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
|
||||
@@ -47,7 +48,7 @@ export default class Response extends React.Component {
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
fn: PropTypes.object.isRequired,
|
||||
contentType: PropTypes.string,
|
||||
controlsAcceptHeader: PropTypes.bool,
|
||||
@@ -99,7 +100,7 @@ export default class Response extends React.Component {
|
||||
var schema, specPathWithPossibleSchema
|
||||
|
||||
if(isOAS3()) {
|
||||
const schemaPath = ["content", this.state.responseContentType, "schema"]
|
||||
const schemaPath = List(["content", this.state.responseContentType, "schema"])
|
||||
const oas3SchemaForContentType = response.getIn(schemaPath)
|
||||
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
|
||||
includeReadOnly: true
|
||||
@@ -108,7 +109,7 @@ export default class Response extends React.Component {
|
||||
specPathWithPossibleSchema = oas3SchemaForContentType ? schemaPath : specPath
|
||||
} else {
|
||||
schema = inferSchema(response.toJS()) // TODO: don't convert back and forth. Lets just stick with immutable for inferSchema
|
||||
specPathWithPossibleSchema = response.has("schema") ? [...specPath, "schema"] : specPath
|
||||
specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath
|
||||
sampleResponse = schema ? getSampleSchema(schema, contentType, {
|
||||
includeReadOnly: true,
|
||||
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { fromJS, Iterable } from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
|
||||
|
||||
export default class Responses extends React.Component {
|
||||
@@ -17,7 +18,7 @@ export default class Responses extends React.Component {
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
specActions: PropTypes.object.isRequired,
|
||||
oas3Actions: PropTypes.object.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
fn: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ export default class Responses extends React.Component {
|
||||
let className = tryItOutResponse && tryItOutResponse.get("status") == code ? "response_current" : ""
|
||||
return (
|
||||
<Response key={ code }
|
||||
specPath={[...specPath, code]}
|
||||
specPath={specPath.push(code)}
|
||||
isDefault={defaultCode === code}
|
||||
fn={fn}
|
||||
className={ className }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { PureComponent } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import { helpers } from "swagger-client"
|
||||
import { Iterable, fromJS } from "immutable"
|
||||
|
||||
@@ -31,8 +32,7 @@ export default class OperationContainer extends PureComponent {
|
||||
request: PropTypes.instanceOf(Iterable),
|
||||
security: PropTypes.instanceOf(Iterable),
|
||||
isDeepLinkingEnabled: PropTypes.bool.isRequired,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
authActions: PropTypes.object,
|
||||
oas3Actions: PropTypes.object,
|
||||
|
||||
@@ -38,7 +38,7 @@ const RequestBody = ({
|
||||
expandDepth={1}
|
||||
isExecute={isExecute}
|
||||
schema={mediaTypeValue.get("schema")}
|
||||
specPath={[...specPath, "content", contentType]}
|
||||
specPath={specPath.push("content", contentType)}
|
||||
example={<RequestBodyEditor
|
||||
requestBody={requestBody}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -29,7 +29,7 @@ class Parameters extends Component {
|
||||
fn: PropTypes.object.isRequired,
|
||||
tryItOutEnabled: PropTypes.bool,
|
||||
allowTryItOut: PropTypes.bool,
|
||||
specPath: PropTypes.array.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
onTryoutClick: PropTypes.func,
|
||||
onCancelClick: PropTypes.func,
|
||||
onChangeKey: PropTypes.array,
|
||||
@@ -107,7 +107,7 @@ class Parameters extends Component {
|
||||
const { isOAS3 } = specSelectors
|
||||
|
||||
const requestBody = operation.get("requestBody")
|
||||
const requestBodySpecPath = [...specPath.slice(0, -1), "requestBody"] // remove the "parameters" part
|
||||
const requestBodySpecPath = specPath.slice(0, -1).push("requestBody") // remove the "parameters" part
|
||||
|
||||
return (
|
||||
<div className="opblock-section">
|
||||
@@ -143,7 +143,7 @@ class Parameters extends Component {
|
||||
eachMap(parameters, (parameter, i) => (
|
||||
<ParameterRow fn={ fn }
|
||||
getComponent={ getComponent }
|
||||
specPath={[...specPath, i]}
|
||||
specPath={specPath.push(i)}
|
||||
getConfigs={ getConfigs }
|
||||
param={ parameter }
|
||||
key={ parameter.get( "name" ) }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react"
|
||||
import expect from "expect"
|
||||
import { shallow } from "enzyme"
|
||||
import { fromJS } from "immutable"
|
||||
import { fromJS, List } from "immutable"
|
||||
import ObjectModel from "components/object-model"
|
||||
import ModelExample from "components/model-example"
|
||||
import Immutable from "immutable"
|
||||
@@ -25,7 +25,7 @@ describe("<ObjectModel />", function() {
|
||||
}
|
||||
},
|
||||
isRef : false,
|
||||
specPath: [],
|
||||
specPath: List(),
|
||||
schema: Immutable.fromJS(
|
||||
{
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user