Skip to content

Commit

Permalink
Merge pull request #225 from plone/nested-schemas
Browse files Browse the repository at this point in the history
Added support for nested schemas.
  • Loading branch information
robgietema committed Jul 19, 2018
2 parents dc58817 + a609635 commit 492df06
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

* Add Pastanaga Icon System @sneridagh
* Support for nested schemas @robgietema

### Changes

Expand Down
68 changes: 56 additions & 12 deletions src/components/manage/Form/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Form extends Component {
}),
),
properties: PropTypes.objectOf(PropTypes.any),
definitions: PropTypes.objectOf(PropTypes.any),
required: PropTypes.arrayOf(PropTypes.string),
}).isRequired,
formData: PropTypes.objectOf(PropTypes.any),
Expand Down Expand Up @@ -185,12 +186,24 @@ class Form extends Component {
* @returns {undefined}
*/
onChangeField(id, value) {
this.setState({
formData: {
...this.state.formData,
[id]: value || null,
},
});
if (id.indexOf('|') !== -1) {
this.setState({
formData: {
...this.state.formData,
[id.split('|')[0]]: {
...this.state.formData[id.split('|')[0]],
[id.split('|')[1]]: value || null,
},
},
});
} else {
this.setState({
formData: {
...this.state.formData,
[id]: value || null,
},
});
}
}

/**
Expand Down Expand Up @@ -281,8 +294,18 @@ class Form extends Component {
const errors = {};
map(this.props.schema.fieldsets, fieldset =>
map(fieldset.fields, fieldId => {
const field = this.props.schema.properties[fieldId];
const data = this.state.formData[fieldId];
const field =
fieldId.indexOf('|') !== -1
? this.props.schema.definitions[fieldId.split('|')[0]].properties[
fieldId.split('|')[1]
]
: this.props.schema.properties[fieldId];

const data =
fieldId.indexOf('|') !== -1
? this.state.formData[fieldId.split('|')[0]] &&
this.state.formData[fieldId.split('|')[0]][fieldId.split('|')[1]]
: this.state.formData[fieldId];
if (this.props.schema.required.indexOf(fieldId) !== -1) {
if (field.type !== 'boolean' && !data) {
errors[fieldId] = errors[field] || [];
Expand Down Expand Up @@ -440,9 +463,20 @@ class Form extends Component {
),
...map(item.fields, field => (
<Field
{...schema.properties[field]}
{...(field.indexOf('|') !== -1
? schema.definitions[field.split('|')[0]].properties[
field.split('|')[1]
]
: schema.properties[field])}
id={field}
value={this.state.formData[field]}
value={
field.indexOf('|') !== -1
? this.state.formData[field.split('|')[0]] &&
this.state.formData[field.split('|')[0]][
field.split('|')[1]
]
: this.state.formData[field]
}
required={schema.required.indexOf(field) !== -1}
onChange={this.onChangeField}
key={field}
Expand Down Expand Up @@ -483,9 +517,19 @@ class Form extends Component {
)}
{map(schema.fieldsets[0].fields, field => (
<Field
{...schema.properties[field]}
{...(field.indexOf('|') !== -1
? schema.definitions[field.split('|')[0]].properties[
field.split('|')[1]
]
: schema.properties[field])}
id={field}
value={this.state.formData[field]}
value={
field.indexOf('|') !== -1
? this.state.formData[field.split('|')[0]][
field.split('|')[1]
]
: this.state.formData[field]
}
required={schema.required.indexOf(field) !== -1}
onChange={this.onChangeField}
key={field}
Expand Down
59 changes: 58 additions & 1 deletion src/reducers/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
* @module reducers/schema/schema
*/

import {
flatten,
filter,
keys,
omitBy,
pickBy,
isPlainObject,
isArray,
map,
} from 'lodash';

import { GET_SCHEMA } from '../../constants/ActionTypes';

const initialState = {
Expand Down Expand Up @@ -34,7 +45,53 @@ export default function schema(state = initialState, action = {}) {
error: null,
loading: false,
loaded: true,
schema: action.result,
schema: {
...action.result,
required: [
...action.result.required,
...flatten(
map(keys(pickBy(action.result.properties, isArray)), fieldset =>
map(
action.result.definitions[fieldset].required,
required => `${fieldset}|${required}`,
),
),
),
],
fieldsets:
action.result.fieldsets ||
filter(
[
{
fields: keys(
omitBy(
pickBy(action.result.properties, isPlainObject),
field => field.readonly,
),
),
id: 'default',
title: 'Default',
},
...map(
keys(
omitBy(
pickBy(action.result.properties, isArray),
field => field.readonly,
),
),
fieldset => ({
fields: map(
keys(action.result.definitions[fieldset].properties),
field => `${fieldset}|${field}`,
),
id: fieldset,
title: action.result.definitions[fieldset].title,
}),
),
],
fieldset => fieldset.fields.length > 0,
),
},
};
case `${GET_SCHEMA}_FAIL`:
return {
Expand Down
11 changes: 9 additions & 2 deletions src/reducers/schema/schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ describe('Schema reducer', () => {
expect(
schema(undefined, {
type: `${GET_SCHEMA}_SUCCESS`,
result: 'My schema',
result: {
required: [],
properties: {},
},
}),
).toEqual({
error: null,
loaded: true,
loading: false,
schema: 'My schema',
schema: {
fieldsets: [],
required: [],
properties: {},
},
});
});

Expand Down

0 comments on commit 492df06

Please sign in to comment.