import { keepPreviousData, useQuery, UseQueryOptions, } from '@tanstack/react-query'; import {PaginatedBackendResponse} from '../../http/backend-response/pagination-response'; import {apiClient} from '../../http/query-client'; export interface GetDatatableDataParams { orderBy?: string; orderDir?: 'asc' | 'desc'; filters?: string | null; query?: string; with?: string; perPage?: number | string | null; page?: number | string; [key: string]: string | number | boolean | undefined | null; } export const DatatableDataQueryKey = ( endpoint: string, params?: GetDatatableDataParams | Record, ) => { // split endpoint by slash, so we can clear cache from the root later, // for example, 'link-group' will clear 'link-group/1/links' endpoint const key: (string | GetDatatableDataParams)[] = endpoint.split('/'); if (params) { key.push(params); } return key; }; export function useDatatableData( endpoint: string, params: GetDatatableDataParams, options?: Omit< UseQueryOptions< PaginatedBackendResponse, unknown, PaginatedBackendResponse, any[] >, 'queryKey' | 'queryFn' >, onLoad?: (data: PaginatedBackendResponse) => void, ) { return useQuery({ queryKey: DatatableDataQueryKey(endpoint, params), queryFn: () => paginate(endpoint, params, onLoad), placeholderData: keepPreviousData, ...options, }); } async function paginate( endpoint: string, params: GetDatatableDataParams, onLoad?: (data: PaginatedBackendResponse) => void, ): Promise> { const response = await apiClient .get(endpoint, {params}) .then(response => response.data); onLoad?.(response); return response; }