chore: catalog page size 100

This commit is contained in:
jialin
2025-01-06 08:29:56 +08:00
parent cc45ec85fd
commit 5c401f3858
3 changed files with 138 additions and 22 deletions
+100 -22
View File
@@ -12,6 +12,7 @@ import {
Row, Row,
Select, Select,
Space, Space,
Spin,
message message
} from 'antd'; } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
@@ -19,6 +20,7 @@ import ResizeObserver from 'rc-resize-observer';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { createModel, queryCatalogList } from './apis'; import { createModel, queryCatalogList } from './apis';
import CatalogItem from './components/catalog-item'; import CatalogItem from './components/catalog-item';
import CatalogSkelton from './components/catalog-skelton';
import DelopyBuiltInModal from './components/deploy-builtin-modal'; import DelopyBuiltInModal from './components/deploy-builtin-modal';
import { modelCategories, modelSourceMap } from './config'; import { modelCategories, modelSourceMap } from './config';
import { CatalogItem as CatalogItemType, FormData } from './config/types'; import { CatalogItem as CatalogItemType, FormData } from './config/types';
@@ -39,7 +41,7 @@ const Catalog: React.FC = () => {
}); });
const [queryParams, setQueryParams] = useState({ const [queryParams, setQueryParams] = useState({
page: 1, page: 1,
perPage: 9, perPage: 100,
search: '', search: '',
categories: [] categories: []
}); });
@@ -49,9 +51,32 @@ const Catalog: React.FC = () => {
current: {}, current: {},
source: modelSourceMap.huggingface_value source: modelSourceMap.huggingface_value
}); });
const cacheData = React.useRef<CatalogItemType[]>([]);
const categoryOptions = [...modelCategories.filter((item) => item.value)]; const categoryOptions = [...modelCategories.filter((item) => item.value)];
const filterData = (data: { search: string; categories: string[] }) => {
const { search, categories } = data;
const dataList = cacheData.current.filter((item) => {
if (search && categories.length > 0) {
return (
_.toLower(item.name).includes(search) &&
categories.some((category) => item.categories.includes(category))
);
}
if (search) {
return _.toLower(item.name).includes(search);
}
if (categories.length > 0) {
return categories.some((category) =>
item.categories.includes(category)
);
}
return true;
});
return dataList;
};
const fetchData = useCallback(async () => { const fetchData = useCallback(async () => {
setDataSource((pre) => { setDataSource((pre) => {
pre.loading = true; pre.loading = true;
@@ -59,16 +84,18 @@ const Catalog: React.FC = () => {
}); });
try { try {
const params = { const params = {
..._.pickBy(queryParams, (val: any) => !!val) ..._.pick(queryParams, ['page', 'perPage'])
}; };
const res: any = await queryCatalogList(params); const res: any = await queryCatalogList(params);
cacheData.current = res.items || [];
setDataSource({ setDataSource({
dataList: res.items, dataList: res.items,
loading: false, loading: false,
total: res.pagination.total total: res.pagination.total
}); });
} catch (error) { } catch (error) {
cacheData.current = [];
setDataSource({ setDataSource({
dataList: [], dataList: [],
loading: false, loading: false,
@@ -151,24 +178,44 @@ const Catalog: React.FC = () => {
}; };
const handleNameChange = _.debounce((e: any) => { const handleNameChange = _.debounce((e: any) => {
const dataList = filterData({
search: e.target.value,
categories: queryParams.categories
});
setQueryParams({ setQueryParams({
...queryParams, ...queryParams,
page: 1, page: 1,
search: e.target.value search: e.target.value
}); });
}, 350);
setDataSource({
dataList,
loading: false,
total: dataSource.total
});
}, 200);
const handleCategoryChange = (value: any) => { const handleCategoryChange = (value: any) => {
const dataList = filterData({
search: queryParams.search,
categories: value
});
setQueryParams({ setQueryParams({
...queryParams, ...queryParams,
page: 1, page: 1,
categories: value categories: value
}); });
setDataSource({
dataList,
loading: false,
total: dataSource.total
});
}; };
useEffect(() => { useEffect(() => {
fetchData(); fetchData();
}, [queryParams]); }, []);
return ( return (
<PageContainer <PageContainer
@@ -188,6 +235,13 @@ const Catalog: React.FC = () => {
style={{ width: 200 }} style={{ width: 200 }}
size="large" size="large"
allowClear allowClear
onClear={() =>
handleNameChange({
target: {
value: ''
}
})
}
onChange={handleNameChange} onChange={handleNameChange}
></Input> ></Input>
<Select <Select
@@ -209,25 +263,49 @@ const Catalog: React.FC = () => {
</Space> </Space>
} }
></PageTools> ></PageTools>
<ResizeObserver onResize={handleResize}> <div className="relative" style={{ width: '100%' }}>
<Row gutter={[16, 16]}> <ResizeObserver onResize={handleResize}>
{dataSource.dataList.map((item: CatalogItemType, index) => { <Row gutter={[16, 16]}>
return ( {dataSource.dataList.map((item: CatalogItemType, index) => {
<Col span={span} key={item.id}> return (
<CatalogItem <Col span={span} key={item.id}>
onClick={handleOnDeploy} <CatalogItem
activeId={activeId} onClick={handleOnDeploy}
data={item} activeId={activeId}
></CatalogItem> data={item}
</Col> ></CatalogItem>
); </Col>
})} );
</Row> })}
</ResizeObserver> </Row>
{dataSource.loading && (
<div
style={{
width: '100%',
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
height: 400,
right: 0
}}
>
<Spin
spinning={dataSource.loading}
style={{ width: '100%' }}
wrapperClassName="skelton-wrapper"
>
<CatalogSkelton span={span}></CatalogSkelton>
</Spin>
</div>
)}
</ResizeObserver>
</div>
<div style={{ marginBlock: '32px 16px' }}> <div style={{ marginBlock: '32px 16px' }}>
<Pagination <Pagination
pageSizeOptions={['9', '12', '36', '100']} hideOnSinglePage={queryParams.perPage === 100}
hideOnSinglePage={queryParams.perPage === 9}
align="end" align="end"
defaultCurrent={1} defaultCurrent={1}
total={dataSource.total} total={dataSource.total}
@@ -250,4 +328,4 @@ const Catalog: React.FC = () => {
); );
}; };
export default Catalog; export default React.memo(Catalog);
@@ -0,0 +1,34 @@
import { Col, Row, Skeleton } from 'antd';
import React from 'react';
interface CatalogSkeltonProps {
span: number;
}
const CatalogSkelton: React.FC<CatalogSkeltonProps> = (props) => {
return (
<Row gutter={[16, 16]}>
{Array(6)
.fill(1)
.map((_, index) => {
return (
<Col span={props.span} key={index}>
<Skeleton
avatar={{
size: 32
}}
paragraph={{ rows: 2 }}
style={{
border: '1px solid var(--ant-color-border)',
borderRadius: 'var(--border-radius-base)',
padding: '16px 16px'
}}
></Skeleton>
</Col>
);
})}
</Row>
);
};
export default React.memo(CatalogSkelton);
@@ -111,3 +111,7 @@
opacity: 0.7; opacity: 0.7;
} }
} }
.skelton-wrapper {
width: 100%;
}