import { GenerationInstructions, topLevel } from "@amplicode/storybook-extensions"; import { Typography } from "@mui/material"; import { Meta, StoryObj } from "@storybook/react"; import { dataProvider, users } from "../../../dataProvider"; import { attributeName, resourceName } from "../../../ideExtension"; import { useState, useEffect } from "react"; import { AdminContext, defaultI18nProvider, Labeled, ListContextProvider, ListControllerResult, RecordContextProvider, ReferenceField, ReferenceManyField, ResourceContextProvider, Show, SimpleList, SimpleShowLayout, TextField, useDataProvider, useListContext } from "react-admin"; import { AnyPropsComponent } from "../../../utils"; const meta = { title: "Relations/Reference/ListContextAdapter", component: AnyPropsComponent, decorators: [(Story) => defaultDecorator(Story)], // excludeStories: /.*/, } satisfies Meta; export default meta; type Story = StoryObj; export const Deafult: Story = { render: () => { const ListContextAdapter = topLevel(({ children, }: { children: React.ReactNode, }) => { const listContext = useListContext(); const [modifiedData, setModifiedData] = useState(); useEffect(() => { if (listContext.data) { // Write necessary data processing here setModifiedData(listContext.data); } }, [listContext.data]); let value: ListControllerResult if (listContext.isLoading || listContext.isPending || listContext.isFetching || listContext.error || !modifiedData ) { value = { ...listContext, }; } else { value = { ...listContext, data: modifiedData, } } return {children} }); return `${record.grade} ${record.name}`} secondaryText={record => record.description} /> }, } export const WithDataFetching: Story = { render: ({ reference, source }) => { const ListContextAdapter = topLevel(({ children, reference: resource, source, }: { children: React.ReactNode, source: string, reference: string, }) => { const listContext = useListContext(); const [joinedData, setJoinedData] = useState(); const dataProvider = useDataProvider(); useEffect(() => { const updateChildrenState = async (data: any[]) => { const { data: children } = await dataProvider.getMany(resource, { ids: data.map(parentRecord => parentRecord[source]), }); const joinedData = data.map(parentRecord => { const childRecord = children.find(child => child.id === parentRecord[source])!; return { ...parentRecord, ...childRecord }; }) setJoinedData(joinedData); } if (listContext.data) { updateChildrenState(listContext.data); } }, [listContext.data, dataProvider]); let value: ListControllerResult if (listContext.isLoading || listContext.isPending || listContext.isFetching || listContext.error || !joinedData ) { value = { ...listContext, }; } else { value = { ...listContext, data: joinedData, } } return {children} }); return `${record.grade} ${record.name}`} secondaryText={record => record.description} /> }, args: { reference: resourceName("competences", { title: 'Child Resource', resourceId: 'subresource', allowContext: false, }), source: attributeName("competenceId", { resourceId: 'parentResource', attributeSelectTitle: 'Reference Attribute from JoinResource Resource to Child Resource' } ) } } const defaultDecorator = (Story: () => React.JSX.Element) => ( Custom component for modifying list context User );