| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| import AppCard from '@/app/components/app/overview/appCard' | |||||
| import AppCard from '@/app/components/app/overview/app-card' | |||||
| import Loading from '@/app/components/base/loading' | import Loading from '@/app/components/base/loading' | ||||
| import MCPServiceCard from '@/app/components/tools/mcp/mcp-service-card' | import MCPServiceCard from '@/app/components/tools/mcp/mcp-service-card' | ||||
| import { ToastContext } from '@/app/components/base/toast' | import { ToastContext } from '@/app/components/base/toast' | ||||
| import type { UpdateAppSiteCodeResponse } from '@/models/app' | import type { UpdateAppSiteCodeResponse } from '@/models/app' | ||||
| import { asyncRunSafe } from '@/utils' | import { asyncRunSafe } from '@/utils' | ||||
| import { NEED_REFRESH_APP_LIST_KEY } from '@/config' | import { NEED_REFRESH_APP_LIST_KEY } from '@/config' | ||||
| import type { IAppCardProps } from '@/app/components/app/overview/appCard' | |||||
| import type { IAppCardProps } from '@/app/components/app/overview/app-card' | |||||
| import { useStore as useAppStore } from '@/app/components/app/store' | import { useStore as useAppStore } from '@/app/components/app/store' | ||||
| export type ICardViewProps = { | export type ICardViewProps = { |
| import dayjs from 'dayjs' | import dayjs from 'dayjs' | ||||
| import quarterOfYear from 'dayjs/plugin/quarterOfYear' | import quarterOfYear from 'dayjs/plugin/quarterOfYear' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import type { PeriodParams } from '@/app/components/app/overview/appChart' | |||||
| import { AvgResponseTime, AvgSessionInteractions, AvgUserInteractions, ConversationsChart, CostChart, EndUsersChart, MessagesChart, TokenPerSecond, UserSatisfactionRate, WorkflowCostChart, WorkflowDailyTerminalsChart, WorkflowMessagesChart } from '@/app/components/app/overview/appChart' | |||||
| import type { PeriodParams } from '@/app/components/app/overview/app-chart' | |||||
| import { AvgResponseTime, AvgSessionInteractions, AvgUserInteractions, ConversationsChart, CostChart, EndUsersChart, MessagesChart, TokenPerSecond, UserSatisfactionRate, WorkflowCostChart, WorkflowDailyTerminalsChart, WorkflowMessagesChart } from '@/app/components/app/overview/app-chart' | |||||
| import type { Item } from '@/app/components/base/select' | import type { Item } from '@/app/components/base/select' | ||||
| import { SimpleSelect } from '@/app/components/base/select' | import { SimpleSelect } from '@/app/components/base/select' | ||||
| import { TIME_PERIOD_MAPPING } from '@/app/components/app/log/filter' | import { TIME_PERIOD_MAPPING } from '@/app/components/app/log/filter' |
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| import type { AppSSO } from '@/types/app' | import type { AppSSO } from '@/types/app' | ||||
| import Indicator from '@/app/components/header/indicator' | import Indicator from '@/app/components/header/indicator' | ||||
| import { fetchAppDetail } from '@/service/apps' | |||||
| import { fetchAppDetailDirect } from '@/service/apps' | |||||
| import { AccessMode } from '@/models/access-control' | import { AccessMode } from '@/models/access-control' | ||||
| import AccessControl from '../app-access-control' | import AccessControl from '../app-access-control' | ||||
| import { useAppWhiteListSubjects } from '@/service/access-control' | import { useAppWhiteListSubjects } from '@/service/access-control' | ||||
| return | return | ||||
| setShowAccessControl(true) | setShowAccessControl(true) | ||||
| }, [appDetail]) | }, [appDetail]) | ||||
| const handleAccessControlUpdate = useCallback(() => { | |||||
| fetchAppDetail({ url: '/apps', id: appDetail!.id }).then((res) => { | |||||
| const handleAccessControlUpdate = useCallback(async () => { | |||||
| try { | |||||
| const res = await fetchAppDetailDirect({ url: '/apps', id: appDetail!.id }) | |||||
| setAppDetail(res) | setAppDetail(res) | ||||
| setShowAccessControl(false) | setShowAccessControl(false) | ||||
| }) | |||||
| } | |||||
| catch (error) { | |||||
| console.error('Failed to fetch app detail:', error) | |||||
| } | |||||
| }, [appDetail, setAppDetail]) | }, [appDetail, setAppDetail]) | ||||
| return ( | return ( |
| ? '' | ? '' | ||||
| : <span>{t('appOverview.analysis.tokenUsage.consumed')} Tokens<span className='text-sm'> | : <span>{t('appOverview.analysis.tokenUsage.consumed')} Tokens<span className='text-sm'> | ||||
| <span className='ml-1 text-text-tertiary'>(</span> | <span className='ml-1 text-text-tertiary'>(</span> | ||||
| <span className='text-orange-400'>~{sum(statistics.map(item => Number.parseFloat(get(item, 'total_price', '0')))).toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 })}</span> | |||||
| <span className='text-orange-400'>~{sum(statistics.map(item => Number.parseFloat(String(get(item, 'total_price', '0'))))).toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 })}</span> | |||||
| <span className='text-text-tertiary'>)</span> | <span className='text-text-tertiary'>)</span> | ||||
| </span></span>} | </span></span>} | ||||
| textStyle={{ main: `!text-3xl !font-normal ${sumData === 0 ? '!text-text-quaternary' : ''}` }} /> | textStyle={{ main: `!text-3xl !font-normal ${sumData === 0 ? '!text-text-quaternary' : ''}` }} /> |