From a9731c547c9fb740ebb469ec90590416b1bd8245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Wed, 6 Mar 2024 16:32:54 +0100 Subject: [PATCH] refactor(components): rewrite ModelExample into functional component (#9668) --- src/core/components/model-example.jsx | 268 ++++++++++++++------------ 1 file changed, 142 insertions(+), 126 deletions(-) diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx index 307e4878..447b1591 100644 --- a/src/core/components/model-example.jsx +++ b/src/core/components/model-example.jsx @@ -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, - } +const usePrevious = (value) => { + const ref = useRef() + useEffect(() => { + ref.current = value + }) + return ref.current +} - constructor(props, context) { - super(props, context) - let { getConfigs, isExecute, schema } = this.props - let { defaultModelRendering } = getConfigs() +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) + }, []) - let activeTab = defaultModelRendering - - if (defaultModelRendering !== "example" && defaultModelRendering !== "model") { - activeTab = "example" + useEffect(() => { + if (prevIsExecute && !isExecute && example) { + setActiveTab(tabs.example) } + }, [prevIsExecute, isExecute, example]) - if (!schema) { - activeTab = "example" - } + return { activeTab, onTabChange: handleTabChange, tabs } +} - if(isExecute) { - activeTab = "example" - } +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, + }) - this.state = { - activeTab, - } - } - - activeTab = ( e ) => { - let { target : { dataset : { name } } } = e - - this.setState({ - activeTab: name - }) - } - - UNSAFE_componentWillReceiveProps(nextProps) { - if ( - nextProps.isExecute && - !this.props.isExecute && - this.props.example - ) { - this.setState({ activeTab: "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") - - let isOAS3 = specSelectors.isOAS3() - - return ( -
-
+ ) } + +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