Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add example of Table component with pagination #10621

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 112 additions & 1 deletion www/apps/resources/app/admin-components/components/table/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const Table = ({
setCurrentPage,
}: TableProps) => {
const pageCount = useMemo(() => {
return Math.ceil(data.length / pageSize)
return Math.ceil(count / pageSize)
}, [data, pageSize])

const canNextPage = useMemo(() => {
Expand Down Expand Up @@ -243,3 +243,114 @@ export default ProductWidget
```

This widget also uses the [Container](../container.mdx) custom component.

---

## Example With Data Fetching

This section shows you how to use the `Table` component when fetching data from the Medusa application's API routes.

Assuming you've set up the JS SDK as explained in [this guide](../../../js-sdk/page.mdx), create the UI route `src/admin/routes/custom/page.tsx` with the following content:

export const tableExampleHighlights = [
["12", "currentPage", "The table's current page."],
["13", "limit", "The maximum number of items per page."],
["14", "offset", "The number of items to skip before retrieving the current page's items."],
["18", "data", "The response fields."],
["18", "useQuery", "Fetch products from the Medusa application."]
]

```tsx title="src/admin/routes/custom/page.tsx" collapsibleLines="1-10" expandButtonLabel="Show Imports" highlights={tableExampleHighlights}
import { defineRouteConfig } from "@medusajs/admin-sdk"
import { ChatBubbleLeftRight } from "@medusajs/icons"
import { useQuery } from "@tanstack/react-query"
import { SingleColumnLayout } from "../../layouts/single-column"
import { Table } from "../../components/table"
import { sdk } from "../../lib/config"
import { useMemo, useState } from "react"
import { Container } from "../../components/container"
import { Header } from "../../components/header"

const CustomPage = () => {
const [currentPage, setCurrentPage] = useState(0)
const limit = 15
const offset = useMemo(() => {
return currentPage * limit
}, [currentPage])

const { data } = useQuery({
queryFn: () => sdk.admin.product.list({
limit,
offset
}),
queryKey: [["products", limit, offset]],
})

// TODO display table
}

export const config = defineRouteConfig({
label: "Custom",
icon: ChatBubbleLeftRight,
})

export default CustomPage
```

In the `CustomPage` component, you define:

- A state variable `currentPage` that stores the current page of the table.
- A `limit` variable, indicating how many items to retrieve per page
- An `offset` memoized variable indicating how many items to skip before the retrieved items. It's calculated as a multiplication of `currentPage` and `limit`.

Then, you use `useQuery` from [Tanstack Query](https://tanstack.com/query/latest) to retrieve products using the JS SDK. You pass `limit` and `offset` as query parameters, and you set the `queryKey`, which is used for caching and revalidation, to be based on the key `products`, along with the current limit and offset. So, whenever the `offset` variable changes, the request is sent again to retrieve the products of the current page.

<Note title="Tip">

You can change the query to send a request to a custom API route as explained in [this guide](../../../js-sdk/page.mdx#send-requests-to-custom-routes).

</Note>

`useQuery` returns an object containing `data`, which holds the response fields including the products and pagination fields.

Then, to display the table, replace the `TODO` with the following:

```tsx
return (
<SingleColumnLayout>
<Container>
<Header title="Products" />
{data && (
<Table
columns={[
{
key: "id",
label: "ID"
},
{
key: "title",
label: "Title"
}
]}
data={data.products as any}
pageSize={data.limit}
count={data.count}
currentPage={currentPage}
setCurrentPage={setCurrentPage}
/>
)}
</Container>
</SingleColumnLayout>
)
```

Aside from the `Table` component, this UI route also uses the [SingleColumnLayout](../../layouts/single-column/page.mdx), [Container](../container/page.mdx), and [Header](../header/page.mdx) custom component.

If `data` isn't `undefined`, you display the `Table` component passing it the following props:

- `columns`: The columns to show. You only show the product's ID and title.
- `data`: The rows of the table. You pass it the `products` property of `data`.
- `pageSize`: The maximum number of items per page. You pass it the `count` property of `data`.
- `currentPage` and `setCurrentPage`: The current page and the function to change it.

To test it out, log into the Medusa Admin and open `http://localhost:9000/app/custom`. You'll find a table of products with pagination.
2 changes: 1 addition & 1 deletion www/apps/resources/generated/edit-dates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,7 @@ export const generatedEditDates = {
"app/admin-components/components/header/page.mdx": "2024-10-07T11:16:47.407Z",
"app/admin-components/components/json-view-section/page.mdx": "2024-10-07T11:15:58.833Z",
"app/admin-components/components/section-row/page.mdx": "2024-10-07T11:15:58.832Z",
"app/admin-components/components/table/page.mdx": "2024-10-07T11:15:58.833Z",
"app/admin-components/components/table/page.mdx": "2024-12-16T15:28:59.428Z",
"app/admin-components/page.mdx": "2024-10-07T11:09:49.493Z",
"app/admin-components/layouts/single-column/page.mdx": "2024-10-07T11:16:06.435Z",
"app/admin-components/layouts/two-column/page.mdx": "2024-10-07T11:16:10.092Z",
Expand Down
Loading