mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-17 01:06:37 +08:00
feat: i18n support
This commit is contained in:
parent
b7f008cd72
commit
e183e3b9b0
@ -292,16 +292,43 @@
|
||||
},
|
||||
"log": {
|
||||
"title": "Operation Log",
|
||||
"search": "Search logs...",
|
||||
"usage_details": "Usage Details",
|
||||
"total_quota": "Total Quota Used",
|
||||
"click_to_view": "Click to View",
|
||||
"type": {
|
||||
"select": "Select Log Type",
|
||||
"all": "All",
|
||||
"topup": "Top Up",
|
||||
"usage": "Usage",
|
||||
"admin": "Admin",
|
||||
"system": "System",
|
||||
"test": "Test"
|
||||
},
|
||||
"table": {
|
||||
"id": "ID",
|
||||
"username": "Username",
|
||||
"time": "Time",
|
||||
"channel": "Channel",
|
||||
"type": "Type",
|
||||
"content": "Content",
|
||||
"amount": "Amount",
|
||||
"time": "Time"
|
||||
"model": "Model",
|
||||
"username": "Username",
|
||||
"token_name": "Token Name",
|
||||
"token_name_placeholder": "Optional",
|
||||
"model_name": "Model Name",
|
||||
"model_name_placeholder": "Optional",
|
||||
"start_time": "Start Time",
|
||||
"end_time": "End Time",
|
||||
"channel_id": "Channel ID",
|
||||
"channel_id_placeholder": "Optional",
|
||||
"username_placeholder": "Optional",
|
||||
"prompt_tokens": "Prompt Tokens",
|
||||
"completion_tokens": "Completion Tokens",
|
||||
"quota": "Quota",
|
||||
"detail": "Detail"
|
||||
},
|
||||
"buttons": {
|
||||
"query": "Action",
|
||||
"submit": "Query",
|
||||
"refresh": "Refresh"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
|
@ -292,16 +292,43 @@
|
||||
},
|
||||
"log": {
|
||||
"title": "操作日志",
|
||||
"search": "搜索日志...",
|
||||
"usage_details": "使用明细",
|
||||
"total_quota": "总消耗额度",
|
||||
"click_to_view": "点击查看",
|
||||
"type": {
|
||||
"select": "选择明细分类",
|
||||
"all": "全部",
|
||||
"topup": "充值",
|
||||
"usage": "消费",
|
||||
"admin": "管理",
|
||||
"system": "系统",
|
||||
"test": "测试"
|
||||
},
|
||||
"table": {
|
||||
"id": "ID",
|
||||
"username": "用户名",
|
||||
"time": "时间",
|
||||
"channel": "渠道",
|
||||
"type": "类型",
|
||||
"content": "内容",
|
||||
"amount": "数量",
|
||||
"time": "时间"
|
||||
"model": "模型",
|
||||
"username": "用户名",
|
||||
"token_name": "令牌名称",
|
||||
"token_name_placeholder": "可选值",
|
||||
"model_name": "模型名称",
|
||||
"model_name_placeholder": "可选值",
|
||||
"start_time": "起始时间",
|
||||
"end_time": "结束时间",
|
||||
"channel_id": "渠道 ID",
|
||||
"channel_id_placeholder": "可选值",
|
||||
"username_placeholder": "可选值",
|
||||
"prompt_tokens": "提示词消耗",
|
||||
"completion_tokens": "补全消耗",
|
||||
"quota": "额度",
|
||||
"detail": "详情"
|
||||
},
|
||||
"buttons": {
|
||||
"query": "操作",
|
||||
"submit": "查询",
|
||||
"refresh": "刷新"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
Segment,
|
||||
Select,
|
||||
Table,
|
||||
Popup,
|
||||
} from 'semantic-ui-react';
|
||||
import {
|
||||
API,
|
||||
@ -46,15 +47,6 @@ const MODE_OPTIONS = [
|
||||
{ key: 'self', text: '当前用户', value: 'self' },
|
||||
];
|
||||
|
||||
const LOG_OPTIONS = [
|
||||
{ key: '0', text: '全部', value: 0 },
|
||||
{ key: '1', text: '充值', value: 1 },
|
||||
{ key: '2', text: '消费', value: 2 },
|
||||
{ key: '3', text: '管理', value: 3 },
|
||||
{ key: '4', text: '系统', value: 4 },
|
||||
{ key: '5', text: '测试', value: 5 },
|
||||
];
|
||||
|
||||
function renderType(type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
@ -170,6 +162,15 @@ const LogsTable = () => {
|
||||
token: 0,
|
||||
});
|
||||
|
||||
const LOG_OPTIONS = [
|
||||
{ key: '0', text: t('log.type.all'), value: 0 },
|
||||
{ key: '1', text: t('log.type.topup'), value: 1 },
|
||||
{ key: '2', text: t('log.type.usage'), value: 2 },
|
||||
{ key: '3', text: t('log.type.admin'), value: 3 },
|
||||
{ key: '4', text: t('log.type.system'), value: 4 },
|
||||
{ key: '5', text: t('log.type.test'), value: 5 },
|
||||
];
|
||||
|
||||
const handleInputChange = (e, { name, value }) => {
|
||||
setInputs((inputs) => ({ ...inputs, [name]: value }));
|
||||
};
|
||||
@ -309,296 +310,295 @@ const LogsTable = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<>
|
||||
<Header as='h3'>
|
||||
{t('log.usage_details')}({t('log.total_quota')}:
|
||||
{showStat && renderQuota(stat.quota, t)}
|
||||
{!showStat && (
|
||||
<span
|
||||
onClick={handleEyeClick}
|
||||
style={{ cursor: 'pointer', color: 'gray' }}
|
||||
>
|
||||
{t('log.click_to_view')}
|
||||
</span>
|
||||
)}
|
||||
)
|
||||
</Header>
|
||||
<Form>
|
||||
<Form.Group>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={'令牌名称'}
|
||||
width={3}
|
||||
value={token_name}
|
||||
placeholder={'可选值'}
|
||||
name='token_name'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label='模型名称'
|
||||
width={3}
|
||||
value={model_name}
|
||||
placeholder='可选值'
|
||||
name='model_name'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label='起始时间'
|
||||
width={4}
|
||||
value={start_timestamp}
|
||||
type='datetime-local'
|
||||
name='start_timestamp'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label='结束时间'
|
||||
width={4}
|
||||
value={end_timestamp}
|
||||
type='datetime-local'
|
||||
name='end_timestamp'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Button fluid label='操作' width={2} onClick={refresh}>
|
||||
查询
|
||||
</Form.Button>
|
||||
</Form.Group>
|
||||
{isAdminUser && (
|
||||
<>
|
||||
<Form.Group>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={'渠道 ID'}
|
||||
width={3}
|
||||
value={channel}
|
||||
placeholder='可选值'
|
||||
name='channel'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={'用户名称'}
|
||||
width={3}
|
||||
value={username}
|
||||
placeholder={'可选值'}
|
||||
name='username'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
<Table basic={'very'} compact size='small'>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('created_time');
|
||||
}}
|
||||
<Header as='h3'>
|
||||
{t('log.usage_details')}({t('log.total_quota')}:
|
||||
{showStat && renderQuota(stat.quota, t)}
|
||||
{!showStat && (
|
||||
<span
|
||||
onClick={handleEyeClick}
|
||||
style={{ cursor: 'pointer', color: 'gray' }}
|
||||
>
|
||||
{t('log.click_to_view')}
|
||||
</span>
|
||||
)}
|
||||
)
|
||||
</Header>
|
||||
<Form>
|
||||
<Form.Group>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.token_name')}
|
||||
width={3}
|
||||
value={token_name}
|
||||
placeholder={t('log.table.token_name_placeholder')}
|
||||
name='token_name'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.model_name')}
|
||||
width={3}
|
||||
value={model_name}
|
||||
placeholder={t('log.table.model_name_placeholder')}
|
||||
name='model_name'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.start_time')}
|
||||
width={4}
|
||||
value={start_timestamp}
|
||||
type='datetime-local'
|
||||
name='start_timestamp'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.end_time')}
|
||||
width={4}
|
||||
value={end_timestamp}
|
||||
type='datetime-local'
|
||||
name='end_timestamp'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Button
|
||||
fluid
|
||||
label={t('log.buttons.query')}
|
||||
width={2}
|
||||
onClick={refresh}
|
||||
>
|
||||
{t('log.buttons.submit')}
|
||||
</Form.Button>
|
||||
</Form.Group>
|
||||
{isAdminUser && (
|
||||
<>
|
||||
<Form.Group>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.channel_id')}
|
||||
width={3}
|
||||
>
|
||||
时间
|
||||
</Table.HeaderCell>
|
||||
{isAdminUser && (
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('channel');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
渠道
|
||||
</Table.HeaderCell>
|
||||
)}
|
||||
value={channel}
|
||||
placeholder={t('log.table.channel_id_placeholder')}
|
||||
name='channel'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Input
|
||||
fluid
|
||||
label={t('log.table.username')}
|
||||
width={3}
|
||||
value={username}
|
||||
placeholder={t('log.table.username_placeholder')}
|
||||
name='username'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
</>
|
||||
)}
|
||||
<Form.Input
|
||||
icon='search'
|
||||
placeholder={t('log.search')}
|
||||
value={searchKeyword}
|
||||
onChange={(e, { value }) => setSearchKeyword(value)}
|
||||
/>
|
||||
</Form>
|
||||
<Table basic={'very'} compact size='small'>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('created_time');
|
||||
}}
|
||||
width={3}
|
||||
>
|
||||
{t('log.table.time')}
|
||||
</Table.HeaderCell>
|
||||
{isAdminUser && (
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('type');
|
||||
sortLog('channel');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
类型
|
||||
{t('log.table.channel')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('model_name');
|
||||
}}
|
||||
width={2}
|
||||
>
|
||||
模型
|
||||
</Table.HeaderCell>
|
||||
{showUserTokenQuota() && (
|
||||
<>
|
||||
{isAdminUser && (
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('username');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
用户
|
||||
</Table.HeaderCell>
|
||||
)}
|
||||
)}
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('type');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
{t('log.table.type')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('model_name');
|
||||
}}
|
||||
width={2}
|
||||
>
|
||||
{t('log.table.model')}
|
||||
</Table.HeaderCell>
|
||||
{showUserTokenQuota() && (
|
||||
<>
|
||||
{isAdminUser && (
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('token_name');
|
||||
sortLog('username');
|
||||
}}
|
||||
width={1}
|
||||
width={2}
|
||||
>
|
||||
令牌
|
||||
{t('log.table.username')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('prompt_tokens');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
提示
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('completion_tokens');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
补全
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('quota');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
额度
|
||||
</Table.HeaderCell>
|
||||
</>
|
||||
)}
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('content');
|
||||
}}
|
||||
width={isAdminUser ? 4 : 6}
|
||||
>
|
||||
详情
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
|
||||
<Table.Body>
|
||||
{logs
|
||||
.slice(
|
||||
(activePage - 1) * ITEMS_PER_PAGE,
|
||||
activePage * ITEMS_PER_PAGE
|
||||
)
|
||||
.map((log, idx) => {
|
||||
if (log.deleted) return <></>;
|
||||
return (
|
||||
<Table.Row key={log.id}>
|
||||
<Table.Cell>
|
||||
{renderTimestamp(log.created_at, log.request_id)}
|
||||
</Table.Cell>
|
||||
{isAdminUser && (
|
||||
<Table.Cell>
|
||||
{log.channel ? (
|
||||
<Label
|
||||
basic
|
||||
as={Link}
|
||||
to={`/channel/edit/${log.channel}`}
|
||||
>
|
||||
{log.channel}
|
||||
</Label>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Table.Cell>
|
||||
)}
|
||||
<Table.Cell>{renderType(log.type)}</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.model_name ? renderColorLabel(log.model_name) : ''}
|
||||
</Table.Cell>
|
||||
{showUserTokenQuota() && (
|
||||
<>
|
||||
{isAdminUser && (
|
||||
<Table.Cell>
|
||||
{log.username ? (
|
||||
<Label
|
||||
basic
|
||||
as={Link}
|
||||
to={`/user/edit/${log.user_id}`}
|
||||
>
|
||||
{log.username}
|
||||
</Label>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Table.Cell>
|
||||
)}
|
||||
<Table.Cell>
|
||||
{log.token_name
|
||||
? renderColorLabel(log.token_name)
|
||||
: ''}
|
||||
</Table.Cell>
|
||||
|
||||
<Table.Cell>
|
||||
{log.prompt_tokens ? log.prompt_tokens : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.completion_tokens ? log.completion_tokens : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.quota ? renderQuota(log.quota, t, 6) : ''}
|
||||
</Table.Cell>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Table.Cell>{renderDetail(log)}</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
})}
|
||||
</Table.Body>
|
||||
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell colSpan={'10'}>
|
||||
<Select
|
||||
placeholder='选择明细分类'
|
||||
options={LOG_OPTIONS}
|
||||
style={{ marginRight: '8px' }}
|
||||
name='logType'
|
||||
value={logType}
|
||||
onChange={(e, { name, value }) => {
|
||||
setLogType(value);
|
||||
)}
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('token_name');
|
||||
}}
|
||||
/>
|
||||
<Button size='small' onClick={refresh} loading={loading}>
|
||||
刷新
|
||||
</Button>
|
||||
<Pagination
|
||||
floated='right'
|
||||
activePage={activePage}
|
||||
onPageChange={onPaginationChange}
|
||||
size='small'
|
||||
siblingRange={1}
|
||||
totalPages={
|
||||
Math.ceil(logs.length / ITEMS_PER_PAGE) +
|
||||
(logs.length % ITEMS_PER_PAGE === 0 ? 1 : 0)
|
||||
}
|
||||
/>
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</>
|
||||
width={2}
|
||||
>
|
||||
{t('log.table.token_name')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('prompt_tokens');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
{t('log.table.prompt_tokens')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('completion_tokens');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
{t('log.table.completion_tokens')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
sortLog('quota');
|
||||
}}
|
||||
width={1}
|
||||
>
|
||||
{t('log.table.quota')}
|
||||
</Table.HeaderCell>
|
||||
</>
|
||||
)}
|
||||
<Table.HeaderCell>{t('log.table.detail')}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
|
||||
<Table.Body>
|
||||
{logs
|
||||
.slice(
|
||||
(activePage - 1) * ITEMS_PER_PAGE,
|
||||
activePage * ITEMS_PER_PAGE
|
||||
)
|
||||
.map((log, idx) => {
|
||||
if (log.deleted) return <></>;
|
||||
return (
|
||||
<Table.Row key={log.id}>
|
||||
<Table.Cell>
|
||||
{renderTimestamp(log.created_at, log.request_id)}
|
||||
</Table.Cell>
|
||||
{isAdminUser && (
|
||||
<Table.Cell>
|
||||
{log.channel ? (
|
||||
<Label
|
||||
basic
|
||||
as={Link}
|
||||
to={`/channel/edit/${log.channel}`}
|
||||
>
|
||||
{log.channel}
|
||||
</Label>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Table.Cell>
|
||||
)}
|
||||
<Table.Cell>{renderType(log.type)}</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.model_name ? renderColorLabel(log.model_name) : ''}
|
||||
</Table.Cell>
|
||||
{showUserTokenQuota() && (
|
||||
<>
|
||||
{isAdminUser && (
|
||||
<Table.Cell>
|
||||
{log.username ? (
|
||||
<Label
|
||||
basic
|
||||
as={Link}
|
||||
to={`/user/edit/${log.user_id}`}
|
||||
>
|
||||
{log.username}
|
||||
</Label>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Table.Cell>
|
||||
)}
|
||||
<Table.Cell>
|
||||
{log.token_name ? renderColorLabel(log.token_name) : ''}
|
||||
</Table.Cell>
|
||||
|
||||
<Table.Cell>
|
||||
{log.prompt_tokens ? log.prompt_tokens : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.completion_tokens ? log.completion_tokens : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{log.quota ? renderQuota(log.quota, t, 6) : ''}
|
||||
</Table.Cell>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Table.Cell>{renderDetail(log)}</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
})}
|
||||
</Table.Body>
|
||||
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell colSpan={'10'}>
|
||||
<Select
|
||||
placeholder={t('log.type.select')}
|
||||
options={LOG_OPTIONS}
|
||||
style={{ marginRight: '8px' }}
|
||||
name='logType'
|
||||
value={logType}
|
||||
onChange={(e, { name, value }) => {
|
||||
setLogType(value);
|
||||
}}
|
||||
/>
|
||||
<Button size='small' onClick={refresh} loading={loading}>
|
||||
{t('log.buttons.refresh')}
|
||||
</Button>
|
||||
<Pagination
|
||||
floated='right'
|
||||
activePage={activePage}
|
||||
onPageChange={onPaginationChange}
|
||||
size='small'
|
||||
siblingRange={1}
|
||||
totalPages={
|
||||
Math.ceil(logs.length / ITEMS_PER_PAGE) +
|
||||
(logs.length % ITEMS_PER_PAGE === 0 ? 1 : 0)
|
||||
}
|
||||
/>
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -86,7 +86,7 @@ const Dashboard = () => {
|
||||
setSummaryData({
|
||||
todayRequests: 0,
|
||||
todayQuota: 0,
|
||||
todayTokens: 0
|
||||
todayTokens: 0,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -224,9 +224,11 @@ const Dashboard = () => {
|
||||
}}
|
||||
formatter={(value) => [
|
||||
value,
|
||||
t('dashboard.charts.requests.tooltip')
|
||||
t('dashboard.charts.requests.tooltip'),
|
||||
]}
|
||||
labelFormatter={(label) => `${t('dashboard.tooltip.date')}: ${label}`}
|
||||
labelFormatter={(label) =>
|
||||
`${t('dashboard.tooltip.date')}: ${label}`
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
type='monotone'
|
||||
@ -277,9 +279,11 @@ const Dashboard = () => {
|
||||
}}
|
||||
formatter={(value) => [
|
||||
value,
|
||||
t('dashboard.charts.quota.tooltip')
|
||||
t('dashboard.charts.quota.tooltip'),
|
||||
]}
|
||||
labelFormatter={(label) => `${t('dashboard.tooltip.date')}: ${label}`}
|
||||
labelFormatter={(label) =>
|
||||
`${t('dashboard.tooltip.date')}: ${label}`
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
type='monotone'
|
||||
@ -328,9 +332,11 @@ const Dashboard = () => {
|
||||
}}
|
||||
formatter={(value) => [
|
||||
value,
|
||||
t('dashboard.charts.tokens.tooltip')
|
||||
t('dashboard.charts.tokens.tooltip'),
|
||||
]}
|
||||
labelFormatter={(label) => `${t('dashboard.tooltip.date')}: ${label}`}
|
||||
labelFormatter={(label) =>
|
||||
`${t('dashboard.tooltip.date')}: ${label}`
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
type='monotone'
|
||||
@ -378,7 +384,9 @@ const Dashboard = () => {
|
||||
borderRadius: '4px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
||||
}}
|
||||
labelFormatter={(label) => `${t('dashboard.tooltip.date')}: ${label}`}
|
||||
labelFormatter={(label) =>
|
||||
`${t('dashboard.tooltip.date')}: ${label}`
|
||||
}
|
||||
/>
|
||||
<Legend
|
||||
wrapperStyle={{
|
||||
|
Loading…
Reference in New Issue
Block a user