Skip to content

Commit

Permalink
refactor(components): rewrite ModelExample into functional component (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
char0n committed Mar 6, 2024
1 parent 227e94f commit a9731c5
Showing 1 changed file with 142 additions and 126 deletions.
268 changes: 142 additions & 126 deletions src/core/components/model-example.jsx
Original file line number Diff line number Diff line change
@@ -1,146 +1,162 @@
import React from "react"
/**
* @prettier
*/
import React, { useMemo, useState, useEffect, useCallback, useRef } from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import cx from "classnames"
import randomBytes from "randombytes"

export default class ModelExample extends React.Component {
static propTypes = {
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.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,
}

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
const usePrevious = (value) => {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}

this.setState({
activeTab: name
})
}
const useTabs = ({ initialTab, isExecute, schema, example }) => {
const tabs = useMemo(() => ({ example: "example", model: "model" }), [])
const allowedTabs = useMemo(() => Object.keys(tabs), [tabs])
const tab =
!allowedTabs.includes(initialTab) || !schema || isExecute
? tabs.example
: initialTab
const prevIsExecute = usePrevious(isExecute)
const [activeTab, setActiveTab] = useState(tab)
const handleTabChange = useCallback((e) => {
setActiveTab(e.target.dataset.name)
}, [])

UNSAFE_componentWillReceiveProps(nextProps) {
if (
nextProps.isExecute &&
!this.props.isExecute &&
this.props.example
) {
this.setState({ activeTab: "example" })
useEffect(() => {
if (prevIsExecute && !isExecute && example) {
setActiveTab(tabs.example)
}
}
}, [prevIsExecute, isExecute, example])

render() {
let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath, includeReadOnly, includeWriteOnly } = this.props
let { defaultModelExpandDepth } = getConfigs()
const ModelWrapper = getComponent("ModelWrapper")
const HighlightCode = getComponent("highlightCode")
const exampleTabId = randomBytes(5).toString("base64")
const examplePanelId = randomBytes(5).toString("base64")
const modelTabId = randomBytes(5).toString("base64")
const modelPanelId = randomBytes(5).toString("base64")
return { activeTab, onTabChange: handleTabChange, tabs }
}

let isOAS3 = specSelectors.isOAS3()
const ModelExample = ({
schema,
example,
isExecute = false,
specPath,
includeWriteOnly = false,
includeReadOnly = false,
getComponent,
getConfigs,
specSelectors,
}) => {
const { defaultModelRendering, defaultModelExpandDepth } = getConfigs()
const ModelWrapper = getComponent("ModelWrapper")
const HighlightCode = getComponent("highlightCode")
const exampleTabId = randomBytes(5).toString("base64")
const examplePanelId = randomBytes(5).toString("base64")
const modelTabId = randomBytes(5).toString("base64")
const modelPanelId = randomBytes(5).toString("base64")
const isOAS3 = specSelectors.isOAS3()
const { activeTab, tabs, onTabChange } = useTabs({
initialTab: defaultModelRendering,
isExecute,
schema,
example,
})

return (
<div className="model-example">
<ul className="tab" role="tablist">
<li className={cx("tabitem", { active: this.state.activeTab === "example" })} role="presentation">
return (
<div className="model-example">
<ul className="tab" role="tablist">
<li
className={cx("tabitem", { active: activeTab === tabs.example })}
role="presentation"
>
<button
aria-controls={examplePanelId}
aria-selected={activeTab === tabs.example}
className="tablinks"
data-name="example"
id={exampleTabId}
onClick={onTabChange}
role="tab"
>
{isExecute ? "Edit Value" : "Example Value"}
</button>
</li>
{schema && (
<li
className={cx("tabitem", { active: activeTab === tabs.model })}
role="presentation"
>
<button
aria-controls={examplePanelId}
aria-selected={this.state.activeTab === "example"}
className="tablinks"
data-name="example"
id={exampleTabId}
onClick={ this.activeTab }
aria-controls={modelPanelId}
aria-selected={activeTab === tabs.model}
className={cx("tablinks", { inactive: isExecute })}
data-name="model"
id={modelTabId}
onClick={onTabChange}
role="tab"
>
{isExecute ? "Edit Value" : "Example Value"}
{isOAS3 ? "Schema" : "Model"}
</button>
</li>
{ schema && (
<li className={cx("tabitem", { active: this.state.activeTab === "model" })} role="presentation">
<button
aria-controls={modelPanelId}
aria-selected={this.state.activeTab === "model"}
className={cx("tablinks", { inactive: isExecute })}
data-name="model"
id={modelTabId}
onClick={ this.activeTab }
role="tab"
>
{isOAS3 ? "Schema" : "Model" }
</button>
</li>
)}
</ul>
{this.state.activeTab === "example" && (
<div
aria-hidden={this.state.activeTab !== "example"}
aria-labelledby={exampleTabId}
data-name="examplePanel"
id={examplePanelId}
role="tabpanel"
tabIndex="0"
>
{example ? example : (
<HighlightCode value="(no example available)" getConfigs={ getConfigs } />
)}
</div>
)}

{this.state.activeTab === "model" && (
<div
aria-hidden={this.state.activeTab === "example"}
aria-labelledby={modelTabId}
data-name="modelPanel"
id={modelPanelId}
role="tabpanel"
tabIndex="0"
>
<ModelWrapper
schema={ schema }
getComponent={ getComponent }
getConfigs={ getConfigs }
specSelectors={ specSelectors }
expandDepth={ defaultModelExpandDepth }
specPath={specPath}
includeReadOnly = {includeReadOnly}
includeWriteOnly = {includeWriteOnly}
</ul>
{activeTab === tabs.example && (
<div
aria-hidden={activeTab !== tabs.example}
aria-labelledby={exampleTabId}
data-name="examplePanel"
id={examplePanelId}
role="tabpanel"
tabIndex="0"
>
{example ? (
example
) : (
<HighlightCode
value="(no example available)"
getConfigs={getConfigs}
/>
</div>
)}
</div>
)
}
)}
</div>
)}

{activeTab === tabs.model && (
<div
aria-hidden={activeTab === tabs.example}
aria-labelledby={modelTabId}
data-name="modelPanel"
id={modelPanelId}
role="tabpanel"
tabIndex="0"
>
<ModelWrapper
schema={schema}
getComponent={getComponent}
getConfigs={getConfigs}
specSelectors={specSelectors}
expandDepth={defaultModelExpandDepth}
specPath={specPath}
includeReadOnly={includeReadOnly}
includeWriteOnly={includeWriteOnly}
/>
</div>
)}
</div>
)
}

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

0 comments on commit a9731c5

Please sign in to comment.