@@ -6,18 +6,29 @@ import {
6
6
useRecordContext ,
7
7
TestMemoryRouter ,
8
8
useEditContext ,
9
+ IsOffline ,
9
10
} from 'ra-core' ;
10
11
import polyglotI18nProvider from 'ra-i18n-polyglot' ;
11
12
import englishMessages from 'ra-language-english' ;
12
- import { Box , Card , Stack , ThemeOptions , Typography } from '@mui/material' ;
13
+ import fakeRestDataProvider from 'ra-data-fakerest' ;
14
+
15
+ import {
16
+ Alert ,
17
+ Box ,
18
+ Card ,
19
+ Stack ,
20
+ ThemeOptions ,
21
+ Typography ,
22
+ } from '@mui/material' ;
13
23
14
24
import { TextInput } from '../input' ;
15
25
import { SimpleForm } from '../form/SimpleForm' ;
16
26
import { ShowButton , SaveButton } from '../button' ;
17
27
import TopToolbar from '../layout/TopToolbar' ;
18
- import { Edit } from './Edit' ;
28
+ import { Edit , EditProps } from './Edit' ;
19
29
import { deepmerge } from '@mui/utils' ;
20
30
import { defaultLightTheme } from '../theme' ;
31
+ import { onlineManager , useMutationState } from '@tanstack/react-query' ;
21
32
22
33
export default { title : 'ra-ui-materialui/detail/Edit' } ;
23
34
@@ -30,9 +41,9 @@ const book = {
30
41
year : 1869 ,
31
42
} ;
32
43
33
- const dataProvider = {
34
- getOne : ( ) => Promise . resolve ( { data : book } ) ,
35
- } as any ;
44
+ const dataProvider = fakeRestDataProvider ( {
45
+ books : [ book ] ,
46
+ } ) ;
36
47
37
48
const BookTitle = ( ) => {
38
49
const record = useRecordContext ( ) ;
@@ -418,3 +429,91 @@ export const WithRenderProp = () => (
418
429
</ Admin >
419
430
</ TestMemoryRouter >
420
431
) ;
432
+
433
+ export const Offline = ( {
434
+ isOnline = true ,
435
+ offline,
436
+ } : {
437
+ isOnline ?: boolean ;
438
+ offline ?: React . ReactNode ;
439
+ } ) => {
440
+ React . useEffect ( ( ) => {
441
+ onlineManager . setOnline ( isOnline ) ;
442
+ } , [ isOnline ] ) ;
443
+ return (
444
+ < TestMemoryRouter initialEntries = { [ '/books/1/show' ] } >
445
+ < Admin dataProvider = { dataProvider } >
446
+ < Resource
447
+ name = "books"
448
+ show = { < BookEditOffline offline = { offline } /> }
449
+ />
450
+ </ Admin >
451
+ </ TestMemoryRouter >
452
+ ) ;
453
+ } ;
454
+
455
+ const BookEditOffline = ( props : EditProps ) => {
456
+ return (
457
+ < Edit
458
+ emptyWhileLoading
459
+ { ...props }
460
+ redirect = { false }
461
+ mutationMode = "pessimistic"
462
+ >
463
+ < OfflineIndicator />
464
+ < SimpleForm >
465
+ < TextInput source = "title" />
466
+ < TextInput source = "author" />
467
+ < TextInput source = "summary" />
468
+ < TextInput source = "year" />
469
+ </ SimpleForm >
470
+ </ Edit >
471
+ ) ;
472
+ } ;
473
+
474
+ const OfflineIndicator = ( ) => {
475
+ const pendingMutations = useMutationState ( {
476
+ filters : {
477
+ status : 'pending' ,
478
+ } ,
479
+ } ) ;
480
+
481
+ if ( pendingMutations . length === 0 ) {
482
+ return (
483
+ < IsOffline >
484
+ < Alert severity = "warning" >
485
+ You are offline, the data may be outdated
486
+ </ Alert >
487
+ </ IsOffline >
488
+ ) ;
489
+ }
490
+ return (
491
+ < IsOffline >
492
+ < Alert severity = "warning" > You have pending mutations</ Alert >
493
+ </ IsOffline >
494
+ ) ;
495
+ } ;
496
+
497
+ const CustomOffline = ( ) => {
498
+ return < Alert severity = "warning" > You are offline!</ Alert > ;
499
+ } ;
500
+
501
+ Offline . args = {
502
+ isOnline : true ,
503
+ offline : 'default' ,
504
+ } ;
505
+
506
+ Offline . argTypes = {
507
+ isOnline : {
508
+ control : { type : 'boolean' } ,
509
+ } ,
510
+ offline : {
511
+ name : 'Offline component' ,
512
+ control : { type : 'radio' } ,
513
+ options : [ 'default' , 'custom' ] ,
514
+ mapping : {
515
+ default : undefined ,
516
+ custom : < CustomOffline /> ,
517
+ } ,
518
+ } ,
519
+ } ;
0 commit comments