chore: catalog: scroll to load more data

This commit is contained in:
jialin
2025-05-07 16:34:12 +08:00
parent 42f9a27851
commit 816c22979f
8 changed files with 126 additions and 82 deletions
+96 -57
View File
@@ -10,12 +10,18 @@ import { Button, Input, Pagination, Select, Space, message } from 'antd';
import { useAtom } from 'jotai';
import _ from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { createModel, queryCatalogList } from './apis';
import CatalogList from './components/catalog-list';
import DelopyBuiltInModal from './components/deploy-builtin-modal';
import { modelCategories, modelSourceMap } from './config';
import { CatalogItem as CatalogItemType, FormData } from './config/types';
const PageWrapper = styled.div`
display: none;
margin-block: 32px 16px;
`;
const Catalog: React.FC = () => {
const intl = useIntl();
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
@@ -26,14 +32,16 @@ const Catalog: React.FC = () => {
dataList: CatalogItemType[];
loading: boolean;
total: number;
totalPage: number;
}>({
dataList: [],
loading: false,
total: 0
total: 0,
totalPage: 0
});
const [queryParams, setQueryParams] = useState({
page: 1,
perPage: 100,
perPage: 12,
search: '',
categories: ''
});
@@ -71,39 +79,62 @@ const Catalog: React.FC = () => {
[cacheData.current]
);
const fetchData = useCallback(async () => {
setDataSource((pre) => {
pre.loading = true;
return { ...pre };
});
try {
const params = {
..._.pick(queryParams, ['page', 'perPage'])
const fetchData = useCallback(
async (query?: any) => {
const searchQuery = {
...queryParams,
...query
};
const res: any = await queryCatalogList(params);
if (
dataSource.loading ||
(searchQuery.page > dataSource.totalPage && dataSource.totalPage > 0)
) {
return;
}
setDataSource((pre) => {
pre.loading = true;
cacheData.current = res.items || [];
const dataList = filterData({
search: queryParams.search,
categories: queryParams.categories
return { ...pre };
});
setDataSource({
dataList: dataList,
loading: false,
total: res.pagination.total
});
} catch (error) {
cacheData.current = [];
setDataSource({
dataList: [],
loading: false,
total: dataSource.total
});
console.log('error', error);
} finally {
setIsFirst(false);
}
}, [queryParams, cacheData.current]);
try {
const params = {
..._.pickBy(searchQuery, (val: string | number) => !!val)
};
const res: any = await queryCatalogList(params);
const dataList =
searchQuery.page === 1
? res.items
: _.concat(dataSource.dataList, res.items);
setDataSource({
dataList: dataList,
loading: false,
total: res.pagination.total,
totalPage: res.pagination.totalPage
});
setQueryParams({
...queryParams,
...query
});
} catch (error) {
cacheData.current = [];
setDataSource({
dataList: [],
loading: false,
total: dataSource.total,
totalPage: dataSource.totalPage
});
setQueryParams({
...queryParams,
...query
});
console.log('error', error);
} finally {
setIsFirst(false);
}
},
[queryParams, cacheData.current]
);
const handleDeployModalCancel = () => {
setOpenDeployModal({
@@ -160,49 +191,57 @@ const Catalog: React.FC = () => {
);
const handleSearch = (e: any) => {
fetchData();
fetchData({
...queryParams,
page: 1
});
};
const handleNameChange = _.debounce((e: any) => {
const dataList = filterData({
search: e.target.value,
categories: queryParams.categories
});
setQueryParams({
fetchData({
...queryParams,
page: 1,
search: e.target.value
});
setDataSource({
dataList,
loading: false,
total: dataSource.total
});
}, 200);
const handleCategoryChange = (value: any) => {
const dataList = filterData({
search: queryParams.search,
categories: value
});
setQueryParams({
fetchData({
...queryParams,
page: 1,
categories: value
});
setDataSource({
dataList,
loading: false,
total: dataSource.total
});
};
useEffect(() => {
fetchData();
}, []);
useEffect(() => {
const handleScroll = async () => {
// Determine the scrolling element
const scrollingElement = document.documentElement || document.body;
// Calculate if the user has scrolled to the bottom
const isAtBottom =
scrollingElement.scrollTop + scrollingElement.clientHeight >=
scrollingElement.scrollHeight - 20; // Adding a small buffer for precision
if (isAtBottom) {
fetchData({
...queryParams,
page: queryParams.page + 1
});
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [fetchData]);
return (
<PageContainer
ghost
@@ -259,7 +298,7 @@ const Catalog: React.FC = () => {
activeId={-1}
isFirst={isFirst}
></CatalogList>
<div style={{ marginBlock: '32px 16px' }}>
<PageWrapper>
<Pagination
hideOnSinglePage={queryParams.perPage === 100}
align="end"
@@ -269,7 +308,7 @@ const Catalog: React.FC = () => {
showSizeChanger
onChange={handleOnPageChange}
/>
</div>
</PageWrapper>
<DelopyBuiltInModal
open={openDeployModal.show}
action={PageAction.CREATE}