From ed4be2328f3f97982086a2368270b1e494a13eb0 Mon Sep 17 00:00:00 2001 From: jialin Date: Fri, 27 Feb 2026 19:29:54 +0800 Subject: [PATCH] chore: store pagination for list --- src/atoms/pagination.ts | 20 ++++++++++ src/config/settings.ts | 14 +++++++ src/hooks/use-pagination-status.ts | 44 ++++++++++++++++++++++ src/hooks/use-table-fetch.ts | 24 +++++++++--- src/pages/llmodels/index.tsx | 1 + src/pages/resources/components/workers.tsx | 3 +- 6 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/atoms/pagination.ts create mode 100644 src/hooks/use-pagination-status.ts diff --git a/src/atoms/pagination.ts b/src/atoms/pagination.ts new file mode 100644 index 00000000..343018e9 --- /dev/null +++ b/src/atoms/pagination.ts @@ -0,0 +1,20 @@ +import { getDefaultStore } from 'jotai'; +import { atomWithStorage } from 'jotai/utils'; + +export interface PaginationState { + perPage: number; +} + +export const paginationAtom = atomWithStorage>( + 'paginationStatus', + {}, + undefined, + { getOnInit: true } +); + +export const getPaginationStatus = (key: string) => { + if (!key) return {}; + const store = getDefaultStore(); + const cache = store.get(paginationAtom); + return cache[key] || {}; +}; diff --git a/src/config/settings.ts b/src/config/settings.ts index 501659b3..ce3f5979 100644 --- a/src/config/settings.ts +++ b/src/config/settings.ts @@ -30,3 +30,17 @@ export const tableSorter = (order: number | boolean) => { // } // return order; }; + +export const PaginationKey = { + Deployments: 'Deployments', + Workers: 'Workers', + Clusters: 'Clusters', + Routes: 'Routes', + Providers: 'Providers', + Benchmarks: 'Benchmarks', + GPUs: 'GPUs', + ModelFiles: 'ModelFiles', + Users: 'Users', + APIKeys: 'APIKeys', + Credentials: 'Credentials' +}; diff --git a/src/hooks/use-pagination-status.ts b/src/hooks/use-pagination-status.ts new file mode 100644 index 00000000..fdb8e08c --- /dev/null +++ b/src/hooks/use-pagination-status.ts @@ -0,0 +1,44 @@ +import { + getPaginationStatus, + paginationAtom, + PaginationState +} from '@/atoms/pagination'; +import { useAtom } from 'jotai'; + +export const usePaginationStatus = (key: string) => { + const [cache, setCache] = useAtom(paginationAtom); + + const value = cache[key] || {}; + + const setPagination = (val: PaginationState) => { + if (!key) return; + + setCache((prev) => ({ + ...prev, + [key]: { + ...prev[key], + ...val + } + })); + }; + + const getPagination = () => { + return cache[key] || {}; + }; + + const clearPagination = () => { + if (!key) return; + + const newCache = { ...cache }; + delete newCache[key]; + setCache(newCache); + }; + + return { + pagination: value, + getPaginationStatus, + setPagination, + getPagination, + clearPagination + }; +}; diff --git a/src/hooks/use-table-fetch.ts b/src/hooks/use-table-fetch.ts index acb92770..8eb98890 100644 --- a/src/hooks/use-table-fetch.ts +++ b/src/hooks/use-table-fetch.ts @@ -8,6 +8,8 @@ import { handleBatchRequest } from '@/utils'; import _ from 'lodash'; import qs from 'query-string'; import { useEffect, useRef, useState } from 'react'; +import { PaginationKey } from '../config/settings'; +import { usePaginationStatus } from './use-pagination-status'; import { useTableMultiSort } from './use-table-sort'; type EventsType = 'CREATE' | 'UPDATE' | 'DELETE' | 'INSERT'; @@ -33,6 +35,7 @@ type WatchConfig = */ export default function useTableFetch( options: { + key?: (typeof PaginationKey)[keyof typeof PaginationKey]; fetchAPI: (params: any, options?: any) => Promise>; deleteAPI?: (id: number, params?: any) => Promise; contentForDelete?: string; @@ -63,6 +66,9 @@ export default function useTableFetch( const { sortOrder, handleMultiSortChange } = useTableMultiSort(); const axiosTokenRef = useRef(null); const timerIDRef = useRef(null); + const hasInitRef = useRef(false); + const mountedRef = useRef(true); + const { pagination, setPagination } = usePaginationStatus(options.key || ''); // for skeleton loading const [extraStatus, setExtraStatus] = useState>({ @@ -87,6 +93,7 @@ export default function useTableFetch( perPage: 10, search: '', sort_by: '', + ...pagination, ...defaultQueryParams }); const queryParamsRef = useRef(queryParams); @@ -297,6 +304,9 @@ export default function useTableFetch( const handlePageChange = (page: number, pageSize: number) => { handleQueryChange({ page, perPage: pageSize || 10 }, { paginate: true }); + setPagination({ + perPage: pageSize || 10 + }); }; const handleTableChange = ( @@ -402,22 +412,26 @@ export default function useTableFetch( }, [dataSource.loadend, queryParams]); useEffect(() => { - let mounted = true; - const init = async () => { - await fetchData(); + if (hasInitRef.current) return; + hasInitRef.current = true; + await fetchData({ + query: { ...queryParams, ...pagination } + }); timerIDRef.current = setTimeout(() => { - if (mounted) { + if (mountedRef.current) { createTableListChunkRequest(); } }, 200); }; init(); + }, [pagination?.perPage]); + useEffect(() => { return () => { - mounted = false; + mountedRef.current = false; clearTimeout(timerIDRef.current); chunkRequestRef.current?.current?.cancel?.(); axiosTokenRef.current?.cancel?.(); diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index fc6ad2a7..67a05b65 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -172,6 +172,7 @@ const Models: React.FC<{ clusterId?: number }> = ({ clusterId }) => { const handlePageChange = useMemoizedFn( (page: number, pageSize: number | undefined) => { + console.log('page change', page, pageSize); handleQueryChange({ page: page, perPage: pageSize || 10 diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx index 4b167a65..33b0ec3e 100644 --- a/src/pages/resources/components/workers.tsx +++ b/src/pages/resources/components/workers.tsx @@ -1,6 +1,6 @@ import DeleteModal from '@/components/delete-modal'; import { FilterBar } from '@/components/page-tools'; -import { TABLE_SORT_DIRECTIONS } from '@/config/settings'; +import { PaginationKey, TABLE_SORT_DIRECTIONS } from '@/config/settings'; import useTableFetch from '@/hooks/use-table-fetch'; import PageBox from '@/pages/_components/page-box'; import { DockerStepsFromWorker } from '@/pages/cluster-management/components/add-worker/config'; @@ -56,6 +56,7 @@ const Workers: React.FC<{ handleQueryChange, handleNameChange } = useTableFetch({ + key: PaginationKey.Workers, events: ['UPDATE', 'DELETE', 'CREATE'], fetchAPI: queryWorkersList, deleteAPI: deleteWorker,