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

[RFR] Convert DataProvider to Object #3726

Merged
merged 30 commits into from
Sep 30, 2019
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e7e29b5
Introduce new DataProvider
djhi Sep 24, 2019
acbf414
Update hooks
djhi Sep 24, 2019
8200214
Fix build
djhi Sep 24, 2019
1bf05ab
Fix tests
djhi Sep 24, 2019
cc7bca9
Updates to jsDoc and signatures
fzaninotto Sep 24, 2019
a005e86
Make useMutation accept both defintition and call time params
fzaninotto Sep 25, 2019
2522d84
Fix failing test
fzaninotto Sep 25, 2019
2525498
Make the change backwards compatible for withDataProvider users
fzaninotto Sep 25, 2019
e4e2004
fix type
fzaninotto Sep 25, 2019
deab63e
fix usequeryWithstore when used with new verbs
fzaninotto Sep 25, 2019
e457cef
Migrate custom queries of demo app
fzaninotto Sep 25, 2019
5b49a76
Fix createController
fzaninotto Sep 25, 2019
17765c6
Fix unit test
fzaninotto Sep 25, 2019
4489996
Fix linter warnings
fzaninotto Sep 25, 2019
40bded8
convert ra-data-fakerest provider to object
fzaninotto Sep 25, 2019
0d9f7c2
Remove generics in dataProvider types because TypeScript is dump
fzaninotto Sep 25, 2019
9cd3f10
Migrate simple rest data provider to object
fzaninotto Sep 26, 2019
6a076ad
rewrite DataProvider documentation
fzaninotto Sep 27, 2019
8227e47
Allow to customize action in specialized query hooks
fzaninotto Sep 27, 2019
08c877c
fix useGetList hook updates list view by default
fzaninotto Sep 27, 2019
6301eb8
Update Actions documentation
fzaninotto Sep 27, 2019
2ac7dc8
data provider hooks should not define the action
fzaninotto Sep 27, 2019
84bb1c1
Review
fzaninotto Sep 27, 2019
04d26df
Various doc fixes
fzaninotto Sep 28, 2019
4c88b3b
Migrate raèdata-json-server provider to object
fzaninotto Sep 29, 2019
b002b35
Various fixes
fzaninotto Sep 29, 2019
cf84832
Fix bad types
fzaninotto Sep 29, 2019
cce2e40
Fix unit test
fzaninotto Sep 29, 2019
9e67c77
Rview
fzaninotto Sep 30, 2019
3713986
Fix limit case in pagination
fzaninotto Sep 30, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
784 changes: 303 additions & 481 deletions docs/Actions.md

Large diffs are not rendered by default.

26 changes: 12 additions & 14 deletions docs/Admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,20 @@ Here are all the props accepted by the component:

## `dataProvider`

The only required prop, it must be a function returning a promise, with the following signature:
The only required prop, it must be an object with the following methods returning a promise:

```jsx
/**
* Query a data provider and return a promise for a response
*
* @example
* dataProvider(GET_ONE, 'posts', { id: 123 })
* => new Promise(resolve => resolve({ id: 123, title: "hello, world" }))
*
* @param {string} type Request type, e.g GET_LIST
* @param {string} resource Resource name, e.g. "posts"
* @param {Object} payload Request parameters. Depends on the action type
* @returns {Promise} the Promise for a response
*/
const dataProvider = (type, resource, params) => new Promise();
const dataProvider = {
getList: (resource, params) => Promise,
getOne: (resource, params) => Promise,
getMany: (resource, params) => Promise,
getManyReference: (resource, params) => Promise,
create: (resource, params) => Promise,
update: (resource, params) => Promise,
updateMany: (resource, params) => Promise,
delete: (resource, params) => Promise,
deleteMany: (resource, params) => Promise,
}
```

The `dataProvider` is also the ideal place to add custom HTTP headers, authentication, etc. The [Data Providers Chapter](./DataProviders.md) of the documentation lists available data providers, and explains how to build your own.
Expand Down
105 changes: 105 additions & 0 deletions docs/CreateEdit.md
Original file line number Diff line number Diff line change
Expand Up @@ -945,3 +945,108 @@ export const UserEdit = ({ permissions, ...props }) =>
</Edit>;
```
{% endraw %}

## Altering the Form Values before Submitting

Sometimes, you may want your custom action to alter the form values before actually sending them to the `dataProvider`.
For those cases, you should know that every buttons inside a form [Toolbar](/CreateEdit.md#toolbar) receive two props:
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved

- `handleSubmit` which calls the default form save method
- `handleSubmitWithRedirect` which calls the default form save method but allows to specify a custom redirection

Knowing this, there are two ways to alter the form values before submit:

1. Using react-final-form API to send change events

```jsx
import React, { useCallback } from 'react';
import { useForm } from 'react-final-form';
import { SaveButton, Toolbar, useCreate, useRedirect, useNotify } from 'react-admin';

const SaveWithNoteButton = ({ handleSubmitWithRedirect, ...props }) => {
const [create] = useCreate('posts');
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath, redirect } = props;

const form = useForm();

const handleClick = useCallback(() => {
form.change('average_note', 10);

handleSubmitWithRedirect('edit');
}, [form]);

return <SaveButton {...props} handleSubmitWithRedirect={handleClick} />;
};
```

2. Using react-admin hooks to run custom mutations
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved

For instance, in the `simple` example:

```jsx
import React, { useCallback } from 'react';
import { useFormState } from 'react-final-form';
import { SaveButton, Toolbar, useCreate, useRedirect, useNotify } from 'react-admin';

const SaveWithNoteButton = props => {
const [create] = useCreate('posts');
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath, redirect } = props;

const formState = useFormState();
const handleClick = useCallback(() => {
if (!formState.valid) {
return;
}

create(
{
data: { ...formState.values, average_note: 10 },
},
{
onSuccess: ({ data: newRecord }) => {
notify('ra.notification.created', 'info', {
smart_count: 1,
});
redirectTo(redirect, basePath, newRecord.id, newRecord);
},
}
);
}, [
formState.valid,
formState.values,
create,
notify,
redirectTo,
redirect,
basePath,
]);

return <SaveButton {...props} handleSubmitWithRedirect={handleClick} />;
};
```

This button can be used in the `PostCreateToolbar` component:

```jsx
const PostCreateToolbar = props => (
<Toolbar {...props}>
<SaveButton
label="post.action.save_and_show"
redirect="show"
submitOnEnter={true}
/>
<SaveWithNoteButton
label="post.action.save_with_average_note"
redirect="show"
submitOnEnter={false}
variant="text"
/>
</Toolbar>
);
```

**Note**: This technique will not trigger a form validation pass.
Loading