Get data from a custom endpoint in react-admin - react-admin

I'm using react-admin with data that I get from a restAPI data source that I can customize for my needs, I've added a standard resource with only a list and an edit attributes:
<Resource name="topic" edit={TopicsEdit} list={TopicsList} />
When I look at the network tab of Chrome dev tools I see that I use the right endpoints:
For the list:
GET request for http://api.loc/topic
And for the edit:
GET request for http://api.loc/topic/{{topic_id}}
Up to this point everything works just fine.
My problem starts when I try to have the edit screen split into two tabs, one of them will be for editing the topic (This works just fine), and the other tab should use data from a different endpoint:
http://api.loc/topic/{{topic_id}}/modifiers
The code for my TopicsEdit file:
<Show {...props}>
<TabbedShowLayout>
<Tab label='topic'>
<Edit {...props}>
<SimpleForm>
<TextInput source="id"/>
<TextInput source="title"/>
</SimpleForm>
</Edit>
</Tab>
<Tab label='modifiers' path='modifiers'>
<List {...props}>
<Datagrid>
<TextField source="id"/>
<TextField source="name"/>
</Datagrid>
</List>
</Tab>
</TabbedShowLayout>
</Show>
In the topic tab everything is working as I mentioned before, but when I switch to the modifiers tab I see in the network dev tool that the data arrives from
http://api.loc/topic
instead of
http://api.loc/topic/{{topic_id}}/modifiers
How can I customize the URL that the modifiers tab will pull the data from?
The only thing I did find was to use a <ReferenceInput> but the problem here is that the reference="" attribute will only get the info from a predefined structure, meaning that if I use reference="modifiers" it tries to fetch the data from:
http://api.loc/modifiers
And not from the desired URL.

Related

How to add a click handler to Fluent UI v9's SplitButton?

The documentation of Fluent UI v9's SplitButton is not clear on how to add a click handler to the primary button.
Can anyone show me an example of how that is done?
I have tried finding examples on their GitHub page and I've googled for possible examples and I found one GitHub issue noting that this is a problem with their documentation.
Figured it out:
<Menu positioning="below-end">
<MenuTrigger disableButtonEnhancement>
{(triggerProps: MenuButtonProps) => (
<SplitButton
primaryActionButton={{ onClick: handleClick }}
menuButton={triggerProps}
>
Example
</SplitButton>
)}
</MenuTrigger>
<MenuPopover>
<MenuList>
<MenuItem>
Remove file
</MenuItem>
</MenuList>
</MenuPopover>
</Menu>

Can't get ReferenceManyField to display data

Have spent several hours trying to get ReferenceManyField to display some data in a nested DataGrid.
<Show {...this.props}>
<SimpleShowLayout>
<TextField source="id" />
<TextField source="name" />
{/* THE FOLLOWING COMPONENT DOES NOT DISPLAY ANY DATA. WHY NOT??? */}
<ReferenceManyField label="Stores" reference="stores" target="companies_id">
<Datagrid rowClick="show">
<TextField source="id" />
<TextField source="storeName" />
</Datagrid>
</ReferenceManyField>
</SimpleShowLayout>
</Show>
I have created a massively stripped down version of my app, which demonstrates the problem:
https://codesandbox.io/s/react-admin-referencemanyfield-issue-forked-lde6c
I am certain there has to be a simple explanation for this issue, but as a relative newcomer to React/ReactAdmin/Typescript I just can't see it. What am I doing wrong?
Grateful for any tips & advice.
You haven't declared the stores resource in your Admin component.
Add a <Resource name="stores" /> inside Admin

Injecting List, Show, Edit, Create in any places

I would like create a file browser with <List /> component in <Show /> component.
Let's say we have a user with home directory and we want to create a file browser to this directory with ability to remove files. The idea of files doesn't match the idea of simple tables, which rows can be edited.
So I have created my own component with username and directory as states, useDataprovider() as hook, and <Table/> from MUI, altered data provider a bit. And it works quite nice.
The problem comes when there are many position in list, like 50+. A pagination would be nice. So I tried to fake props of <List /> and later <ListView /> to replace <Table /> but I failed.
After short code review, it looks like implementing <List /> as is, is not possible, because many hooks and other things it uses. In general nesting one into another of any type would be a mess in come.
My idea of this would look like this:
function HomedirBrowser({username}) {
const [usrPath, setUsrPath] = React.useState("/");
return (<List
resource={`/users/${username}/dir/${usrPath}`}
>
<Datagrid>
<TextField source="type"/>
<TextField source="name"/>
<TextField source="last_edit"/>
<TextField source="size"/>
<Button onClick={({record}) => setUsrPath(usrPath + "/" + record.name)}>Enter</Button>
</Datagrid>
</List>)
}
The custom resource which would depend on a state and the button could alter the state.
Is this possible to do? Or there is any other way to achieve nesting one element into another.
Of course, I don't want to save state to browsing in url of anywhere at all.
I had a similar problem. I wanted to place a List component inside a Show component. Here is an example what I wanted to achieve:
const AuthorShow = props => (
<Show {...props}>
<TabbedShowLayout>
<Tab label='author'>
<TextField source="firstName"/>
<TextField source="lastName"/>
</Tab>
<Tab label='books'>
<List {...props}
resource='books'
filter={{authorId: props.id}}>
<Datagrid>
<TextField source="title" />
</Datagrid>
</List>
</Tab>
</TabbedShowLayout>
</Show>)
Although I explicitly passed 'resource' prop, it was ignored and Show resource was used - authors. I managed to fix this behavior by wrapping List in a Fragment.
const AuthorShow = props => (
<Show {...props}>
<TabbedShowLayout>
<Tab label='author'>
<TextField source="firstName"/>
<TextField source="lastName"/>
</Tab>
<Tab label='books'>
<Fragment>
<List {...props}
resource='books'
filter={{authorId: props.id}}>
<Datagrid>
<TextField source="title" />
</Datagrid>
</List>
</Fragment>
</Tab>
</TabbedShowLayout>
</Show>)
I don't know what caused that you failed to use List but this one may give you some clue at least.
I have the similar code:
<Fragment>
<List
{...props}
resource="card_program_options"
filterDefaultValues={{ card_id: 1 }}
sort={{ field: "id", order: "ASC" }}
>
<Datagrid>
<TextField source="card_id" />
<TextField source="card_programs_id" />
</Datagrid>
</List>
</Fragment>
But the only thing i see on the page is No results found
screenshot of No results found in show
I see the request made in the backend and completes with a 200 response code.
Help is appreciated!

In React-Admin, could I disable the mailto link created by EmailField?

I'm setting an admin panel and listing the users that are registered in a platform.
In the listing page, when I click over the row I am linked to edit page. However, one of the fields is 'email' and I use EmailField to get advantage of validations, what it automatically creates an anchor tag with a mailto functionality.
For all the fields I am showing, 'email' is the unique field that has a link so, from the UX point of view, it invites to click it. And when I click over the link, the email client is opened. That is why I want to disable the link.
I could change to TextField, but I want to keep EmailField's validations. So, is there a way to avoid creating a mailto anchor over the email? I can't find it in the docs or in google.
export const UserList = props => (
<List bulkActionButtons={false} {...props} filters=
{<UserFilter/>} perPage={10} sort={{ field: 'email', order: 'ASC'
}} pagination={<UserPagination />} >
<Datagrid rowClick="edit">
<EmailField source="email" />
<BooleanField source="isAdmin" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
);
Thanks for your help.

Clickable "ChipField" element

In the list page, I'm using a component as follows in the Datagrid
<ArrayField source="functions">
<SingleFieldList>
<ChipField source="id" />
</SingleFieldList>
</ArrayField>
But this causes a clickable element in the grid. I don't want this element to be clickable. Is it possible?
Assuming you are using the latest version of react-admin 2.3, adding linkType={false} to your <SingleFieldList> will do the work.
Your snippet will become:
<ArrayField source="functions">
<SingleFieldList linkType={false}>
<ChipField source="id" />
</SingleFieldList>
</ArrayField>