Skip to content

Commit

Permalink
feat(oas31): resolve components.schemas field before rendering
Browse files Browse the repository at this point in the history
Refs #8513
  • Loading branch information
char0n committed Apr 26, 2023
1 parent 3a5a605 commit fa829e3
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -161,7 +162,7 @@ const JSONSchema = ({ schema, name }) => {
</JSONSchemaDeepExpansionContext.Provider>
</JSONSchemaLevelContext.Provider>
)
}
})

JSONSchema.propTypes = {
name: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
Expand Down
36 changes: 34 additions & 2 deletions src/core/plugins/oas31/components/models.jsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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}
Expand All @@ -43,6 +71,7 @@ const Models = ({
{Object.entries(schemas).map(([schemaName, schema]) => (
<JSONSchema202012
key={schemaName}
ref={handleJSONSchema202012Ref(schemaName)}
schema={schema}
name={fn.upperFirst(schemaName)}
/>
Expand All @@ -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,
Expand Down
17 changes: 15 additions & 2 deletions src/core/plugins/oas31/spec-extensions/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
{}
)
}
)
12 changes: 10 additions & 2 deletions src/core/plugins/oas31/wrap-components/models.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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",
},
Expand Down Expand Up @@ -106,7 +112,9 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
},
})

return <ModelsWithJSONContext />
return <ModelsWrapper.ModelsWithJSONContext />
})

ModelsWrapper.ModelsWithJSONContext = null

export default ModelsWrapper

0 comments on commit fa829e3

Please sign in to comment.