From 4fabdfc436066c70b4d6221d1d32703a013df0e2 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 16 Dec 2024 17:31:15 +0200 Subject: [PATCH] docs: add example of Table component with pagination --- .../components/table/page.mdx | 113 +++++++++++++++++- www/apps/resources/generated/edit-dates.mjs | 2 +- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/www/apps/resources/app/admin-components/components/table/page.mdx b/www/apps/resources/app/admin-components/components/table/page.mdx index 8296bf5fca90e..65337762eafc2 100644 --- a/www/apps/resources/app/admin-components/components/table/page.mdx +++ b/www/apps/resources/app/admin-components/components/table/page.mdx @@ -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(() => { @@ -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. + + + +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). + + + +`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 ( + + +
+ {data && ( + + )} + + +) +``` + +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. diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 06ec617959ab8..8a6c2e275663a 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -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",