-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Add ReferenceManyField #2
Merged
Merged
Changes from 13 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
0d19e53
Refactor reference fetch to prepare for the reference_many impl
fzaninotto 31f8b97
Implement basic one to many field (WIP)
fzaninotto 6ae3eb8
Impove look and feel
fzaninotto c8539f7
Move label out of ReferenceManyField
fzaninotto 2dc4fac
Introducing ReferenceManyField component
fzaninotto 983e59f
Introducing ChipField, to be used in ReferenceManyField
fzaninotto 36dad06
Don't Repeat Yourself
fzaninotto fe981dc
Reverted example to use <ReferenceManyDatagridField> for posts
fzaninotto 988e359
Change <ReferenceField> to use a child field to display ref source
fzaninotto 734015a
Add unit test for ReferenceManyField component
fzaninotto df66802
Make Datagrid element public, push its use in ReferenceManyListField
fzaninotto 67d7159
Use React.cloneElement() instead of <children.type {...props} />
fzaninotto 3d74992
Automate label handling
fzaninotto dd786f5
Improve code readability
fzaninotto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React, { PropTypes } from 'react'; | ||
import Chip from 'material-ui/Chip'; | ||
|
||
const ChipField = ({ source, record = {} }) => <Chip style={{ margin: 4 }}>{record[source]}</Chip>; | ||
|
||
ChipField.propTypes = { | ||
source: PropTypes.string.isRequired, | ||
label: PropTypes.string, | ||
record: PropTypes.object, | ||
}; | ||
|
||
export default ChipField; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
import { connect } from 'react-redux'; | ||
import LinearProgress from 'material-ui/LinearProgress'; | ||
import { crudGetManyReference as crudGetManyReferenceAction } from '../../actions/dataActions'; | ||
import { getReferences, relatedTo } from '../../reducer/references/oneToMany'; | ||
|
||
/** | ||
* Render related records in a list of a single field. | ||
* | ||
* The child field will be repeated as many times as there are related records. | ||
* | ||
* @example Display all the books by the current author | ||
* <ReferenceManyField reference="books" target="author_id"> | ||
* <ChipField source="title" /> | ||
* </ReferenceManyField> | ||
*/ | ||
export class ReferenceManyField extends Component { | ||
componentDidMount() { | ||
this.props.crudGetManyReference(this.props.reference, this.props.target, this.props.record.id, relatedTo(this.props.reference, this.props.record.id, this.props.resource, this.props.target)); | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
if (this.props.record.id !== nextProps.record.id) { | ||
this.props.crudGetManyReference(nextProps.reference, nextProps.target, nextProps.record.id, relatedTo(nextProps.reference, nextProps.record.id, nextProps.resource, nextProps.target)); | ||
} | ||
} | ||
|
||
render() { | ||
const { resource, reference, referenceRecords, children, basePath } = this.props; | ||
if (React.Children.count(children) !== 1) { | ||
throw new Error('<ReferenceManyField> only accepts a single child'); | ||
} | ||
if (typeof referenceRecords === 'undefined') { | ||
return <LinearProgress style={{ marginTop: '1em' }} />; | ||
} | ||
const referenceBasePath = basePath.replace(resource, reference); // FIXME obviously very weak | ||
return ( | ||
<div style={{ display: 'flex', flexWrap: 'wrap' }}> | ||
{Object.keys(referenceRecords).map(index => | ||
React.cloneElement(children, { | ||
key: index, | ||
record: referenceRecords[index], | ||
resource: reference, | ||
basePath: referenceBasePath, | ||
}) | ||
)} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
ReferenceManyField.propTypes = { | ||
resource: PropTypes.string.isRequired, | ||
record: PropTypes.object, | ||
label: PropTypes.string, | ||
reference: PropTypes.string.isRequired, | ||
target: PropTypes.string.isRequired, | ||
referenceRecords: PropTypes.object, | ||
basePath: PropTypes.string.isRequired, | ||
children: PropTypes.element.isRequired, | ||
crudGetManyReference: PropTypes.func.isRequired, | ||
}; | ||
|
||
function mapStateToProps(state, props) { | ||
return { | ||
referenceRecords: getReferences(state, props.reference, relatedTo(props.reference, props.record.id, props.resource, props.target)), | ||
}; | ||
} | ||
|
||
export default connect(mapStateToProps, { | ||
crudGetManyReference: crudGetManyReferenceAction, | ||
})(ReferenceManyField); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React from 'react'; | ||
import assert from 'assert'; | ||
import { shallow } from 'enzyme'; | ||
import { ReferenceManyField } from './ReferenceManyField'; | ||
import TextField from './TextField'; | ||
|
||
describe('<ReferenceManyField />', () => { | ||
it('should render a loading indicator when related records are not yet fetched', () => { | ||
const wrapper = shallow( | ||
<ReferenceManyField | ||
resource="foo" | ||
reference="bar" | ||
target="foo_id" | ||
basePath="" | ||
crudGetManyReference={() => {}} | ||
> | ||
<TextField source="title" /> | ||
</ReferenceManyField> | ||
); | ||
const ProgressElements = wrapper.find('LinearProgress'); | ||
assert.equal(ProgressElements.length, 1); | ||
const TextFieldElements = wrapper.find('TextField'); | ||
assert.equal(TextFieldElements.length, 0); | ||
}); | ||
|
||
it('should render a list of the child component', () => { | ||
const referenceRecords = { | ||
1: { id: 1, title: 'hello' }, | ||
2: { id: 2, title: 'world' }, | ||
}; | ||
const wrapper = shallow( | ||
<ReferenceManyField | ||
resource="foo" | ||
reference="bar" | ||
target="foo_id" | ||
basePath="" | ||
referenceRecords={referenceRecords} | ||
crudGetManyReference={() => {}} | ||
> | ||
<TextField source="title" /> | ||
</ReferenceManyField> | ||
); | ||
const ProgressElements = wrapper.find('LinearProgress'); | ||
assert.equal(ProgressElements.length, 0); | ||
const TextFieldElements = wrapper.find('TextField'); | ||
assert.equal(TextFieldElements.length, 2); | ||
assert.equal(TextFieldElements.at(0).prop('resource'), 'bar'); | ||
assert.deepEqual(TextFieldElements.at(0).prop('record'), { id: 1, title: 'hello' }); | ||
assert.equal(TextFieldElements.at(1).prop('resource'), 'bar'); | ||
assert.deepEqual(TextFieldElements.at(1).prop('record'), { id: 2, title: 'world' }); | ||
}); | ||
|
||
it('should render nothing when there are no related records', () => { | ||
const wrapper = shallow( | ||
<ReferenceManyField | ||
resource="foo" | ||
reference="bar" | ||
target="foo_id" | ||
basePath="" | ||
referenceRecords={{}} | ||
crudGetManyReference={() => {}} | ||
> | ||
<TextField source="title" /> | ||
</ReferenceManyField> | ||
); | ||
const ProgressElements = wrapper.find('LinearProgress'); | ||
assert.equal(ProgressElements.length, 0); | ||
const TextFieldElements = wrapper.find('TextField'); | ||
assert.equal(TextFieldElements.length, 0); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you like one liners but this is annoying to review on github.
same for the others in
componentWillReceiveProps
,mapStateToProps
andReferenceManyListField
?