other-emerald
other-emerald2mo ago

How to create Multiple resource based on permanent filter?

How to create multiple resources from the same API endpoint but the difference is each resource has a different permanent filter?
8 Replies
kapa.ai
kapa.ai2mo ago
Hi @regn. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To create multiple resources based on permanent filters in refine, you can utilize the filters.permanent property when defining your resources. This allows you to create different resources from the same API endpoint, each with its own permanent filter. Here's how you can approach this: 1. Define separate resources in your <Refine> component, each with a unique name. 2. For each resource, use the appropriate hook (e.g., useTable, useSimpleList, etc.) and set the filters.permanent property with the desired filter. Here's an example of how you might implement this using the useTable hook:
// Resource 1: Products with material "Cotton"
const CottonProducts = () => {
const { tableProps } = useTable({
filters: {
permanent: [
{
field: "material",
operator: "eq",
value: "Cotton",
},
],
},
});

// Render your table here
};

// Resource 2: Products with material "Bronze"
const BronzeProducts = () => {
const { tableProps } = useTable({
filters: {
permanent: [
{
field: "material",
operator: "eq",
value: "Bronze",
},
],
},
});

// Render your table here
};
// Resource 1: Products with material "Cotton"
const CottonProducts = () => {
const { tableProps } = useTable({
filters: {
permanent: [
{
field: "material",
operator: "eq",
value: "Cotton",
},
],
},
});

// Render your table here
};

// Resource 2: Products with material "Bronze"
const BronzeProducts = () => {
const { tableProps } = useTable({
filters: {
permanent: [
{
field: "material",
operator: "eq",
value: "Bronze",
},
],
},
});

// Render your table here
};
In this example, we've created two separate components, each using the useTable hook with a different permanent filter. The filters.permanent property ensures that these filters are always applied and cannot be changed by the user. You can then define these as separate resources in your <Refine> component:
<Refine
resources={[
{
name: "cotton-products",
list: CottonProducts,
// other CRUD components...
},
{
name: "bronze-products",
list: BronzeProducts,
// other CRUD components...
},
]}
// other Refine configurations...
/>
<Refine
resources={[
{
name: "cotton-products",
list: CottonProducts,
// other CRUD components...
},
{
name: "bronze-products",
list: BronzeProducts,
// other CRUD components...
},
]}
// other Refine configurations...
/>
This approach allows you to create multiple resources that use the same API endpoint but have different permanent filters applied. For more information on using permanent filters, you can refer to the following documentation: - useTable filters.permanent (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-table/#filterspermanent) - useSimpleList filters.permanent (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-simple-list/#filterspermanent) Remember that the permanent filter is unchangeable and will always be applied, unlike initial filters which can be modified by the user. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@336843331416096768> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
other-emerald
other-emeraldOP2mo ago
@kapa.ai In my case, I have a resource called warehouse_listing, so I want to have 2 list pages, the first one will shows only data with pending status, and the other one is for the 'done' status
{
name: "warehouse_listing",
list: "/warehouse_listing",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "warehouse_listing",
list: "/warehouse_listing",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "warehouse_listing",
list: "/warehouse_listing",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "warehouse_listing",
list: "/warehouse_listing",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
The API endpoint is the same, but I want to use the permanent filter
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand you want to create two separate list pages for your warehouse_listing resource, one for pending status and another for done status, using the same API endpoint but with different permanent filters. Here's how you can achieve this using refine: 1. First, you need to create two distinct resources with different names, even though they use the same API endpoint. Let's modify your resource definitions:
{
name: "pending_warehouse_listing",
list: "/warehouse_listing/pending",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "done_warehouse_listing",
list: "/warehouse_listing/done",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "pending_warehouse_listing",
list: "/warehouse_listing/pending",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "done_warehouse_listing",
list: "/warehouse_listing/done",
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
2. Now, create two separate list components for pending and done statuses. In each component, use the useTable hook with a permanent filter:
// PendingWarehouseList.tsx
import { useTable } from "@refinedev/core";

const PendingWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "pending",
},
],
},
});

// Render your table here
};

// DoneWarehouseList.tsx
import { useTable } from "@refinedev/core";
const DoneWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "done",
},
],
},
});

// Render your table here
};
// PendingWarehouseList.tsx
import { useTable } from "@refinedev/core";

const PendingWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "pending",
},
],
},
});

// Render your table here
};

// DoneWarehouseList.tsx
import { useTable } from "@refinedev/core";
const DoneWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "done",
},
],
},
});

// Render your table here
};
3. Finally, update your resource definitions to use these new components:
{
name: "pending_warehouse_listing",
list: PendingWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "done_warehouse_listing",
list: DoneWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "pending_warehouse_listing",
list: PendingWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "done_warehouse_listing",
list: DoneWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
},
This approach allows you to have two separate list pages for pending and done warehouse listings, using the same API endpoint but with different permanent filters. The filters.permanent property ensures that these filters are always applied and cannot be changed by the user useTable filters.permanent (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-table/#filterspermanent). Remember to adjust the field names and values in the permanent filters according to your actual API structure and requirements. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@336843331416096768> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
other-emerald
other-emeraldOP2mo ago
This approach affects my edit page, how can I make it only for the list page? This approach affects my edit page, how can I make it only for the list page? @kapa.ai
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand your concern about the approach affecting your edit page. You're right to point this out, as we want to apply the permanent filter only to the list pages without impacting other CRUD operations. Let's modify the approach to achieve this. Here's how you can make the permanent filter apply only to the list pages: 1. Instead of setting the permanent filter in the resource definition, we'll move it directly into the list components. 2. For the edit, create, and show pages, we'll use the original warehouse_listing resource name. Here's the updated approach: 1. Modify your resource definitions:
{
name: "warehouse_listing",
list: PendingWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "warehouse_listing",
list: DoneWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
}
{
name: "warehouse_listing",
list: PendingWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Pending Warehouse Listing",
parent: "warehouse_module",
},
},
{
name: "warehouse_listing",
list: DoneWarehouseList,
create: "/warehouse_listing/create",
edit: "/warehouse_listing/edit/:id",
show: "/warehouse_listing/show/:id",
meta: {
canDelete: true,
label: "Done Warehouse Listing",
parent: "warehouse_module",
},
}
2. Update your list components to include the permanent filter:
// PendingWarehouseList.tsx
import { useTable } from "@refinedev/core";

const PendingWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "pending",
},
],
},
});

// Render your table here
};

// DoneWarehouseList.tsx
import { useTable } from "@refinedev/core";
const DoneWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "done",
},
],
},
});

// Render your table here
};
// PendingWarehouseList.tsx
import { useTable } from "@refinedev/core";

const PendingWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "pending",
},
],
},
});

// Render your table here
};

// DoneWarehouseList.tsx
import { useTable } from "@refinedev/core";
const DoneWarehouseList = () => {
const { tableProps } = useTable({
resource: "warehouse_listing",
filters: {
permanent: [
{
field: "status",
operator: "eq",
value: "done",
},
],
},
});

// Render your table here
};
This approach ensures that: 1. The permanent filters are only applied to the list pages. 2. The edit, create, and show pages will use the same warehouse_listing resource without any permanent filters. By moving the filter logic into the list components, we isolate the filtering behavior to just the list pages. The edit, create, and show pages will function as before, using the common warehouse_listing resource without any permanent filters applied. This solution allows you to have separate list views for pending and done statuses while maintaining a single, unfiltered resource for other CRUD operations. The permanent filters will only be active in the useTable hook calls within the list components useTable filters.permanent (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-table/#filterspermanent). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@336843331416096768> Kapa.ai is still learning and improving, please let me know how I did by reacting below.