You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.tsx 6.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import KFEmpty, { EmptyType } from '@/components/KFEmpty';
  2. import KFIcon from '@/components/KFIcon';
  3. import { CommonTabKeys } from '@/enums';
  4. import AddModelModal from '@/pages/Dataset/components/AddModelModal';
  5. import { openAntdModal } from '@/utils/modal';
  6. import { to } from '@/utils/promise';
  7. import { modalConfirm } from '@/utils/ui';
  8. import { useNavigate } from '@umijs/max';
  9. import { App, Button, Input, Pagination, PaginationProps } from 'antd';
  10. import { pick } from 'lodash';
  11. import { Ref, forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
  12. import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../config';
  13. import AddDatasetModal from '../AddDatasetModal';
  14. import ResourceItem from '../ResourceItem';
  15. import styles from './index.less';
  16. export type ResourceListRef = {
  17. reset: () => void;
  18. };
  19. type ResourceListProps = {
  20. resourceType: ResourceType;
  21. dataType?: string;
  22. dataTag?: string;
  23. isPublic: boolean;
  24. typeList: CategoryData[];
  25. tagList: CategoryData[];
  26. initialSearchText?: string;
  27. initialPagination?: PaginationProps;
  28. setCacheState: (state?: any) => void;
  29. };
  30. function ResourceList(
  31. {
  32. resourceType,
  33. dataType,
  34. dataTag,
  35. typeList,
  36. tagList,
  37. isPublic,
  38. initialSearchText,
  39. initialPagination,
  40. setCacheState,
  41. }: ResourceListProps,
  42. ref: Ref<ResourceListRef>,
  43. ) {
  44. const navigate = useNavigate();
  45. const [dataList, setDataList] = useState<ResourceData[] | undefined>(undefined);
  46. const [total, setTotal] = useState(0);
  47. const [pagination, setPagination] = useState<PaginationProps>(
  48. initialPagination ?? {
  49. current: 1,
  50. pageSize: 20,
  51. },
  52. );
  53. const [searchText, setSearchText] = useState(initialSearchText);
  54. const [inputText, setInputText] = useState(initialSearchText);
  55. const { message } = App.useApp();
  56. const config = resourceConfig[resourceType];
  57. // 获取数据请求
  58. const getDataList = useCallback(async () => {
  59. const params: Record<string, any> = {
  60. page: pagination.current! - 1,
  61. size: pagination.pageSize,
  62. is_public: isPublic,
  63. [config.typeParamKey]: dataType,
  64. [config.tagParamKey]: dataTag,
  65. name: searchText || undefined,
  66. };
  67. const request = config.getList;
  68. const [res] = await to(request(params));
  69. if (res && res.data && res.data.content) {
  70. setDataList(res.data.content);
  71. setTotal(res.data.totalElements);
  72. } else {
  73. setDataList([]);
  74. setTotal(0);
  75. }
  76. }, [dataType, dataTag, pagination, searchText, isPublic, config]);
  77. useEffect(() => {
  78. getDataList();
  79. }, [getDataList]);
  80. useImperativeHandle(
  81. ref,
  82. () => {
  83. return {
  84. reset: () => {
  85. setPagination({
  86. current: 1,
  87. pageSize: 20,
  88. });
  89. setSearchText('');
  90. setInputText('');
  91. setDataList(undefined);
  92. setTotal(0);
  93. },
  94. };
  95. },
  96. [],
  97. );
  98. // 删除请求
  99. const deleteRecord = async (params: { owner: string; identifier: string; repo_id?: number }) => {
  100. const request = config.deleteRecord;
  101. const [res] = await to(request(params));
  102. if (res) {
  103. getDataList();
  104. message.success('删除成功');
  105. }
  106. };
  107. // 搜索
  108. const handleSearch = (value: string) => {
  109. setSearchText(value);
  110. setPagination((prev) => ({
  111. ...prev,
  112. current: 1,
  113. }));
  114. };
  115. // 删除
  116. const handleRemove = (record: ResourceData) => {
  117. modalConfirm({
  118. title: config.deleteModalTitle,
  119. onOk: () => {
  120. deleteRecord(pick(record, ['owner', 'identifier', 'id', 'is_public']));
  121. },
  122. });
  123. };
  124. // 跳转
  125. const handleClick = (record: ResourceData) => {
  126. setCacheState({
  127. activeTab: isPublic ? CommonTabKeys.Public : CommonTabKeys.Private,
  128. pagination,
  129. searchText,
  130. activeType: dataType,
  131. activeTag: dataTag,
  132. });
  133. const prefix = config.prefix;
  134. navigate(
  135. `/dataset/${prefix}/info/${record.id}?name=${record.name}&owner=${record.owner}&identifier=${record.identifier}&is_public=${record.is_public}`,
  136. );
  137. };
  138. // 分页切换
  139. const handlePageChange: PaginationProps['onChange'] = (page, pageSize) => {
  140. setPagination({
  141. current: page,
  142. pageSize: pageSize,
  143. });
  144. };
  145. // 新建弹框
  146. const showModal = () => {
  147. const Modal = resourceType === ResourceType.Dataset ? AddDatasetModal : AddModelModal;
  148. const { close } = openAntdModal(Modal, {
  149. typeList: typeList,
  150. tagList: tagList,
  151. onOk: () => {
  152. getDataList();
  153. close();
  154. },
  155. });
  156. };
  157. return (
  158. <div className={styles['resource-list']}>
  159. <div className={styles['resource-list__header']}>
  160. <span>数据总数:{total} 个</span>
  161. <div>
  162. <Input.Search
  163. placeholder={`按${config.name}名称筛选`}
  164. allowClear
  165. onSearch={handleSearch}
  166. style={{
  167. width: 300,
  168. }}
  169. onChange={(e) => setInputText(e.target.value)}
  170. value={inputText}
  171. />
  172. {!isPublic && (
  173. <Button
  174. type="default"
  175. style={{ marginLeft: '20px' }}
  176. onClick={showModal}
  177. icon={<KFIcon type="icon-xinjian2" />}
  178. >
  179. {config.addBtnTitle}
  180. </Button>
  181. )}
  182. </div>
  183. </div>
  184. {dataList && dataList.length > 0 && (
  185. <>
  186. <div className={styles['resource-list__content']}>
  187. {dataList?.map((item) => (
  188. <ResourceItem
  189. item={item}
  190. key={item.id}
  191. isPublic={isPublic}
  192. onRemove={handleRemove}
  193. onClick={handleClick}
  194. ></ResourceItem>
  195. ))}
  196. </div>
  197. <Pagination
  198. align="end"
  199. total={total}
  200. showSizeChanger
  201. defaultPageSize={20}
  202. pageSizeOptions={[20, 40, 60, 80, 100]}
  203. showQuickJumper
  204. onChange={handlePageChange}
  205. {...pagination}
  206. />
  207. </>
  208. )}
  209. {dataList && dataList.length === 0 && (
  210. <KFEmpty
  211. className={styles['resource-list__empty']}
  212. type={EmptyType.NoData}
  213. title="暂无数据"
  214. content={'很抱歉,没有搜索到您想要的内容\n建议刷新试试'}
  215. hasFooter={true}
  216. onButtonClick={getDataList}
  217. />
  218. )}
  219. </div>
  220. );
  221. }
  222. export default forwardRef(ResourceList);