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:
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import Icon from '@fastgpt/web/components/common/Icon';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
export const codeLight: { [key: string]: React.CSSProperties } = {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
ModalCloseButton
|
||||
} from '@chakra-ui/react';
|
||||
import Icon from '@fastgpt/web/components/common/Icon';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMarkdownWidth } from '../hooks';
|
||||
import type { IconNameType } from '@fastgpt/web/components/common/Icon/type.d';
|
||||
|
||||
@@ -26,6 +26,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||
import dynamic from 'next/dynamic';
|
||||
import CopyBox from '@fastgpt/web/components/common/String/CopyBox';
|
||||
|
||||
const MyModal = dynamic(() => import('@fastgpt/web/components/common/MyModal'));
|
||||
|
||||
@@ -252,7 +253,9 @@ const ModelTable = () => {
|
||||
<Td fontSize={'sm'}>
|
||||
<HStack>
|
||||
<Avatar src={item.avatar} w={'1.2rem'} />
|
||||
<Box color={'myGray.900'}>{item.name}</Box>
|
||||
<CopyBox value={item.name} color={'myGray.900'}>
|
||||
{item.name}
|
||||
</CopyBox>
|
||||
</HStack>
|
||||
</Td>
|
||||
<Td>
|
||||
|
||||
@@ -15,7 +15,7 @@ import ChatFunctionTip from './Tip';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
|
||||
const TTSSelect = ({
|
||||
value = defaultTTSConfig,
|
||||
|
||||
@@ -30,7 +30,7 @@ import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/ut
|
||||
import ChatFunctionTip from './Tip';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import InputTypeConfig from '@/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodePluginIO/InputTypeConfig';
|
||||
import InputTypeConfig from '@/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/InputTypeConfig';
|
||||
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
|
||||
|
||||
export const defaultVariable: VariableItemType = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { Flex, FlexProps, css, useTheme } from '@chakra-ui/react';
|
||||
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
|
||||
@@ -15,7 +15,7 @@ import FilesBlock from './FilesBox';
|
||||
import { ChatBoxContext } from '../Provider';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import AIResponseBox from '../../../components/AIResponseBox';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AdminFbkType } from '@fastgpt/global/core/chat/type.d';
|
||||
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
|
||||
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
|
||||
const InputDataModal = dynamic(() => import('@/pageComponents/dataset/detail/InputDataModal'));
|
||||
|
||||
export type AdminMarkType = {
|
||||
feedbackDataId?: string;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { SearchScoreTypeEnum, SearchScoreTypeMap } from '@fastgpt/global/core/da
|
||||
import type { readCollectionSourceBody } from '@/pages/api/core/dataset/collection/read';
|
||||
import Markdown from '@/components/Markdown';
|
||||
|
||||
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
|
||||
const InputDataModal = dynamic(() => import('@/pageComponents/dataset/detail/InputDataModal'));
|
||||
|
||||
type ScoreItemType = SearchDataResponseItemType['score'][0];
|
||||
const scoreTheme: Record<
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
import type { EditApiKeyProps } from '@/global/support/openapi/api.d';
|
||||
import dayjs from 'dayjs';
|
||||
import { AddIcon } from '@chakra-ui/icons';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { TeamTagItemType } from '@fastgpt/global/support/user/team/type';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { RepeatIcon } from '@chakra-ui/icons';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getTeamsTags, loadTeamTagsByDomain } from '@/web/support/user/team/api';
|
||||
|
||||
@@ -3,8 +3,8 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Button, Flex, ModalBody, ModalFooter, useDisclosure } from '@chakra-ui/react';
|
||||
import { NotSufficientModalType, useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import ExtraPlan from '@/pages/price/components/ExtraPlan';
|
||||
import StandardPlan from '@/pages/price/components/Standard';
|
||||
import ExtraPlan from '@/pageComponents/price/ExtraPlan';
|
||||
import StandardPlan from '@/pageComponents/price/Standard';
|
||||
import FillRowTabs from '@fastgpt/web/components/common/Tabs/FillRowTabs';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
|
||||
@@ -27,7 +27,7 @@ import dayjs from 'dayjs';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useCallback, useState } from 'react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||
import Divider from '@/pageComponents/app/detail/WorkflowComponents/Flow/components/Divider';
|
||||
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
||||
import { InvoiceHeaderSingleForm } from './InvoiceHeaderForm';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
@@ -1,4 +1,4 @@
|
||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||
import Divider from '@/pageComponents/app/detail/WorkflowComponents/Flow/components/Divider';
|
||||
import { getTeamInvoiceHeader, updateTeamInvoiceHeader } from '@/web/support/user/team/api';
|
||||
import { Box, Button, Flex, HStack, Input, InputProps, Radio, RadioGroup } from '@chakra-ui/react';
|
||||
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
||||
@@ -51,6 +51,7 @@ import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import { putUpdateWithJson } from '@/web/core/ai/config';
|
||||
import CopyBox from '@fastgpt/web/components/common/String/CopyBox';
|
||||
|
||||
const MyModal = dynamic(() => import('@fastgpt/web/components/common/MyModal'));
|
||||
|
||||
@@ -396,7 +397,9 @@ const ModelTable = ({ Tab }: { Tab: React.ReactNode }) => {
|
||||
<Td fontSize={'sm'}>
|
||||
<HStack>
|
||||
<Avatar src={item.avatar} w={'1.2rem'} />
|
||||
<Box color={'myGray.900'}>{item.name}</Box>
|
||||
<CopyBox value={item.name} color={'myGray.900'}>
|
||||
{item.name}
|
||||
</CopyBox>
|
||||
</HStack>
|
||||
</Td>
|
||||
<Td>
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Box, Button, Flex, Input, ModalBody, ModalFooter } from '@chakra-ui/react';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import React from 'react';
|
||||
import { ThirdPartyAccountType } from '../index';
|
||||
import { ThirdPartyAccountType } from '../../../pages/account/thirdParty/index';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
@@ -1,13 +1,11 @@
|
||||
import { getTotalPoints } from '@/web/support/wallet/usage/api';
|
||||
import { getDashboardData } from '@/web/support/wallet/usage/api';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { addDays } from 'date-fns';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
ResponsiveContainer,
|
||||
LineChart,
|
||||
@@ -19,7 +17,8 @@ import {
|
||||
TooltipProps
|
||||
} from 'recharts';
|
||||
import { NameType, ValueType } from 'recharts/types/component/DefaultTooltipContent';
|
||||
import { UnitType } from '../index';
|
||||
import { UnitType, UsageFilterParams } from './type';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export type usageFormType = {
|
||||
date: string;
|
||||
@@ -53,60 +52,57 @@ const CustomTooltip = ({ active, payload }: TooltipProps<ValueType, NameType>) =
|
||||
return null;
|
||||
};
|
||||
|
||||
const UsageForm = ({
|
||||
dateRange,
|
||||
selectTmbIds,
|
||||
usageSources,
|
||||
unit,
|
||||
const UsageDashboard = ({
|
||||
filterParams,
|
||||
Tabs,
|
||||
Selectors
|
||||
}: {
|
||||
dateRange: DateRangeType;
|
||||
selectTmbIds: string[];
|
||||
usageSources: UsageSourceEnum[];
|
||||
unit: UnitType;
|
||||
filterParams: UsageFilterParams;
|
||||
Tabs: React.ReactNode;
|
||||
Selectors: React.ReactNode;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
run: getTotalPointsData,
|
||||
data: totalPoints,
|
||||
loading: totalPointsLoading
|
||||
} = useRequest2(
|
||||
const { dateRange, selectTmbIds, usageSources, unit, isSelectAllSource, isSelectAllTmb } =
|
||||
filterParams;
|
||||
|
||||
const { data: totalPoints = [], loading: totalPointsLoading } = useRequest2(
|
||||
() =>
|
||||
getTotalPoints({
|
||||
dateStart: dateRange.from || new Date(),
|
||||
dateEnd: addDays(dateRange.to || new Date(), 1),
|
||||
teamMemberIds: selectTmbIds,
|
||||
sources: usageSources,
|
||||
getDashboardData({
|
||||
dateStart: dateRange.from
|
||||
? new Date(dateRange.from.setHours(0, 0, 0, 0))
|
||||
: new Date(new Date().setHours(0, 0, 0, 0)),
|
||||
dateEnd: dateRange.to
|
||||
? new Date(addDays(dateRange.to, 1).setHours(0, 0, 0, 0))
|
||||
: new Date(addDays(new Date(), 1).setHours(0, 0, 0, 0)),
|
||||
sources: isSelectAllSource ? undefined : usageSources,
|
||||
teamMemberIds: isSelectAllTmb ? undefined : selectTmbIds,
|
||||
unit
|
||||
}),
|
||||
}).then((res) =>
|
||||
res.map((item) => ({
|
||||
...item,
|
||||
date: dayjs(item.date).format('YYYY-MM-DD')
|
||||
}))
|
||||
),
|
||||
{
|
||||
manual: true
|
||||
manual: false,
|
||||
refreshDeps: [filterParams]
|
||||
}
|
||||
);
|
||||
|
||||
const totalUsage = useMemo(() => {
|
||||
return totalPoints?.reduce((acc, curr) => acc + curr.totalPoints, 0);
|
||||
return totalPoints.reduce((acc, curr) => acc + curr.totalPoints, 0);
|
||||
}, [totalPoints]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectTmbIds.length === 0 || usageSources.length === 0) return;
|
||||
getTotalPointsData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [usageSources, selectTmbIds.length, dateRange, unit]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>{Tabs}</Box>
|
||||
<Box>{Selectors}</Box>
|
||||
<MyBox isLoading={totalPointsLoading}>
|
||||
<Box mt={4}>{Selectors}</Box>
|
||||
<MyBox overflowY={'auto'} isLoading={totalPointsLoading}>
|
||||
<Flex fontSize={'20px'} fontWeight={'medium'} my={6}>
|
||||
<Box color={'black'}>{`${t('account_usage:total_usage')}:`}</Box>
|
||||
<Box color={'primary.600'} ml={2}>
|
||||
{`${formatNumber(totalUsage || 0)} ${t('account_usage:points')}`}
|
||||
{`${formatNumber(totalUsage)} ${t('account_usage:points')}`}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex mb={4} fontSize={'mini'} color={'myGray.500'} fontWeight={'medium'}>
|
||||
@@ -127,31 +123,13 @@ const UsageForm = ({
|
||||
tickMargin={12}
|
||||
tick={{ fontSize: '12px', color: '#667085', fontWeight: '500' }}
|
||||
/>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
verticalCoordinatesGenerator={(props) => {
|
||||
const { width } = props;
|
||||
if (width < 500) {
|
||||
return [width * 0.2, width * 0.4, width * 0.6, width * 0.8];
|
||||
} else {
|
||||
return [
|
||||
width * 0.125,
|
||||
width * 0.25,
|
||||
width * 0.375,
|
||||
width * 0.5,
|
||||
width * 0.625,
|
||||
width * 0.75,
|
||||
width * 0.875
|
||||
];
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<CartesianGrid strokeDasharray="3 3" horizontal={true} vertical={false} />
|
||||
<Tooltip content={<CustomTooltip />} />
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="totalPoints"
|
||||
stroke="#5E8FFF"
|
||||
strokeWidth={1.5}
|
||||
strokeWidth={2.5}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
@@ -161,4 +139,4 @@ const UsageForm = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(UsageForm);
|
||||
export default React.memo(UsageDashboard);
|
||||
@@ -11,115 +11,95 @@ import {
|
||||
Tr
|
||||
} from '@chakra-ui/react';
|
||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||
import { UsageSourceEnum, UsageSourceMap } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
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 { useEffect, useState } from 'react';
|
||||
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 { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
|
||||
import { addDays } from 'date-fns';
|
||||
import { ExportModalParams } from './ExportModal';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
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 ExportModal = dynamic(() => import('./ExportModal'));
|
||||
|
||||
const UsageTableList = ({
|
||||
dateRange,
|
||||
selectTmbIds,
|
||||
usageSources,
|
||||
projectName,
|
||||
members,
|
||||
memberTotal,
|
||||
isSelectAllTmb,
|
||||
filterParams,
|
||||
Tabs,
|
||||
Selectors
|
||||
}: {
|
||||
dateRange: DateRangeType;
|
||||
selectTmbIds: string[];
|
||||
usageSources: UsageSourceEnum[];
|
||||
projectName: string;
|
||||
members: TeamMemberItemType[];
|
||||
memberTotal: number;
|
||||
isSelectAllTmb: boolean;
|
||||
Tabs: React.ReactNode;
|
||||
Selectors: React.ReactNode;
|
||||
filterParams: UsageFilterParams;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isPc } = useSystem();
|
||||
const { toast } = useToast();
|
||||
|
||||
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,
|
||||
getData,
|
||||
total
|
||||
} = usePagination(getUserUsages, {
|
||||
pageSize: isPc ? 20 : 10,
|
||||
params: {
|
||||
dateStart: dateRange.from || new Date(),
|
||||
dateEnd: addDays(dateRange.to || new Date(), 1),
|
||||
sources: usageSources,
|
||||
teamMemberIds: selectTmbIds,
|
||||
isSelectAllTmb,
|
||||
projectName
|
||||
},
|
||||
defaultRequest: false
|
||||
pageSize: 20,
|
||||
params: requestParans,
|
||||
refreshDeps: [requestParans]
|
||||
});
|
||||
|
||||
const [usageDetail, setUsageDetail] = useState<UsageItemType>();
|
||||
const [currentParams, setCurrentParams] = useState<ExportModalParams | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if ((!isSelectAllTmb && selectTmbIds.length === 0) || usageSources.length === 0) return;
|
||||
getData(1);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [usageSources, selectTmbIds.length, projectName, dateRange, isSelectAllTmb]);
|
||||
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 flexDir={['column', 'row']} w={'100%'} alignItems={['flex-end', 'center']}>
|
||||
<Flex mt={4} w={'100%'}>
|
||||
<Box>{Selectors}</Box>
|
||||
<Box flex={'1'} />
|
||||
<Button
|
||||
size={'md'}
|
||||
onClick={() => {
|
||||
if ((selectTmbIds.length === 0 && !isSelectAllTmb) || usageSources.length === 0) {
|
||||
return toast({
|
||||
status: 'warning',
|
||||
title: t('account_usage:select_member_and_source_first')
|
||||
});
|
||||
}
|
||||
|
||||
setCurrentParams({
|
||||
dateStart: dateRange.from || new Date(),
|
||||
dateEnd: addDays(dateRange.to || new Date(), 1),
|
||||
sources: usageSources,
|
||||
teamMemberIds: selectTmbIds,
|
||||
teamMemberNames: members
|
||||
.filter((item) =>
|
||||
isSelectAllTmb
|
||||
? !selectTmbIds.includes(item.tmbId)
|
||||
: selectTmbIds.includes(item.tmbId)
|
||||
)
|
||||
.map((item) => item.memberName),
|
||||
isSelectAllTmb,
|
||||
projectName
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common:Export')}
|
||||
</Button>
|
||||
<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>
|
||||
@@ -172,17 +152,8 @@ const UsageTableList = ({
|
||||
{!!usageDetail && (
|
||||
<UsageDetail usage={usageDetail} onClose={() => setUsageDetail(undefined)} />
|
||||
)}
|
||||
|
||||
{!!currentParams && (
|
||||
<ExportModal
|
||||
onClose={() => setCurrentParams(null)}
|
||||
params={currentParams}
|
||||
memberTotal={isSelectAllTmb ? memberTotal - selectTmbIds.length : selectTmbIds.length}
|
||||
total={total}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsageTableList;
|
||||
export default React.memo(UsageTableList);
|
||||
13
projects/app/src/pageComponents/account/usage/type.d.ts
vendored
Normal file
13
projects/app/src/pageComponents/account/usage/type.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
|
||||
|
||||
export type UnitType = 'day' | 'month';
|
||||
|
||||
export type UsageFilterParams = {
|
||||
dateRange: DateRangeType;
|
||||
selectTmbIds: string[];
|
||||
isSelectAllTmb: boolean;
|
||||
usageSources: UsageSourceEnum[];
|
||||
isSelectAllSource: boolean;
|
||||
projectName: string;
|
||||
unit: UnitType;
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import { Box, Flex } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { filterSensitiveNodesData } from '@/web/core/workflow/utils';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||
import { fileDownload } from '@/web/common/file/utils';
|
||||
import { AppChatConfigType, AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import CollaboratorContextProvider from '@/components/support/permission/MemberManager/context';
|
||||
import ResumeInherit from '@/components/support/permission/ResumeInheritText';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from './context';
|
||||
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { resumeInheritPer } from '@/web/core/app/api';
|
||||
@@ -11,7 +11,7 @@ import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||
import { PluginRunBoxTabEnum } from '@/components/core/chat/ChatContainer/PluginRunBox/constants';
|
||||
import CloseIcon from '@fastgpt/web/components/common/Icon/close';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { PcHeader } from '@/pages/chat/components/ChatHeader';
|
||||
import { PcHeader } from '@/pageComponents/chat/ChatHeader';
|
||||
import { GetChatTypeEnum } from '@/global/core/chat/constants';
|
||||
import ChatItemContextProvider, { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||
import ChatRecordContextProvider, {
|
||||
@@ -6,7 +6,7 @@ import { Box, Flex, FlexProps, Grid, ModalBody, Switch, useTheme } from '@chakra
|
||||
import MyRadio from '@/components/common/MyRadio';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { fileToBase64 } from '@/web/common/file/utils';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
putShareChat
|
||||
} from '@/web/support/outLink/api';
|
||||
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { defaultOutLinkForm } from '@/web/core/app/constants';
|
||||
import type { OutLinkEditType, OutLinkSchema } from '@fastgpt/global/support/outLink/type.d';
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { Box, Image, Flex, ModalBody } from '@chakra-ui/react';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
@@ -16,7 +16,7 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import TagsEditModal from '../TagsEditModal';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
@@ -27,7 +27,7 @@ import type { SettingAIDataType } from '@fastgpt/global/core/app/type.d';
|
||||
import { TTSTypeEnum } from '@/web/core/app/constants';
|
||||
import { workflowSystemVariables } from '@/web/core/app/utils';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import VariableTip from '@/components/common/Textarea/MyTextarea/VariableTip';
|
||||
@@ -23,7 +23,7 @@ import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { getTeamsTags } from '@/web/support/user/team/api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from './context';
|
||||
|
||||
const TagsEditModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -8,8 +8,8 @@ import { useTranslation } from 'next-i18next';
|
||||
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { useChatTest } from '@/pages/app/detail/components/useChatTest';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import { useChatTest } from '../../useChatTest';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||
import { PluginRunBoxTabEnum } from '@/components/core/chat/ChatContainer/PluginRunBox/constants';
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Node, useKeyPress } from 'reactflow';
|
||||
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||
@@ -44,7 +44,7 @@ import IOTitle from '../../components/IOTitle';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../../context';
|
||||
import { useCreation, useMemoizedFn } from 'ahooks';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { getEditorVariables } from '../../../utils';
|
||||
@@ -30,7 +30,7 @@ import { SourceHandle } from '../render/Handle';
|
||||
import { Position, useReactFlow } from 'reactflow';
|
||||
import { getRefData } from '@/web/core/workflow/utils';
|
||||
import DragIcon from '@fastgpt/web/components/common/DndDrag/DragIcon';
|
||||
import { AppContext } from '@/pages/app/detail/components/context';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
|
||||
const ListItem = ({
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user