housekeeping: factor out components for easier BaseLayout reuse (#4604)
* improve: wrap schemes to encapsulate rendering logic * improve: wrap filter to encapsulate rendering logic * improve: wrap info section to encapsulate rendering logic * improve: wrap servers plugin to encapsulate rendering logic * improve: added tests for schemes-wrapper rendering logic * improve: added tests for info-wrapper rendering logic, also do not render info if info is undefined * improve: added tests for filter rendering logic * improve: added tests for servers-wrapper rendering logic * `InfoWrapper` -> `InfoContainer` * add `containers` alias to Babel configuration * `SchemesWrapper` -> `SchemesContainer` * drop `container` from container file names * `ServersWrapper` -> `ServersContainer` * `Filter` -> `FilterContainer` * follow `core/containers` pattern in BasePreset
This commit is contained in:
@@ -6,67 +6,35 @@ export default class BaseLayout extends React.Component {
|
||||
static propTypes = {
|
||||
errSelectors: PropTypes.object.isRequired,
|
||||
errActions: PropTypes.object.isRequired,
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
oas3Selectors: PropTypes.object.isRequired,
|
||||
oas3Actions: PropTypes.object.isRequired,
|
||||
layoutSelectors: PropTypes.object.isRequired,
|
||||
layoutActions: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
onFilterChange =(e) => {
|
||||
let {target: {value}} = e
|
||||
this.props.layoutActions.updateFilter(value)
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
specSelectors,
|
||||
specActions,
|
||||
getComponent,
|
||||
layoutSelectors,
|
||||
oas3Selectors,
|
||||
oas3Actions
|
||||
} = this.props
|
||||
|
||||
let info = specSelectors.info()
|
||||
let url = specSelectors.url()
|
||||
let basePath = specSelectors.basePath()
|
||||
let host = specSelectors.host()
|
||||
let securityDefinitions = specSelectors.securityDefinitions()
|
||||
let externalDocs = specSelectors.externalDocs()
|
||||
let schemes = specSelectors.schemes()
|
||||
let servers = specSelectors.servers()
|
||||
let {specSelectors, getComponent} = this.props
|
||||
|
||||
let SvgAssets = getComponent("SvgAssets")
|
||||
let InfoContainer = getComponent("InfoContainer", true)
|
||||
let VersionPragmaFilter = getComponent("VersionPragmaFilter")
|
||||
let Info = getComponent("info")
|
||||
let Operations = getComponent("operations", true)
|
||||
let Models = getComponent("Models", true)
|
||||
let AuthorizeBtn = getComponent("authorizeBtn", true)
|
||||
let Row = getComponent("Row")
|
||||
let Col = getComponent("Col")
|
||||
let Servers = getComponent("Servers")
|
||||
let ServersContainer = getComponent("ServersContainer", true)
|
||||
let Errors = getComponent("errors", true)
|
||||
|
||||
const SchemesContainer = getComponent("SchemesContainer", true)
|
||||
const FilterContainer = getComponent("FilterContainer", true)
|
||||
let isSwagger2 = specSelectors.isSwagger2()
|
||||
let isOAS3 = specSelectors.isOAS3()
|
||||
|
||||
let isLoading = specSelectors.loadingStatus() === "loading"
|
||||
let isFailed = specSelectors.loadingStatus() === "failed"
|
||||
let filter = layoutSelectors.currentFilter()
|
||||
|
||||
let inputStyle = {}
|
||||
if(isFailed) inputStyle.color = "red"
|
||||
if(isLoading) inputStyle.color = "#aaa"
|
||||
|
||||
const Schemes = getComponent("schemes")
|
||||
|
||||
const isSpecEmpty = !specSelectors.specStr()
|
||||
|
||||
if(isSpecEmpty) {
|
||||
let loadingMessage
|
||||
let isLoading = specSelectors.loadingStatus() === "loading"
|
||||
if(isLoading) {
|
||||
loadingMessage = <div className="loading"></div>
|
||||
} else {
|
||||
@@ -88,53 +56,15 @@ export default class BaseLayout extends React.Component {
|
||||
<Errors/>
|
||||
<Row className="information-container">
|
||||
<Col mobile={12}>
|
||||
{ info.count() ? (
|
||||
<Info info={ info } url={ url } host={ host } basePath={ basePath } externalDocs={externalDocs} getComponent={getComponent}/>
|
||||
) : null }
|
||||
<InfoContainer/>
|
||||
</Col>
|
||||
</Row>
|
||||
{ schemes && schemes.size || securityDefinitions ? (
|
||||
<div className="scheme-container">
|
||||
<Col className="schemes wrapper" mobile={12}>
|
||||
{ schemes && schemes.size ? (
|
||||
<Schemes
|
||||
currentScheme={specSelectors.operationScheme()}
|
||||
schemes={ schemes }
|
||||
specActions={ specActions } />
|
||||
) : null }
|
||||
|
||||
{ securityDefinitions ? (
|
||||
<AuthorizeBtn />
|
||||
) : null }
|
||||
</Col>
|
||||
</div>
|
||||
) : null }
|
||||
<SchemesContainer/>
|
||||
|
||||
{ servers && servers.size ? (
|
||||
<div className="global-server-container">
|
||||
<Col className="servers wrapper" mobile={12}>
|
||||
<span className="servers-title">Server</span>
|
||||
<Servers
|
||||
servers={servers}
|
||||
currentServer={oas3Selectors.selectedServer()}
|
||||
setSelectedServer={oas3Actions.setSelectedServer}
|
||||
setServerVariableValue={oas3Actions.setServerVariableValue}
|
||||
getServerVariable={oas3Selectors.serverVariableValue}
|
||||
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
|
||||
/>
|
||||
</Col>
|
||||
</div>
|
||||
<ServersContainer/>
|
||||
|
||||
) : null}
|
||||
|
||||
{
|
||||
filter === null || filter === false ? null :
|
||||
<div className="filter-container">
|
||||
<Col className="filter wrapper" mobile={12}>
|
||||
<input className="operation-filter-input" placeholder="Filter by tag" type="text" onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter} disabled={isLoading} style={inputStyle} />
|
||||
</Col>
|
||||
</div>
|
||||
}
|
||||
<FilterContainer/>
|
||||
|
||||
<Row>
|
||||
<Col mobile={12} desktop={12} >
|
||||
|
||||
44
src/core/containers/filter.jsx
Normal file
44
src/core/containers/filter.jsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class FilterContainer extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
layoutSelectors: PropTypes.object.isRequired,
|
||||
layoutActions: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
onFilterChange = (e) => {
|
||||
const {target: {value}} = e
|
||||
this.props.layoutActions.updateFilter(value)
|
||||
}
|
||||
|
||||
render () {
|
||||
const {specSelectors, layoutSelectors, getComponent} = this.props
|
||||
const Col = getComponent("Col")
|
||||
|
||||
const isLoading = specSelectors.loadingStatus() === "loading"
|
||||
const isFailed = specSelectors.loadingStatus() === "failed"
|
||||
const filter = layoutSelectors.currentFilter()
|
||||
|
||||
const inputStyle = {}
|
||||
if (isFailed) inputStyle.color = "red"
|
||||
if (isLoading) inputStyle.color = "#aaa"
|
||||
|
||||
return (
|
||||
<div>
|
||||
{filter === null || filter === false ? null :
|
||||
<div className="filter-container">
|
||||
<Col className="filter wrapper" mobile={12}>
|
||||
<input className="operation-filter-input" placeholder="Filter by tag" type="text"
|
||||
onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter}
|
||||
disabled={isLoading} style={inputStyle}/>
|
||||
</Col>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
32
src/core/containers/info.jsx
Normal file
32
src/core/containers/info.jsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class InfoContainer extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render () {
|
||||
const {specSelectors, getComponent} = this.props
|
||||
|
||||
const info = specSelectors.info()
|
||||
const url = specSelectors.url()
|
||||
const basePath = specSelectors.basePath()
|
||||
const host = specSelectors.host()
|
||||
const externalDocs = specSelectors.externalDocs()
|
||||
|
||||
const Info = getComponent("info")
|
||||
|
||||
return (
|
||||
<div>
|
||||
{info && info.count() ? (
|
||||
<Info info={info} url={url} host={host} basePath={basePath} externalDocs={externalDocs}
|
||||
getComponent={getComponent}/>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
43
src/core/containers/schemes.jsx
Normal file
43
src/core/containers/schemes.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class SchemesContainer extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render () {
|
||||
const {specActions, specSelectors, getComponent} = this.props
|
||||
const currentScheme = specSelectors.operationScheme()
|
||||
const schemes = specSelectors.schemes()
|
||||
const securityDefinitions = specSelectors.securityDefinitions()
|
||||
|
||||
const Col = getComponent("Col")
|
||||
const AuthorizeBtn = getComponent("authorizeBtn", true)
|
||||
const Schemes = getComponent("schemes")
|
||||
|
||||
return (
|
||||
<div>
|
||||
{schemes && schemes.size || securityDefinitions ? (
|
||||
<div className="scheme-container">
|
||||
<Col className="schemes wrapper" mobile={12}>
|
||||
{schemes && schemes.size ? (
|
||||
<Schemes
|
||||
currentScheme={currentScheme}
|
||||
schemes={schemes}
|
||||
specActions={specActions}
|
||||
/>
|
||||
) : null}
|
||||
{securityDefinitions ? (
|
||||
<AuthorizeBtn/>
|
||||
) : null}
|
||||
</Col>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import Callbacks from "./callbacks"
|
||||
import RequestBody from "./request-body"
|
||||
import OperationLink from "./operation-link.jsx"
|
||||
import Servers from "./servers"
|
||||
import ServersContainer from "./servers-container"
|
||||
import RequestBodyEditor from "./request-body-editor"
|
||||
import HttpAuth from "./http-auth"
|
||||
import OperationServers from "./operation-servers"
|
||||
@@ -11,6 +12,7 @@ export default {
|
||||
HttpAuth,
|
||||
RequestBody,
|
||||
Servers,
|
||||
ServersContainer,
|
||||
RequestBodyEditor,
|
||||
OperationServers,
|
||||
operationLink: OperationLink
|
||||
|
||||
42
src/core/plugins/oas3/components/servers-container.jsx
Normal file
42
src/core/plugins/oas3/components/servers-container.jsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class ServersContainer extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
oas3Selectors: PropTypes.object.isRequired,
|
||||
oas3Actions: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render () {
|
||||
const {specSelectors, oas3Selectors, oas3Actions, getComponent} = this.props
|
||||
|
||||
const servers = specSelectors.servers()
|
||||
|
||||
const Col = getComponent("Col")
|
||||
const Servers = getComponent("Servers")
|
||||
|
||||
return (
|
||||
<div>
|
||||
{servers && servers.size ? (
|
||||
<div className="global-server-container">
|
||||
<Col className="servers wrapper" mobile={12}>
|
||||
<span className="servers-title">Server</span>
|
||||
<Servers
|
||||
servers={servers}
|
||||
currentServer={oas3Selectors.selectedServer()}
|
||||
setSelectedServer={oas3Actions.setSelectedServer}
|
||||
setServerVariableValue={oas3Actions.setServerVariableValue}
|
||||
getServerVariable={oas3Selectors.serverVariableValue}
|
||||
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
|
||||
/>
|
||||
</Col>
|
||||
</div>
|
||||
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -51,10 +51,13 @@ import Info, {
|
||||
InfoUrl,
|
||||
InfoBasePath
|
||||
} from "core/components/info"
|
||||
import InfoContainer from "core/containers/info"
|
||||
import Footer from "core/components/footer"
|
||||
import FilterContainer from "core/containers/filter"
|
||||
import ParamBody from "core/components/param-body"
|
||||
import Curl from "core/components/curl"
|
||||
import Schemes from "core/components/schemes"
|
||||
import SchemesContainer from "core/containers/schemes"
|
||||
import ModelCollapse from "core/components/model-collapse"
|
||||
import ModelExample from "core/components/model-example"
|
||||
import ModelWrapper from "core/components/model-wrapper"
|
||||
@@ -95,6 +98,7 @@ export default function() {
|
||||
clear: Clear,
|
||||
liveResponse: LiveResponse,
|
||||
info: Info,
|
||||
InfoContainer,
|
||||
onlineValidatorBadge: OnlineValidatorBadge,
|
||||
operations: Operations,
|
||||
operation: Operation,
|
||||
@@ -110,9 +114,11 @@ export default function() {
|
||||
contentType: ContentType,
|
||||
overview: Overview,
|
||||
footer: Footer,
|
||||
FilterContainer,
|
||||
ParamBody: ParamBody,
|
||||
curl: Curl,
|
||||
schemes: Schemes,
|
||||
SchemesContainer,
|
||||
modelExample: ModelExample,
|
||||
ModelWrapper,
|
||||
ModelCollapse,
|
||||
|
||||
Reference in New Issue
Block a user