Skip to content

Commit 8416b04

Browse files
sverdlovkashockey
authored andcommitted
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
1 parent 0eb591b commit 8416b04

File tree

12 files changed

+511
-80
lines changed

12 files changed

+511
-80
lines changed

.babelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
"expose": "components",
1919
"src": "src/core/components"
2020
},
21+
{
22+
"expose": "containers",
23+
"src": "src/core/containers"
24+
},
2125
{
2226
"expose": "core",
2327
"src": "src/core"

src/core/components/layouts/base.jsx

Lines changed: 10 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,35 @@ export default class BaseLayout extends React.Component {
66
static propTypes = {
77
errSelectors: PropTypes.object.isRequired,
88
errActions: PropTypes.object.isRequired,
9-
specActions: PropTypes.object.isRequired,
109
specSelectors: PropTypes.object.isRequired,
1110
oas3Selectors: PropTypes.object.isRequired,
1211
oas3Actions: PropTypes.object.isRequired,
13-
layoutSelectors: PropTypes.object.isRequired,
14-
layoutActions: PropTypes.object.isRequired,
1512
getComponent: PropTypes.func.isRequired
1613
}
1714

18-
onFilterChange =(e) => {
19-
let {target: {value}} = e
20-
this.props.layoutActions.updateFilter(value)
21-
}
22-
2315
render() {
24-
let {
25-
specSelectors,
26-
specActions,
27-
getComponent,
28-
layoutSelectors,
29-
oas3Selectors,
30-
oas3Actions
31-
} = this.props
32-
33-
let info = specSelectors.info()
34-
let url = specSelectors.url()
35-
let basePath = specSelectors.basePath()
36-
let host = specSelectors.host()
37-
let securityDefinitions = specSelectors.securityDefinitions()
38-
let externalDocs = specSelectors.externalDocs()
39-
let schemes = specSelectors.schemes()
40-
let servers = specSelectors.servers()
16+
let {specSelectors, getComponent} = this.props
4117

4218
let SvgAssets = getComponent("SvgAssets")
19+
let InfoContainer = getComponent("InfoContainer", true)
4320
let VersionPragmaFilter = getComponent("VersionPragmaFilter")
44-
let Info = getComponent("info")
4521
let Operations = getComponent("operations", true)
4622
let Models = getComponent("Models", true)
47-
let AuthorizeBtn = getComponent("authorizeBtn", true)
4823
let Row = getComponent("Row")
4924
let Col = getComponent("Col")
50-
let Servers = getComponent("Servers")
25+
let ServersContainer = getComponent("ServersContainer", true)
5126
let Errors = getComponent("errors", true)
5227

28+
const SchemesContainer = getComponent("SchemesContainer", true)
29+
const FilterContainer = getComponent("FilterContainer", true)
5330
let isSwagger2 = specSelectors.isSwagger2()
5431
let isOAS3 = specSelectors.isOAS3()
5532

56-
let isLoading = specSelectors.loadingStatus() === "loading"
57-
let isFailed = specSelectors.loadingStatus() === "failed"
58-
let filter = layoutSelectors.currentFilter()
59-
60-
let inputStyle = {}
61-
if(isFailed) inputStyle.color = "red"
62-
if(isLoading) inputStyle.color = "#aaa"
63-
64-
const Schemes = getComponent("schemes")
65-
6633
const isSpecEmpty = !specSelectors.specStr()
6734

6835
if(isSpecEmpty) {
6936
let loadingMessage
37+
let isLoading = specSelectors.loadingStatus() === "loading"
7038
if(isLoading) {
7139
loadingMessage = <div className="loading"></div>
7240
} else {
@@ -88,53 +56,15 @@ export default class BaseLayout extends React.Component {
8856
<Errors/>
8957
<Row className="information-container">
9058
<Col mobile={12}>
91-
{ info.count() ? (
92-
<Info info={ info } url={ url } host={ host } basePath={ basePath } externalDocs={externalDocs} getComponent={getComponent}/>
93-
) : null }
59+
<InfoContainer/>
9460
</Col>
9561
</Row>
96-
{ schemes && schemes.size || securityDefinitions ? (
97-
<div className="scheme-container">
98-
<Col className="schemes wrapper" mobile={12}>
99-
{ schemes && schemes.size ? (
100-
<Schemes
101-
currentScheme={specSelectors.operationScheme()}
102-
schemes={ schemes }
103-
specActions={ specActions } />
104-
) : null }
105-
106-
{ securityDefinitions ? (
107-
<AuthorizeBtn />
108-
) : null }
109-
</Col>
110-
</div>
111-
) : null }
11262

113-
{ servers && servers.size ? (
114-
<div className="global-server-container">
115-
<Col className="servers wrapper" mobile={12}>
116-
<span className="servers-title">Server</span>
117-
<Servers
118-
servers={servers}
119-
currentServer={oas3Selectors.selectedServer()}
120-
setSelectedServer={oas3Actions.setSelectedServer}
121-
setServerVariableValue={oas3Actions.setServerVariableValue}
122-
getServerVariable={oas3Selectors.serverVariableValue}
123-
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
124-
/>
125-
</Col>
126-
</div>
63+
<SchemesContainer/>
12764

128-
) : null}
65+
<ServersContainer/>
12966

130-
{
131-
filter === null || filter === false ? null :
132-
<div className="filter-container">
133-
<Col className="filter wrapper" mobile={12}>
134-
<input className="operation-filter-input" placeholder="Filter by tag" type="text" onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter} disabled={isLoading} style={inputStyle} />
135-
</Col>
136-
</div>
137-
}
67+
<FilterContainer/>
13868

13969
<Row>
14070
<Col mobile={12} desktop={12} >

src/core/containers/filter.jsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
4+
export default class FilterContainer extends React.Component {
5+
6+
static propTypes = {
7+
specSelectors: PropTypes.object.isRequired,
8+
layoutSelectors: PropTypes.object.isRequired,
9+
layoutActions: PropTypes.object.isRequired,
10+
getComponent: PropTypes.func.isRequired,
11+
}
12+
13+
onFilterChange = (e) => {
14+
const {target: {value}} = e
15+
this.props.layoutActions.updateFilter(value)
16+
}
17+
18+
render () {
19+
const {specSelectors, layoutSelectors, getComponent} = this.props
20+
const Col = getComponent("Col")
21+
22+
const isLoading = specSelectors.loadingStatus() === "loading"
23+
const isFailed = specSelectors.loadingStatus() === "failed"
24+
const filter = layoutSelectors.currentFilter()
25+
26+
const inputStyle = {}
27+
if (isFailed) inputStyle.color = "red"
28+
if (isLoading) inputStyle.color = "#aaa"
29+
30+
return (
31+
<div>
32+
{filter === null || filter === false ? null :
33+
<div className="filter-container">
34+
<Col className="filter wrapper" mobile={12}>
35+
<input className="operation-filter-input" placeholder="Filter by tag" type="text"
36+
onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter}
37+
disabled={isLoading} style={inputStyle}/>
38+
</Col>
39+
</div>
40+
}
41+
</div>
42+
)
43+
}
44+
}

src/core/containers/info.jsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
4+
export default class InfoContainer extends React.Component {
5+
6+
static propTypes = {
7+
specActions: PropTypes.object.isRequired,
8+
specSelectors: PropTypes.object.isRequired,
9+
getComponent: PropTypes.func.isRequired,
10+
}
11+
12+
render () {
13+
const {specSelectors, getComponent} = this.props
14+
15+
const info = specSelectors.info()
16+
const url = specSelectors.url()
17+
const basePath = specSelectors.basePath()
18+
const host = specSelectors.host()
19+
const externalDocs = specSelectors.externalDocs()
20+
21+
const Info = getComponent("info")
22+
23+
return (
24+
<div>
25+
{info && info.count() ? (
26+
<Info info={info} url={url} host={host} basePath={basePath} externalDocs={externalDocs}
27+
getComponent={getComponent}/>
28+
) : null}
29+
</div>
30+
)
31+
}
32+
}

src/core/containers/schemes.jsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
4+
export default class SchemesContainer extends React.Component {
5+
6+
static propTypes = {
7+
specActions: PropTypes.object.isRequired,
8+
specSelectors: PropTypes.object.isRequired,
9+
getComponent: PropTypes.func.isRequired,
10+
}
11+
12+
render () {
13+
const {specActions, specSelectors, getComponent} = this.props
14+
const currentScheme = specSelectors.operationScheme()
15+
const schemes = specSelectors.schemes()
16+
const securityDefinitions = specSelectors.securityDefinitions()
17+
18+
const Col = getComponent("Col")
19+
const AuthorizeBtn = getComponent("authorizeBtn", true)
20+
const Schemes = getComponent("schemes")
21+
22+
return (
23+
<div>
24+
{schemes && schemes.size || securityDefinitions ? (
25+
<div className="scheme-container">
26+
<Col className="schemes wrapper" mobile={12}>
27+
{schemes && schemes.size ? (
28+
<Schemes
29+
currentScheme={currentScheme}
30+
schemes={schemes}
31+
specActions={specActions}
32+
/>
33+
) : null}
34+
{securityDefinitions ? (
35+
<AuthorizeBtn/>
36+
) : null}
37+
</Col>
38+
</div>
39+
) : null}
40+
</div>
41+
)
42+
}
43+
}

src/core/plugins/oas3/components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Callbacks from "./callbacks"
22
import RequestBody from "./request-body"
33
import OperationLink from "./operation-link.jsx"
44
import Servers from "./servers"
5+
import ServersContainer from "./servers-container"
56
import RequestBodyEditor from "./request-body-editor"
67
import HttpAuth from "./http-auth"
78
import OperationServers from "./operation-servers"
@@ -11,6 +12,7 @@ export default {
1112
HttpAuth,
1213
RequestBody,
1314
Servers,
15+
ServersContainer,
1416
RequestBodyEditor,
1517
OperationServers,
1618
operationLink: OperationLink
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
4+
export default class ServersContainer extends React.Component {
5+
6+
static propTypes = {
7+
specSelectors: PropTypes.object.isRequired,
8+
oas3Selectors: PropTypes.object.isRequired,
9+
oas3Actions: PropTypes.object.isRequired,
10+
getComponent: PropTypes.func.isRequired,
11+
}
12+
13+
render () {
14+
const {specSelectors, oas3Selectors, oas3Actions, getComponent} = this.props
15+
16+
const servers = specSelectors.servers()
17+
18+
const Col = getComponent("Col")
19+
const Servers = getComponent("Servers")
20+
21+
return (
22+
<div>
23+
{servers && servers.size ? (
24+
<div className="global-server-container">
25+
<Col className="servers wrapper" mobile={12}>
26+
<span className="servers-title">Server</span>
27+
<Servers
28+
servers={servers}
29+
currentServer={oas3Selectors.selectedServer()}
30+
setSelectedServer={oas3Actions.setSelectedServer}
31+
setServerVariableValue={oas3Actions.setServerVariableValue}
32+
getServerVariable={oas3Selectors.serverVariableValue}
33+
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
34+
/>
35+
</Col>
36+
</div>
37+
38+
) : null}
39+
</div>
40+
)
41+
}
42+
}

src/core/presets/base.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,13 @@ import Info, {
5151
InfoUrl,
5252
InfoBasePath
5353
} from "core/components/info"
54+
import InfoContainer from "core/containers/info"
5455
import Footer from "core/components/footer"
56+
import FilterContainer from "core/containers/filter"
5557
import ParamBody from "core/components/param-body"
5658
import Curl from "core/components/curl"
5759
import Schemes from "core/components/schemes"
60+
import SchemesContainer from "core/containers/schemes"
5861
import ModelCollapse from "core/components/model-collapse"
5962
import ModelExample from "core/components/model-example"
6063
import ModelWrapper from "core/components/model-wrapper"
@@ -95,6 +98,7 @@ export default function() {
9598
clear: Clear,
9699
liveResponse: LiveResponse,
97100
info: Info,
101+
InfoContainer,
98102
onlineValidatorBadge: OnlineValidatorBadge,
99103
operations: Operations,
100104
operation: Operation,
@@ -110,9 +114,11 @@ export default function() {
110114
contentType: ContentType,
111115
overview: Overview,
112116
footer: Footer,
117+
FilterContainer,
113118
ParamBody: ParamBody,
114119
curl: Curl,
115120
schemes: Schemes,
121+
SchemesContainer,
116122
modelExample: ModelExample,
117123
ModelWrapper,
118124
ModelCollapse,

0 commit comments

Comments
 (0)