feat(oas31): resolve components.schemas field before rendering
Refs #8513
This commit is contained in:
committed by
Vladimír Gorej
parent
3a5a605c8e
commit
fa829e3368
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @prettier
|
* @prettier
|
||||||
*/
|
*/
|
||||||
import React, { useState, useCallback, useEffect } from "react"
|
import React, { forwardRef, useState, useCallback, useEffect } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import classNames from "classnames"
|
import classNames from "classnames"
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
JSONSchemaCyclesContext,
|
JSONSchemaCyclesContext,
|
||||||
} from "../../context"
|
} from "../../context"
|
||||||
|
|
||||||
const JSONSchema = ({ schema, name }) => {
|
const JSONSchema = forwardRef(({ schema, name }, ref) => {
|
||||||
const fn = useFn()
|
const fn = useFn()
|
||||||
const isExpandedDeeply = useIsExpandedDeeply()
|
const isExpandedDeeply = useIsExpandedDeeply()
|
||||||
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
||||||
@@ -96,6 +96,7 @@ const JSONSchema = ({ schema, name }) => {
|
|||||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||||
<JSONSchemaCyclesContext.Provider value={renderedSchemas}>
|
<JSONSchemaCyclesContext.Provider value={renderedSchemas}>
|
||||||
<article
|
<article
|
||||||
|
ref={ref}
|
||||||
data-json-schema-level={level}
|
data-json-schema-level={level}
|
||||||
className={classNames("json-schema-2020-12", {
|
className={classNames("json-schema-2020-12", {
|
||||||
"json-schema-2020-12--embedded": isEmbedded,
|
"json-schema-2020-12--embedded": isEmbedded,
|
||||||
@@ -161,7 +162,7 @@ const JSONSchema = ({ schema, name }) => {
|
|||||||
</JSONSchemaDeepExpansionContext.Provider>
|
</JSONSchemaDeepExpansionContext.Provider>
|
||||||
</JSONSchemaLevelContext.Provider>
|
</JSONSchemaLevelContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
JSONSchema.propTypes = {
|
JSONSchema.propTypes = {
|
||||||
name: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
name: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @prettier
|
* @prettier
|
||||||
*/
|
*/
|
||||||
import React, { useCallback } from "react"
|
import React, { useCallback, useEffect } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import classNames from "classnames"
|
import classNames from "classnames"
|
||||||
|
|
||||||
const Models = ({
|
const Models = ({
|
||||||
|
specActions,
|
||||||
specSelectors,
|
specSelectors,
|
||||||
layoutSelectors,
|
layoutSelectors,
|
||||||
layoutActions,
|
layoutActions,
|
||||||
@@ -21,12 +22,39 @@ const Models = ({
|
|||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
const JSONSchema202012 = getComponent("JSONSchema202012")
|
const JSONSchema202012 = getComponent("JSONSchema202012")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Effects.
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen && specSelectors.specResolvedSubtree(schemasPath) == null) {
|
||||||
|
specActions.requestResolvedSubtree(schemasPath)
|
||||||
|
}
|
||||||
|
}, [isOpen])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handlers.
|
||||||
|
*/
|
||||||
const handleCollapse = useCallback(() => {
|
const handleCollapse = useCallback(() => {
|
||||||
layoutActions.show(schemasPath, !isOpen)
|
layoutActions.show(schemasPath, !isOpen)
|
||||||
}, [layoutActions, schemasPath, isOpen])
|
}, [layoutActions, schemasPath, isOpen])
|
||||||
|
|
||||||
|
const handleModelsRef = useCallback((node) => {
|
||||||
|
if (node !== null) {
|
||||||
|
layoutActions.readyToScroll(schemasPath, node)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleJSONSchema202012Ref = (schemaName) => (node) => {
|
||||||
|
if (node !== null) {
|
||||||
|
layoutActions.readyToScroll([...schemasPath, schemaName], node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={classNames("models", { "is-open": isOpen })}>
|
<section
|
||||||
|
className={classNames("models", { "is-open": isOpen })}
|
||||||
|
ref={handleModelsRef}
|
||||||
|
>
|
||||||
<h4>
|
<h4>
|
||||||
<button
|
<button
|
||||||
aria-expanded={isOpen}
|
aria-expanded={isOpen}
|
||||||
@@ -43,6 +71,7 @@ const Models = ({
|
|||||||
{Object.entries(schemas).map(([schemaName, schema]) => (
|
{Object.entries(schemas).map(([schemaName, schema]) => (
|
||||||
<JSONSchema202012
|
<JSONSchema202012
|
||||||
key={schemaName}
|
key={schemaName}
|
||||||
|
ref={handleJSONSchema202012Ref(schemaName)}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
name={fn.upperFirst(schemaName)}
|
name={fn.upperFirst(schemaName)}
|
||||||
/>
|
/>
|
||||||
@@ -58,6 +87,9 @@ Models.propTypes = {
|
|||||||
specSelectors: PropTypes.shape({
|
specSelectors: PropTypes.shape({
|
||||||
selectSchemas: PropTypes.func.isRequired,
|
selectSchemas: PropTypes.func.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
specActions: PropTypes.shape({
|
||||||
|
requestResolvedSubtree: PropTypes.func.isRequired,
|
||||||
|
}).isRequired,
|
||||||
layoutSelectors: PropTypes.shape({
|
layoutSelectors: PropTypes.shape({
|
||||||
isShown: PropTypes.func.isRequired,
|
isShown: PropTypes.func.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
|||||||
@@ -169,7 +169,20 @@ export const selectJsonSchemaDialectDefault = () =>
|
|||||||
|
|
||||||
export const selectSchemas = createSelector(
|
export const selectSchemas = createSelector(
|
||||||
(state, system) => system.specSelectors.definitions(),
|
(state, system) => system.specSelectors.definitions(),
|
||||||
(schemas) => {
|
(state, system) =>
|
||||||
return Map.isMap(schemas) ? schemas.toJS() : {}
|
system.specSelectors.specResolvedSubtree(["components", "schemas"]),
|
||||||
|
|
||||||
|
(rawSchemas, resolvedSchemas) => {
|
||||||
|
if (!Map.isMap(rawSchemas)) return {}
|
||||||
|
if (!Map.isMap(resolvedSchemas)) return rawSchemas.toJS()
|
||||||
|
|
||||||
|
return Object.entries(rawSchemas.toJS()).reduce(
|
||||||
|
(acc, [schemaName, rawSchema]) => {
|
||||||
|
const resolvedSchema = resolvedSchemas.get(schemaName)
|
||||||
|
acc[schemaName] = resolvedSchema?.toJS() || rawSchema
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import { createOnlyOAS31ComponentWrapper } from "../fn"
|
|||||||
|
|
||||||
const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
||||||
const { getComponent, fn } = getSystem()
|
const { getComponent, fn } = getSystem()
|
||||||
|
|
||||||
|
if (ModelsWrapper.ModelsWithJSONContext) {
|
||||||
|
return <ModelsWrapper.ModelsWithJSONContext />
|
||||||
|
}
|
||||||
|
|
||||||
const Models = getComponent("OAS31Models", true)
|
const Models = getComponent("OAS31Models", true)
|
||||||
const JSONSchema = getComponent("JSONSchema202012")
|
const JSONSchema = getComponent("JSONSchema202012")
|
||||||
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
||||||
@@ -61,7 +66,8 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
|||||||
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
||||||
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
||||||
const withSchemaContext = getComponent("withJSONSchema202012Context")
|
const withSchemaContext = getComponent("withJSONSchema202012Context")
|
||||||
const ModelsWithJSONContext = withSchemaContext(Models, {
|
|
||||||
|
ModelsWrapper.ModelsWithJSONContext = withSchemaContext(Models, {
|
||||||
config: {
|
config: {
|
||||||
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
||||||
},
|
},
|
||||||
@@ -106,7 +112,9 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return <ModelsWithJSONContext />
|
return <ModelsWrapper.ModelsWithJSONContext />
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ModelsWrapper.ModelsWithJSONContext = null
|
||||||
|
|
||||||
export default ModelsWrapper
|
export default ModelsWrapper
|
||||||
|
|||||||
Reference in New Issue
Block a user