refactor(components): rewrite ModelExample into functional component (#9668)
This commit is contained in:
@@ -1,101 +1,99 @@
|
|||||||
import React from "react"
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import React, { useMemo, useState, useEffect, useCallback, useRef } 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 cx from "classnames"
|
import cx from "classnames"
|
||||||
import randomBytes from "randombytes"
|
import randomBytes from "randombytes"
|
||||||
|
|
||||||
export default class ModelExample extends React.Component {
|
const usePrevious = (value) => {
|
||||||
static propTypes = {
|
const ref = useRef()
|
||||||
getComponent: PropTypes.func.isRequired,
|
useEffect(() => {
|
||||||
specSelectors: PropTypes.object.isRequired,
|
ref.current = value
|
||||||
schema: PropTypes.object.isRequired,
|
|
||||||
example: PropTypes.any.isRequired,
|
|
||||||
isExecute: PropTypes.bool,
|
|
||||||
getConfigs: PropTypes.func.isRequired,
|
|
||||||
specPath: ImPropTypes.list.isRequired,
|
|
||||||
includeReadOnly: PropTypes.bool,
|
|
||||||
includeWriteOnly: PropTypes.bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context)
|
|
||||||
let { getConfigs, isExecute, schema } = this.props
|
|
||||||
let { defaultModelRendering } = getConfigs()
|
|
||||||
|
|
||||||
let activeTab = defaultModelRendering
|
|
||||||
|
|
||||||
if (defaultModelRendering !== "example" && defaultModelRendering !== "model") {
|
|
||||||
activeTab = "example"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!schema) {
|
|
||||||
activeTab = "example"
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isExecute) {
|
|
||||||
activeTab = "example"
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
activeTab,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
activeTab = ( e ) => {
|
|
||||||
let { target : { dataset : { name } } } = e
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
activeTab: name
|
|
||||||
})
|
})
|
||||||
|
return ref.current
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
const useTabs = ({ initialTab, isExecute, schema, example }) => {
|
||||||
if (
|
const tabs = useMemo(() => ({ example: "example", model: "model" }), [])
|
||||||
nextProps.isExecute &&
|
const allowedTabs = useMemo(() => Object.keys(tabs), [tabs])
|
||||||
!this.props.isExecute &&
|
const tab =
|
||||||
this.props.example
|
!allowedTabs.includes(initialTab) || !schema || isExecute
|
||||||
) {
|
? tabs.example
|
||||||
this.setState({ activeTab: "example" })
|
: initialTab
|
||||||
|
const prevIsExecute = usePrevious(isExecute)
|
||||||
|
const [activeTab, setActiveTab] = useState(tab)
|
||||||
|
const handleTabChange = useCallback((e) => {
|
||||||
|
setActiveTab(e.target.dataset.name)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (prevIsExecute && !isExecute && example) {
|
||||||
|
setActiveTab(tabs.example)
|
||||||
}
|
}
|
||||||
|
}, [prevIsExecute, isExecute, example])
|
||||||
|
|
||||||
|
return { activeTab, onTabChange: handleTabChange, tabs }
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const ModelExample = ({
|
||||||
let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath, includeReadOnly, includeWriteOnly } = this.props
|
schema,
|
||||||
let { defaultModelExpandDepth } = getConfigs()
|
example,
|
||||||
|
isExecute = false,
|
||||||
|
specPath,
|
||||||
|
includeWriteOnly = false,
|
||||||
|
includeReadOnly = false,
|
||||||
|
getComponent,
|
||||||
|
getConfigs,
|
||||||
|
specSelectors,
|
||||||
|
}) => {
|
||||||
|
const { defaultModelRendering, defaultModelExpandDepth } = getConfigs()
|
||||||
const ModelWrapper = getComponent("ModelWrapper")
|
const ModelWrapper = getComponent("ModelWrapper")
|
||||||
const HighlightCode = getComponent("highlightCode")
|
const HighlightCode = getComponent("highlightCode")
|
||||||
const exampleTabId = randomBytes(5).toString("base64")
|
const exampleTabId = randomBytes(5).toString("base64")
|
||||||
const examplePanelId = randomBytes(5).toString("base64")
|
const examplePanelId = randomBytes(5).toString("base64")
|
||||||
const modelTabId = randomBytes(5).toString("base64")
|
const modelTabId = randomBytes(5).toString("base64")
|
||||||
const modelPanelId = randomBytes(5).toString("base64")
|
const modelPanelId = randomBytes(5).toString("base64")
|
||||||
|
const isOAS3 = specSelectors.isOAS3()
|
||||||
let isOAS3 = specSelectors.isOAS3()
|
const { activeTab, tabs, onTabChange } = useTabs({
|
||||||
|
initialTab: defaultModelRendering,
|
||||||
|
isExecute,
|
||||||
|
schema,
|
||||||
|
example,
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="model-example">
|
<div className="model-example">
|
||||||
<ul className="tab" role="tablist">
|
<ul className="tab" role="tablist">
|
||||||
<li className={cx("tabitem", { active: this.state.activeTab === "example" })} role="presentation">
|
<li
|
||||||
|
className={cx("tabitem", { active: activeTab === tabs.example })}
|
||||||
|
role="presentation"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
aria-controls={examplePanelId}
|
aria-controls={examplePanelId}
|
||||||
aria-selected={this.state.activeTab === "example"}
|
aria-selected={activeTab === tabs.example}
|
||||||
className="tablinks"
|
className="tablinks"
|
||||||
data-name="example"
|
data-name="example"
|
||||||
id={exampleTabId}
|
id={exampleTabId}
|
||||||
onClick={ this.activeTab }
|
onClick={onTabChange}
|
||||||
role="tab"
|
role="tab"
|
||||||
>
|
>
|
||||||
{isExecute ? "Edit Value" : "Example Value"}
|
{isExecute ? "Edit Value" : "Example Value"}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{schema && (
|
{schema && (
|
||||||
<li className={cx("tabitem", { active: this.state.activeTab === "model" })} role="presentation">
|
<li
|
||||||
|
className={cx("tabitem", { active: activeTab === tabs.model })}
|
||||||
|
role="presentation"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
aria-controls={modelPanelId}
|
aria-controls={modelPanelId}
|
||||||
aria-selected={this.state.activeTab === "model"}
|
aria-selected={activeTab === tabs.model}
|
||||||
className={cx("tablinks", { inactive: isExecute })}
|
className={cx("tablinks", { inactive: isExecute })}
|
||||||
data-name="model"
|
data-name="model"
|
||||||
id={modelTabId}
|
id={modelTabId}
|
||||||
onClick={ this.activeTab }
|
onClick={onTabChange}
|
||||||
role="tab"
|
role="tab"
|
||||||
>
|
>
|
||||||
{isOAS3 ? "Schema" : "Model"}
|
{isOAS3 ? "Schema" : "Model"}
|
||||||
@@ -103,24 +101,29 @@ export default class ModelExample extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
{this.state.activeTab === "example" && (
|
{activeTab === tabs.example && (
|
||||||
<div
|
<div
|
||||||
aria-hidden={this.state.activeTab !== "example"}
|
aria-hidden={activeTab !== tabs.example}
|
||||||
aria-labelledby={exampleTabId}
|
aria-labelledby={exampleTabId}
|
||||||
data-name="examplePanel"
|
data-name="examplePanel"
|
||||||
id={examplePanelId}
|
id={examplePanelId}
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
>
|
>
|
||||||
{example ? example : (
|
{example ? (
|
||||||
<HighlightCode value="(no example available)" getConfigs={ getConfigs } />
|
example
|
||||||
|
) : (
|
||||||
|
<HighlightCode
|
||||||
|
value="(no example available)"
|
||||||
|
getConfigs={getConfigs}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.state.activeTab === "model" && (
|
{activeTab === tabs.model && (
|
||||||
<div
|
<div
|
||||||
aria-hidden={this.state.activeTab === "example"}
|
aria-hidden={activeTab === tabs.example}
|
||||||
aria-labelledby={modelTabId}
|
aria-labelledby={modelTabId}
|
||||||
data-name="modelPanel"
|
data-name="modelPanel"
|
||||||
id={modelPanelId}
|
id={modelPanelId}
|
||||||
@@ -143,4 +146,17 @@ export default class ModelExample extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelExample.propTypes = {
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
specSelectors: PropTypes.shape({ isOAS3: PropTypes.func.isRequired })
|
||||||
|
.isRequired,
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
example: PropTypes.any.isRequired,
|
||||||
|
isExecute: PropTypes.bool,
|
||||||
|
getConfigs: PropTypes.func.isRequired,
|
||||||
|
specPath: ImPropTypes.list.isRequired,
|
||||||
|
includeReadOnly: PropTypes.bool,
|
||||||
|
includeWriteOnly: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default ModelExample
|
||||||
|
|||||||
Reference in New Issue
Block a user