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 5.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * @Author: 赵伟
  3. * @Date: 2024-04-11 16:31:18
  4. * @Description: 选择代码
  5. */
  6. import KFIcon from '@/components/KFIcon';
  7. import KFModal from '@/components/KFModal';
  8. import { type CodeConfigData } from '@/pages/CodeConfig/List';
  9. import { getCodeConfigListReq, getCodeConfigPageNumReq } from '@/services/codeConfig';
  10. import { CustomPartial } from '@/types';
  11. import { to } from '@/utils/promise';
  12. import type { ModalProps, PaginationProps } from 'antd';
  13. import { Empty, Input, Pagination } from 'antd';
  14. import { useEffect, useState } from 'react';
  15. import CodeConfigItem from '../CodeConfigItem';
  16. import './index.less';
  17. export { type CodeConfigData };
  18. export type SelectCodeData = CustomPartial<
  19. CodeConfigData,
  20. | 'id'
  21. | 'code_repo_name'
  22. | 'git_url'
  23. | 'git_branch'
  24. | 'git_user_name'
  25. | 'git_password'
  26. | 'ssh_key'
  27. | 'is_public'
  28. >;
  29. export interface CodeSelectorModalProps extends Omit<ModalProps, 'onOk'> {
  30. defaultSelected?: SelectCodeData;
  31. onOk?: (params: SelectCodeData | undefined) => void;
  32. }
  33. /** 选择代码配置的弹窗,推荐使用函数的方式打开 */
  34. function CodeSelectorModal({ defaultSelected, onOk, ...rest }: CodeSelectorModalProps) {
  35. const DefaultPageSize = 18;
  36. const [dataList, setDataList] = useState<CodeConfigData[]>([]);
  37. const [total, setTotal] = useState(0);
  38. const [searchText, setSearchText] = useState<string | undefined>(undefined);
  39. const [inputText, setInputText] = useState<string | undefined>(undefined);
  40. const [selected, setSelected] = useState(defaultSelected);
  41. const [isScrolled, setIsScrolled] = useState(false);
  42. const [pagination, setPagination] = useState<PaginationProps>({
  43. current: defaultSelected?.id ? 0 : 1, // 为 0 时,不请求,等待接口返回选中的代码配置在第几页
  44. pageSize: DefaultPageSize,
  45. });
  46. useEffect(() => {
  47. const getCodeConfigPageNum = async (id: number, size: number) => {
  48. const [res] = await to(
  49. getCodeConfigPageNumReq(id, {
  50. size,
  51. }),
  52. );
  53. if (res) {
  54. setPagination({
  55. current: typeof res.data === 'number' ? Math.max(0, res.data) + 1 : 1,
  56. pageSize: DefaultPageSize,
  57. });
  58. } else {
  59. setPagination({
  60. current: 1,
  61. pageSize: DefaultPageSize,
  62. });
  63. }
  64. };
  65. if (defaultSelected?.id) {
  66. getCodeConfigPageNum(defaultSelected?.id, DefaultPageSize);
  67. }
  68. }, [defaultSelected?.id]);
  69. useEffect(() => {
  70. // 获取数据请求
  71. const getDataList = async () => {
  72. // 为 0 时,不请求,等待接口返回选中的代码配置在第几页
  73. if (pagination.current === 0) {
  74. return;
  75. }
  76. const params = {
  77. page: pagination.current! - 1,
  78. size: pagination.pageSize,
  79. code_repo_name: searchText || undefined,
  80. };
  81. const [res] = await to(getCodeConfigListReq(params));
  82. if (res && res.data && res.data.content) {
  83. setDataList(res.data.content);
  84. setTotal(res.data.totalElements);
  85. }
  86. };
  87. getDataList();
  88. }, [pagination, searchText]);
  89. useEffect(() => {
  90. if (dataList.length > 0 && !isScrolled && defaultSelected?.id) {
  91. const selectedItem = document.getElementById(`code-config-item-${defaultSelected?.id}`);
  92. if (selectedItem) {
  93. selectedItem.scrollIntoView();
  94. }
  95. setIsScrolled(true);
  96. }
  97. }, [isScrolled, dataList, defaultSelected?.id]);
  98. // 搜索
  99. const handleSearch = (value: string) => {
  100. setSearchText(value);
  101. setPagination((prev) => ({
  102. ...prev,
  103. current: 1,
  104. }));
  105. };
  106. const handleChange = (item: CodeConfigData, checked: boolean) => {
  107. if (checked) {
  108. setSelected(item);
  109. } else {
  110. setSelected(undefined);
  111. }
  112. };
  113. // 分页切换
  114. const handlePageChange: PaginationProps['onChange'] = (page, pageSize) => {
  115. setPagination({
  116. current: page,
  117. pageSize: pageSize,
  118. });
  119. };
  120. return (
  121. <KFModal
  122. {...rest}
  123. title="选择代码配置"
  124. image={require('@/assets/img/modal-code-config.png')}
  125. width={920}
  126. onOk={() => onOk?.(selected)}
  127. destroyOnClose
  128. >
  129. <div className="kf-code-selector-modal">
  130. <Input.Search
  131. className="kf-code-selector-modal__search"
  132. placeholder="按代码仓库名称筛选"
  133. allowClear
  134. onSearch={handleSearch}
  135. size="large"
  136. onChange={(e) => setInputText(e.target.value)}
  137. suffix={null}
  138. value={inputText}
  139. prefix={
  140. <KFIcon type="icon-sousuo" color="rgba(22,100,255,0.4" style={{ marginLeft: '10px' }} />
  141. }
  142. />
  143. {dataList?.length !== 0 ? (
  144. <>
  145. <div className="kf-code-selector-modal__content">
  146. {dataList?.map((item) => (
  147. <CodeConfigItem
  148. item={item}
  149. key={item.id}
  150. checked={item.id === selected?.id}
  151. onChange={handleChange}
  152. />
  153. ))}
  154. </div>
  155. <Pagination
  156. align="end"
  157. total={total}
  158. showSizeChanger
  159. defaultPageSize={DefaultPageSize}
  160. pageSizeOptions={[
  161. DefaultPageSize,
  162. 2 * DefaultPageSize,
  163. 3 * DefaultPageSize,
  164. 4 * DefaultPageSize,
  165. 5 * DefaultPageSize,
  166. ]}
  167. showQuickJumper
  168. onChange={handlePageChange}
  169. {...pagination}
  170. />
  171. </>
  172. ) : (
  173. <div className="kf-code-selector-modal__empty">
  174. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
  175. </div>
  176. )}
  177. </div>
  178. </KFModal>
  179. );
  180. }
  181. export default CodeSelectorModal;