From 69441cdfc48f359850d87fa4b842856f1f139eb2 Mon Sep 17 00:00:00 2001 From: LukasBoll Date: Fri, 19 Aug 2022 21:37:43 +0200 Subject: [PATCH] Resolve schemas in combinator mappings Within the combinator mappings we try to determine the best fitting schema so that the renderer can decide which tab to show. With the removal of the auto-resolving this no longer worked in cases where the combinator contained references. The situation is now improved by resolving references on the combinator level. This should help in many use cases but still does not restore the old behavior completely. Fully checking and resolving the whole sub schema is out of the scope with the new simplified resolving architecture. If that is needed the user either needs use a custom renderer or restore the old behavior by fully resolving their JSON Schema before handing it over to JSON Forms, for example via json-refs. This commit also removes the full resolving of the JSON Schema within the example application which did mask this bug. --- packages/core/src/util/renderer.ts | 12 ++++++++--- packages/example/src/App.tsx | 28 ++----------------------- packages/examples/src/examples/oneOf.ts | 5 ++--- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/packages/core/src/util/renderer.ts b/packages/core/src/util/renderer.ts index 2b8afaa6c..7161c7dd3 100644 --- a/packages/core/src/util/renderer.ts +++ b/packages/core/src/util/renderer.ts @@ -928,9 +928,9 @@ export const mapStateToCombinatorRendererProps = ( ownProps: OwnPropsOfControl, keyword: CombinatorKeyword ): StatePropsOfCombinator => { - const { data, schema, ...props } = mapStateToControlProps( + const { data, schema, rootSchema, ...props } = mapStateToControlProps( state, - ownProps + ownProps, ); const ajv = state.jsonforms.core.ajv; @@ -954,7 +954,12 @@ export const mapStateToCombinatorRendererProps = ( // element for (let i = 0; i < schema[keyword]?.length; i++) { try { - const valFn = ajv.compile(schema[keyword][i]); + let _schema = schema[keyword][i]; + if(_schema.$ref){ + _schema = Resolve.schema( rootSchema, _schema.$ref, rootSchema + ); + } + const valFn = ajv.compile(_schema); valFn(data); if (dataIsValid(valFn.errors)) { indexOfFittingSchema = i; @@ -968,6 +973,7 @@ export const mapStateToCombinatorRendererProps = ( return { data, schema, + rootSchema, ...props, indexOfFittingSchema, uischemas: getUISchemas(state) diff --git a/packages/example/src/App.tsx b/packages/example/src/App.tsx index 7ea0f36b4..49aaaf4bc 100644 --- a/packages/example/src/App.tsx +++ b/packages/example/src/App.tsx @@ -24,14 +24,12 @@ */ import React, { useEffect, useMemo, useState } from 'react'; -import { JsonForms, JsonFormsInitStateProps, JsonFormsReactProps } from '@jsonforms/react'; +import { JsonForms, JsonFormsInitStateProps } from '@jsonforms/react'; import { ExampleDescription } from '@jsonforms/examples'; import { JsonFormsCellRendererRegistryEntry, JsonFormsRendererRegistryEntry, - JsonSchema } from '@jsonforms/core'; -import { resolveRefs } from 'json-refs'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import Highlight from 'react-highlight'; import 'highlight.js/styles/default.css'; @@ -48,28 +46,6 @@ type Action = { apply: any }; -const ResolvedJsonForms = ( - props: JsonFormsInitStateProps & JsonFormsReactProps -) => { - const [init, setInit] = useState(false); - const [schema, setSchema] = useState(); - useEffect(() => { - if (!props.schema) { - setInit(true); - setSchema(props.schema); - } else { - resolveRefs(props.schema).then((result) => { - setInit(true); - setSchema(result.resolved); - }); - } - }, [props.schema]); - if (!init) { - return null; - } - return ; -}; - const getProps = (example: ExampleDescription, cells?: any, renderers?: any) => { const schema = example.schema; const uischema = example.uischema; @@ -194,7 +170,7 @@ const App = ({ examples, cells, renderers}: AppProps) => { ))}
- changeData(data)} diff --git a/packages/examples/src/examples/oneOf.ts b/packages/examples/src/examples/oneOf.ts index ce0f3d67c..1c9237622 100644 --- a/packages/examples/src/examples/oneOf.ts +++ b/packages/examples/src/examples/oneOf.ts @@ -77,9 +77,8 @@ export const uischema = { const data = { name: 'test', addressOrUser: { - street_address: '1600 Pennsylvania Avenue NW', - city: 'Washington', - state: 'DC' + name: 'User', + mail: 'mail@example.com', } };