import * as React from 'react';
import { QueryClient, useIsMutating } from '@tanstack/react-query';
import fakeRestDataProvider from 'ra-data-fakerest';
import { CoreAdmin, CoreAdminContext, Resource } from '../core';
import { useCreate } from './useCreate';
import { useGetOne } from './useGetOne';
import type { MutationMode as MutationModeType } from '../types';
import {
CreateBase,
ListBase,
RecordsIterator,
useRegisterMutationMiddleware,
} from '../controller';
import { useNotificationContext } from '../notification';
import { useTakeUndoableMutation } from './undo';
import { Form, InputProps, useInput } from '../form';
import { TestMemoryRouter } from '../routing';
import { testDataProvider } from './testDataProvider';
import { useRefresh } from './useRefresh';
export default { title: 'ra-core/dataProvider/useCreate' };
export const MutationMode = ({ timeout = 1000 }) => {
const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }];
const dataProvider = {
getOne: (resource, params) => {
return new Promise((resolve, reject) => {
const data = posts.find(p => p.id === params.id);
setTimeout(() => {
if (!data) {
reject(new Error('nothing yet'));
}
resolve({ data });
}, timeout);
});
},
create: (resource, params) => {
return new Promise(resolve => {
setTimeout(() => {
posts.push(params.data);
resolve({ data: params.data });
}, timeout);
});
},
} as any;
return (
);
};
const MutationModeCore = () => {
const isMutating = useIsMutating();
const [success, setSuccess] = React.useState();
const [mutationMode, setMutationMode] =
React.useState('pessimistic');
const {
isPending: isPendingGetOne,
data,
error,
refetch,
} = useGetOne('posts', { id: 2 });
const [create, { isPending }] = useCreate(
'posts',
{
data: { id: 2, title: 'Hello World' },
},
{
mutationMode,
onSuccess: () => setSuccess('success'),
}
);
const handleClick = () => {
create();
};
return (
<>
{isPendingGetOne ? (
Loading...
) : error ? (
{error.message}
) : (
- id
- {data?.id}
- 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 new Promise((resolve, reject) => {
const data = posts.find(p => p.id === params.id);
setTimeout(() => {
if (!data) {
reject(new Error('nothing yet'));
}
resolve({ data });
}, timeout);
});
},
create: (resource, params) => {
return new Promise(resolve => {
setTimeout(() => {
posts.push(params.data);
resolve({ data: params.data });
}, timeout);
});
},
} as any;
return (
);
};
const ParamsCore = () => {
const isMutating = useIsMutating();
const [success, setSuccess] = React.useState();
const [params, setParams] = React.useState({ title: 'Hello World' });
const {
isPending: isPendingGetOne,
data,
error,
refetch,
} = useGetOne('posts', { id: 2 });
const [create, { isPending }] = useCreate(
'posts',
{
data: { id: 2, ...params },
},
{
mutationMode: 'optimistic',
onSuccess: () => setSuccess('success'),
}
);
const handleClick = () => {
create();
};
return (
<>
{isPendingGetOne ? (
Loading...
) : error ? (
{error.message}
) : (
- id
- {data?.id}
- title
- {data?.title}
- author
- {data?.author}
)}
{success && {success}
}
{isMutating !== 0 && mutating
}
>
);
};
export const Middleware = ({
middleware = (resource: string, params: any) => {
console.log(
`Creating 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,
});
},
create: (resource, params) => {
return new Promise(resolve => {
setTimeout(() => {
const post = { id: posts.length + 1, ...params.data };
// @ts-ignore
posts.push(post);
// @ts-ignore
resolve({ data: post });
}, timeout);
});
},
});
return (
(
<>
{children}
>
)}
>
}
create={
({
id:
mutationMode === 'pessimistic'
? undefined
: posts.length + 1,
...data,
})}
>
}
/>
);
};
Middleware.args = {
timeout: 1000,
mutationMode: 'optimistic',
};
Middleware.argTypes = {
timeout: {
control: {
type: 'number',
},
},
mutationMode: {
control: {
type: 'select',
},
options: ['pessimistic', 'optimistic', 'undoable'],
},
};
const CreateMiddleware = ({
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 (
);
};
const RefreshButton = () => {
const refresh = useRefresh();
return (
);
};
export const InvalidateList = ({
mutationMode,
}: {
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 (
}
list={
Loading...
}>
(
{record.id}: {record.title}
)}
/>
}
/>
);
};
InvalidateList.args = {
mutationMode: 'undoable',
};
InvalidateList.argTypes = {
mutationMode: {
control: {
type: 'select',
},
options: ['pessimistic', 'optimistic', 'undoable'],
},
};
export const CreateIdZero = ({
mutationMode,
}: {
mutationMode: MutationModeType;
}) => {
const dataProvider = fakeRestDataProvider(
{
posts: [],
},
process.env.NODE_ENV !== 'test',
process.env.NODE_ENV === 'test' ? 10 : 1000
);
return (
}
list={
Loading...}>
(
{record.id}: {record.title}
)}
/>
}
/>
);
};
CreateIdZero.args = {
mutationMode: 'undoable',
};
CreateIdZero.argTypes = {
mutationMode: {
control: {
type: 'select',
},
options: ['pessimistic', 'optimistic', 'undoable'],
},
};