refactor(components): rewrite ModelExample into functional component (#9668)

This commit is contained in:
Vladimír Gorej
2024-03-06 16:32:54 +01:00
committed by GitHub
parent 227e94f748
commit a9731c547c

View File

@@ -1,101 +1,99 @@
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
this.setState({
activeTab: name
const usePrevious = (value) => {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (
nextProps.isExecute &&
!this.props.isExecute &&
this.props.example
) {
this.setState({ activeTab: "example" })
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)
}, [])
useEffect(() => {
if (prevIsExecute && !isExecute && example) {
setActiveTab(tabs.example)
}
}, [prevIsExecute, isExecute, example])
return { activeTab, onTabChange: handleTabChange, tabs }
}
render() {
let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath, includeReadOnly, includeWriteOnly } = this.props
let { defaultModelExpandDepth } = getConfigs()
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")
let isOAS3 = specSelectors.isOAS3()
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">
<li
className={cx("tabitem", { active: activeTab === tabs.example })}
role="presentation"
>
<button
aria-controls={examplePanelId}
aria-selected={this.state.activeTab === "example"}
aria-selected={activeTab === tabs.example}
className="tablinks"
data-name="example"
id={exampleTabId}
onClick={ this.activeTab }
onClick={onTabChange}
role="tab"
>
{isExecute ? "Edit Value" : "Example Value"}
</button>
</li>
{schema && (
<li className={cx("tabitem", { active: this.state.activeTab === "model" })} role="presentation">
<li
className={cx("tabitem", { active: activeTab === tabs.model })}
role="presentation"
>
<button
aria-controls={modelPanelId}
aria-selected={this.state.activeTab === "model"}
aria-selected={activeTab === tabs.model}
className={cx("tablinks", { inactive: isExecute })}
data-name="model"
id={modelTabId}
onClick={ this.activeTab }
onClick={onTabChange}
role="tab"
>
{isOAS3 ? "Schema" : "Model"}
@@ -103,24 +101,29 @@ export default class ModelExample extends React.Component {
</li>
)}
</ul>
{this.state.activeTab === "example" && (
{activeTab === tabs.example && (
<div
aria-hidden={this.state.activeTab !== "example"}
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 } />
{example ? (
example
) : (
<HighlightCode
value="(no example available)"
getConfigs={getConfigs}
/>
)}
</div>
)}
{this.state.activeTab === "model" && (
{activeTab === tabs.model && (
<div
aria-hidden={this.state.activeTab === "example"}
aria-hidden={activeTab === tabs.example}
aria-labelledby={modelTabId}
data-name="modelPanel"
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