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
|
||||
*/
|
||||
import React, { useState, useCallback, useEffect } from "react"
|
||||
import React, { forwardRef, useState, useCallback, useEffect } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
JSONSchemaCyclesContext,
|
||||
} from "../../context"
|
||||
|
||||
const JSONSchema = ({ schema, name }) => {
|
||||
const JSONSchema = forwardRef(({ schema, name }, ref) => {
|
||||
const fn = useFn()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
||||
@@ -96,6 +96,7 @@ const JSONSchema = ({ schema, name }) => {
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<JSONSchemaCyclesContext.Provider value={renderedSchemas}>
|
||||
<article
|
||||
ref={ref}
|
||||
data-json-schema-level={level}
|
||||
className={classNames("json-schema-2020-12", {
|
||||
"json-schema-2020-12--embedded": isEmbedded,
|
||||
@@ -161,7 +162,7 @@ const JSONSchema = ({ schema, name }) => {
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
JSONSchema.propTypes = {
|
||||
name: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback } from "react"
|
||||
import React, { useCallback, useEffect } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
const Models = ({
|
||||
specActions,
|
||||
specSelectors,
|
||||
layoutSelectors,
|
||||
layoutActions,
|
||||
@@ -21,12 +22,39 @@ const Models = ({
|
||||
const Collapse = getComponent("Collapse")
|
||||
const JSONSchema202012 = getComponent("JSONSchema202012")
|
||||
|
||||
/**
|
||||
* Effects.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (isOpen && specSelectors.specResolvedSubtree(schemasPath) == null) {
|
||||
specActions.requestResolvedSubtree(schemasPath)
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleCollapse = useCallback(() => {
|
||||
layoutActions.show(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 (
|
||||
<section className={classNames("models", { "is-open": isOpen })}>
|
||||
<section
|
||||
className={classNames("models", { "is-open": isOpen })}
|
||||
ref={handleModelsRef}
|
||||
>
|
||||
<h4>
|
||||
<button
|
||||
aria-expanded={isOpen}
|
||||
@@ -43,6 +71,7 @@ const Models = ({
|
||||
{Object.entries(schemas).map(([schemaName, schema]) => (
|
||||
<JSONSchema202012
|
||||
key={schemaName}
|
||||
ref={handleJSONSchema202012Ref(schemaName)}
|
||||
schema={schema}
|
||||
name={fn.upperFirst(schemaName)}
|
||||
/>
|
||||
@@ -58,6 +87,9 @@ Models.propTypes = {
|
||||
specSelectors: PropTypes.shape({
|
||||
selectSchemas: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
specActions: PropTypes.shape({
|
||||
requestResolvedSubtree: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
layoutSelectors: PropTypes.shape({
|
||||
isShown: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
@@ -169,7 +169,20 @@ export const selectJsonSchemaDialectDefault = () =>
|
||||
|
||||
export const selectSchemas = createSelector(
|
||||
(state, system) => system.specSelectors.definitions(),
|
||||
(schemas) => {
|
||||
return Map.isMap(schemas) ? schemas.toJS() : {}
|
||||
(state, system) =>
|
||||
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 { getComponent, fn } = getSystem()
|
||||
|
||||
if (ModelsWrapper.ModelsWithJSONContext) {
|
||||
return <ModelsWrapper.ModelsWithJSONContext />
|
||||
}
|
||||
|
||||
const Models = getComponent("OAS31Models", true)
|
||||
const JSONSchema = getComponent("JSONSchema202012")
|
||||
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
||||
@@ -61,7 +66,8 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
||||
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
||||
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
||||
const withSchemaContext = getComponent("withJSONSchema202012Context")
|
||||
const ModelsWithJSONContext = withSchemaContext(Models, {
|
||||
|
||||
ModelsWrapper.ModelsWithJSONContext = withSchemaContext(Models, {
|
||||
config: {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user