Skip to content

Commit

Permalink
Add optional next page boolean, and make total items optional
Browse files Browse the repository at this point in the history
Signed-off-by: brookewp <[email protected]>
  • Loading branch information
brookewp committed Feb 25, 2025
1 parent d91e9bd commit 1ec7391
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 13 deletions.
5 changes: 5 additions & 0 deletions inc/Integrations/Shopify/ShopifyIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ public static function get_queries( ShopifyDataSource $data_source ): array {
'path' => '$.data.products.pageInfo.startCursor',
'type' => 'string',
],
'has_next_page' => [
'name' => 'Has next page',
'path' => '$.data.products.pageInfo.hasNextPage',
'type' => 'boolean',
],
],
'graphql_query' => file_get_contents( __DIR__ . '/Queries/SearchProducts.graphql' ),
] ),
Expand Down
18 changes: 14 additions & 4 deletions inc/Validation/ConfigSchemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,10 @@ private static function generate_http_query_config_schema(): array {
// including cursor-based pagination.
'total_items' => Types::nullable(
Types::object( [
'name' => Types::nullable( Types::string() ),
'path' => Types::json_path(),
'type' => Types::enum( 'integer' ),
] ),
'name' => Types::nullable( Types::string() ),
'path' => Types::json_path(),
'type' => Types::enum( 'integer' ),
] ),
),
// This field provides a pagination cursor for the next page of
// paginated results, or a null value if there is no next page. This
Expand All @@ -318,6 +318,16 @@ private static function generate_http_query_config_schema(): array {
'type' => Types::enum( 'string' ),
] ),
),
// This field provides a boolean indicating if there is a next page of
// paginated results. This is helpful if the API does not provide a
// total number of items.
'has_next_page' => Types::nullable(
Types::object( [
'name' => Types::nullable( Types::string() ),
'path' => Types::json_path(),
'type' => Types::enum( 'boolean' ),
] )
),
] )
),
'preprocess_response' => Types::nullable( Types::callable() ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function getResultsWithId( results: RemoteDataResult[], instanceId: string ): Re
interface ItemListProps {
availableBindings: Record< string, RemoteDataBinding >;
blockName: string;
hasNextPage: boolean;
loading: boolean;
onSelect: ( data: RemoteDataQueryInput ) => void;
onSelectField?: ( data: FieldSelection, fieldValue: string ) => void;
Expand All @@ -35,6 +36,7 @@ interface ItemListProps {
remoteData?: RemoteData;
searchInput: string;
setPage: ( newPage: number ) => void;
setPerPage: ( newPerPage: number ) => void;
setSearchInput: ( newValue: string ) => void;
supportsSearch: boolean;
totalItems?: number;
Expand All @@ -45,6 +47,7 @@ export function ItemList( props: ItemListProps ) {
const {
availableBindings,
blockName,
hasNextPage,
loading,
onSelect,
onSelectField,
Expand All @@ -53,6 +56,7 @@ export function ItemList( props: ItemListProps ) {
remoteData,
searchInput,
setPage,
setPerPage,
setSearchInput,
supportsSearch,
totalItems,
Expand Down Expand Up @@ -121,6 +125,7 @@ export function ItemList( props: ItemListProps ) {

function onChangeView( newView: View ) {
setPage( newView.page ?? 1 );
setPerPage( newView.perPage ?? perPage ?? data.length );
setSearchInput( newView.search ?? '' );
setView( newView );
}
Expand Down Expand Up @@ -157,7 +162,7 @@ export function ItemList( props: ItemListProps ) {
onChangeView={ onChangeView }
paginationInfo={ {
totalItems: totalItems ?? data.length,
totalPages: totalPages ?? 1,
totalPages: totalPages ?? ( hasNextPage ? page + 1 : page - 1 ),
} }
search={ supportsSearch }
view={ view }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ export const DataViewsModal: React.FC< DataViewsModalProps > = props => {
const { close, isOpen, open } = useModalState();
const {
data,
hasNextPage,
loading,
page,
searchInput,
setPage,
setPerPage,
setSearchInput,
supportsSearch,
totalItems,
Expand Down Expand Up @@ -72,13 +74,15 @@ export const DataViewsModal: React.FC< DataViewsModalProps > = props => {
<ItemList
availableBindings={ availableBindings }
blockName={ blockName }
hasNextPage={ hasNextPage }
loading={ loading }
onSelect={ onSelect ? onSelectItem : close }
onSelectField={ onSelectField }
page={ page }
remoteData={ data }
searchInput={ searchInput }
setPage={ setPage }
setPerPage={ setPerPage }
setSearchInput={ setSearchInput }
supportsSearch={ supportsSearch }
totalItems={ totalItems }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@/blocks/remote-data-container/config/constants';

interface UsePaginationVariables {
hasNextPage?: boolean;
onFetch: ( remoteData: RemoteData ) => void;
page: number;
paginationQueryInput: RemoteDataQueryInput;
Expand All @@ -35,7 +36,7 @@ export function usePaginationVariables( {
initialPerPage,
inputVariables,
}: UsePaginationVariablesInput ): UsePaginationVariables {
const [ paginationData, setPaginationData ] = useState< RemoteDataPagination >();
const [ paginationData, setPaginationData ] = useState< RemoteDataPagination >( {} );
const [ page, setPage ] = useState< number >( initialPage );
const [ perPage, setPerPage ] = useState< number | null >( initialPerPage ?? null );

Expand Down Expand Up @@ -88,6 +89,7 @@ export function usePaginationVariables( {
supportsCursorPagination || supportsPagePagination || supportsOffsetPagination;
const totalItems = paginationData?.totalItems;
const totalPages = totalItems && perPage ? Math.ceil( totalItems / perPage ) : undefined;
const hasNextPage = paginationData?.hasNextPage;

function onFetch( remoteData: RemoteData ): void {
if ( ! supportsPagination ) {
Expand Down Expand Up @@ -120,6 +122,7 @@ export function usePaginationVariables( {
}

return {
hasNextPage,
onFetch,
page,
paginationQueryInput,
Expand Down
7 changes: 4 additions & 3 deletions src/blocks/remote-data-container/hooks/useRemoteData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async function fetchRemoteData( requestData: RemoteDataApiRequest ): Promise< Re
pagination: body.pagination && {
cursorNext: body.pagination.cursor_next,
cursorPrevious: body.pagination.cursor_previous,
hasNextPage: body.pagination.has_next_page,
totalItems: body.pagination.total_items,
},
queryInput: body.query_input,
Expand All @@ -51,8 +52,7 @@ interface UseRemoteData {
data?: RemoteData;
error?: Error;
fetch: ( queryInput: RemoteDataQueryInput ) => Promise< void >;
hasNextPage: boolean;
hasPreviousPage: boolean;
hasNextPage?: boolean;
loading: boolean;
page: number;
perPage?: number;
Expand Down Expand Up @@ -126,6 +126,7 @@ export function useRemoteData( {
const inputVariables = query.inputs;

const {
hasNextPage,
onFetch: onFetchForPagination,
page,
perPage,
Expand Down Expand Up @@ -237,7 +238,7 @@ export function useRemoteData( {
data: resolvedData,
error,
fetch,
hasNextPage: totalPages ? page < totalPages : supportsPagination,
hasNextPage: hasNextPage ?? ( totalPages ? page < totalPages : supportsPagination ),
hasPreviousPage: page > 1,
loading,
page,
Expand Down
10 changes: 6 additions & 4 deletions types/remote-data.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ interface InnerBlockContext {
}

interface RemoteDataPagination {
cursorNext?: string;
cursorPrevious?: string;
totalItems: number;
hasNextPage?: boolean;
cursorNext?: string;
cursorPrevious?: string;
totalItems?: number;
}

interface RemoteDataResultFields {
Expand Down Expand Up @@ -87,7 +88,8 @@ interface RemoteDataApiResponseBody {
pagination?: {
cursor_next?: string;
cursor_previous?: string;
total_items: number;
has_next_page?: boolean;
total_items?: number;
};
query_input: RemoteDataQueryInput;
result_id: string;
Expand Down

0 comments on commit 1ec7391

Please sign in to comment.