Skip to content

Commit bb82ac2

Browse files
eneufeldedgarmueller
authored andcommitted
[material] Query UI schema registry before generating an UI (#1363)
Object renderer and all combinator renderers call findUISchema instead of directly generated an UI schema.
1 parent 5ecd9da commit bb82ac2

File tree

9 files changed

+318
-185
lines changed

9 files changed

+318
-185
lines changed

packages/core/src/generators/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export const Generate: {
3232
uiSchema(
3333
jsonSchema: JsonSchema,
3434
layoutType?: string,
35-
prefix?: string
35+
prefix?: string,
36+
rootSchema?: JsonSchema
3637
): UISchemaElement;
3738
controlElement(ref: string): ControlElement;
3839
} = {

packages/core/src/reducers/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ import { JsonSchema } from '../models/jsonSchema';
6161
import { ControlElement, UISchemaElement } from '../models/uischema';
6262
import { Generate } from '../generators';
6363

64-
export { rendererReducer, cellReducer, coreReducer, UISchemaTester };
64+
export {
65+
rendererReducer,
66+
cellReducer,
67+
coreReducer,
68+
UISchemaTester,
69+
findMatchingUISchema
70+
};
6571
export { JsonFormsCore };
6672

6773
export const jsonformsReducer = (
@@ -108,7 +114,8 @@ export const findUISchema = (
108114
schemaPath: string,
109115
path: string,
110116
fallbackLayoutType = 'VerticalLayout',
111-
control?: ControlElement
117+
control?: ControlElement,
118+
rootSchema?: JsonSchema
112119
): UISchemaElement => {
113120
// handle options
114121
if (control && control.options && control.options.detail) {
@@ -130,7 +137,7 @@ export const findUISchema = (
130137
// default
131138
const uiSchema = findMatchingUISchema(uischemas)(schema, schemaPath, path);
132139
if (uiSchema === undefined) {
133-
return Generate.uiSchema(schema, fallbackLayoutType);
140+
return Generate.uiSchema(schema, fallbackLayoutType, '#', rootSchema);
134141
}
135142
return uiSchema;
136143
};

packages/core/src/util/combinators.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
*/
2525

2626
import { JsonSchema } from '../models/jsonSchema';
27-
import { UISchemaElement } from '../models/uischema';
27+
import { ControlElement, UISchemaElement } from '../models/uischema';
2828
import { resolveSchema } from './resolvers';
29-
import { generateDefaultUISchema } from '../generators';
29+
import { findUISchema, UISchemaTester } from '../reducers';
3030

3131
export interface CombinatorSubSchemaRenderInfo {
3232
schema: JsonSchema;
@@ -69,14 +69,20 @@ export const resolveSubSchemas = (
6969
export const createCombinatorRenderInfos = (
7070
combinatorSubSchemas: JsonSchema[],
7171
rootSchema: JsonSchema,
72-
keyword: CombinatorKeyword
72+
keyword: CombinatorKeyword,
73+
control: ControlElement,
74+
path: string,
75+
uischemas: { tester: UISchemaTester; uischema: UISchemaElement }[]
7376
): CombinatorSubSchemaRenderInfo[] =>
7477
combinatorSubSchemas.map((subSchema, subSchemaIndex) => ({
7578
schema: subSchema,
76-
uischema: generateDefaultUISchema(
79+
uischema: findUISchema(
80+
uischemas,
7781
subSchema,
78-
'VerticalLayout',
79-
`#`,
82+
control.scope,
83+
path,
84+
undefined,
85+
control,
8086
rootSchema
8187
),
8288
label: createLabel(subSchema, subSchemaIndex, keyword)

packages/core/src/util/renderer.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import union from 'lodash/union';
2828
import find from 'lodash/find';
2929
import RefParser from 'json-schema-ref-parser';
3030
import {
31+
findUISchema,
3132
getConfig,
3233
getData,
3334
getErrorAt,
@@ -41,8 +42,8 @@ import {
4142
import { RankedTester } from '../testers';
4243
import { JsonSchema } from '../models/jsonSchema';
4344
import {
44-
CombinatorKeyword,
4545
composePaths,
46+
CombinatorKeyword,
4647
composeWithUi,
4748
createLabelDescriptionFrom,
4849
formatErrorMessage,
@@ -56,7 +57,6 @@ import {
5657
import has from 'lodash/has';
5758
import { update } from '../actions';
5859
import { ErrorObject } from 'ajv';
59-
import { generateDefaultUISchema } from '../generators';
6060
import { JsonFormsState } from '../store';
6161
import { AnyAction, Dispatch } from 'redux';
6262
import { JsonFormsRendererRegistryEntry } from '../reducers/renderers';
@@ -667,7 +667,12 @@ export const mapStateToJsonFormsRendererProps = (
667667
let uischema = ownProps.uischema;
668668
if (uischema === undefined) {
669669
if (ownProps.schema) {
670-
uischema = generateDefaultUISchema(ownProps.schema);
670+
uischema = findUISchema(
671+
state.jsonforms.uischemas,
672+
ownProps.schema,
673+
undefined,
674+
ownProps.path
675+
);
671676
} else {
672677
uischema = getUiSchema(state);
673678
}
@@ -693,6 +698,7 @@ export interface StatePropsOfCombinator extends OwnPropsOfControl {
693698
path: string;
694699
id: string;
695700
indexOfFittingSchema: number;
701+
uischemas: { tester: UISchemaTester; uischema: UISchemaElement }[];
696702
}
697703

698704
const mapStateToCombinatorRendererProps = (
@@ -742,7 +748,9 @@ const mapStateToCombinatorRendererProps = (
742748
rootSchema,
743749
visible,
744750
id,
745-
indexOfFittingSchema
751+
indexOfFittingSchema,
752+
uischemas: state.jsonforms.uischemas,
753+
uischema
746754
};
747755
};
748756

packages/material/src/complex/MaterialAllOfRenderer.tsx

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,69 @@ import { Hidden } from '@material-ui/core';
2727

2828
import {
2929
createCombinatorRenderInfos,
30+
findMatchingUISchema,
3031
isAllOfControl,
3132
JsonSchema,
3233
RankedTester,
3334
rankWith,
3435
resolveSubSchemas,
35-
StatePropsOfCombinator,
36+
StatePropsOfCombinator
3637
} from '@jsonforms/core';
3738
import { JsonFormsDispatch, withJsonFormsAllOfProps } from '@jsonforms/react';
3839

39-
const MaterialAllOfRenderer = ({ schema, rootSchema, visible, renderers, path }: StatePropsOfCombinator) => {
40+
const MaterialAllOfRenderer = ({
41+
schema,
42+
rootSchema,
43+
visible,
44+
renderers,
45+
path,
46+
uischemas,
47+
uischema
48+
}: StatePropsOfCombinator) => {
4049
const _schema = resolveSubSchemas(schema, rootSchema, 'allOf');
41-
const allOfRenderInfos = createCombinatorRenderInfos((_schema as JsonSchema).allOf, rootSchema, 'allOf');
50+
const delegateUISchema = findMatchingUISchema(uischemas)(
51+
_schema,
52+
uischema.scope,
53+
path
54+
);
55+
if (delegateUISchema) {
56+
return (
57+
<Hidden xsUp={!visible}>
58+
<JsonFormsDispatch
59+
schema={_schema}
60+
uischema={delegateUISchema}
61+
path={path}
62+
renderers={renderers}
63+
/>
64+
</Hidden>
65+
);
66+
}
67+
const allOfRenderInfos = createCombinatorRenderInfos(
68+
(_schema as JsonSchema).allOf,
69+
rootSchema,
70+
'allOf',
71+
uischema,
72+
path,
73+
uischemas
74+
);
4275

4376
return (
4477
<Hidden xsUp={!visible}>
45-
{
46-
allOfRenderInfos.map((allOfRenderInfo, allOfIndex) => (
47-
<JsonFormsDispatch
48-
key={allOfIndex}
49-
schema={allOfRenderInfo.schema}
50-
uischema={allOfRenderInfo.uischema}
51-
path={path}
52-
renderers={renderers}
53-
/>
54-
))
55-
}
78+
{allOfRenderInfos.map((allOfRenderInfo, allOfIndex) => (
79+
<JsonFormsDispatch
80+
key={allOfIndex}
81+
schema={allOfRenderInfo.schema}
82+
uischema={allOfRenderInfo.uischema}
83+
path={path}
84+
renderers={renderers}
85+
/>
86+
))}
5687
</Hidden>
5788
);
5889
};
5990

60-
export const materialAllOfControlTester: RankedTester = rankWith(3, isAllOfControl);
91+
export const materialAllOfControlTester: RankedTester = rankWith(
92+
3,
93+
isAllOfControl
94+
);
6195
export default withJsonFormsAllOfProps(MaterialAllOfRenderer);

packages/material/src/complex/MaterialAnyOfRenderer.tsx

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,68 @@ import {
3131
RankedTester,
3232
rankWith,
3333
resolveSubSchemas,
34-
StatePropsOfCombinator,
34+
StatePropsOfCombinator
3535
} from '@jsonforms/core';
3636
import { JsonFormsDispatch, withJsonFormsAnyOfProps } from '@jsonforms/react';
3737
import { Hidden, Tab, Tabs } from '@material-ui/core';
3838
import CombinatorProperties from './CombinatorProperties';
3939

40-
const MaterialAnyOfRenderer =
41-
({ schema, rootSchema, indexOfFittingSchema, visible, path, renderers }: StatePropsOfCombinator) => {
42-
const [selectedAnyOf, setSelectedAnyOf] = useState(indexOfFittingSchema || 0);
43-
const handleChange = useCallback((_ev: any, value: number) => setSelectedAnyOf(value), [setSelectedAnyOf]);
44-
const anyOf = 'anyOf';
45-
const _schema = resolveSubSchemas(schema, rootSchema, anyOf);
46-
const anyOfRenderInfos = createCombinatorRenderInfos((_schema as JsonSchema).anyOf, rootSchema, anyOf);
40+
const MaterialAnyOfRenderer = ({
41+
schema,
42+
rootSchema,
43+
indexOfFittingSchema,
44+
visible,
45+
path,
46+
renderers,
47+
uischema,
48+
uischemas
49+
}: StatePropsOfCombinator) => {
50+
const [selectedAnyOf, setSelectedAnyOf] = useState(indexOfFittingSchema || 0);
51+
const handleChange = useCallback(
52+
(_ev: any, value: number) => setSelectedAnyOf(value),
53+
[setSelectedAnyOf]
54+
);
55+
const anyOf = 'anyOf';
56+
const _schema = resolveSubSchemas(schema, rootSchema, anyOf);
57+
const anyOfRenderInfos = createCombinatorRenderInfos(
58+
(_schema as JsonSchema).anyOf,
59+
rootSchema,
60+
anyOf,
61+
uischema,
62+
path,
63+
uischemas
64+
);
4765

48-
return (
49-
<Hidden xsUp={!visible}>
50-
<CombinatorProperties
51-
schema={_schema}
52-
combinatorKeyword={'anyOf'}
53-
path={path}
54-
/>
55-
<Tabs value={selectedAnyOf} onChange={handleChange}>
56-
{anyOfRenderInfos.map(anyOfRenderInfo => <Tab key={anyOfRenderInfo.label} label={anyOfRenderInfo.label} />)}
57-
</Tabs>
58-
{
59-
anyOfRenderInfos.map((anyOfRenderInfo, anyOfIndex) => (
60-
selectedAnyOf === anyOfIndex &&
66+
return (
67+
<Hidden xsUp={!visible}>
68+
<CombinatorProperties
69+
schema={_schema}
70+
combinatorKeyword={'anyOf'}
71+
path={path}
72+
/>
73+
<Tabs value={selectedAnyOf} onChange={handleChange}>
74+
{anyOfRenderInfos.map(anyOfRenderInfo => (
75+
<Tab key={anyOfRenderInfo.label} label={anyOfRenderInfo.label} />
76+
))}
77+
</Tabs>
78+
{anyOfRenderInfos.map(
79+
(anyOfRenderInfo, anyOfIndex) =>
80+
selectedAnyOf === anyOfIndex && (
6181
<JsonFormsDispatch
6282
key={anyOfIndex}
6383
schema={anyOfRenderInfo.schema}
6484
uischema={anyOfRenderInfo.uischema}
6585
path={path}
6686
renderers={renderers}
6787
/>
68-
))
69-
}
70-
</Hidden>
71-
);
72-
};
88+
)
89+
)}
90+
</Hidden>
91+
);
92+
};
7393

74-
export const materialAnyOfControlTester: RankedTester = rankWith(3, isAnyOfControl);
94+
export const materialAnyOfControlTester: RankedTester = rankWith(
95+
3,
96+
isAnyOfControl
97+
);
7598
export default withJsonFormsAnyOfProps(MaterialAnyOfRenderer);

0 commit comments

Comments
 (0)