Hello, I am trying to build an index table with bulk action.
Mine looks like this
import { useState, useCallback } from "react";
import { Filters, Layout, Page, IndexTable, useIndexResourceState, Pagination } from "@shopify/polaris";
import { TitleBar } from "@shopify/app-bridge-react";
export default function Products() {
const [queryValue, setQueryValue] = useState(""); // Search bar state
const [currentPage, setCurrentPage] = useState(1); // Track the current page
const itemsPerPage = 3; // Number of rows per page
const [orders, setOrders] = useState([
{ id: "1", property1: "ABCDEFG", property2: "Category X", property3: 100 },
{ id: "2", property1: "HIJKLMN", property2: "Category Y", property3: 200 },
{ id: "3", property1: "OPQRSTU", property2: "Category X", property3: 150 },
{ id: "4", property1: "VWXYZAB", property2: "Category Z", property3: 250 },
]);
const resourceName = {
singular: "product",
plural: "products",
};
// Filter Logic: Apply search query to filter orders
const filteredOrders = orders.filter((order) => {
return (
queryValue === "" ||
order.property1.toLowerCase().includes(queryValue.toLowerCase()) ||
order.property2.toLowerCase().includes(queryValue.toLowerCase()) ||
String(order.property3).includes(queryValue)
);
});
// Pagination Logic: Apply pagination to filtered orders
const totalPages = Math.ceil(filteredOrders.length / itemsPerPage);
const paginatedOrders = filteredOrders.slice(
(currentPage - 1) * itemsPerPage,
currentPage * itemsPerPage
);
const { selectedResources, allResourcesSelected, handleSelectionChange } =
useIndexResourceState(paginatedOrders);
const rowMarkup = paginatedOrders.map(
({ id, property1, property2, property3 }, index) => (
<IndexTable.Row
id={id}
key={id}
selected={selectedResources.includes(id)}
position={index}
>
<IndexTable.Cell>{property1}</IndexTable.Cell>
<IndexTable.Cell>{property2}</IndexTable.Cell>
<IndexTable.Cell numeric>{property3}</IndexTable.Cell>
</IndexTable.Row>
)
);
// Handlers for Search and Pagination
const handleQueryChange = useCallback((value) => {
setQueryValue(value);
setCurrentPage(1); // Reset to first page after search
}, []);
const handleQueryClear = useCallback(() => {
setQueryValue("");
setCurrentPage(1); // Reset to first page after clearing search
}, []);
const handleNextPage = useCallback(() => {
if (currentPage < totalPages) {
setCurrentPage((prev) => prev + 1);
}
}, [currentPage, totalPages]);
const handlePreviousPage = useCallback(() => {
if (currentPage > 1) {
setCurrentPage((prev) => prev - 1);
}
}, [currentPage]);
// Custom Selection Change Handler for "Select All"
const customSelectionChange = useCallback(() => {
if (allResourcesSelected) {
// Clear all selections
handleSelectionChange([]);
} else {
// Select all items on the current page
const currentPageIds = paginatedOrders.map((order) => order.id);
handleSelectionChange(currentPageIds);
}
}, [allResourcesSelected, handleSelectionChange, paginatedOrders]);
return (
<Page>
<TitleBar title="Products" />
<Layout>
<Layout.Section>
<Filters
queryValue={queryValue}
queryPlaceholder="Search by property 1, 2, or 3"
filters={[]}
onQueryChange={handleQueryChange}
onQueryClear={handleQueryClear}
/>
</Layout.Section>
<Layout.Section>
{paginatedOrders.length === 0 ? (
<p>No data available</p>
) : (
<>
<IndexTable
resourceName={resourceName}
itemCount={filteredOrders.length} // Use filteredOrders for total count
selectedItemsCount={
allResourcesSelected ? "All" : selectedResources.length
}
selectedResources={selectedResources}
onSelectionChange={handleSelectionChange}
headings={[
{ title: "Property 1" },
{ title: "Property 2" },
{ title: "Property 3" },
]}
>
{rowMarkup}
</IndexTable>
</>
)}
</Layout.Section>
<Layout.Section>
<Pagination
hasPrevious={currentPage > 1}
onPrevious={handlePreviousPage}
hasNext={currentPage < totalPages}
onNext={handleNextPage}
accessibilityLabels={{
previous: "Go to previous page",
next: "Go to next page",
}}
/>
</Layout.Section>
</Layout>
</Page>
);
}
While the select all checkbox select all rows, it doesn’t clear the selections when I click on it again.
Why is that?
Thank you!