Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import {
type UseResourceListConfig,
useResourceList,
} from "#ui/resources/useResourceList"
import type { ResourceListProps } from "#ui/resources/useResourceList/useResourceList"
import type {
ResourceListProps,
UseResourceListReturnWithPagination,
} from "#ui/resources/useResourceList/useResourceList"
import { makeFilterAdapters } from "./adapters"
import {
FiltersForm as FiltersFormComponent,
Expand Down Expand Up @@ -193,17 +196,29 @@ function ResourceListComponent<TResource extends ListableResourceType>({
metricsQuery,
type,
query,
paginationType = "infinite",
...listProps
}: UseResourceListConfig<TResource> &
ResourceListProps<TResource>): JSX.Element {
const hookConfig: UseResourceListConfig<TResource> = {
}: UseResourceListConfig<TResource> & {
paginationType?: "infinite" | "pagination"
} & ResourceListProps<TResource>): JSX.Element {
const result = useResourceList<TResource>({
type,
query,
metricsQuery,
}
const { ResourceList } = useResourceList(hookConfig)
paginationType,
})

return <ResourceList {...listProps} />
const paginationResult =
paginationType === "pagination"
? (result as UseResourceListReturnWithPagination<TResource>)
: null

return (
<>
<result.ResourceList {...listProps} />
{paginationResult != null && <paginationResult.Pagination />}
</>
)
}

const makeFilteredList: (options: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { JSX } from "react"
import { Icon } from "#ui/atoms/Icon"
import { Spacer } from "#ui/atoms/Spacer"
import { Text } from "#ui/atoms/Text"
import { makeCurrentPageOffsets } from "#utils/pagination"

export interface PaginationInfoProps {
currentPage: number
pageCount: number
recordsPerPage: number
recordCount: number
isLoading: boolean
onPageChange: (page: number) => void
}

export function PaginationInfo({
currentPage,
pageCount,
recordsPerPage,
recordCount,
isLoading,
onPageChange,
}: PaginationInfoProps): JSX.Element {
const offsets = makeCurrentPageOffsets({
currentPage,
recordsPerPage,
recordCount,
})

return (
<Spacer top="6">
<div className="flex items-center justify-between mt-auto">
<Text variant="info" tag="div" size="x-small">
{offsets.firstOfPage.toLocaleString()}-
{offsets.lastOfPage.toLocaleString()} of{" "}
{recordCount.toLocaleString()}
</Text>
<div className="flex gap-2 items-center justify-between text-xs">
<button
type="button"
disabled={isLoading || currentPage === 1}
onClick={() => onPageChange(currentPage - 1)}
className="p-2 disabled:opacity-30 rounded-[8px] border border-gray-200"
>
<Icon name="caretRight" className="rotate-180" />
</button>
<button
type="button"
disabled={isLoading || currentPage === pageCount}
onClick={() => onPageChange(currentPage + 1)}
className="p-2 disabled:opacity-30 rounded-[8px] border border-gray-200"
>
<Icon name="caretRight" />
Comment thread
gciotola marked this conversation as resolved.
Outdated
</button>
</div>
</div>
</Spacer>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ export interface FetcherResponse<TResource> {
}
}

export async function infiniteFetcher<TResource extends ListableResourceType>({
export async function listFetcher<TResource extends ListableResourceType>({
currentData,
resourceType,
client,
clientType,
query,
mode = "infinite",
pageNumber,
}: {
currentData?: FetcherResponse<Resource<TResource>>
resourceType: TResource
mode?: "infinite" | "pagination"
pageNumber?: number
} & (
| {
client: CommerceLayerClient
Expand All @@ -51,7 +55,8 @@ export async function infiniteFetcher<TResource extends ListableResourceType>({
}
)): Promise<FetcherResponse<Resource<TResource>>> {
const currentPage = currentData?.meta.currentPage ?? 0
const pageToFetch = currentPage + 1
const pageToFetch =
mode === "pagination" && pageNumber != null ? pageNumber : currentPage + 1

if (clientType === "metricsClient" && !isValidMetricsResource(resourceType)) {
throw new Error("Metrics client is not available for this resource type")
Expand All @@ -75,7 +80,11 @@ export async function infiniteFetcher<TResource extends ListableResourceType>({
// we need the primitive array
// without the sdk added methods ('meta' | 'first' | 'last' | 'get')
const existingList = currentData?.list ?? []
const uniqueList = uniqBy(existingList.concat(listResponse), "id")
// In pagination mode, replace the list instead of accumulating
const uniqueList =
mode === "pagination"
? [...listResponse]
: uniqBy(existingList.concat(listResponse), "id")
const meta = listResponse.meta

return { list: uniqueList, meta }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
adaptMetricsOrderToCore,
type MetricsResourceOrder,
} from "./adaptMetricsOrderToCore"
import type { Resource } from "./infiniteFetcher"
import type { Resource } from "./listFetcher"

export type MetricsResources = "orders" | "returns"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ListableResourceType } from "@commercelayer/sdk"
import type { FetcherResponse, Resource } from "./infiniteFetcher"
import type { FetcherResponse, Resource } from "./listFetcher"

interface ResourceListInternalState<TResource extends ListableResourceType> {
isLoading: boolean
Expand Down
Loading
Loading