Skip to content

Commit 97438e1

Browse files
committed
Add mutationOptions
1 parent 11992e1 commit 97438e1

File tree

3 files changed

+69
-23
lines changed

3 files changed

+69
-23
lines changed

docs/InPlaceEditor.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const choices = [
102102
| `children` | Optional | `ReactNode` | | The component to render in read mode. |
103103
| `editor` | Optional | `ReactNode` | | The component to render in edit mode. |
104104
| `mutationMode` | Optional | `string` | `pessimistic` | The mutation mode to use when saving the record. |
105+
| `mutationOptions` | Optional | `object` | | The options to pass to the `useUpdate` hook. |
105106
| `notifyOnSuccess` | Optional | `boolean` | `false` | Whether to show a notification on successful save. |
106107
| `resource` | Optional | `string` | | The name of the resource. |
107108
| `showButtons` | Optional | `boolean` | `false` | Whether to show the save and cancel buttons. |
@@ -206,6 +207,21 @@ You can use any of the following values:
206207
<InPlaceEditor source="phone" mutationMode="optimistic" />
207208
```
208209

210+
## `mutationOptions`
211+
212+
If you need to pass options to the `useUpdate` hook, you can use this prop.
213+
214+
This can be useful e.g. to pass [a custom `meta`](./Actions.md#meta-parameter) to the `dataProvider.update()` call.
215+
216+
{% raw %}
217+
```tsx
218+
<InPlaceEditor
219+
source="phone"
220+
mutationOptions={{ meta: { foo: 'bar' } }}
221+
/>
222+
```
223+
{% endraw %}
224+
209225
## `notifyOnSuccess`
210226

211227
By default, the component does not show a notification when the record is saved. If you want to show a notification on successful save, set this prop to `true`.

packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.stories.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ export const ShowButtons = () => (
193193
</Wrapper>
194194
);
195195

196+
export const MutationOptions = () => (
197+
<Wrapper>
198+
<InPlaceEditor
199+
source="name"
200+
mutationOptions={{ meta: { foo: 'bar' } }}
201+
/>
202+
</Wrapper>
203+
);
204+
196205
export const SX = () => (
197206
<Wrapper>
198207
<InPlaceEditor

packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
useUpdate,
99
Form,
1010
RecordContextProvider,
11+
type UseUpdateOptions,
12+
type RaRecord,
1113
} from 'ra-core';
1214
import isEqual from 'lodash/isEqual';
1315
import { styled } from '@mui/material/styles';
@@ -30,9 +32,13 @@ export type InPlaceEditorValue =
3032
| { state: 'saving'; values: any }
3133
| { state: 'reading' };
3234

33-
export interface InPlaceEditorProps {
35+
export interface InPlaceEditorProps<
36+
RecordType extends RaRecord = any,
37+
ErrorType = Error,
38+
> {
3439
source?: string;
3540
mutationMode?: 'optimistic' | 'pessimistic' | 'undoable';
41+
mutationOptions?: UseUpdateOptions<RecordType, ErrorType>;
3642
cancelOnBlur?: boolean;
3743
notifyOnSuccess?: boolean;
3844
resource?: string;
@@ -48,10 +54,16 @@ export interface InPlaceEditorProps {
4854
* The editable field is rendered inside a Form component, so InPlaceEditor
4955
* cannot be used inside another Form component.
5056
*/
51-
export const InPlaceEditor = (props: InPlaceEditorProps) => {
57+
export const InPlaceEditor = <
58+
RecordType extends RaRecord = any,
59+
ErrorType extends Error = Error,
60+
>(
61+
props: InPlaceEditorProps<RecordType, ErrorType>
62+
) => {
5263
const {
5364
source,
5465
mutationMode,
66+
mutationOptions = {},
5567
sx,
5668
cancelOnBlur,
5769
children = source ? (
@@ -119,6 +131,32 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
119131
const translate = useTranslate();
120132
const [update] = useUpdate();
121133

134+
const {
135+
meta: mutationMeta,
136+
onSuccess = () => {
137+
dispatch({ type: 'success' });
138+
if (mutationMode !== 'undoable' && !notifyOnSuccess) return;
139+
notify(`resources.${resource}.notifications.updated`, {
140+
type: 'info',
141+
messageArgs: {
142+
smart_count: 1,
143+
_: translate('ra.notification.updated', {
144+
smart_count: 1,
145+
}),
146+
},
147+
undoable: mutationMode === 'undoable',
148+
});
149+
},
150+
onError = error => {
151+
notify('ra.notification.http_error', {
152+
type: 'error',
153+
messageArgs: { _: error.message },
154+
});
155+
dispatch({ type: 'error', error });
156+
},
157+
...otherMutationOptions
158+
} = mutationOptions;
159+
122160
const handleSave = async values => {
123161
if (!record) {
124162
throw new Error('No record found');
@@ -134,30 +172,13 @@ export const InPlaceEditor = (props: InPlaceEditorProps) => {
134172
id: record.id,
135173
data: values,
136174
previousData: record,
175+
meta: mutationMeta,
137176
},
138177
{
178+
onSuccess,
179+
onError,
139180
mutationMode,
140-
onSuccess: () => {
141-
dispatch({ type: 'success' });
142-
if (mutationMode !== 'undoable' && !notifyOnSuccess) return;
143-
notify(`resources.${resource}.notifications.updated`, {
144-
type: 'info',
145-
messageArgs: {
146-
smart_count: 1,
147-
_: translate('ra.notification.updated', {
148-
smart_count: 1,
149-
}),
150-
},
151-
undoable: mutationMode === 'undoable',
152-
});
153-
},
154-
onError: error => {
155-
notify('ra.notification.http_error', {
156-
type: 'error',
157-
messageArgs: { _: error.message },
158-
});
159-
dispatch({ type: 'error', error });
160-
},
181+
...otherMutationOptions,
161182
}
162183
);
163184
};

0 commit comments

Comments
 (0)