perf: usages list;perf: move components (#3654)
* perf: usages list * team sub plan load * perf: usage dashboard code * perf: dashboard ui * perf: move components
This commit is contained in:
159
projects/app/src/pageComponents/account/usage/UsageTable.tsx
Normal file
159
projects/app/src/pageComponents/account/usage/UsageTable.tsx
Normal file
@@ -0,0 +1,159 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
Table,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Th,
|
||||
Thead,
|
||||
Tr
|
||||
} from '@chakra-ui/react';
|
||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||
import { UsageSourceMap } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { UsageItemType } from '@fastgpt/global/support/wallet/usage/type';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import dayjs from 'dayjs';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
||||
import { getUserUsages } from '@/web/support/wallet/usage/api';
|
||||
import { addDays } from 'date-fns';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { UsageFilterParams } from './type';
|
||||
import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { downloadFetch } from '@/web/common/system/utils';
|
||||
|
||||
const UsageDetail = dynamic(() => import('./UsageDetail'));
|
||||
|
||||
const UsageTableList = ({
|
||||
filterParams,
|
||||
Tabs,
|
||||
Selectors
|
||||
}: {
|
||||
Tabs: React.ReactNode;
|
||||
Selectors: React.ReactNode;
|
||||
filterParams: UsageFilterParams;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { dateRange, selectTmbIds, isSelectAllTmb, usageSources, isSelectAllSource, projectName } =
|
||||
filterParams;
|
||||
const requestParans = useMemo(
|
||||
() => ({
|
||||
dateStart: dateRange.from || new Date(),
|
||||
dateEnd: addDays(dateRange.to || new Date(), 1),
|
||||
sources: isSelectAllSource ? undefined : usageSources,
|
||||
teamMemberIds: isSelectAllTmb ? undefined : selectTmbIds,
|
||||
projectName
|
||||
}),
|
||||
[
|
||||
dateRange.from,
|
||||
dateRange.to,
|
||||
isSelectAllSource,
|
||||
isSelectAllTmb,
|
||||
projectName,
|
||||
selectTmbIds,
|
||||
usageSources
|
||||
]
|
||||
);
|
||||
|
||||
const {
|
||||
data: usages,
|
||||
isLoading,
|
||||
Pagination,
|
||||
total
|
||||
} = usePagination(getUserUsages, {
|
||||
pageSize: 20,
|
||||
params: requestParans,
|
||||
refreshDeps: [requestParans]
|
||||
});
|
||||
|
||||
const [usageDetail, setUsageDetail] = useState<UsageItemType>();
|
||||
|
||||
const { runAsync: exportUsage } = useRequest2(
|
||||
async () => {
|
||||
await downloadFetch({
|
||||
url: `/api/proApi/support/wallet/usage/exportUsage`,
|
||||
filename: `usage.csv`,
|
||||
body: requestParans
|
||||
});
|
||||
},
|
||||
{
|
||||
refreshDeps: [requestParans]
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>{Tabs}</Box>
|
||||
<Flex mt={4} w={'100%'}>
|
||||
<Box>{Selectors}</Box>
|
||||
<Box flex={'1'} />
|
||||
<PopoverConfirm
|
||||
Trigger={<Button size={'md'}>{t('common:Export')}</Button>}
|
||||
showCancel
|
||||
content={t('account_usage:export_confirm_tip', { total })}
|
||||
onConfirm={exportUsage}
|
||||
/>
|
||||
</Flex>
|
||||
<MyBox position={'relative'} overflowY={'auto'} mt={3} flex={1} isLoading={isLoading}>
|
||||
<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>{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>
|
||||
</MyBox>
|
||||
<Flex mt={3} justifyContent={'center'}>
|
||||
<Pagination />
|
||||
</Flex>
|
||||
|
||||
{!!usageDetail && (
|
||||
<UsageDetail usage={usageDetail} onClose={() => setUsageDetail(undefined)} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(UsageTableList);
|
||||
Reference in New Issue
Block a user