2024-07-17 19:07:34 +08:00
|
|
|
import { useFetchChunkList } from '@/hooks/chunk-hooks';
|
|
|
|
import { useDeleteChunkByIds } from '@/hooks/knowledge-hooks';
|
2024-01-18 18:27:38 +08:00
|
|
|
import type { PaginationProps } from 'antd';
|
2024-03-01 11:28:58 +08:00
|
|
|
import { Divider, Flex, Pagination, Space, Spin, message } from 'antd';
|
2024-03-20 11:13:51 +08:00
|
|
|
import classNames from 'classnames';
|
2024-02-07 18:04:25 +08:00
|
|
|
import { useCallback, useEffect, useState } from 'react';
|
2024-02-02 18:49:54 +08:00
|
|
|
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
2024-02-06 18:45:20 +08:00
|
|
|
import ChunkCard from './components/chunk-card';
|
2024-03-07 14:23:42 +08:00
|
|
|
import CreatingModal from './components/chunk-creating-modal';
|
2024-02-05 19:26:03 +08:00
|
|
|
import ChunkToolBar from './components/chunk-toolbar';
|
2024-03-01 18:49:21 +08:00
|
|
|
import DocumentPreview from './components/document-preview/preview';
|
2024-03-20 11:13:51 +08:00
|
|
|
import {
|
2024-04-30 18:43:26 +08:00
|
|
|
useChangeChunkTextMode,
|
2024-03-20 11:13:51 +08:00
|
|
|
useHandleChunkCardClick,
|
|
|
|
useSelectChunkListLoading,
|
|
|
|
useSelectDocumentInfo,
|
|
|
|
} from './hooks';
|
2024-02-06 18:45:20 +08:00
|
|
|
import { ChunkModelState } from './model';
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-04-07 17:41:29 +08:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2024-03-07 14:23:42 +08:00
|
|
|
import styles from './index.less';
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-02-02 18:49:54 +08:00
|
|
|
const Chunk = () => {
|
2024-01-30 19:26:29 +08:00
|
|
|
const dispatch = useDispatch();
|
2024-02-06 18:45:20 +08:00
|
|
|
const chunkModel: ChunkModelState = useSelector(
|
|
|
|
(state: any) => state.chunkModel,
|
|
|
|
);
|
|
|
|
const [selectedChunkIds, setSelectedChunkIds] = useState<string[]>([]);
|
2024-02-02 18:49:54 +08:00
|
|
|
const [searchParams] = useSearchParams();
|
2024-02-07 18:04:25 +08:00
|
|
|
const { data = [], total, pagination } = chunkModel;
|
2024-03-20 11:13:51 +08:00
|
|
|
const loading = useSelectChunkListLoading();
|
2024-02-02 18:49:54 +08:00
|
|
|
const documentId: string = searchParams.get('doc_id') || '';
|
2024-02-07 18:04:25 +08:00
|
|
|
const [chunkId, setChunkId] = useState<string | undefined>();
|
|
|
|
const { removeChunk } = useDeleteChunkByIds();
|
2024-03-01 11:28:58 +08:00
|
|
|
const documentInfo = useSelectDocumentInfo();
|
2024-03-01 18:49:21 +08:00
|
|
|
const { handleChunkCardClick, selectedChunkId } = useHandleChunkCardClick();
|
2024-03-07 11:38:32 +08:00
|
|
|
const isPdf = documentInfo.type === 'pdf';
|
2024-04-07 17:41:29 +08:00
|
|
|
const { t } = useTranslation();
|
2024-04-30 18:43:26 +08:00
|
|
|
const { changeChunkTextMode, textMode } = useChangeChunkTextMode();
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-03-20 11:13:51 +08:00
|
|
|
const getChunkList = useFetchChunkList();
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-02-07 18:04:25 +08:00
|
|
|
const handleEditChunk = useCallback(
|
|
|
|
(chunk_id?: string) => {
|
|
|
|
setChunkId(chunk_id);
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-02-07 18:04:25 +08:00
|
|
|
dispatch({
|
|
|
|
type: 'chunkModel/setIsShowCreateModal',
|
|
|
|
payload: true,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[dispatch],
|
|
|
|
);
|
2024-01-30 19:26:29 +08:00
|
|
|
|
2024-02-06 18:45:20 +08:00
|
|
|
const onPaginationChange: PaginationProps['onShowSizeChange'] = (
|
2024-01-30 19:26:29 +08:00
|
|
|
page,
|
|
|
|
size,
|
|
|
|
) => {
|
2024-02-06 18:45:20 +08:00
|
|
|
setSelectedChunkIds([]);
|
|
|
|
dispatch({
|
|
|
|
type: 'chunkModel/setPagination',
|
2024-01-18 18:27:38 +08:00
|
|
|
payload: {
|
2024-02-06 18:45:20 +08:00
|
|
|
current: page,
|
|
|
|
pageSize: size,
|
2024-01-18 18:27:38 +08:00
|
|
|
},
|
|
|
|
});
|
2024-02-06 18:45:20 +08:00
|
|
|
getChunkList();
|
2024-01-30 19:26:29 +08:00
|
|
|
};
|
2024-01-18 18:27:38 +08:00
|
|
|
|
2024-02-06 18:45:20 +08:00
|
|
|
const selectAllChunk = useCallback(
|
|
|
|
(checked: boolean) => {
|
|
|
|
setSelectedChunkIds(checked ? data.map((x) => x.chunk_id) : []);
|
|
|
|
},
|
|
|
|
[data],
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleSingleCheckboxClick = useCallback(
|
|
|
|
(chunkId: string, checked: boolean) => {
|
|
|
|
setSelectedChunkIds((previousIds) => {
|
|
|
|
const idx = previousIds.findIndex((x) => x === chunkId);
|
|
|
|
const nextIds = [...previousIds];
|
|
|
|
if (checked && idx === -1) {
|
|
|
|
nextIds.push(chunkId);
|
|
|
|
} else if (!checked && idx !== -1) {
|
|
|
|
nextIds.splice(idx, 1);
|
|
|
|
}
|
|
|
|
return nextIds;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[],
|
|
|
|
);
|
2024-04-30 18:43:26 +08:00
|
|
|
|
|
|
|
const showSelectedChunkWarning = useCallback(() => {
|
2024-04-07 17:41:29 +08:00
|
|
|
message.warning(t('message.pleaseSelectChunk'));
|
2024-04-30 18:43:26 +08:00
|
|
|
}, [t]);
|
2024-02-07 18:04:25 +08:00
|
|
|
|
|
|
|
const handleRemoveChunk = useCallback(async () => {
|
|
|
|
if (selectedChunkIds.length > 0) {
|
|
|
|
const resCode: number = await removeChunk(selectedChunkIds, documentId);
|
|
|
|
if (resCode === 0) {
|
|
|
|
setSelectedChunkIds([]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
showSelectedChunkWarning();
|
|
|
|
}
|
2024-04-30 18:43:26 +08:00
|
|
|
}, [selectedChunkIds, documentId, removeChunk, showSelectedChunkWarning]);
|
2024-02-07 18:04:25 +08:00
|
|
|
|
|
|
|
const switchChunk = useCallback(
|
|
|
|
async (available?: number, chunkIds?: string[]) => {
|
|
|
|
let ids = chunkIds;
|
|
|
|
if (!chunkIds) {
|
|
|
|
ids = selectedChunkIds;
|
|
|
|
if (selectedChunkIds.length === 0) {
|
|
|
|
showSelectedChunkWarning();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const resCode: number = await dispatch<any>({
|
|
|
|
type: 'chunkModel/switch_chunk',
|
|
|
|
payload: {
|
|
|
|
chunk_ids: ids,
|
|
|
|
available_int: available,
|
|
|
|
doc_id: documentId,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
if (!chunkIds && resCode === 0) {
|
|
|
|
getChunkList();
|
|
|
|
}
|
|
|
|
},
|
2024-04-30 18:43:26 +08:00
|
|
|
[
|
|
|
|
dispatch,
|
|
|
|
documentId,
|
|
|
|
getChunkList,
|
|
|
|
selectedChunkIds,
|
|
|
|
showSelectedChunkWarning,
|
|
|
|
],
|
2024-02-07 18:04:25 +08:00
|
|
|
);
|
2024-02-06 18:45:20 +08:00
|
|
|
|
2024-01-18 18:27:38 +08:00
|
|
|
useEffect(() => {
|
2024-01-30 19:26:29 +08:00
|
|
|
getChunkList();
|
2024-02-06 18:45:20 +08:00
|
|
|
return () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'chunkModel/resetFilter', // TODO: need to reset state uniformly
|
|
|
|
});
|
|
|
|
};
|
2024-02-07 18:04:25 +08:00
|
|
|
}, [dispatch, getChunkList]);
|
2024-02-06 18:45:20 +08:00
|
|
|
|
2024-01-30 19:26:29 +08:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<div className={styles.chunkPage}>
|
2024-02-06 18:45:20 +08:00
|
|
|
<ChunkToolBar
|
|
|
|
getChunkList={getChunkList}
|
|
|
|
selectAllChunk={selectAllChunk}
|
2024-02-07 18:04:25 +08:00
|
|
|
createChunk={handleEditChunk}
|
|
|
|
removeChunk={handleRemoveChunk}
|
2024-02-06 18:45:20 +08:00
|
|
|
checked={selectedChunkIds.length === data.length}
|
2024-02-07 18:04:25 +08:00
|
|
|
switchChunk={switchChunk}
|
2024-04-30 18:43:26 +08:00
|
|
|
changeChunkTextMode={changeChunkTextMode}
|
2024-02-06 18:45:20 +08:00
|
|
|
></ChunkToolBar>
|
2024-02-07 18:04:25 +08:00
|
|
|
<Divider></Divider>
|
2024-03-01 11:28:58 +08:00
|
|
|
<Flex flex={1} gap={'middle'}>
|
2024-03-07 14:23:42 +08:00
|
|
|
<Flex
|
|
|
|
vertical
|
|
|
|
className={isPdf ? styles.pagePdfWrapper : styles.pageWrapper}
|
|
|
|
>
|
2024-03-20 11:13:51 +08:00
|
|
|
<Spin spinning={loading} className={styles.spin} size="large">
|
|
|
|
<div className={styles.pageContent}>
|
2024-03-01 11:28:58 +08:00
|
|
|
<Space
|
|
|
|
direction="vertical"
|
|
|
|
size={'middle'}
|
2024-03-07 14:23:42 +08:00
|
|
|
className={classNames(styles.chunkContainer, {
|
|
|
|
[styles.chunkOtherContainer]: !isPdf,
|
|
|
|
})}
|
2024-03-01 11:28:58 +08:00
|
|
|
>
|
|
|
|
{data.map((item) => (
|
|
|
|
<ChunkCard
|
|
|
|
item={item}
|
|
|
|
key={item.chunk_id}
|
|
|
|
editChunk={handleEditChunk}
|
|
|
|
checked={selectedChunkIds.some(
|
|
|
|
(x) => x === item.chunk_id,
|
|
|
|
)}
|
|
|
|
handleCheckboxClick={handleSingleCheckboxClick}
|
|
|
|
switchChunk={switchChunk}
|
2024-03-01 18:49:21 +08:00
|
|
|
clickChunkCard={handleChunkCardClick}
|
|
|
|
selected={item.chunk_id === selectedChunkId}
|
2024-04-30 18:43:26 +08:00
|
|
|
textMode={textMode}
|
2024-03-01 11:28:58 +08:00
|
|
|
></ChunkCard>
|
|
|
|
))}
|
|
|
|
</Space>
|
2024-03-20 11:13:51 +08:00
|
|
|
</div>
|
|
|
|
</Spin>
|
2024-03-01 11:28:58 +08:00
|
|
|
<div className={styles.pageFooter}>
|
|
|
|
<Pagination
|
|
|
|
responsive
|
|
|
|
showLessItems
|
|
|
|
showQuickJumper
|
|
|
|
showSizeChanger
|
|
|
|
onChange={onPaginationChange}
|
|
|
|
pageSize={pagination.pageSize}
|
|
|
|
pageSizeOptions={[10, 30, 60, 90]}
|
|
|
|
current={pagination.current}
|
2024-03-07 14:23:42 +08:00
|
|
|
size={'small'}
|
2024-03-01 11:28:58 +08:00
|
|
|
total={total}
|
2024-07-18 11:38:02 +08:00
|
|
|
showTotal={(total) => (
|
|
|
|
<Space>
|
|
|
|
{t('total', { keyPrefix: 'common' })}
|
|
|
|
{total}
|
|
|
|
</Space>
|
|
|
|
)}
|
2024-03-01 11:28:58 +08:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</Flex>
|
|
|
|
|
2024-03-07 11:38:32 +08:00
|
|
|
{isPdf && (
|
2024-03-01 11:28:58 +08:00
|
|
|
<section className={styles.documentPreview}>
|
2024-03-01 18:49:21 +08:00
|
|
|
<DocumentPreview
|
|
|
|
selectedChunkId={selectedChunkId}
|
|
|
|
></DocumentPreview>
|
2024-03-01 11:28:58 +08:00
|
|
|
</section>
|
|
|
|
)}
|
|
|
|
</Flex>
|
2024-01-18 18:27:38 +08:00
|
|
|
</div>
|
2024-02-07 18:04:25 +08:00
|
|
|
<CreatingModal doc_id={documentId} chunkId={chunkId} />
|
2024-01-30 19:26:29 +08:00
|
|
|
</>
|
|
|
|
);
|
2024-01-18 18:27:38 +08:00
|
|
|
};
|
|
|
|
|
2024-01-30 19:26:29 +08:00
|
|
|
export default Chunk;
|