Skip to content

Commit a24fa50

Browse files
eneufeldedgarmueller
authored andcommitted
Improved React Material Object Renderer
* added test cases * fixed rendering issues
1 parent aff4c3e commit a24fa50

File tree

6 files changed

+443
-36
lines changed

6 files changed

+443
-36
lines changed

packages/core/src/generators/uischema.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import * as _ from 'lodash';
2626

2727
import { JsonSchema } from '../models/jsonSchema';
28-
import { ControlElement, LabelElement, Layout, UISchemaElement } from '../models/uischema';
28+
import { ControlElement, isGroup, LabelElement, Layout, UISchemaElement } from '../models/uischema';
2929
import { resolveSchema } from '../util/resolvers';
3030

3131
/**
@@ -109,12 +109,17 @@ const wrapInLayoutIfNecessary = (uischema: UISchemaElement, layoutType: string):
109109
*/
110110
const addLabel = (layout: Layout, labelName: string) => {
111111
if (!_.isEmpty(labelName) ) {
112-
// add label with name
113-
const label: LabelElement = {
114-
type: 'Label',
115-
text: _.startCase(labelName)
116-
};
117-
layout.elements.push(label);
112+
const fixedLabel = _.startCase(labelName);
113+
if (isGroup(layout)) {
114+
layout.label = fixedLabel;
115+
} else {
116+
// add label with name
117+
const label: LabelElement = {
118+
type: 'Label',
119+
text: fixedLabel
120+
};
121+
layout.elements.push(label);
122+
}
118123
}
119124
};
120125

packages/core/src/models/uischema.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
THE SOFTWARE.
2424
*/
25-
import {JsonSchema} from './jsonSchema';
25+
import { JsonSchema } from './jsonSchema';
2626

2727
/**
2828
* Interface for describing an UI schema element that is referencing
@@ -105,20 +105,20 @@ export interface SchemaBasedCondition extends Condition {
105105
*/
106106
export interface UISchemaElement {
107107

108-
/**
109-
* The type of this UI schema element.
110-
*/
111-
type: string;
108+
/**
109+
* The type of this UI schema element.
110+
*/
111+
type: string;
112112

113-
/**
114-
* An optional rule.
115-
*/
116-
rule?: Rule;
113+
/**
114+
* An optional rule.
115+
*/
116+
rule?: Rule;
117117

118-
/**
119-
* Any additional options.
120-
*/
121-
options?: any;
118+
/**
119+
* Any additional options.
120+
*/
121+
options?: any;
122122
}
123123

124124
/**
@@ -221,5 +221,7 @@ export interface Categorization extends UISchemaElement {
221221
* The child elements of this categorization which are either of type
222222
* {@link Category} or {@link Categorization}.
223223
*/
224-
elements: (Category|Categorization)[];
224+
elements: (Category | Categorization)[];
225225
}
226+
227+
export const isGroup = (layout: Layout): layout is GroupLayout => layout.type === 'Group';

packages/examples/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import * as text from './text';
4949
import * as numbers from './numbers';
5050
import * as listWithDetail from './list-with-detail';
5151
import * as listWithDetailRegistered from './list-with-detail-registered';
52+
import * as object from './object';
5253
import * as i18n from './i18n';
5354
import * as issue_1169 from './1169';
5455
export * from './register';
@@ -81,6 +82,7 @@ export {
8182
numbers,
8283
listWithDetail,
8384
listWithDetailRegistered,
85+
object,
8486
i18n,
8587
issue_1169
8688
};

packages/examples/src/object.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { registerExamples } from './register';
2+
3+
export const schema = {
4+
'$schema': 'http://json-schema.org/draft-07/schema#',
5+
6+
'type': 'object',
7+
8+
'properties': {
9+
'address': {
10+
'type': 'object',
11+
'properties': {
12+
'street_address': { 'type': 'string' },
13+
'city': { 'type': 'string' },
14+
'state': { 'type': 'string' }
15+
},
16+
'required': ['street_address', 'city', 'state']
17+
},
18+
'user': {
19+
'type': 'object',
20+
'properties': {
21+
'name': { 'type': 'string' },
22+
'mail': { 'type': 'string' },
23+
},
24+
'required': ['name', 'mail']
25+
}
26+
}
27+
};
28+
29+
export const uischemaRoot = {
30+
type: 'Control',
31+
scope: '#'
32+
};
33+
34+
export const uischemaNonRoot = {
35+
type: 'VerticalLayout',
36+
elements: [
37+
{
38+
type: 'Control',
39+
scope: '#/properties/address'
40+
},
41+
{
42+
type: 'Control',
43+
scope: '#/properties/user',
44+
rule: {
45+
effect: 'SHOW',
46+
condition: {
47+
type: 'LEAF' ,
48+
scope: '#/properties/address/properties/state',
49+
expectedValue: 'DC'
50+
}
51+
}
52+
}
53+
]
54+
};
55+
56+
const data = {
57+
'address': {
58+
'street_address': '1600 Pennsylvania Avenue NW',
59+
'city': 'Washington',
60+
'state': 'DC',
61+
}
62+
};
63+
64+
registerExamples([
65+
{
66+
name: 'rootObject',
67+
label: 'Root Object',
68+
data,
69+
schema,
70+
uischema: uischemaRoot
71+
},
72+
{
73+
name: 'object',
74+
label: 'Object',
75+
data,
76+
schema,
77+
uischema: uischemaNonRoot
78+
},
79+
]);

packages/material/src/complex/MaterialObjectRenderer.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
import * as React from 'react';
21
import {
32
ControlProps,
43
findUISchema,
5-
isObjectControl, JsonFormsState,
4+
GroupLayout,
5+
isObjectControl,
6+
JsonFormsState,
67
JsonSchema,
7-
mapStateToControlProps, OwnPropsOfControl,
8+
mapStateToControlProps,
9+
OwnPropsOfControl,
810
RankedTester,
9-
rankWith, UISchemaElement,
11+
rankWith,
12+
UISchemaElement
1013
} from '@jsonforms/core';
1114
import { connectToJsonForms, JsonForms } from '@jsonforms/react';
15+
import { Hidden } from '@material-ui/core';
16+
import * as _ from 'lodash';
17+
import * as React from 'react';
1218

1319
interface MaterialObjectRendererProps extends ControlProps {
1420
findUiSchema(
@@ -28,20 +34,22 @@ class MaterialObjectRenderer extends React.Component<MaterialObjectRendererProps
2834
visible,
2935
} = this.props;
3036

31-
const style: {[x: string]: any} = { marginBottom: '10px' };
32-
if (!visible) {
33-
style.display = 'none';
34-
}
35-
3637
const detailUiSchema = findUiSchema(scopedSchema, undefined, path, 'Group');
38+
if (_.isEmpty(path)) {
39+
detailUiSchema.type = 'VerticalLayout';
40+
} else {
41+
(detailUiSchema as GroupLayout).label = _.startCase(path);
42+
}
3743

3844
return (
39-
<JsonForms
40-
visible={visible}
41-
schema={scopedSchema}
42-
uischema={detailUiSchema}
43-
path={path}
44-
/>
45+
<Hidden xsUp={!visible}>
46+
<JsonForms
47+
visible={visible}
48+
schema={scopedSchema}
49+
uischema={detailUiSchema}
50+
path={path}
51+
/>
52+
</Hidden>
4553
);
4654
}
4755
}

0 commit comments

Comments
 (0)