mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-06 01:02:54 +08:00
perf: page ui (#5469)
* perf: page ui * fix: icon * limit chat items * limit chat items
This commit is contained in:
@@ -60,9 +60,10 @@ const BillTable = () => {
|
||||
isLoading,
|
||||
Pagination,
|
||||
getData,
|
||||
total
|
||||
total,
|
||||
pageSize
|
||||
} = usePagination(getBills, {
|
||||
pageSize: 20,
|
||||
defaultPageSize: 20,
|
||||
params: {
|
||||
type: billType
|
||||
},
|
||||
@@ -95,8 +96,8 @@ const BillTable = () => {
|
||||
}, [billType]);
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} position={'relative'} h={'100%'} minH={'50vh'}>
|
||||
<TableContainer>
|
||||
<MyBox isLoading={isLoading} display={'flex'} flexDir={'column'} h={'100%'}>
|
||||
<TableContainer flex={'1 0 0'} h={0} overflowY={'auto'}>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
@@ -147,11 +148,6 @@ const BillTable = () => {
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{total >= 20 && (
|
||||
<Flex mt={3} justifyContent={'flex-end'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
{!isLoading && bills.length === 0 && (
|
||||
<Flex
|
||||
mt={'20vh'}
|
||||
@@ -167,6 +163,11 @@ const BillTable = () => {
|
||||
)}
|
||||
</TableContainer>
|
||||
|
||||
{total >= pageSize && (
|
||||
<Flex mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
{!!billDetail && (
|
||||
<BillDetailModal bill={billDetail} onClose={() => setBillDetail(undefined)} />
|
||||
)}
|
||||
|
||||
@@ -32,14 +32,15 @@ const InvoiceTable = () => {
|
||||
data: invoices,
|
||||
isLoading,
|
||||
Pagination,
|
||||
total
|
||||
total,
|
||||
pageSize
|
||||
} = usePagination(getInvoiceRecords, {
|
||||
pageSize: 20
|
||||
defaultPageSize: 10
|
||||
});
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} position={'relative'} h={'100%'} overflow={'overlay'}>
|
||||
<TableContainer minH={'50vh'}>
|
||||
<MyBox isLoading={isLoading} position={'relative'} minH={'50vh'} overflow={'overlay'}>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<Thead h="3rem">
|
||||
<Tr>
|
||||
@@ -101,11 +102,6 @@ const InvoiceTable = () => {
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{total >= 20 && (
|
||||
<Flex mt={3} justifyContent={'flex-end'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
{!isLoading && invoices.length === 0 && (
|
||||
<Flex
|
||||
mt={'20vh'}
|
||||
@@ -120,6 +116,11 @@ const InvoiceTable = () => {
|
||||
</Flex>
|
||||
)}
|
||||
</TableContainer>
|
||||
{total >= pageSize && (
|
||||
<Flex mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
{!!invoiceDetailData && (
|
||||
<InvoiceDetailModal invoice={invoiceDetailData} onClose={() => setInvoiceDetailData('')} />
|
||||
)}
|
||||
|
||||
@@ -68,7 +68,7 @@ const UsageTableList = ({
|
||||
Pagination,
|
||||
total
|
||||
} = usePagination(getUserUsages, {
|
||||
pageSize: 20,
|
||||
defaultPageSize: 20,
|
||||
params: requestParams,
|
||||
refreshDeps: [requestParams]
|
||||
});
|
||||
@@ -111,7 +111,7 @@ const UsageTableList = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MyBox display={'flex'} flexDirection={'column'} h={'100%'} isLoading={isLoading}>
|
||||
<Box>{Tabs}</Box>
|
||||
<Flex mt={4} w={'100%'}>
|
||||
<Box>{Selectors}</Box>
|
||||
@@ -123,54 +123,46 @@ const UsageTableList = ({
|
||||
onConfirm={exportUsage}
|
||||
/>
|
||||
</Flex>
|
||||
<MyBox mt={3} flex={'1 0 0'} h={0} isLoading={isLoading}>
|
||||
<Box h={'100%'} overflow={'auto'}>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{t('common:user.Time')}</Th>
|
||||
<Th>{t('account_usage:member')}</Th>
|
||||
<Th>{t('account_usage:user_type')}</Th>
|
||||
<Th>{t('account_usage:project_name')}</Th>
|
||||
<Th>{t('account_usage:total_points')}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody fontSize={'sm'}>
|
||||
{usages.map((item) => (
|
||||
<Tr key={item.id}>
|
||||
<Td>{dayjs(item.time).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
||||
<Td>
|
||||
<Flex alignItems={'center'} color={'myGray.500'}>
|
||||
<Avatar src={item.sourceMember.avatar} w={'20px'} mr={1} rounded={'full'} />
|
||||
{item.sourceMember.name}
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{t(UsageSourceMap[item.source]?.label as any) || '-'}</Td>
|
||||
<Td className="textEllipsis" maxW={'400px'} title={t(item.appName as any)}>
|
||||
{t(item.appName as any) || '-'}
|
||||
</Td>
|
||||
<Td>{formatNumber(item.totalPoints) || 0}</Td>
|
||||
<Td>
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
onClick={() => setUsageDetail(item)}
|
||||
>
|
||||
{t('account_usage:details')}
|
||||
</Button>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{!isLoading && usages.length === 0 && (
|
||||
<EmptyTip text={t('account_usage:no_usage_records')}></EmptyTip>
|
||||
)}
|
||||
</TableContainer>
|
||||
</Box>
|
||||
</MyBox>
|
||||
<TableContainer mt={3} flex={'1 0 0'} h={0} overflowY={'auto'}>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{t('common:user.Time')}</Th>
|
||||
<Th>{t('account_usage:member')}</Th>
|
||||
<Th>{t('account_usage:user_type')}</Th>
|
||||
<Th>{t('account_usage:project_name')}</Th>
|
||||
<Th>{t('account_usage:total_points')}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody fontSize={'sm'}>
|
||||
{usages.map((item) => (
|
||||
<Tr key={item.id}>
|
||||
<Td>{dayjs(item.time).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
||||
<Td>
|
||||
<Flex alignItems={'center'} color={'myGray.500'}>
|
||||
<Avatar src={item.sourceMember.avatar} w={'20px'} mr={1} rounded={'full'} />
|
||||
{item.sourceMember.name}
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{t(UsageSourceMap[item.source]?.label as any) || '-'}</Td>
|
||||
<Td className="textEllipsis" maxW={'400px'} title={t(item.appName as any)}>
|
||||
{t(item.appName as any) || '-'}
|
||||
</Td>
|
||||
<Td>{formatNumber(item.totalPoints) || 0}</Td>
|
||||
<Td>
|
||||
<Button size={'sm'} variant={'whitePrimary'} onClick={() => setUsageDetail(item)}>
|
||||
{t('account_usage:details')}
|
||||
</Button>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{!isLoading && usages.length === 0 && (
|
||||
<EmptyTip text={t('account_usage:no_usage_records')}></EmptyTip>
|
||||
)}
|
||||
</TableContainer>
|
||||
<Flex mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
@@ -178,7 +170,7 @@ const UsageTableList = ({
|
||||
{!!usageDetail && (
|
||||
<UsageDetail usage={usageDetail} onClose={() => setUsageDetail(undefined)} />
|
||||
)}
|
||||
</>
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
} from '@fastgpt/global/core/app/logs/constants';
|
||||
import { formatDateByTimespan } from '@fastgpt/global/core/app/logs/utils';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
|
||||
export type HeaderControlProps = {
|
||||
appId: string;
|
||||
@@ -149,7 +150,7 @@ const LogChart = ({
|
||||
|
||||
const [offset, setOffset] = useState<string>(offsetOptions[0].value);
|
||||
|
||||
const { data: chartData } = useRequest2(
|
||||
const { data: chartData, loading } = useRequest2(
|
||||
async () => {
|
||||
return getAppChartData({
|
||||
appId,
|
||||
@@ -331,7 +332,7 @@ const LogChart = ({
|
||||
]);
|
||||
|
||||
return (
|
||||
<Flex flexDir={'column'} h={'full'}>
|
||||
<MyBox isLoading={loading} display={'flex'} flexDir={'column'} h={'full'}>
|
||||
<HeaderControl
|
||||
appId={appId}
|
||||
chatSources={chatSources}
|
||||
@@ -751,7 +752,7 @@ const LogChart = ({
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
import dynamic from 'next/dynamic';
|
||||
import type { HeaderControlProps } from './LogChart';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
|
||||
const DetailLogsModal = dynamic(() => import('./DetailLogsModal'));
|
||||
|
||||
@@ -196,9 +197,10 @@ const LogTable = ({
|
||||
Pagination,
|
||||
getData,
|
||||
pageNum,
|
||||
total
|
||||
total,
|
||||
pageSize
|
||||
} = usePagination(getAppChatLogs, {
|
||||
pageSize: 20,
|
||||
defaultPageSize: 20,
|
||||
params,
|
||||
refreshDeps: [params]
|
||||
});
|
||||
@@ -338,7 +340,7 @@ const LogTable = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex flexDir={'column'} h={'full'} overflow={'auto'} px={[4, 8]}>
|
||||
<MyBox isLoading={isLoading} display={'flex'} flexDir={'column'} h={'full'} px={[4, 8]}>
|
||||
<Flex alignItems={'center'} gap={3} flexWrap={'wrap'}>
|
||||
{showSourceSelector && (
|
||||
<Flex>
|
||||
@@ -465,7 +467,7 @@ const LogTable = ({
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
<TableContainer mt={[2, 4]} flex={['', '1 0 0']} h={['auto', 0]} overflowY={'auto'}>
|
||||
<TableContainer mt={[2, 4]} flex={'1 0 0'} overflowY={'auto'}>
|
||||
<Table variant={'simple'} fontSize={'sm'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
@@ -496,9 +498,11 @@ const LogTable = ({
|
||||
{logs.length === 0 && !isLoading && <EmptyTip text={t('app:logs_empty')}></EmptyTip>}
|
||||
</TableContainer>
|
||||
|
||||
<HStack w={'100%'} mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</HStack>
|
||||
{total >= pageSize && (
|
||||
<Flex mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{!!detailLogsId && (
|
||||
<DetailLogsModal
|
||||
@@ -510,7 +514,7 @@ const LogTable = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -149,11 +149,12 @@ const Header = () => {
|
||||
p={0.5}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={6}
|
||||
cursor={'pointer'}
|
||||
onClick={isSaved ? onBack : onOpenBackConfirm}
|
||||
<IconButton
|
||||
icon={<MyIcon name={'common/leftArrowLight'} color={'myGray.600'} w={'0.8rem'} />}
|
||||
aria-label={''}
|
||||
size={'xs'}
|
||||
w={'1rem'}
|
||||
variant={'ghost'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -213,8 +214,6 @@ const Header = () => {
|
||||
isPc,
|
||||
currentTab,
|
||||
isSaved,
|
||||
onBack,
|
||||
onOpenBackConfirm,
|
||||
isV2Workflow,
|
||||
t,
|
||||
showHistoryModal,
|
||||
|
||||
@@ -149,11 +149,12 @@ const Header = () => {
|
||||
p={0.5}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={6}
|
||||
cursor={'pointer'}
|
||||
onClick={isSaved ? onBack : onOpenBackConfirm}
|
||||
<IconButton
|
||||
icon={<MyIcon name={'common/leftArrowLight'} color={'myGray.600'} w={'0.8rem'} />}
|
||||
aria-label={''}
|
||||
size={'xs'}
|
||||
w={'1rem'}
|
||||
variant={'ghost'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -213,8 +214,6 @@ const Header = () => {
|
||||
isPc,
|
||||
currentTab,
|
||||
isSaved,
|
||||
onBack,
|
||||
onOpenBackConfirm,
|
||||
isV2Workflow,
|
||||
t,
|
||||
showHistoryModal,
|
||||
|
||||
@@ -97,9 +97,11 @@ const EvaluationDetailModal = ({
|
||||
const {
|
||||
data: evalItemsList,
|
||||
Pagination,
|
||||
pageSize,
|
||||
total,
|
||||
getData: fetchData
|
||||
} = usePagination(getEvalItemsList, {
|
||||
pageSize: 10,
|
||||
defaultPageSize: 20,
|
||||
params: {
|
||||
evalId: evalDetail._id
|
||||
},
|
||||
@@ -440,9 +442,11 @@ const EvaluationDetailModal = ({
|
||||
})}
|
||||
</Box>
|
||||
|
||||
<Box px={6} py={3}>
|
||||
<Pagination />
|
||||
</Box>
|
||||
{total >= pageSize && (
|
||||
<Flex my={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
{evalItem ? (
|
||||
|
||||
@@ -128,7 +128,7 @@ const CollectionPageContextProvider = ({ children }: { children: ReactNode }) =>
|
||||
pageNum,
|
||||
pageSize
|
||||
} = usePagination(getDatasetCollections, {
|
||||
pageSize: 20,
|
||||
defaultPageSize: 20,
|
||||
params: {
|
||||
datasetId,
|
||||
parentId,
|
||||
|
||||
@@ -10,14 +10,16 @@ import {
|
||||
Td,
|
||||
Tbody,
|
||||
MenuButton,
|
||||
Switch
|
||||
Switch,
|
||||
Checkbox,
|
||||
HStack,
|
||||
Button
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
delDatasetCollectionById,
|
||||
putDatasetCollectionById,
|
||||
postLinkCollectionSync
|
||||
} from '@/web/core/dataset/api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
@@ -49,6 +51,7 @@ import { useFolderDrag } from '@/components/common/folder/useFolderDrag';
|
||||
import TagsPopOver from './TagsPopOver';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import TrainingStates from './TrainingStates';
|
||||
import { useTableMultipleSelect } from '@fastgpt/web/hooks/useTableMultipleSelect';
|
||||
|
||||
const Header = dynamic(() => import('./Header'));
|
||||
const EmptyCollectionTip = dynamic(() => import('./EmptyCollectionTip'));
|
||||
@@ -103,6 +106,19 @@ const CollectionCard = () => {
|
||||
[collections, t]
|
||||
);
|
||||
|
||||
const {
|
||||
selectedItems,
|
||||
toggleSelect,
|
||||
isSelected,
|
||||
setSelectedItems,
|
||||
FloatingActionBar,
|
||||
isSelecteAll,
|
||||
selectAllTrigger
|
||||
} = useTableMultipleSelect({
|
||||
list: formatCollections,
|
||||
getItemId: (e) => e._id
|
||||
});
|
||||
|
||||
const [moveCollectionData, setMoveCollectionData] = useState<{ collectionId: string }>();
|
||||
|
||||
const { onOpenModal: onOpenEditTitleModal, EditModal: EditTitleModal } = useEditTitle({
|
||||
@@ -123,9 +139,9 @@ const CollectionCard = () => {
|
||||
type: 'delete'
|
||||
});
|
||||
const { runAsync: onDelCollection } = useRequest2(
|
||||
(collectionId: string) => {
|
||||
(collectionIds: string[]) => {
|
||||
return delDatasetCollectionById({
|
||||
id: collectionId
|
||||
collectionIds
|
||||
});
|
||||
},
|
||||
{
|
||||
@@ -156,18 +172,17 @@ const CollectionCard = () => {
|
||||
[formatCollections]
|
||||
);
|
||||
|
||||
useQuery(
|
||||
['refreshCollection'],
|
||||
() => {
|
||||
useRequest2(
|
||||
async () => {
|
||||
if (!hasTrainingData && datasetDetail.status === DatasetStatusEnum.active) return;
|
||||
getData(pageNum);
|
||||
if (datasetDetail.status !== DatasetStatusEnum.active) {
|
||||
loadDatasetDetail(datasetDetail._id);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
{
|
||||
refetchInterval: 6000,
|
||||
enabled: hasTrainingData || datasetDetail.status !== DatasetStatusEnum.active
|
||||
retryInterval: 6000,
|
||||
refreshDeps: [hasTrainingData, datasetDetail.status]
|
||||
}
|
||||
);
|
||||
|
||||
@@ -186,21 +201,25 @@ const CollectionCard = () => {
|
||||
}
|
||||
});
|
||||
|
||||
const isLoading =
|
||||
isUpdating || isSyncing || (isGetting && collections.length === 0) || isDropping;
|
||||
const isLoading = isUpdating || isSyncing || isGetting || isDropping;
|
||||
|
||||
return (
|
||||
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]}>
|
||||
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]} overflow={'hidden'}>
|
||||
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 0]} h={'100%'} px={[2, 6]}>
|
||||
{/* header */}
|
||||
<Header hasTrainingData={hasTrainingData} />
|
||||
|
||||
{/* collection table */}
|
||||
<TableContainer mt={3} overflowY={'auto'} fontSize={'sm'}>
|
||||
<TableContainer mt={3} overflowY={'auto'} fontSize={'sm'} flex={'1 0 0'} h={0}>
|
||||
<Table variant={'simple'} draggable={false}>
|
||||
<Thead draggable={false}>
|
||||
<Tr>
|
||||
<Th py={4}>{t('common:Name')}</Th>
|
||||
<Th py={4}>
|
||||
<HStack>
|
||||
<Checkbox isChecked={isSelecteAll} onChange={selectAllTrigger} />
|
||||
<Box>{t('common:Name')}</Box>
|
||||
</HStack>
|
||||
</Th>
|
||||
<Th py={4}>{t('dataset:collection.training_type')}</Th>
|
||||
<Th py={4}>{t('dataset:collection_data_count')}</Th>
|
||||
<Th py={4}>{t('dataset:collection.Create update time')}</Th>
|
||||
@@ -241,17 +260,27 @@ const CollectionCard = () => {
|
||||
}}
|
||||
>
|
||||
<Td minW={'150px'} maxW={['200px', '300px']} draggable py={2}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={collection.icon as any} w={'1.25rem'} mr={2} />
|
||||
<MyTooltip label={t('common:click_drag_tip')} shouldWrapChildren={false}>
|
||||
<Box color={'myGray.900'} fontWeight={'500'} className="textEllipsis">
|
||||
{collection.name}
|
||||
</Box>
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
{feConfigs?.isPlus && !!collection.tags?.length && (
|
||||
<TagsPopOver currentCollection={collection} />
|
||||
)}
|
||||
<HStack>
|
||||
<Box onClick={(e) => e.stopPropagation()}>
|
||||
<Checkbox
|
||||
isChecked={isSelected(collection)}
|
||||
onChange={(e) => toggleSelect(collection)}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={collection.icon as any} w={'1.25rem'} mr={2} />
|
||||
<MyTooltip label={t('common:click_drag_tip')} shouldWrapChildren={false}>
|
||||
<Box color={'myGray.900'} fontWeight={'500'} className="textEllipsis">
|
||||
{collection.name}
|
||||
</Box>
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
{feConfigs?.isPlus && !!collection.tags?.length && (
|
||||
<TagsPopOver currentCollection={collection} />
|
||||
)}
|
||||
</Box>
|
||||
</HStack>
|
||||
</Td>
|
||||
<Td py={2}>
|
||||
{collection.trainingType
|
||||
@@ -394,7 +423,7 @@ const CollectionCard = () => {
|
||||
type: 'danger',
|
||||
onClick: () =>
|
||||
openDeleteConfirm(
|
||||
() => onDelCollection(collection._id),
|
||||
() => onDelCollection([collection._id]),
|
||||
undefined,
|
||||
collection.type === DatasetCollectionTypeEnum.folder
|
||||
? t('common:dataset.collections.Confirm to delete the folder')
|
||||
@@ -411,13 +440,39 @@ const CollectionCard = () => {
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
|
||||
{total === 0 && <EmptyCollectionTip />}
|
||||
</TableContainer>
|
||||
|
||||
<FloatingActionBar
|
||||
Controler={
|
||||
<HStack>
|
||||
<Button
|
||||
variant={'whiteBase'}
|
||||
onClick={() =>
|
||||
openDeleteConfirm(
|
||||
() =>
|
||||
onDelCollection(selectedItems.map((e) => e._id)).then(() =>
|
||||
setSelectedItems([])
|
||||
),
|
||||
undefined,
|
||||
t('dataset:confirm_delete_collection', {
|
||||
num: selectedItems.length
|
||||
})
|
||||
)()
|
||||
}
|
||||
>
|
||||
{t('dataset:batch_delete')}
|
||||
</Button>
|
||||
</HStack>
|
||||
}
|
||||
>
|
||||
{total > pageSize && (
|
||||
<Flex mt={2} justifyContent={'center'}>
|
||||
<Flex justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
)}
|
||||
{total === 0 && <EmptyCollectionTip />}
|
||||
</TableContainer>
|
||||
</FloatingActionBar>
|
||||
|
||||
<ConfirmDeleteModal />
|
||||
<ConfirmSyncModal />
|
||||
|
||||
Reference in New Issue
Block a user