Skip to content
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

Merged
merged 1 commit into from Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
86 changes: 55 additions & 31 deletions src/AdminBuilder.js
@@ -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}
Copy link

@Gregcop1 Gregcop1 Oct 19, 2017

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

{
  ...props, 
  create, 
  edit,
  remove,
  show,
  list,
  name
}

Copy link
Contributor Author

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:

            {...{
              ...props,
              create,
              edit,
              key: name,
              list,
              name,
              options: {
                api,
                fieldFactory,
                inputFactory,
                resource,
              },
              remove,
              show,
            }}

Do you prefer this syntax?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope ^^

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.

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;
53 changes: 30 additions & 23 deletions src/Create.js
@@ -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;
57 changes: 32 additions & 25 deletions src/Edit.js
@@ -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;
78 changes: 42 additions & 36 deletions src/List.js
@@ -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;
55 changes: 31 additions & 24 deletions src/Show.js
@@ -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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disgusting :p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha ha nested object destructuring is a "today" javascript!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. It's not.

Copy link
Member

Choose a reason for hiding this comment

The 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;