import * as React from 'react'; import { useState } from 'react'; import { QueryClient, useIsMutating } from '@tanstack/react-query'; import fakeRestDataProvider from 'ra-data-fakerest'; import { CoreAdmin, CoreAdminContext, Resource } from '../core'; import { useUpdate } from './useUpdate'; import { useGetOne } from './useGetOne'; import type { MutationMode as MutationModeType } from '../types'; import { EditBase, ListBase, RecordsIterator, useRegisterMutationMiddleware, } from '../controller'; import { Form, InputProps, useInput } from '../form'; import { TestMemoryRouter, LinkBase } from '../routing'; import { testDataProvider } from './testDataProvider'; import { useNotificationContext } from '../notification'; import { useTakeUndoableMutation } from './undo'; export default { title: 'ra-core/dataProvider/useUpdate' }; export const MutationMode = ({ timeout = 1000 }) => { const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }]; const dataProvider = { getOne: (resource, params) => { return Promise.resolve({ data: posts.find(p => p.id === params.id), }); }, update: (resource, params) => { return new Promise(resolve => { setTimeout(() => { const post = posts.find(p => p.id === params.id); if (post) { post.title = params.data.title; } resolve({ data: post }); }, timeout); }); }, } as any; return ( ); }; const MutationModeCore = () => { const isMutating = useIsMutating(); const [success, setSuccess] = useState(); const { data, refetch } = useGetOne('posts', { id: 1 }); const [mutationMode, setMutationMode] = React.useState('pessimistic'); const [update, { isPending }] = useUpdate( 'posts', { id: 1, data: { title: 'Hello World' }, }, { mutationMode, onSuccess: () => setSuccess('success'), } ); const handleClick = () => { update(); }; return ( <>
title
{data?.title}
author
{data?.author}
   
{success &&
{success}
} {isMutating !== 0 &&
mutating
} ); }; export const Params = ({ timeout = 1000 }) => { const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }]; const dataProvider = { getOne: (resource, params) => { return Promise.resolve({ data: posts.find(p => p.id === params.id), }); }, update: (resource, params) => { return new Promise(resolve => { setTimeout(() => { const post = posts.find(p => p.id === params.id); if (post) { post.title = params.data.title; } resolve({ data: post }); }, timeout); }); }, } as any; return ( ); }; const ParamsCore = () => { const isMutating = useIsMutating(); const [success, setSuccess] = useState(); const { data, refetch } = useGetOne('posts', { id: 1 }); const [params, setParams] = React.useState({ title: 'Hello World' }); const [update, { isPending }] = useUpdate( 'posts', { id: 1, data: params, }, { mutationMode: 'optimistic', onSuccess: () => setSuccess('success'), } ); const handleClick = () => { update(); }; return ( <>
title
{data?.title}
author
{data?.author}
   
{success &&
{success}
} {isMutating !== 0 &&
mutating
} ); }; export const Middleware = ({ middleware = (resource: string, params: any) => { console.log( `Updating resource ${resource} with params:`, JSON.stringify(params) ); }, mutationMode = 'undoable', timeout = 1000, }: { mutationMode?: MutationModeType; timeout?: number; middleware?: (resource: string, params: any) => void; }) => { const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }]; const dataProvider = testDataProvider({ // @ts-ignore getList: () => { return Promise.resolve({ data: posts, total: posts.length, }); }, // @ts-ignore getOne: (resource, params) => { return Promise.resolve({ // eslint-disable-next-line eqeqeq data: posts.find(p => p.id == params.id), }); }, update: (resource, params) => { return new Promise(resolve => { setTimeout(() => { // eslint-disable-next-line eqeqeq const post = posts.find(p => p.id == params.id); if (post) { post.title = params.data.title; } // @ts-ignore resolve({ data: post }); }, timeout); }); }, }); return ( ( <> {children} )} >
    (
  • {record.title}
  • )} />
} edit={
} />
); }; Middleware.args = { timeout: 1000, mutationMode: 'optimistic', }; Middleware.argTypes = { timeout: { control: { type: 'number', }, }, mutationMode: { control: { type: 'select', }, options: ['pessimistic', 'optimistic', 'undoable'], }, }; const UpdateMiddleware = ({ middleware, }: { middleware: (resource: string, params: any) => void; }) => { useRegisterMutationMiddleware((resource, params, next) => { middleware(resource, params); return next(resource, params); }); return null; }; const Notification = () => { const { notifications, resetNotifications } = useNotificationContext(); const takeMutation = useTakeUndoableMutation(); return notifications.length > 0 ? ( <>
{notifications[0].message}
) : null; }; const TextInput = (props: InputProps) => { const { field, id } = useInput(props); return (
); }; export const InvalidateList = ({ mutationMode = 'undoable', }: { mutationMode?: MutationModeType; }) => { const dataProvider = fakeRestDataProvider( { posts: [ { id: 1, title: 'Hello' }, { id: 2, title: 'World' }, ], }, process.env.NODE_ENV !== 'test', process.env.NODE_ENV === 'test' ? 10 : 1000 ); return ( Loading...

}> (
{record.id}: {record.title}
)} /> } edit={
} />
); }; InvalidateList.args = { mutationMode: 'undoable', }; InvalidateList.argTypes = { mutationMode: { control: { type: 'select', }, options: ['pessimistic', 'optimistic', 'undoable'], }, };