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
Customize CRUD components #63
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,62 @@ | ||
import React, {Component} from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import {Admin, Resource, Delete} from 'admin-on-rest'; | ||
import Api from '@api-platform/api-doc-parser/lib/Api'; | ||
import List from './List'; | ||
import Show from './Show'; | ||
import {Admin, Delete, Resource} from 'admin-on-rest'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import Create from './Create'; | ||
import Edit from './Edit'; | ||
import fieldFactory from './fieldFactory'; | ||
import inputFactory from './inputFactory'; | ||
import List from './List'; | ||
import Show from './Show'; | ||
|
||
export default class extends Component { | ||
static propTypes = { | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
restClient: PropTypes.func.isRequired, | ||
}; | ||
|
||
render() { | ||
let props = {...this.props}; | ||
if (!props.title) props.title = this.props.api.title; | ||
const AdminBuilder = props => { | ||
const {api, fieldFactory, inputFactory, title = api.title} = props; | ||
|
||
return ( | ||
<Admin {...props}> | ||
{this.props.api.resources.map(resource => ( | ||
return ( | ||
<Admin {...props} title={title}> | ||
{api.resources.map(resource => { | ||
const { | ||
create = Create, | ||
edit = Edit, | ||
list = List, | ||
name, | ||
props, | ||
remove = Delete, | ||
show = Show, | ||
} = resource; | ||
return ( | ||
<Resource | ||
options={{api: this.props.api, resource}} | ||
key={resource.name} | ||
name={resource.name} | ||
list={List} | ||
show={Show} | ||
create={Create} | ||
edit={Edit} | ||
remove={Delete} | ||
{...resource.props} | ||
{...props} | ||
create={create} | ||
edit={edit} | ||
key={name} | ||
list={list} | ||
name={name} | ||
options={{ | ||
api, | ||
fieldFactory, | ||
inputFactory, | ||
resource, | ||
}} | ||
remove={remove} | ||
show={show} | ||
/> | ||
))} | ||
</Admin> | ||
); | ||
} | ||
} | ||
); | ||
})} | ||
</Admin> | ||
); | ||
}; | ||
|
||
AdminBuilder.defaultProps = { | ||
fieldFactory, | ||
inputFactory, | ||
}; | ||
|
||
AdminBuilder.propTypes = { | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
fieldFactory: PropTypes.func, | ||
inputFactory: PropTypes.func, | ||
restClient: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default AdminBuilder; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,33 @@ | ||
import React, {Component} from 'react'; | ||
import Api from '@api-platform/api-doc-parser/lib/Api'; | ||
import Resource from '@api-platform/api-doc-parser/lib/Resource'; | ||
import {Create as BaseCreate, SimpleForm} from 'admin-on-rest'; | ||
import inputFactory from './inputFactory'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
|
||
export default class extends Component { | ||
render() { | ||
const factory = this.props.options.inputFactory | ||
? this.props.options.inputFactory | ||
: inputFactory; | ||
const Create = props => { | ||
const {options: {api, inputFactory, resource}} = props; | ||
|
||
return ( | ||
<BaseCreate {...this.props}> | ||
<SimpleForm> | ||
{this.props.options.resource.writableFields.map(field => | ||
factory( | ||
field, | ||
this.props.options.resource, | ||
'create', | ||
this.props.options.api, | ||
), | ||
)} | ||
</SimpleForm> | ||
</BaseCreate> | ||
); | ||
} | ||
} | ||
return ( | ||
<BaseCreate {...props}> | ||
<SimpleForm> | ||
{resource.writableFields.map(field => | ||
inputFactory(field, { | ||
action: 'create', | ||
api, | ||
resource, | ||
}), | ||
)} | ||
</SimpleForm> | ||
</BaseCreate> | ||
); | ||
}; | ||
|
||
Create.propTypes = { | ||
options: PropTypes.shape({ | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
inputFactory: PropTypes.func.isRequired, | ||
resource: PropTypes.instanceOf(Resource).isRequired, | ||
}), | ||
}; | ||
|
||
export default Create; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
import React, {Component} from 'react'; | ||
import {Edit as BaseEdit, SimpleForm, DisabledInput} from 'admin-on-rest'; | ||
import inputFactory from './inputFactory'; | ||
import Api from '@api-platform/api-doc-parser/lib/Api'; | ||
import Resource from '@api-platform/api-doc-parser/lib/Resource'; | ||
import {DisabledInput, Edit as BaseEdit, SimpleForm} from 'admin-on-rest'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
|
||
export default class extends Component { | ||
render() { | ||
const factory = this.props.options.inputFactory | ||
? this.props.options.inputFactory | ||
: inputFactory; | ||
const Edit = props => { | ||
const {options: {api, inputFactory, resource}} = props; | ||
|
||
return ( | ||
<BaseEdit {...this.props}> | ||
<SimpleForm> | ||
<DisabledInput source="id" /> | ||
{this.props.options.resource.writableFields.map(field => | ||
factory( | ||
field, | ||
this.props.options.resource, | ||
'edit', | ||
this.props.options.api, | ||
), | ||
)} | ||
</SimpleForm> | ||
</BaseEdit> | ||
); | ||
} | ||
} | ||
return ( | ||
<BaseEdit {...props}> | ||
<SimpleForm> | ||
<DisabledInput source="id" /> | ||
{resource.writableFields.map(field => | ||
inputFactory(field, { | ||
action: 'edit', | ||
api, | ||
resource, | ||
}), | ||
)} | ||
</SimpleForm> | ||
</BaseEdit> | ||
); | ||
}; | ||
|
||
Edit.propTypes = { | ||
options: PropTypes.shape({ | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
inputFactory: PropTypes.func.isRequired, | ||
resource: PropTypes.instanceOf(Resource).isRequired, | ||
}), | ||
}; | ||
|
||
export default Edit; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,49 @@ | ||
import React, {Component} from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Api from '@api-platform/api-doc-parser/lib/Api'; | ||
import Resource from '@api-platform/api-doc-parser/lib/Resource'; | ||
import { | ||
List as BaseList, | ||
Datagrid, | ||
TextField, | ||
ShowButton, | ||
EditButton, | ||
List as BaseList, | ||
ShowButton, | ||
TextField, | ||
} from 'admin-on-rest'; | ||
import fieldFactory from './fieldFactory'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
|
||
const List = props => { | ||
const {hasEdit, hasShow, options: {api, fieldFactory, resource}} = props; | ||
|
||
return ( | ||
<BaseList {...props}> | ||
<Datagrid> | ||
<TextField source="id" /> | ||
{resource.readableFields.map(field => | ||
fieldFactory(field, { | ||
action: 'list', | ||
api, | ||
resource, | ||
}), | ||
)} | ||
{hasShow && <ShowButton />} | ||
{hasEdit && <EditButton />} | ||
</Datagrid> | ||
</BaseList> | ||
); | ||
}; | ||
|
||
export default class extends Component { | ||
static defaultProps = { | ||
perPage: 30, // Default value in API Platform | ||
}; | ||
static propTypes = { | ||
perPage: PropTypes.number, | ||
}; | ||
List.defaultProps = { | ||
perPage: 30, // Default value in API Platform | ||
}; | ||
|
||
render() { | ||
const factory = this.props.options.fieldFactory | ||
? this.props.options.fieldFactory | ||
: fieldFactory; | ||
List.propTypes = { | ||
options: PropTypes.shape({ | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
fieldFactory: PropTypes.func.isRequired, | ||
resource: PropTypes.instanceOf(Resource).isRequired, | ||
}), | ||
perPage: PropTypes.number, | ||
hasEdit: PropTypes.bool.isRequired, | ||
hasShow: PropTypes.bool.isRequired, | ||
}; | ||
|
||
return ( | ||
<BaseList {...this.props}> | ||
<Datagrid> | ||
<TextField source="id" /> | ||
{this.props.options.resource.readableFields.map(field => | ||
factory( | ||
field, | ||
this.props.options.resource, | ||
'list', | ||
this.props.options.api, | ||
), | ||
)} | ||
<ShowButton /> | ||
<EditButton /> | ||
</Datagrid> | ||
</BaseList> | ||
); | ||
} | ||
} | ||
export default List; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
import React, {Component} from 'react'; | ||
import Api from '@api-platform/api-doc-parser/lib/Api'; | ||
import Resource from '@api-platform/api-doc-parser/lib/Resource'; | ||
import {Show as BaseShow, SimpleShowLayout, TextField} from 'admin-on-rest'; | ||
import fieldFactory from './fieldFactory'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
|
||
export default class extends Component { | ||
render() { | ||
const factory = this.props.options.fieldFactory | ||
? this.props.options.fieldFactory | ||
: fieldFactory; | ||
const Show = props => { | ||
const {options: {api, fieldFactory, resource}} = props; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. disgusting :p There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ha ha nested object destructuring is a "today" javascript! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. It's not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So is the spread operator then. |
||
|
||
return ( | ||
<BaseShow {...this.props}> | ||
<SimpleShowLayout> | ||
<TextField source="id" /> | ||
{this.props.options.resource.readableFields.map(field => | ||
factory( | ||
field, | ||
this.props.options.resource, | ||
'show', | ||
this.props.options.api, | ||
), | ||
)} | ||
</SimpleShowLayout> | ||
</BaseShow> | ||
); | ||
} | ||
} | ||
return ( | ||
<BaseShow {...props}> | ||
<SimpleShowLayout> | ||
<TextField source="id" /> | ||
{resource.readableFields.map(field => | ||
fieldFactory(field, { | ||
action: 'show', | ||
api, | ||
resource, | ||
}), | ||
)} | ||
</SimpleShowLayout> | ||
</BaseShow> | ||
); | ||
}; | ||
|
||
Show.propTypes = { | ||
options: PropTypes.shape({ | ||
api: PropTypes.instanceOf(Api).isRequired, | ||
fieldFactory: PropTypes.func.isRequired, | ||
resource: PropTypes.instanceOf(Resource).isRequired, | ||
}), | ||
}; | ||
|
||
export default Show; |
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'm not sure but I think you can
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.
It does not work but the following syntax works:
Do you prefer this syntax?
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.
nope ^^
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 think it’s better than the above as it’s more explicit, and therefore more readable.