chore: locales
This commit is contained in:
@@ -1,5 +1,31 @@
|
|||||||
export default {
|
export default {
|
||||||
'usage.title': 'Usage',
|
'usage.title': 'Usage',
|
||||||
'usage.filter.user': 'Filter by user',
|
'usage.filter.user': 'Filter by user',
|
||||||
'usage.filter.model': 'Filter by model'
|
'usage.filter.model': 'Filter by model',
|
||||||
|
'usage.filter.apikey': 'Filter by API key',
|
||||||
|
'usage.filter.metric': 'Metric',
|
||||||
|
'usage.filter.groupBy': 'Group by',
|
||||||
|
'usage.filter.group.user': 'User',
|
||||||
|
'usage.filter.group.model': 'Model',
|
||||||
|
'usage.filter.group.apikey': 'API Key',
|
||||||
|
'usage.filter.inputTokens': 'Input Tokens',
|
||||||
|
'usage.filter.outputTokens': 'Output Tokens',
|
||||||
|
'usage.filter.totalTokens': 'Total Tokens',
|
||||||
|
'usage.filter.apiRequests': 'API Requests',
|
||||||
|
'usage.filter.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.apiKeysUsed': 'API Keys Used',
|
||||||
|
'usage.table.lastActive': 'Last Active',
|
||||||
|
'usage.filter.granularity': 'Granularity',
|
||||||
|
'usage.filter.granularity.day': 'Day',
|
||||||
|
'usage.filter.granularity.week': 'Week',
|
||||||
|
'usage.filter.granularity.month': 'Month',
|
||||||
|
'usage.tabs.models': 'Models',
|
||||||
|
'usage.tabs.apikeys': 'API Keys',
|
||||||
|
'usage.tabs.users': 'User',
|
||||||
|
'usage.export.chart': 'Export Chart Data',
|
||||||
|
'usage.export.table': 'Export Table Data',
|
||||||
|
'usage.user.currentAccount': 'Current Account',
|
||||||
|
'usage.table.cluster': 'Cluster',
|
||||||
|
'usage.table.provider': 'Provider'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
export default {
|
export default {
|
||||||
'usage.title': '使用状況',
|
'usage.title': 'Usage',
|
||||||
'usage.filter.user': 'ユーザーでフィルタ',
|
'usage.filter.user': 'Filter by user',
|
||||||
'usage.filter.model': 'モデルでフィルタ'
|
'usage.filter.model': 'Filter by model',
|
||||||
|
'usage.filter.apikey': 'Filter by API key',
|
||||||
|
'usage.filter.metric': 'Metric',
|
||||||
|
'usage.filter.groupBy': 'Group by',
|
||||||
|
'usage.filter.group.user': 'User',
|
||||||
|
'usage.filter.group.model': 'Model',
|
||||||
|
'usage.filter.group.apikey': 'API Key',
|
||||||
|
'usage.filter.inputTokens': 'Input Tokens',
|
||||||
|
'usage.filter.outputTokens': 'Output Tokens',
|
||||||
|
'usage.filter.totalTokens': 'Total Tokens',
|
||||||
|
'usage.filter.apiRequests': 'API Requests',
|
||||||
|
'usage.filter.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.apiKeysUsed': 'API Keys Used',
|
||||||
|
'usage.table.lastActive': 'Last Active',
|
||||||
|
'usage.filter.granularity': 'Granularity',
|
||||||
|
'usage.filter.granularity.day': 'Day',
|
||||||
|
'usage.filter.granularity.week': 'Week',
|
||||||
|
'usage.filter.granularity.month': 'Month',
|
||||||
|
'usage.tabs.models': 'Models',
|
||||||
|
'usage.tabs.apikeys': 'API Keys',
|
||||||
|
'usage.tabs.users': 'User',
|
||||||
|
'usage.export.chart': 'Export Chart Data',
|
||||||
|
'usage.export.table': 'Export Table Data',
|
||||||
|
'usage.user.currentAccount': 'Current Account',
|
||||||
|
'usage.table.cluster': 'Cluster',
|
||||||
|
'usage.table.provider': 'Provider'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
export default {
|
export default {
|
||||||
'usage.title': 'Использование',
|
'usage.title': 'Usage',
|
||||||
'usage.filter.user': 'Фильтр по пользователю',
|
'usage.filter.user': 'Filter by user',
|
||||||
'usage.filter.model': 'Фильтр по модели'
|
'usage.filter.model': 'Filter by model',
|
||||||
|
'usage.filter.apikey': 'Filter by API key',
|
||||||
|
'usage.filter.metric': 'Metric',
|
||||||
|
'usage.filter.groupBy': 'Group by',
|
||||||
|
'usage.filter.group.user': 'User',
|
||||||
|
'usage.filter.group.model': 'Model',
|
||||||
|
'usage.filter.group.apikey': 'API Key',
|
||||||
|
'usage.filter.inputTokens': 'Input Tokens',
|
||||||
|
'usage.filter.outputTokens': 'Output Tokens',
|
||||||
|
'usage.filter.totalTokens': 'Total Tokens',
|
||||||
|
'usage.filter.apiRequests': 'API Requests',
|
||||||
|
'usage.filter.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.apiKeysUsed': 'API Keys Used',
|
||||||
|
'usage.table.lastActive': 'Last Active',
|
||||||
|
'usage.filter.granularity': 'Granularity',
|
||||||
|
'usage.filter.granularity.day': 'Day',
|
||||||
|
'usage.filter.granularity.week': 'Week',
|
||||||
|
'usage.filter.granularity.month': 'Month',
|
||||||
|
'usage.tabs.models': 'Models',
|
||||||
|
'usage.tabs.apikeys': 'API Keys',
|
||||||
|
'usage.tabs.users': 'User',
|
||||||
|
'usage.export.chart': 'Export Chart Data',
|
||||||
|
'usage.export.table': 'Export Table Data',
|
||||||
|
'usage.user.currentAccount': 'Current Account',
|
||||||
|
'usage.table.cluster': 'Cluster',
|
||||||
|
'usage.table.provider': 'Provider'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
export default {
|
export default {
|
||||||
'usage.title': 'Kullanım',
|
'usage.title': 'Usage',
|
||||||
'usage.filter.user': 'Kullanıcıya göre filtrele',
|
'usage.filter.user': 'Filter by user',
|
||||||
'usage.filter.model': 'Modele göre filtrele'
|
'usage.filter.model': 'Filter by model',
|
||||||
|
'usage.filter.apikey': 'Filter by API key',
|
||||||
|
'usage.filter.metric': 'Metric',
|
||||||
|
'usage.filter.groupBy': 'Group by',
|
||||||
|
'usage.filter.group.user': 'User',
|
||||||
|
'usage.filter.group.model': 'Model',
|
||||||
|
'usage.filter.group.apikey': 'API Key',
|
||||||
|
'usage.filter.inputTokens': 'Input Tokens',
|
||||||
|
'usage.filter.outputTokens': 'Output Tokens',
|
||||||
|
'usage.filter.totalTokens': 'Total Tokens',
|
||||||
|
'usage.filter.apiRequests': 'API Requests',
|
||||||
|
'usage.filter.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.modelsUsed': 'Models Used',
|
||||||
|
'usage.table.user.apiKeysUsed': 'API Keys Used',
|
||||||
|
'usage.table.lastActive': 'Last Active',
|
||||||
|
'usage.filter.granularity': 'Granularity',
|
||||||
|
'usage.filter.granularity.day': 'Day',
|
||||||
|
'usage.filter.granularity.week': 'Week',
|
||||||
|
'usage.filter.granularity.month': 'Month',
|
||||||
|
'usage.tabs.models': 'Models',
|
||||||
|
'usage.tabs.apikeys': 'API Keys',
|
||||||
|
'usage.tabs.users': 'User',
|
||||||
|
'usage.export.chart': 'Export Chart Data',
|
||||||
|
'usage.export.table': 'Export Table Data',
|
||||||
|
'usage.user.currentAccount': 'Current Account',
|
||||||
|
'usage.table.cluster': 'Cluster',
|
||||||
|
'usage.table.provider': 'Provider'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
export default {
|
export default {
|
||||||
'usage.title': '使用量',
|
'usage.title': '使用量',
|
||||||
'usage.filter.user': '按用户查询',
|
'usage.filter.user': '按用户查询',
|
||||||
'usage.filter.model': '按模型查询'
|
'usage.filter.model': '按模型查询',
|
||||||
|
'usage.filter.apikey': '按 API 密钥查询',
|
||||||
|
'usage.filter.metric': '指标',
|
||||||
|
'usage.filter.groupBy': '分组',
|
||||||
|
'usage.filter.group.user': '用户',
|
||||||
|
'usage.filter.group.model': '模型',
|
||||||
|
'usage.filter.group.apikey': 'API 密钥',
|
||||||
|
'usage.filter.inputTokens': '输入 Token 数',
|
||||||
|
'usage.filter.outputTokens': '输出 Token 数',
|
||||||
|
'usage.filter.totalTokens': '总 Token 数',
|
||||||
|
'usage.filter.apiRequests': 'API 请求数',
|
||||||
|
'usage.filter.modelsUsed': '使用的模型数',
|
||||||
|
'usage.table.user.modelsUsed': '使用的模型',
|
||||||
|
'usage.table.user.apiKeysUsed': '使用的 API 密钥',
|
||||||
|
'usage.table.lastActive': '最后活跃时间',
|
||||||
|
'usage.filter.granularity': '粒度',
|
||||||
|
'usage.filter.granularity.day': '按天',
|
||||||
|
'usage.filter.granularity.week': '按周',
|
||||||
|
'usage.filter.granularity.month': '按月',
|
||||||
|
'usage.tabs.models': '模型',
|
||||||
|
'usage.tabs.apikeys': 'API 密钥',
|
||||||
|
'usage.tabs.users': '用户',
|
||||||
|
'usage.export.chart': '导出图表数据',
|
||||||
|
'usage.export.table': '导出表格数据',
|
||||||
|
'usage.user.currentAccount': '当前账户',
|
||||||
|
'usage.table.cluster': '集群',
|
||||||
|
'usage.table.provider': '提供商'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import CardWrapper from '@/components/card-wrapper';
|
|||||||
import MixLineBar from '@/components/echarts/mix-line-bar';
|
import MixLineBar from '@/components/echarts/mix-line-bar';
|
||||||
import BaseSelect from '@/components/seal-form/base/select';
|
import BaseSelect from '@/components/seal-form/base/select';
|
||||||
import { baseColorMap } from '@/pages/dashboard/config';
|
import { baseColorMap } from '@/pages/dashboard/config';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
import { Segmented } from 'antd';
|
import { Segmented } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
@@ -42,6 +43,7 @@ const labelFormatter = (v: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
||||||
|
const intl = useIntl();
|
||||||
const {
|
const {
|
||||||
timeSeriesData,
|
timeSeriesData,
|
||||||
metric,
|
metric,
|
||||||
@@ -102,8 +104,15 @@ const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
|||||||
<div className="group">
|
<div className="group">
|
||||||
<BaseSelect
|
<BaseSelect
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
prefix={<ControlLabel>Metric</ControlLabel>}
|
prefix={
|
||||||
options={metricOptions}
|
<ControlLabel>
|
||||||
|
{intl.formatMessage({ id: 'usage.filter.metric' })}
|
||||||
|
</ControlLabel>
|
||||||
|
}
|
||||||
|
options={metricOptions.map((item) => ({
|
||||||
|
label: intl.formatMessage({ id: item.label }),
|
||||||
|
value: item.value
|
||||||
|
}))}
|
||||||
value={metric}
|
value={metric}
|
||||||
popupMatchSelectWidth={false}
|
popupMatchSelectWidth={false}
|
||||||
onChange={onMetricChange}
|
onChange={onMetricChange}
|
||||||
@@ -113,8 +122,15 @@ const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
|||||||
<BaseSelect
|
<BaseSelect
|
||||||
allowClear
|
allowClear
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
prefix={<ControlLabel>Group by</ControlLabel>}
|
prefix={
|
||||||
options={groupByOptions}
|
<ControlLabel>
|
||||||
|
{intl.formatMessage({ id: 'usage.filter.groupBy' })}
|
||||||
|
</ControlLabel>
|
||||||
|
}
|
||||||
|
options={groupByOptions.map((item) => ({
|
||||||
|
label: intl.formatMessage({ id: item.label }),
|
||||||
|
value: item.value
|
||||||
|
}))}
|
||||||
value={groupBy}
|
value={groupBy}
|
||||||
popupMatchSelectWidth={false}
|
popupMatchSelectWidth={false}
|
||||||
onChange={handleOnGroupByChange}
|
onChange={handleOnGroupByChange}
|
||||||
@@ -123,7 +139,10 @@ const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<Segmented
|
<Segmented
|
||||||
size="small"
|
size="small"
|
||||||
options={granularities}
|
options={granularities.map((item) => ({
|
||||||
|
label: intl.formatMessage({ id: item.label }),
|
||||||
|
value: item.value
|
||||||
|
}))}
|
||||||
value={granularity}
|
value={granularity}
|
||||||
onChange={onGranularityChange}
|
onChange={onGranularityChange}
|
||||||
></Segmented>
|
></Segmented>
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ const ExportData: React.FC<{
|
|||||||
activeModels: ValueType[][];
|
activeModels: ValueType[][];
|
||||||
activeApiKeys: ValueType[][];
|
activeApiKeys: ValueType[][];
|
||||||
};
|
};
|
||||||
|
commonFilters: {
|
||||||
|
scope: string;
|
||||||
|
start_date: string;
|
||||||
|
end_date: string;
|
||||||
|
models: string[];
|
||||||
|
users: string[];
|
||||||
|
api_keys: string[];
|
||||||
|
};
|
||||||
|
|
||||||
handlePickerChange: (picker: DateType) => void;
|
handlePickerChange: (picker: DateType) => void;
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
@@ -54,6 +62,8 @@ const ExportData: React.FC<{
|
|||||||
key: 'exportTableData'
|
key: 'exportTableData'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('initialState========', initialState);
|
||||||
|
|
||||||
const { filters, commonFilters, filterBar } = useUsageFilters({
|
const { filters, commonFilters, filterBar } = useUsageFilters({
|
||||||
initialScope: initialScope,
|
initialScope: initialScope,
|
||||||
metaData,
|
metaData,
|
||||||
@@ -102,7 +112,7 @@ const ExportData: React.FC<{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Cluster',
|
title: intl.formatMessage({ id: 'usage.table.cluster' }),
|
||||||
dataIndex: ['model', 'identity', 'value', 'cluster_name'],
|
dataIndex: ['model', 'identity', 'value', 'cluster_name'],
|
||||||
render: (text: string) => {
|
render: (text: string) => {
|
||||||
return <AutoTooltip ghost>{text}</AutoTooltip>;
|
return <AutoTooltip ghost>{text}</AutoTooltip>;
|
||||||
@@ -129,26 +139,26 @@ const ExportData: React.FC<{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Key',
|
title: intl.formatMessage({ id: 'usage.filter.group.apikey' }),
|
||||||
dataIndex: ['api_key', 'label'],
|
dataIndex: ['api_key', 'label'],
|
||||||
render: (text: string, record: any) => {
|
render: (text: string, record: any) => {
|
||||||
return <AutoTooltip ghost>{text}</AutoTooltip>;
|
return <AutoTooltip ghost>{text}</AutoTooltip>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Input Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
dataIndex: 'input_tokens'
|
dataIndex: 'input_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Output Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
dataIndex: 'output_tokens'
|
dataIndex: 'output_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
dataIndex: 'total_tokens'
|
dataIndex: 'total_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Requests',
|
title: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
dataIndex: 'api_requests'
|
dataIndex: 'api_requests'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -183,13 +193,19 @@ const ExportData: React.FC<{
|
|||||||
fieldLabels: {
|
fieldLabels: {
|
||||||
date: intl.formatMessage({ id: 'dashboard.usage.export.date' }),
|
date: intl.formatMessage({ id: 'dashboard.usage.export.date' }),
|
||||||
user: intl.formatMessage({ id: 'dashboard.usage.export.user' }),
|
user: intl.formatMessage({ id: 'dashboard.usage.export.user' }),
|
||||||
cluster: 'Cluster',
|
cluster: intl.formatMessage({ id: 'usage.table.cluster' }),
|
||||||
model: intl.formatMessage({ id: 'dashboard.usage.export.model' }),
|
model: intl.formatMessage({ id: 'dashboard.usage.export.model' }),
|
||||||
api_key: 'API Key',
|
api_key: intl.formatMessage({ id: 'usage.table.provider' }),
|
||||||
input_tokens: 'Input Tokens',
|
input_tokens: intl.formatMessage({
|
||||||
output_tokens: 'Output Tokens',
|
id: 'usage.filter.inputTokens'
|
||||||
total_tokens: 'Total Tokens',
|
}),
|
||||||
api_requests: 'API Requests'
|
output_tokens: intl.formatMessage({
|
||||||
|
id: 'usage.filter.outputTokens'
|
||||||
|
}),
|
||||||
|
total_tokens: intl.formatMessage({
|
||||||
|
id: 'usage.filter.totalTokens'
|
||||||
|
}),
|
||||||
|
api_requests: intl.formatMessage({ id: 'usage.filter.apiRequests' })
|
||||||
},
|
},
|
||||||
formatMap: {}
|
formatMap: {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,16 +36,28 @@ interface FilterBarProps {
|
|||||||
modelOptions: GroupOption<UsageFilterItem>[];
|
modelOptions: GroupOption<UsageFilterItem>[];
|
||||||
userOptions: OptionType[];
|
userOptions: OptionType[];
|
||||||
apiKeyOptions: GroupOption<UsageFilterItem>[];
|
apiKeyOptions: GroupOption<UsageFilterItem>[];
|
||||||
|
activeModels: valueType[][];
|
||||||
|
activeApiKeys: valueType[][];
|
||||||
handlePickerChange: (picker: DateType) => void;
|
handlePickerChange: (picker: DateType) => void;
|
||||||
onScopeChange: (value: string) => void;
|
onScopeChange: (value: string) => void;
|
||||||
onDateChange: (dates: any, dateStrings: [string, string]) => void;
|
onDateChange: (dates: any, dateStrings: [string, string]) => void;
|
||||||
onModelsChange: (value: string[]) => void;
|
onModelsChange: (value: string[]) => void;
|
||||||
onUsersChange: (value: string[]) => void;
|
onUsersChange: (value: string[]) => void;
|
||||||
onApiKeysChange: (value: string[]) => void;
|
onApiKeysChange: (value: string[]) => void;
|
||||||
|
handleActiveModelsChange: (value: valueType[][]) => void;
|
||||||
|
handleActiveApiKeysChange: (value: valueType[][]) => void;
|
||||||
onExport?: () => void;
|
onExport?: () => void;
|
||||||
handleSearch?: () => void;
|
handleSearch?: () => void;
|
||||||
onExportChart?: () => void;
|
onExportChart?: () => void;
|
||||||
onExportTable?: () => void;
|
onExportTable?: () => void;
|
||||||
|
commonFilters?: {
|
||||||
|
scope: string;
|
||||||
|
start_date: string;
|
||||||
|
end_date: string;
|
||||||
|
models: string[];
|
||||||
|
users: string[];
|
||||||
|
api_keys: string[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterBar: React.FC<FilterBarProps> = (props) => {
|
const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||||
@@ -58,6 +70,10 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
modelOptions,
|
modelOptions,
|
||||||
userOptions,
|
userOptions,
|
||||||
apiKeyOptions,
|
apiKeyOptions,
|
||||||
|
activeModels,
|
||||||
|
activeApiKeys,
|
||||||
|
handleActiveModelsChange,
|
||||||
|
handleActiveApiKeysChange,
|
||||||
handlePickerChange,
|
handlePickerChange,
|
||||||
onDateChange,
|
onDateChange,
|
||||||
onModelsChange,
|
onModelsChange,
|
||||||
@@ -104,8 +120,8 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const [activeModels, setActiveModels] = React.useState<valueType[][]>([]);
|
// const [activeModels, setActiveModels] = React.useState<valueType[][]>([]);
|
||||||
const [activeApiKeys, setActiveApiKeys] = React.useState<valueType[][]>([]);
|
// const [activeApiKeys, setActiveApiKeys] = React.useState<valueType[][]>([]);
|
||||||
|
|
||||||
const initialInfo = useModel('@@initialState');
|
const initialInfo = useModel('@@initialState');
|
||||||
const { initialState } = initialInfo || {};
|
const { initialState } = initialInfo || {};
|
||||||
@@ -116,7 +132,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
label: (
|
label: (
|
||||||
<span className="flex-center gap-8">
|
<span className="flex-center gap-8">
|
||||||
<IconFont type="icon-chart-01" style={{ fontSize: 14 }} />
|
<IconFont type="icon-chart-01" style={{ fontSize: 14 }} />
|
||||||
<span>Export Chart Data</span>
|
<span>{intl.formatMessage({ id: 'usage.export.chart' })}</span>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
onClick: onExportChart
|
onClick: onExportChart
|
||||||
@@ -126,7 +142,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
label: (
|
label: (
|
||||||
<span className="flex-center gap-8">
|
<span className="flex-center gap-8">
|
||||||
<IconFont type="icon-table" style={{ fontSize: 14 }} />
|
<IconFont type="icon-table" style={{ fontSize: 14 }} />
|
||||||
<span>Export Table Data</span>
|
<span>{intl.formatMessage({ id: 'usage.export.table' })}</span>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
onClick: onExportTable
|
onClick: onExportTable
|
||||||
@@ -134,13 +150,14 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const handleOnModelsChange = (value: valueType[][], selectedOptions: any) => {
|
const handleOnModelsChange = (value: valueType[][], selectedOptions: any) => {
|
||||||
setActiveModels(value);
|
// setActiveModels(value);
|
||||||
const selectedValues: string[] = value.map((item) => {
|
const selectedValues: string[] = value.map((item) => {
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item)) {
|
||||||
return item[item.length - 1] as string; // Get the last value in the array
|
return item[item.length - 1] as string; // Get the last value in the array
|
||||||
}
|
}
|
||||||
return item as string;
|
return item as string;
|
||||||
});
|
});
|
||||||
|
handleActiveModelsChange(value);
|
||||||
onModelsChange(selectedValues);
|
onModelsChange(selectedValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -148,13 +165,14 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
value: valueType[][],
|
value: valueType[][],
|
||||||
selectedOptions: any
|
selectedOptions: any
|
||||||
) => {
|
) => {
|
||||||
setActiveApiKeys(value);
|
// setActiveApiKeys(value);
|
||||||
const selectedValues: string[] = value.map((item) => {
|
const selectedValues: string[] = value.map((item) => {
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item)) {
|
||||||
return item[item.length - 1] as string; // Get the last value in the array
|
return item[item.length - 1] as string; // Get the last value in the array
|
||||||
}
|
}
|
||||||
return item as string;
|
return item as string;
|
||||||
});
|
});
|
||||||
|
handleActiveApiKeysChange(value);
|
||||||
onApiKeysChange(selectedValues);
|
onApiKeysChange(selectedValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -254,7 +272,10 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
<span className="flex-center gap-8">
|
<span className="flex-center gap-8">
|
||||||
<span>{data.label}</span>
|
<span>{data.label}</span>
|
||||||
{data.isCurrent && (
|
{data.isCurrent && (
|
||||||
<span className="text-tertiary"> [Current Account]</span>
|
<span className="text-tertiary">
|
||||||
|
{' '}
|
||||||
|
[{intl.formatMessage({ id: 'usage.user.currentAccount' })}]
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@@ -312,7 +333,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
}}
|
}}
|
||||||
maxTagCount={1}
|
maxTagCount={1}
|
||||||
size="small"
|
size="small"
|
||||||
placeholder={'Filter by model'}
|
placeholder={intl.formatMessage({ id: 'usage.filter.model' })}
|
||||||
options={modelOptions}
|
options={modelOptions}
|
||||||
showCheckedStrategy="SHOW_CHILD"
|
showCheckedStrategy="SHOW_CHILD"
|
||||||
displayRender={displayRender}
|
displayRender={displayRender}
|
||||||
@@ -329,7 +350,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
showSearch
|
showSearch
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
options={userOptions}
|
options={userOptions}
|
||||||
placeholder="Filter by user"
|
placeholder={intl.formatMessage({ id: 'usage.filter.user' })}
|
||||||
styles={{
|
styles={{
|
||||||
wrapper: { flex: 1, maxWidth: 240, minWidth: 150 }
|
wrapper: { flex: 1, maxWidth: 240, minWidth: 150 }
|
||||||
}}
|
}}
|
||||||
@@ -367,7 +388,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
}}
|
}}
|
||||||
maxTagCount={1}
|
maxTagCount={1}
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="Filter by API key"
|
placeholder={intl.formatMessage({ id: 'usage.filter.apikey' })}
|
||||||
options={apiKeyOptions}
|
options={apiKeyOptions}
|
||||||
showCheckedStrategy="SHOW_CHILD"
|
showCheckedStrategy="SHOW_CHILD"
|
||||||
value={activeApiKeys}
|
value={activeApiKeys}
|
||||||
@@ -384,7 +405,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
mode="multiple"
|
mode="multiple"
|
||||||
options={apiKeyOptions?.[0]?.children || []}
|
options={apiKeyOptions?.[0]?.children || []}
|
||||||
maxTagCount={0}
|
maxTagCount={0}
|
||||||
placeholder="Filter by API key"
|
placeholder={intl.formatMessage({ id: 'usage.filter.apikey' })}
|
||||||
styles={{
|
styles={{
|
||||||
wrapper: { flex: 1, maxWidth: 240, minWidth: 100 }
|
wrapper: { flex: 1, maxWidth: 240, minWidth: 100 }
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -7,60 +7,49 @@ export const groupByOptions = [
|
|||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
value: 'model',
|
value: 'model',
|
||||||
label: 'Model'
|
label: 'usage.filter.group.model'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'user',
|
value: 'user',
|
||||||
label: 'User'
|
label: 'usage.filter.group.user'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'api_key',
|
value: 'api_key',
|
||||||
label: 'API Key'
|
label: 'usage.filter.group.apikey'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export const granularities = [
|
export const granularities = [
|
||||||
{
|
{
|
||||||
value: 'day',
|
value: 'day',
|
||||||
label: 'Day'
|
label: 'usage.filter.granularity.day'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'week',
|
value: 'week',
|
||||||
label: 'Week'
|
label: 'usage.filter.granularity.week'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'month',
|
value: 'month',
|
||||||
label: 'Month'
|
label: 'usage.filter.granularity.month'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export const metricOptions = [
|
export const metricOptions = [
|
||||||
{
|
{
|
||||||
value: 'input_tokens',
|
value: 'input_tokens',
|
||||||
label: 'Input Tokens'
|
label: 'usage.filter.inputTokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'output_tokens',
|
value: 'output_tokens',
|
||||||
label: 'Output Tokens'
|
label: 'usage.filter.outputTokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'total_tokens',
|
value: 'total_tokens',
|
||||||
label: 'Total Tokens'
|
label: 'usage.filter.totalTokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'api_requests',
|
value: 'api_requests',
|
||||||
label: 'API Requests'
|
label: 'usage.filter.apiRequests'
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export const scopeOptions = [
|
|
||||||
{
|
|
||||||
value: 'all',
|
|
||||||
label: 'All Users'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'self',
|
|
||||||
label: 'My Usage'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'User',
|
title: intl.formatMessage({ id: 'usage.tabs.users' }),
|
||||||
dataIndex: ['api_key', 'identity', 'value', 'user_name'],
|
dataIndex: ['api_key', 'identity', 'value', 'user_name'],
|
||||||
key: 'user_name',
|
key: 'user_name',
|
||||||
render: (text: string, record: ListItem) => (
|
render: (text: string, record: ListItem) => (
|
||||||
@@ -38,7 +38,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Models Used',
|
title: intl.formatMessage({ id: 'usage.filter.modelsUsed' }),
|
||||||
dataIndex: 'models_called',
|
dataIndex: 'models_called',
|
||||||
key: 'models_called',
|
key: 'models_called',
|
||||||
sorter: tableSorter(2),
|
sorter: tableSorter(2),
|
||||||
@@ -47,7 +47,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Input Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
dataIndex: 'input_tokens',
|
dataIndex: 'input_tokens',
|
||||||
key: 'input_tokens',
|
key: 'input_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -55,7 +55,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Output Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
dataIndex: 'output_tokens',
|
dataIndex: 'output_tokens',
|
||||||
key: 'output_tokens',
|
key: 'output_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -63,7 +63,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
dataIndex: 'total_tokens',
|
dataIndex: 'total_tokens',
|
||||||
key: 'total_tokens',
|
key: 'total_tokens',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -73,7 +73,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Requests',
|
title: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
dataIndex: 'api_requests',
|
dataIndex: 'api_requests',
|
||||||
key: 'api_requests',
|
key: 'api_requests',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -83,7 +83,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Last Active',
|
title: intl.formatMessage({ id: 'usage.table.lastActive' }),
|
||||||
dataIndex: 'last_active',
|
dataIndex: 'last_active',
|
||||||
key: 'last_active',
|
key: 'last_active',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
} from '@/atoms/usage';
|
} from '@/atoms/usage';
|
||||||
import { exportJsonToExcel } from '@/utils/excel-reader';
|
import { exportJsonToExcel } from '@/utils/excel-reader';
|
||||||
import { useStore } from 'jotai';
|
import { useStore } from 'jotai';
|
||||||
|
import _ from 'lodash';
|
||||||
import useAPIKeysColumns from './use-apikeys-columns';
|
import useAPIKeysColumns from './use-apikeys-columns';
|
||||||
import useModelsColumns from './use-models-columns';
|
import useModelsColumns from './use-models-columns';
|
||||||
import useUsersColumns from './use-users-columns';
|
import useUsersColumns from './use-users-columns';
|
||||||
@@ -26,11 +27,11 @@ const useExportTable = () => {
|
|||||||
jsonData: modelsTableData.dataList || [],
|
jsonData: modelsTableData.dataList || [],
|
||||||
sheetName: 'models',
|
sheetName: 'models',
|
||||||
fields: modelsColumns
|
fields: modelsColumns
|
||||||
.map((col: any) => col.dataIndex)
|
.map((col: any) => _.join(col.dataIndex, '_'))
|
||||||
.filter(Boolean) as string[],
|
.filter(Boolean) as string[],
|
||||||
fieldLabels: modelsColumns.reduce(
|
fieldLabels: modelsColumns.reduce(
|
||||||
(map, col) => {
|
(map, col) => {
|
||||||
map[col.dataIndex] = col.title;
|
map[_.join(col.dataIndex, '_')] = col.title;
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
{} as Record<string, any>
|
{} as Record<string, any>
|
||||||
@@ -45,7 +46,7 @@ const useExportTable = () => {
|
|||||||
.filter(Boolean) as string[],
|
.filter(Boolean) as string[],
|
||||||
fieldLabels: apiKeysColumns.reduce(
|
fieldLabels: apiKeysColumns.reduce(
|
||||||
(map, col) => {
|
(map, col) => {
|
||||||
map[col.dataIndex] = col.title;
|
map[_.join(col.dataIndex, '_')] = col.title;
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
{} as Record<string, any>
|
{} as Record<string, any>
|
||||||
@@ -60,7 +61,7 @@ const useExportTable = () => {
|
|||||||
.filter(Boolean) as string[],
|
.filter(Boolean) as string[],
|
||||||
fieldLabels: usersColumns.reduce(
|
fieldLabels: usersColumns.reduce(
|
||||||
(map, col) => {
|
(map, col) => {
|
||||||
map[col.dataIndex] = col.title;
|
map[_.join(col.dataIndex, '_')] = col.title;
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
{} as Record<string, any>
|
{} as Record<string, any>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Cluster',
|
title: intl.formatMessage({ id: 'usage.table.cluster' }),
|
||||||
dataIndex: ['model', 'identity', 'value', 'cluster_name'],
|
dataIndex: ['model', 'identity', 'value', 'cluster_name'],
|
||||||
key: 'cluster_name',
|
key: 'cluster_name',
|
||||||
sorter: tableSorter(2),
|
sorter: tableSorter(2),
|
||||||
@@ -42,7 +42,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Provider',
|
title: intl.formatMessage({ id: 'usage.table.provider' }),
|
||||||
dataIndex: 'provider_name',
|
dataIndex: 'provider_name',
|
||||||
key: 'provider_name',
|
key: 'provider_name',
|
||||||
render: (text: string, record: ListItem) => (
|
render: (text: string, record: ListItem) => (
|
||||||
@@ -57,7 +57,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Input Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
dataIndex: 'input_tokens',
|
dataIndex: 'input_tokens',
|
||||||
key: 'input_tokens',
|
key: 'input_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -65,7 +65,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Output Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
dataIndex: 'output_tokens',
|
dataIndex: 'output_tokens',
|
||||||
key: 'output_tokens',
|
key: 'output_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -73,7 +73,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
dataIndex: 'total_tokens',
|
dataIndex: 'total_tokens',
|
||||||
key: 'total_tokens',
|
key: 'total_tokens',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -83,7 +83,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Requests',
|
title: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
dataIndex: 'api_requests',
|
dataIndex: 'api_requests',
|
||||||
key: 'api_requests',
|
key: 'api_requests',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -93,7 +93,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Last Active',
|
title: intl.formatMessage({ id: 'usage.table.lastActive' }),
|
||||||
dataIndex: 'last_active',
|
dataIndex: 'last_active',
|
||||||
key: 'last_active',
|
key: 'last_active',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
|
|||||||
@@ -184,6 +184,14 @@ export const useUsageFilters = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleActiveModelsChange = (value: ValueType[][]) => {
|
||||||
|
setActiveModels(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleActiveApiKeysChange = (value: ValueType[][]) => {
|
||||||
|
setActiveApiKeys(value);
|
||||||
|
};
|
||||||
|
|
||||||
const handleFilterChange = (
|
const handleFilterChange = (
|
||||||
type: 'models' | 'users' | 'api_keys',
|
type: 'models' | 'users' | 'api_keys',
|
||||||
value: string[]
|
value: string[]
|
||||||
@@ -248,6 +256,8 @@ export const useUsageFilters = ({
|
|||||||
activeApiKeys,
|
activeApiKeys,
|
||||||
activeModels,
|
activeModels,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
|
handleActiveModelsChange,
|
||||||
|
handleActiveApiKeysChange,
|
||||||
onScopeChange: handleScopeChange,
|
onScopeChange: handleScopeChange,
|
||||||
onDateChange: handleDateChange,
|
onDateChange: handleDateChange,
|
||||||
onModelsChange: (value: string[]) => handleFilterChange('models', value),
|
onModelsChange: (value: string[]) => handleFilterChange('models', value),
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Models Used',
|
title: intl.formatMessage({ id: 'usage.filter.modelsUsed' }),
|
||||||
dataIndex: 'models_called',
|
dataIndex: 'models_called',
|
||||||
key: 'models_called',
|
key: 'models_called',
|
||||||
render: (text: string, record: ListItem) => (
|
render: (text: string, record: ListItem) => (
|
||||||
@@ -42,7 +42,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Keys Used',
|
title: intl.formatMessage({ id: 'usage.table.user.apiKeysUsed' }),
|
||||||
dataIndex: 'api_keys_used',
|
dataIndex: 'api_keys_used',
|
||||||
key: 'api_keys_used',
|
key: 'api_keys_used',
|
||||||
sorter: tableSorter(2),
|
sorter: tableSorter(2),
|
||||||
@@ -51,7 +51,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Input Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
dataIndex: 'input_tokens',
|
dataIndex: 'input_tokens',
|
||||||
key: 'input_tokens',
|
key: 'input_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -59,7 +59,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Output Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
dataIndex: 'output_tokens',
|
dataIndex: 'output_tokens',
|
||||||
key: 'output_tokens',
|
key: 'output_tokens',
|
||||||
render: (text: string[], record: ListItem) => (
|
render: (text: string[], record: ListItem) => (
|
||||||
@@ -67,7 +67,7 @@ const useModelsColumns = (): Array<{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
dataIndex: 'total_tokens',
|
dataIndex: 'total_tokens',
|
||||||
key: 'total_tokens',
|
key: 'total_tokens',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -77,7 +77,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Requests',
|
title: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
dataIndex: 'api_requests',
|
dataIndex: 'api_requests',
|
||||||
key: 'api_requests',
|
key: 'api_requests',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
@@ -87,7 +87,7 @@ const useModelsColumns = (): Array<{
|
|||||||
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
render: (text: number) => <AutoTooltip ghost>{text}</AutoTooltip>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Last Active',
|
title: intl.formatMessage({ id: 'usage.table.lastActive' }),
|
||||||
dataIndex: 'last_active',
|
dataIndex: 'last_active',
|
||||||
key: 'last_active',
|
key: 'last_active',
|
||||||
sorter: tableSorter(3),
|
sorter: tableSorter(3),
|
||||||
|
|||||||
+16
-12
@@ -2,6 +2,7 @@ import { SimpleCard } from '@/components/card-wrapper/simple-card';
|
|||||||
import { baseColorMap } from '@/pages/dashboard/config';
|
import { baseColorMap } from '@/pages/dashboard/config';
|
||||||
import { formatLargeNumber } from '@/utils';
|
import { formatLargeNumber } from '@/utils';
|
||||||
import { useModel } from '@@/plugin-model';
|
import { useModel } from '@@/plugin-model';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import BreakdownTabs from './components/breakdown-tabs';
|
import BreakdownTabs from './components/breakdown-tabs';
|
||||||
import DailyUsage from './components/daily-usage';
|
import DailyUsage from './components/daily-usage';
|
||||||
@@ -14,6 +15,7 @@ import useQueryUsageMetaData from './services/use-query-meta-data';
|
|||||||
type DateType = 'date' | 'week' | 'month' | 'quarter' | 'year';
|
type DateType = 'date' | 'week' | 'month' | 'quarter' | 'year';
|
||||||
|
|
||||||
const Usage: React.FC = () => {
|
const Usage: React.FC = () => {
|
||||||
|
const intl = useIntl();
|
||||||
const initialInfo = useModel('@@initialState');
|
const initialInfo = useModel('@@initialState');
|
||||||
const { initialState } = initialInfo || {};
|
const { initialState } = initialInfo || {};
|
||||||
const { exportTable } = useExportTable();
|
const { exportTable } = useExportTable();
|
||||||
@@ -22,27 +24,27 @@ const Usage: React.FC = () => {
|
|||||||
|
|
||||||
const summaryColumns = [
|
const summaryColumns = [
|
||||||
{
|
{
|
||||||
title: 'Input Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
dataIndex: 'input_tokens',
|
dataIndex: 'input_tokens',
|
||||||
key: 'input_tokens'
|
key: 'input_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Output Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
dataIndex: 'output_tokens',
|
dataIndex: 'output_tokens',
|
||||||
key: 'output_tokens'
|
key: 'output_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total Tokens',
|
title: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
dataIndex: 'total_tokens',
|
dataIndex: 'total_tokens',
|
||||||
key: 'total_tokens'
|
key: 'total_tokens'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API Requests',
|
title: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
dataIndex: 'api_requests',
|
dataIndex: 'api_requests',
|
||||||
key: 'api_requests'
|
key: 'api_requests'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Models Used',
|
title: intl.formatMessage({ id: 'usage.filter.modelsUsed' }),
|
||||||
dataIndex: 'models_called',
|
dataIndex: 'models_called',
|
||||||
key: 'models_called'
|
key: 'models_called'
|
||||||
}
|
}
|
||||||
@@ -90,31 +92,31 @@ const Usage: React.FC = () => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: formatLargeNumber(summary.input_tokens) as string,
|
label: formatLargeNumber(summary.input_tokens) as string,
|
||||||
value: 'Input tokens',
|
value: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
|
||||||
color: baseColorMap.baseR3
|
color: baseColorMap.baseR3
|
||||||
// iconType: 'roundRect'
|
// iconType: 'roundRect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatLargeNumber(summary.output_tokens) as string,
|
label: formatLargeNumber(summary.output_tokens) as string,
|
||||||
value: 'Output tokens',
|
value: intl.formatMessage({ id: 'usage.filter.outputTokens' }),
|
||||||
color: baseColorMap.base
|
color: baseColorMap.base
|
||||||
// iconType: 'roundRect'
|
// iconType: 'roundRect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatLargeNumber(summary.total_tokens) as string,
|
label: formatLargeNumber(summary.total_tokens) as string,
|
||||||
value: 'Total tokens',
|
value: intl.formatMessage({ id: 'usage.filter.totalTokens' }),
|
||||||
color: baseColorMap.baseL1
|
color: baseColorMap.baseL1
|
||||||
// iconType: 'roundRect'
|
// iconType: 'roundRect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatLargeNumber(summary.api_requests) as string,
|
label: formatLargeNumber(summary.api_requests) as string,
|
||||||
value: 'API requests',
|
value: intl.formatMessage({ id: 'usage.filter.apiRequests' }),
|
||||||
color: baseColorMap.baseR1
|
color: baseColorMap.baseR1
|
||||||
// iconType: 'circle'
|
// iconType: 'circle'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: summary.models_called.toString(),
|
label: summary.models_called.toString(),
|
||||||
value: 'Models used',
|
value: intl.formatMessage({ id: 'usage.filter.modelsUsed' }),
|
||||||
color: baseColorMap.baseR2
|
color: baseColorMap.baseR2
|
||||||
// iconType: 'roundRect'
|
// iconType: 'roundRect'
|
||||||
}
|
}
|
||||||
@@ -176,7 +178,9 @@ const Usage: React.FC = () => {
|
|||||||
groupBy={chartFilters.group_by}
|
groupBy={chartFilters.group_by}
|
||||||
granularity={chartFilters.granularity}
|
granularity={chartFilters.granularity}
|
||||||
onMetricChange={(value) => handleChartFilterChange('metric', value)}
|
onMetricChange={(value) => handleChartFilterChange('metric', value)}
|
||||||
onGroupByChange={(value) => handleChartFilterChange('group_by', value)}
|
onGroupByChange={(value) =>
|
||||||
|
handleChartFilterChange('group_by', value as string)
|
||||||
|
}
|
||||||
onGranularityChange={(value) =>
|
onGranularityChange={(value) =>
|
||||||
handleChartFilterChange('granularity', value)
|
handleChartFilterChange('granularity', value)
|
||||||
}
|
}
|
||||||
@@ -191,7 +195,7 @@ const Usage: React.FC = () => {
|
|||||||
metaData={metaData}
|
metaData={metaData}
|
||||||
granularity={chartFilters.granularity}
|
granularity={chartFilters.granularity}
|
||||||
initialScope={commonFilters.scope}
|
initialScope={commonFilters.scope}
|
||||||
initialCommonFilters={commonFilters}
|
commonFilters={commonFilters}
|
||||||
open={openExportModal}
|
open={openExportModal}
|
||||||
handlePickerChange={handlePickerChange}
|
handlePickerChange={handlePickerChange}
|
||||||
onCancel={() => setOpenExportModal(false)}
|
onCancel={() => setOpenExportModal(false)}
|
||||||
|
|||||||
Reference in New Issue
Block a user