Skip to content

Commit aff4c3e

Browse files
sdirixedgarmueller
authored andcommitted
Render array according to optional detail information
* Force UISchema Generation with 'options.detail = generate' * Specificy inline UISchema by providing it in 'options.detail' * In all other cases UISchema is queried or generated as before
1 parent be2bb91 commit aff4c3e

File tree

5 files changed

+95
-8
lines changed

5 files changed

+95
-8
lines changed

packages/core/src/reducers/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
} from './core';
4343
import { JsonFormsState } from '../store';
4444
import { findMatchingUISchema, uischemaRegistryReducer, UISchemaTester } from './uischemas';
45-
import { Generate, JsonSchema, UISchemaElement } from '..';
45+
import { ControlElement, Generate, JsonSchema, UISchemaElement } from '..';
4646
import { fetchLocale, findLocalizedSchema, i18nReducer, findLocalizedUISchema } from './i18n';
4747

4848
export {
@@ -79,9 +79,26 @@ export const findUISchema = (state: JsonFormsState) =>
7979
(schema: JsonSchema,
8080
schemaPath: string,
8181
path: string,
82-
fallbackLayoutType = 'VerticalLayout'
82+
fallbackLayoutType = 'VerticalLayout',
83+
control?: ControlElement
8384
): UISchemaElement => {
84-
const uiSchema = findMatchingUISchema(state.jsonforms.uischemas)(schema, schemaPath, path);
85+
// handle options
86+
if (control && control.options && control.options.detail) {
87+
if (typeof control.options.detail === 'string') {
88+
if (control.options.detail.toUpperCase() === 'GENERATE') {
89+
// force generation of uischema
90+
return Generate.uiSchema(schema, fallbackLayoutType);
91+
}
92+
} else if (typeof control.options.detail === 'object') {
93+
// check if detail is a valid uischema
94+
if (control.options.detail.type && typeof control.options.detail.type === 'string') {
95+
return control.options.detail as UISchemaElement;
96+
}
97+
}
98+
}
99+
// default
100+
const uiSchema = findMatchingUISchema(state.jsonforms.uischemas)
101+
(schema, schemaPath, path);
85102
if (uiSchema === undefined) {
86103
return Generate.uiSchema(schema, fallbackLayoutType);
87104
}

packages/core/src/util/renderer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,11 @@ export interface StatePropsOfScopedRenderer extends OwnPropsOfControl, StateProp
222222
* @param schemaPath the according schema path
223223
* @param path the instance path
224224
* @param fallbackLayoutType the type of the layout to use
225+
* @param control may be checked for embedded inline uischema options
225226
*/
226227
findUISchema(schema: JsonSchema, schemaPath: string,
227-
path: string, fallbackLayoutType?: string): UISchemaElement;
228+
path: string, fallbackLayoutType?: string,
229+
control?: ControlElement): UISchemaElement;
228230
}
229231

230232
/**

packages/examples/src/arrays-with-detail.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ export const uischema = {
6262
elements: [
6363
{
6464
type: 'Control',
65-
scope: '#/properties/date'
65+
scope: '#/properties/message'
6666
},
6767
{
6868
type: 'Control',
69-
scope: '#/properties/message'
69+
scope: '#/properties/date'
7070
}
7171
]
7272
}

packages/material/src/layouts/MaterialArrayLayout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ export const MaterialArrayLayout =
9696
{
9797
data ? _.map(data, (childData, index) => {
9898

99-
const foundUISchema = findUISchema(scopedSchema, uischema.scope, path);
99+
const foundUISchema =
100+
findUISchema(scopedSchema, uischema.scope, path, undefined, uischema);
100101
const childPath = composePaths(path, `${index}`);
101102
const childLabel = childData[firstPrimitiveProp];
102103

packages/material/test/renderers/MaterialArrayLayout.test.tsx

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,53 @@ const nestedSchema2 = {
111111
}
112112
};
113113

114+
const uischemaOptions: {
115+
generate: ControlElement,
116+
default: ControlElement,
117+
inline: ControlElement,
118+
} = {
119+
default: {
120+
type: 'Control',
121+
scope: '#',
122+
options: {
123+
detail : 'DEFAULT'
124+
}
125+
},
126+
generate: {
127+
type: 'Control',
128+
scope: '#',
129+
options: {
130+
detail : 'GENERATE'
131+
}
132+
},
133+
inline: {
134+
type: 'Control',
135+
scope: '#',
136+
options: {
137+
detail : {
138+
type: 'HorizontalLayout',
139+
elements: [
140+
{
141+
type: 'Control',
142+
scope: '#/properties/message'
143+
}
144+
]
145+
}
146+
}
147+
}
148+
};
149+
114150
describe('Material array layout', () => {
115-
it('should only be applicable for intermediate array', () => {
151+
it('should only be applicable for intermediate array or when containing proper options', () => {
116152
expect(materialArrayLayoutTester(uischema, schema)).toBe(-1);
117153
expect(materialArrayLayoutTester(uischema, nestedSchema)).toBe(4);
118154
expect(materialArrayLayoutTester(uischema, nestedSchema2)).toBe(4);
155+
156+
expect(materialArrayLayoutTester(uischemaOptions.default, schema)).toBe(-1);
157+
expect(materialArrayLayoutTester(uischemaOptions.generate, schema)).toBe(4);
158+
expect(materialArrayLayoutTester(uischemaOptions.inline, schema)).toBe(4);
119159
});
160+
120161
it('should render two by two children', () => {
121162
const store = initJsonFormsStore();
122163
const tree = TestUtils.renderIntoDocument(
@@ -129,4 +170,30 @@ describe('Material array layout', () => {
129170
// 2 data entries with each having 2 controls
130171
expect(controls.length).toBe(4);
131172
});
173+
174+
it('should generate uischema when options.detail=GENERATE', () => {
175+
const store = initJsonFormsStore();
176+
const tree = TestUtils.renderIntoDocument(
177+
<Provider store={store}>
178+
<MaterialArrayLayout schema={schema} uischema={uischemaOptions.generate}/>
179+
</Provider>
180+
);
181+
182+
const controls = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input');
183+
// 2 data entries with each having 2 controls
184+
expect(controls.length).toBe(4);
185+
});
186+
187+
it('should use inline options.detail uischema', () => {
188+
const store = initJsonFormsStore();
189+
const tree = TestUtils.renderIntoDocument(
190+
<Provider store={store}>
191+
<MaterialArrayLayout schema={schema} uischema={uischemaOptions.inline}/>
192+
</Provider>
193+
);
194+
195+
const controls = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input');
196+
// 2 data entries with each having 1 control
197+
expect(controls.length).toBe(2);
198+
});
132199
});

0 commit comments

Comments
 (0)