import * as React from 'react'; import { onlineManager, QueryClient } from '@tanstack/react-query'; import { RecordsIterator } from 'ra-core'; import { CoreAdmin } from '../../core/CoreAdmin'; import { Resource } from '../../core/Resource'; import { ShowBase } from '../../controller/show/ShowBase'; import { TestMemoryRouter } from '../../routing'; import { ReferenceManyFieldBase } from './ReferenceManyFieldBase'; import { ListBase, useListContext } from '../list'; import fakeRestDataProvider from 'ra-data-fakerest'; import { useIsOffline } from '../../core'; export default { title: 'ra-core/controller/field/ReferenceManyFieldBase', excludeStories: ['dataProviderWithAuthors'], }; const author = { id: 1, first_name: 'Leo', last_name: 'Tolstoy', language: 'Russian', }; const books = [ { id: 1, title: 'War and Peace', author: 1, }, { id: 2, title: 'Anna Karenina', author: 1, }, { id: 3, title: 'The Kreutzer Sonata', author: 1, }, { id: 4, author: 2, title: 'Hamlet', }, ]; export const dataProviderWithAuthors = { getOne: async () => ({ data: author }), getMany: async (_resource, params) => ({ data: books.filter(book => params.ids.includes(book.author)), }), getManyReference: async (_resource, params) => { const result = books.filter(book => book.author === params.id); return { data: result.slice( (params.pagination.page - 1) * params.pagination.perPage, (params.pagination.page - 1) * params.pagination.perPage + params.pagination.perPage ), total: result.length, }; }, } as any; export const Basic = ({ dataProvider = dataProviderWithAuthors }) => ( } /> ); const dataProviderWithAuthorList = fakeRestDataProvider( { authors: [ { id: 1, first_name: 'Leo', last_name: 'Tolstoy', language: 'Russian', }, { id: 2, first_name: 'William', last_name: 'Shakespear', language: 'English', }, ], books, }, process.env.NODE_ENV === 'development' ); export const InAList = ({ dataProvider = dataProviderWithAuthorList }) => ( (

{author.last_name} Books

)} /> } />
); const dataProviderWithAuthorsError = { getOne: () => Promise.resolve({ data: { id: 1, title: 'War and Peace', author: 1, summary: "War and Peace broadly focuses on Napoleon's invasion of Russia, and the impact it had on Tsarist society. The book explores themes such as revolution, revolution and empire, the growth and decline of various states and the impact it had on their economies, culture, and society.", year: 1869, }, }), getMany: (_resource, params) => Promise.resolve({ data: books.filter(book => params.ids.includes(book.author)), }), getManyReference: _resource => Promise.reject(new Error('Error')), } as any; export const Errored = ({ dataProvider = dataProviderWithAuthorsError }) => ( } /> ); const dataProviderWithAuthorsLoading = { getOne: () => Promise.resolve({ data: author, }), getMany: (_resource, params) => Promise.resolve({ data: books.filter(book => params.ids.includes(book.author)), }), getManyReference: _resource => new Promise(() => {}), } as any; export const Loading = ({ dataProvider = dataProviderWithAuthorsLoading }) => ( } /> ); export const WithRenderProp = ({ dataProvider = dataProviderWithAuthors, }: { dataProvider?: any; }) => ( { if (isPending) { return

Loading...

; } if (error) { return (

{error.message}

); } return (

{data?.map((datum, index) => (

  • {datum.title}
  • ))}

    ); }} /> } />
    ); export const Offline = ({ offline }) => { return (

    } />
    ); }; Offline.args = { offline: 'let children handle offline state', }; Offline.argTypes = { offline: { control: { type: 'radio' }, options: [ 'let children handle offline state', 'handle offline state in ReferenceManyFieldBase', ], mapping: { 'let children handle offline state': undefined, 'handle offline state in ReferenceManyFieldBase': (

    You are offline, cannot load data

    ), }, }, }; const SimulateOfflineButton = () => { const isOffline = useIsOffline(); return ( ); }; const RenderChildOnDemand = ({ children }) => { const [showChild, setShowChild] = React.useState(false); return ( <> {showChild &&
    {children}
    } ); }; const AuthorList = ({ source }) => { const { isPaused, isPending, error, data } = useListContext(); if (isPending && !isPaused) { return

    Loading...

    ; } if (isPaused) { return

    AuthorList: Offline. Could not load data

    ; } if (error) { return

    {error.toString()}

    ; } return (

    {data?.map((datum, index) =>

  • {datum[source]}
  • )}

    ); }; // test queryOptions type, it should support onSuccess and onError export const QueryOptions = ({ dataProvider }) => ( console.log('Query successful'), onError: () => console.log('Query failed'), retry: false, }} > } /> ); QueryOptions.args = { dataProvider: dataProviderWithAuthors, }; QueryOptions.argTypes = { dataProvider: { control: { type: 'radio' }, options: ['No error', 'With Error'], mapping: { 'No error': dataProviderWithAuthors, 'With Error': dataProviderWithAuthorsError, }, }, };