|
1 | 1 | import * as React from 'react'; |
2 | 2 | import { QueryClient, useIsMutating } from '@tanstack/react-query'; |
3 | 3 |
|
4 | | -import { CoreAdminContext } from '../core'; |
| 4 | +import { CoreAdmin, CoreAdminContext, Resource } from '../core'; |
5 | 5 | import { useUpdateMany } from './useUpdateMany'; |
6 | 6 | import { useGetList } from './useGetList'; |
7 | 7 | import { useState } from 'react'; |
8 | 8 | import { useGetOne } from './useGetOne'; |
9 | 9 | import { useTakeUndoableMutation } from './undo'; |
10 | 10 | import type { DataProvider, MutationMode as MutationModeType } from '../types'; |
| 11 | +import fakeRestDataProvider from 'ra-data-fakerest'; |
| 12 | +import { TestMemoryRouter, useRedirect } from '../routing'; |
| 13 | +import { useNotificationContext, useNotify } from '../notification'; |
| 14 | +import { EditBase, ListBase, RecordsIterator } from '../controller'; |
11 | 15 |
|
12 | 16 | export default { title: 'ra-core/dataProvider/useUpdateMany' }; |
13 | 17 |
|
@@ -309,3 +313,125 @@ const ParamsCore = () => { |
309 | 313 | </> |
310 | 314 | ); |
311 | 315 | }; |
| 316 | + |
| 317 | +const Notification = () => { |
| 318 | + const { notifications, resetNotifications } = useNotificationContext(); |
| 319 | + const takeMutation = useTakeUndoableMutation(); |
| 320 | + |
| 321 | + return notifications.length > 0 ? ( |
| 322 | + <> |
| 323 | + <div>{notifications[0].message}</div> |
| 324 | + <div style={{ display: 'flex', gap: '16px' }}> |
| 325 | + <button |
| 326 | + onClick={() => { |
| 327 | + if (notifications[0].notificationOptions?.undoable) { |
| 328 | + const mutation = takeMutation(); |
| 329 | + if (mutation) { |
| 330 | + mutation({ isUndo: false }); |
| 331 | + } |
| 332 | + } |
| 333 | + resetNotifications(); |
| 334 | + }} |
| 335 | + > |
| 336 | + Close |
| 337 | + </button> |
| 338 | + </div> |
| 339 | + </> |
| 340 | + ) : null; |
| 341 | +}; |
| 342 | + |
| 343 | +const UpdateButton = ({ mutationMode }: { mutationMode: MutationModeType }) => { |
| 344 | + const notify = useNotify(); |
| 345 | + const redirect = useRedirect(); |
| 346 | + const [updateMany, { isPending }] = useUpdateMany(); |
| 347 | + const handleClick = () => { |
| 348 | + updateMany( |
| 349 | + 'posts', |
| 350 | + { |
| 351 | + ids: [1], |
| 352 | + data: { title: 'Hello updated' }, |
| 353 | + }, |
| 354 | + { |
| 355 | + mutationMode, |
| 356 | + onSuccess: () => { |
| 357 | + // Show undoable notification like controllers do |
| 358 | + notify('resources.posts.notifications.updated', { |
| 359 | + type: 'info', |
| 360 | + undoable: mutationMode === 'undoable', |
| 361 | + }); |
| 362 | + // Redirect to list after mutation succeeds |
| 363 | + redirect('list', 'posts'); |
| 364 | + }, |
| 365 | + } |
| 366 | + ); |
| 367 | + }; |
| 368 | + return ( |
| 369 | + <button onClick={handleClick} disabled={isPending}> |
| 370 | + Update |
| 371 | + </button> |
| 372 | + ); |
| 373 | +}; |
| 374 | + |
| 375 | +export const InvalidateList = ({ |
| 376 | + mutationMode, |
| 377 | +}: { |
| 378 | + mutationMode: MutationModeType; |
| 379 | +}) => { |
| 380 | + const dataProvider = fakeRestDataProvider( |
| 381 | + { |
| 382 | + posts: [ |
| 383 | + { id: 1, title: 'Hello' }, |
| 384 | + { id: 2, title: 'World' }, |
| 385 | + ], |
| 386 | + }, |
| 387 | + process.env.NODE_ENV !== 'test', |
| 388 | + process.env.NODE_ENV === 'test' ? 10 : 1000 |
| 389 | + ); |
| 390 | + |
| 391 | + return ( |
| 392 | + <TestMemoryRouter initialEntries={['/posts/1']}> |
| 393 | + <CoreAdmin dataProvider={dataProvider}> |
| 394 | + <Resource |
| 395 | + name="posts" |
| 396 | + edit={ |
| 397 | + <EditBase> |
| 398 | + <div> |
| 399 | + <h1>Edit Post</h1> |
| 400 | + <UpdateButton mutationMode={mutationMode} /> |
| 401 | + </div> |
| 402 | + </EditBase> |
| 403 | + } |
| 404 | + list={ |
| 405 | + <ListBase loading={<p>Loading...</p>}> |
| 406 | + <RecordsIterator |
| 407 | + render={record => ( |
| 408 | + <div |
| 409 | + style={{ |
| 410 | + display: 'flex', |
| 411 | + gap: '8px', |
| 412 | + alignItems: 'center', |
| 413 | + }} |
| 414 | + > |
| 415 | + {record.id}: {record.title} |
| 416 | + </div> |
| 417 | + )} |
| 418 | + /> |
| 419 | + <Notification /> |
| 420 | + </ListBase> |
| 421 | + } |
| 422 | + /> |
| 423 | + </CoreAdmin> |
| 424 | + </TestMemoryRouter> |
| 425 | + ); |
| 426 | +}; |
| 427 | +InvalidateList.args = { |
| 428 | + mutationMode: 'undoable', |
| 429 | +}; |
| 430 | +InvalidateList.argTypes = { |
| 431 | + mutationMode: { |
| 432 | + control: { |
| 433 | + type: 'select', |
| 434 | + }, |
| 435 | + options: ['pessimistic', 'optimistic', 'undoable'], |
| 436 | + }, |
| 437 | +}; |
0 commit comments