import { ListableResourceType, ListMeta, QueryParamsList, ResourceFields } from '@commercelayer/sdk'; import { default as React, FC, ReactNode } from 'react'; import { SectionProps } from '../../atoms/Section'; import { SkeletonTemplateProps } from '../../atoms/SkeletonTemplate'; import { ThProps } from '../../atoms/Table/Th'; import { Resource } from './listFetcher'; export interface ResourceListItemTemplateProps extends SkeletonTemplateProps<{ /** * The fetched resource */ resource?: Resource; /** * callback to be used to remove the item from the list as UI element. * This needs to be used after a successful API call to delete the resource, since it just affects the current UI rendering and not the server data. */ remove?: () => void; }> { } type TableVariantHeading = Omit & { label: React.ReactNode; }; export type ResourceListProps = Pick & { /** * A react component to be used to render each item in the list. * For best results, pass as `Item` a component already wrapped in a `SkeletonTemplate` (or `withSkeletonTemplate` HOC). * In this way the loading state will be handled automatically. */ ItemTemplate: FC>; /** * An element to be rendered when the list is empty. * When not provided, a default message will be shown. * When a string is provided, it will be rendered as inline text below title and actionButton. * When other ReactNode is provided, it will be rendered as a custom element and no title or actionButton will be shown. */ emptyState?: Awaited; /** * Title. */ title?: ((recordCount: number | undefined) => React.ReactNode) | React.ReactNode; /** * Force the size of the title, when not defined, title size will be `small` by default or `normal` when variant is `table` or `boxed`. */ titleSize?: SectionProps["titleSize"]; } & ({ /** Boxed variant wraps the list in a Card */ variant?: "boxed"; } | { /** Table variant wraps the list in a Table and enables the `headings` prop */ variant: "table"; headings: TableVariantHeading[]; }); export type UseResourceListConfig = { /** * The resource type to be fetched in the list */ type: TResource; /** * SDK query object to be used to fetch the list, excluding the pageNumber that is handled internally for infinite scrolling. */ query?: Omit, "pageNumber">; /** * When set the component will fetch data from the Metrics API, and automatically use the returned cursor for infinite scrolling. */ metricsQuery?: { search: { limit?: number; sort?: "asc" | "desc"; sort_by?: string; fields?: string[]; }; filter: Record; }; /** * Optional function to process the fetched resource list client-side before rendering. * It receives the full list returned by the API and must return the processed list. * Useful for client-side filtering or sorting that cannot be expressed via the API query. * Affects both the `list` value returned by the hook and what is rendered by ``. */ preProcess?: (list: Array>) => Array>; /** * Pagination type: 'infinite' for infinite scrolling (default), 'pagination' for classic prev/next pagination. * Note: 'pagination' mode is only supported for Core API (not Metrics API). */ paginationType?: "infinite" | "pagination"; /** * Controls scroll behavior when the user navigates to a new page. * Only applies when `paginationType` is `'pagination'`. * - `'top'`: scrolls to the top of the page (default) * - `'list'`: scrolls to the top of the list * - `'none'`: no scroll * @default 'top' */ paginationScrollTo?: "top" | "list" | "none"; }; interface UseResourceListReturn { /** The component that renders the list with infinite scrolling or pagination functionality */ ResourceList: FC>; /** The array of resources to display. When `preProcess` is provided, this is the processed result; otherwise it is the raw fetched data, which grows each time a new page is fetched (infinite mode) or shows current page only (pagination mode) */ list?: Array>; /** Metadata related to pagination, as returned by the SDK */ meta?: ListMeta; /** Indicates whether the list is currently loading the next page */ isLoading: boolean; /** Indicates whether the list is loading for the first time (initial page load) */ isFirstLoading: boolean; /** The error message (already parsed) returned from the API when a fetch request fails */ error?: string; /** Removes an item from the list, typically can be triggered after a delete action from the UI */ removeItem: (resourceId: string) => void; /** * Manually triggers data fetching for the next page without requiring the user to reach the infinite scroll trigger. * It does not trigger when last page has been reached. */ fetchMore: () => Promise; /** Refreshes the list by clearing all previously fetched data and resetting the initial loading state before refetching the first page. */ refresh: () => void; /** Indicates whether there are more pages available for fetching */ hasMorePages?: boolean; } export interface UseResourceListReturnWithPagination extends UseResourceListReturn { /** Pagination controls component (only shown when paginationType is 'pagination' and there are multiple pages) */ Pagination: FC; } /** * Renders a list of resources of a given type with infinite scrolling or classic pagination. * It's possible to specify a query to filter the list and either * a React component (`ItemTemplate`) to be used as item template for the list or a function as `children` to render a custom element. */ export declare function useResourceList(config: UseResourceListConfig & { paginationType: "pagination"; }): UseResourceListReturnWithPagination; export declare function useResourceList(config: UseResourceListConfig & { paginationType?: "infinite"; }): UseResourceListReturn; export declare function useResourceList(config: UseResourceListConfig): UseResourceListReturn; export {};