Custom URL for ShowButton on admin-on-rest - admin-on-rest

Does it have any way to make a custom path for some Show buttons?
I have a ReferecenManyField that has 2 types of components underneath and I want to redirect to the Show page of each of these components.
In my CollectionShow I have
<Show title={<CollectionTitle />} actions={<CollectionShowActions />} {...props}>
<SimpleShowLayout>
...
<ReferenceManyField label="Itens" target="collection_id" reference="collection_items">
<Datagrid bodyOptions={{ showRowHover: true }}>
<TextField source="id" />
<TextField label="Tipo" source="collectionable_type" />
<TextField label="Nome" source="collectionable.name" sortable={false} />
<TextField label="Privacidade" source="collectionable.privacy" sortable={false} />
<ShowButton />
</Datagrid>
</ReferenceManyField>
... where my collectionable_type can be either another Collection or a LearningObject.
Is there any way to make a customable URL for the ShowButton?
Maybe something like:
<ShowButton basePath={"/${collectionable_type}/${collectionable.id}"} />

The <ShowButton /> component is dedicated to creating links to a show view managed by admin-on-rest.
To make a customable URL in your Datagrid, you should create a dedicated field component as explained in the documentation Writing Your Own Field Component

Related

Added 'search function' using React-admin package, but not working, why?

I am using React-admin to create a customer dashboard where they can find their invoices for all months. Now I would like to add search function to this so that customers can search invoices according to any field,say entity_name.
I am able to add search element on ui, but its not working.
I added search functionality by importing {Filter, TextInput} from React-admin. And I am using data from "ra-data-simple-rest"; and running sever on port 5000 in my local machine.
Here is my code:
const InvoiceFilter = (props) => (
<Filter {...props}>
<TextInput source="entity_name" alwaysOn />
</Filter>
);
const InvoiceList = (props) => {
return (
<List {...props} filters={<InvoiceFilter />}>
<Datagrid>
<TextField source="id" />
<TextField source="entity_name" />
<DateField source="period_start" />
<DateField source="period_end" />
<TextField source="total" />
</Datagrid>
</List>
);
};
You should use proper components for the filter function.
the filters props is for FilterForm
<FilterForm filters={postFilters} />
Placing the filters props in List component is not doing anything.
Create proper filter and pass it to a proper component like shown in the documentation here
Based on the docs, you could try:
const invoiceFilters = [
<TextInput source="entity_name" alwaysOn />
);
const InvoiceList = () => {
return (
<List filters={invoiceFilters}>
<Datagrid>
<TextField source="id" />
<TextField source="entity_name" />
<DateField source="period_start" />
<DateField source="period_end" />
<TextField source="total" />
</Datagrid>
</List>
);
};

ReferenceManyFields / ReferenceArrayField Combination

I know the usage of both the components is clearly different, ReferenceManyFields used to make request to certain resource by filtering the target with the current id.
ReferenceArrayFields used to make request to certain resource by filtering the referenced id using the source that contain some ids.
ReferenceManyFields has target props, ReferenceArrayFields has source props. Is there any way to send the request based on the target and source ?
Here is my code..
export const ApplicationEdit = (props) => {
return (
<Edit {...props} >
<SimpleForm>
<ReferenceManyFields reference="applications" target="customer_id" source="costumer_id" addLabel={true} label="Application History">
<Datagrid>
<TextField source="id" />
<DateField source="date" />
<TextField source="amount" />
<TextField source="status" />
<TextField source="customer_id" />
</Datagrid>
</ReferenceManyFields>
</SimpleForm>
</Edit>
);
}
This is not possible currently but it looks like a valid use case to me. I'll see if we can address this in next version

Datagrid in Create, Edit page

I want to create a Datagrid inside Create, Edit page to display and manage n-to-n relationship. But I don't know how to pass props into List and Datagrid and what props should be passed.
The Resource to manage this Datagrid named caregiver_student and I put it in my custom restClient file.
Basic info
Relationship info
Here is my code:
<Edit title={<CaregiverTitle />} {...props}>
<TabbedForm>
<FormTab label="Personal Info">
<DisabledInput source="id" />
<TextInput source="name" />
<TextInput source="email" />
<TextInput source="phone" />
<RadioButtonGroupInput source="account_type" choices={[
{ id: 10, name: 'Caregiver' },
{ id: 20, name: 'Guardian' },
]} optionText="name" optionValue="id" />
<BooleanInput source="status" label="Active"/>
</FormTab>
<FormTab label="Relationship">
<List actions={<RelationActions/>} location={false} title={" "}>
<Datagrid>
<TextField source="id" />
<TextField source="name" label="Student"/>
<TextField source="relationship" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
</FormTab>
</TabbedForm>
</Edit>
Thank you for your help!
The linked resources should be enclosed in a ReferenceManyField
You can find a complete example in the demo,
especially the Customers Edit component
Someone started a PR which might help: https://github.com/marmelab/admin-on-rest/pull/744
I have a similar page with a tab that lists "Batchunits" that belong to a particular "batchid".
<FormTab label="resources.batches.tabs.batchunits">
<ReferenceManyField addLabel={false} reference="Batchunits" target="batchid">
<Datagrid bodyOptions={{ stripedRows: true, showRowHover: true}} >
<TextField source="unitcode" />
<DateField source="harvested" />
<BooleanField source="contaminated" label="Contaminated"/>
<TextField source="note" style={{ maxWidth: '10em', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} />
<EditUnitButton />
</Datagrid>
</ReferenceManyField>
</FormTab>
But in this setup, Formtab will not accept a Create "button" to create a record of another resource. e.g another "Batchunit. Would be very useful to create another linked Batchunit. Don't know how to do that...

admin-on-rest: Access row's column data within a Datagrid component

I have a List view where I want to render a ReferenceField field based on the value of the current row being rendered in the table that the Datagrid component creates.
How can I access the current row's data? (the values of the columns of the current row).
I tried record.processed but I get an error saying that the record object doesn't exist (processed is a column in the record that I want to check in order to format the field). I also tried resource.processed, this.props.processed, and this.props.record.processed with no success.
The piece of code that shows what I'm trying to do is the following:
<List title="Sales Inquiries" filter={{ request_type: 'sales' }} {...props}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" label="First Name" />
<TextField source="lastname" label="Last Name" />
<TextField source="company" />
<TextField source="email" />
<DateField source="timestamp" label="Received" />
{record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
<ShowButton />
</Datagrid>
</List>
EDIT
Did as suggested by #kunal pareek Applied a HOC to the ReferenceField field that modifies it in order to show the proper content as follows:
const CustomField = (props) => (
<span>
{props.record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
</span>
);
the record is not really available at the location you want as a variable. It is passed to the component as a prop.
So you can do this.
<List title="Sales Inquiries" filter={{ request_type: 'sales' }} {...props}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" label="First Name" />
<TextField source="lastname" label="Last Name" />
<TextField source="company" />
<TextField source="email" />
<DateField source="timestamp" label="Received" />
<CustomField />
<ShowButton />
</Datagrid>
</List>
const CustomField = (props) => (
{props.record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
)
Above is just a simple example. I have taken your code straight and reformatted it, so it might not work straightaway. But I have been using this method to change the values of my components in several places.
You can also use HOCs. You can find examples here
https://marmelab.com/admin-on-rest/Theming.html
The dependent-input addon can help you with that.

Is there a way to force Show to use a Datagrid?

I am looking for a way to allow Show to be able to use a Datagrid on the show page. I want to be able to click on the show button and when the show page appears, I want to be able to take data and make another grid using Datagrid or something similar. Any Ideas how this is done?
it seems show page take 1 record and render its. on show page you can place related records with current. for example news can related with one project and one project has many news. code below get from api all related news and render its as a table. hope it helps you
export const ProjectShow = ({ ...props }) => (
<Show title={<ProjectTitle />} {...props}>
<SimpleShowLayout>
<ReferenceManyField label="News" reference="news" target="project_id">
<Datagrid>
<TextField source="id" />
<TextField source="title" />
<DateField source="created_at" showTime />
<DateField source="updated_at" showTime />
<EditButton />
</Datagrid>
</ReferenceManyField>
</SimpleShowLayout>
</Show>
);
don't remember place in App.js line:
<Resource name="projects" ...another actions... show={ProjectShow} />

Resources