mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-17 09:16:36 +08:00
feat: i18n support
This commit is contained in:
parent
b1fe81a84f
commit
e7ea7c866f
@ -596,6 +596,77 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"quota": {
|
||||
"title": "Quota Settings",
|
||||
"new_user": "Initial Quota for New Users",
|
||||
"new_user_placeholder": "e.g.: 100",
|
||||
"pre_consume": "Pre-consumed Quota per Request",
|
||||
"pre_consume_placeholder": "Refund or charge difference after request",
|
||||
"inviter_reward": "Reward Quota for Inviter",
|
||||
"inviter_reward_placeholder": "e.g.: 2000",
|
||||
"invitee_reward": "Reward Quota for Using Invite Code",
|
||||
"invitee_reward_placeholder": "e.g.: 1000",
|
||||
"buttons": {
|
||||
"save": "Save Quota Settings"
|
||||
}
|
||||
},
|
||||
"ratio": {
|
||||
"title": "Ratio Settings",
|
||||
"model": {
|
||||
"title": "Model Ratio",
|
||||
"placeholder": "A JSON text where keys are model names and values are ratios"
|
||||
},
|
||||
"completion": {
|
||||
"title": "Completion Ratio",
|
||||
"placeholder": "A JSON text where keys are model names and values are ratios. These ratios are the proportion of completion to prompt ratio, which can override One API's internal ratios"
|
||||
},
|
||||
"group": {
|
||||
"title": "Group Ratio",
|
||||
"placeholder": "A JSON text where keys are group names and values are ratios"
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Save Ratio Settings"
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"title": "Log Settings",
|
||||
"enable_consume": "Enable Quota Consumption Logging",
|
||||
"target_time": "Target Time",
|
||||
"buttons": {
|
||||
"clean": "Clean Historical Logs"
|
||||
}
|
||||
},
|
||||
"monitor": {
|
||||
"title": "Monitor Settings",
|
||||
"max_response_time": "Maximum Response Time",
|
||||
"max_response_time_placeholder": "In seconds, channels exceeding this time during testing will be automatically disabled",
|
||||
"quota_reminder": "Quota Reminder Threshold",
|
||||
"quota_reminder_placeholder": "Users will receive email reminders when quota falls below this value",
|
||||
"auto_disable": "Automatically Disable Channel on Failure",
|
||||
"auto_enable": "Automatically Enable Channel on Success",
|
||||
"buttons": {
|
||||
"save": "Save Monitor Settings"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"title": "General Settings",
|
||||
"topup_link": "Top-up Link",
|
||||
"topup_link_placeholder": "e.g.: Card selling website purchase link",
|
||||
"chat_link": "Chat Page Link",
|
||||
"chat_link_placeholder": "e.g.: ChatGPT Next Web deployment address",
|
||||
"quota_per_unit": "Quota per Dollar",
|
||||
"quota_per_unit_placeholder": "Quota exchangeable per unit of currency",
|
||||
"retry_times": "Retry Times on Failure",
|
||||
"retry_times_placeholder": "Number of retry attempts on failure",
|
||||
"display_in_currency": "Display Quota in Currency Format",
|
||||
"display_token_stat": "Show Token Quota Instead of User Quota in Billing APIs",
|
||||
"approximate_token": "Use Approximate Method to Estimate Token Count",
|
||||
"buttons": {
|
||||
"save": "Save General Settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -596,6 +596,77 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"quota": {
|
||||
"title": "额度设置",
|
||||
"new_user": "新用户初始额度",
|
||||
"new_user_placeholder": "例如:100",
|
||||
"pre_consume": "请求预扣费额度",
|
||||
"pre_consume_placeholder": "请求结束后多退少补",
|
||||
"inviter_reward": "邀请新用户奖励额度",
|
||||
"inviter_reward_placeholder": "例如:2000",
|
||||
"invitee_reward": "新用户使用邀请码奖励额度",
|
||||
"invitee_reward_placeholder": "例如:1000",
|
||||
"buttons": {
|
||||
"save": "保存额度设置"
|
||||
}
|
||||
},
|
||||
"ratio": {
|
||||
"title": "倍率设置",
|
||||
"model": {
|
||||
"title": "模型倍率",
|
||||
"placeholder": "为一个 JSON 文本,键为模型名称,值为倍率"
|
||||
},
|
||||
"completion": {
|
||||
"title": "补全倍率",
|
||||
"placeholder": "为一个 JSON 文本,键为模型名称,值为倍率,此处的倍率设置是模型补全倍率相较于提示倍率的比例,使用该设置可强制覆盖 One API 的内部比例"
|
||||
},
|
||||
"group": {
|
||||
"title": "分组倍率",
|
||||
"placeholder": "为一个 JSON 文本,键为分组名称,值为倍率"
|
||||
},
|
||||
"buttons": {
|
||||
"save": "保存倍率设置"
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"title": "日志设置",
|
||||
"enable_consume": "启用额度消费日志记录",
|
||||
"target_time": "目标时间",
|
||||
"buttons": {
|
||||
"clean": "清理历史日志"
|
||||
}
|
||||
},
|
||||
"monitor": {
|
||||
"title": "监控设置",
|
||||
"max_response_time": "最长响应时间",
|
||||
"max_response_time_placeholder": "单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道",
|
||||
"quota_reminder": "额度提醒阈值",
|
||||
"quota_reminder_placeholder": "低于此额度时将发送邮件提醒用户",
|
||||
"auto_disable": "失败时自动禁用渠道",
|
||||
"auto_enable": "成功时自动启用渠道",
|
||||
"buttons": {
|
||||
"save": "保存监控设置"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"title": "通用设置",
|
||||
"topup_link": "充值链接",
|
||||
"topup_link_placeholder": "例如发卡网站的购买链接",
|
||||
"chat_link": "聊天页面链接",
|
||||
"chat_link_placeholder": "例如 ChatGPT Next Web 的部署地址",
|
||||
"quota_per_unit": "单位美元额度",
|
||||
"quota_per_unit_placeholder": "一单位货币能兑换的额度",
|
||||
"retry_times": "失败重试次数",
|
||||
"retry_times_placeholder": "失败重试次数",
|
||||
"display_in_currency": "以货币形式显示额度",
|
||||
"display_token_stat": "Billing 相关 API 显示令牌额度而非用户额度",
|
||||
"approximate_token": "使用近似的方式估算 token 数以减少计算量",
|
||||
"buttons": {
|
||||
"save": "保存通用设置"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Divider, Form, Grid, Header } from 'semantic-ui-react';
|
||||
import { API, showError, showSuccess, timestamp2string, verifyJSON } from '../helpers';
|
||||
|
||||
const OperationSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
let now = new Date();
|
||||
let [inputs, setInputs] = useState({
|
||||
QuotaForNewUser: 0,
|
||||
@ -160,39 +162,201 @@ const OperationSetting = () => {
|
||||
<Grid.Column>
|
||||
<Form loading={loading}>
|
||||
<Header as='h3'>
|
||||
通用设置
|
||||
{t('setting.operation.quota.title')}
|
||||
</Header>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.Input
|
||||
label={t('setting.operation.quota.new_user')}
|
||||
name='QuotaForNewUser'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForNewUser}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.quota.new_user_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label={t('setting.operation.quota.pre_consume')}
|
||||
name='PreConsumedQuota'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.PreConsumedQuota}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.quota.pre_consume_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label={t('setting.operation.quota.inviter_reward')}
|
||||
name='QuotaForInviter'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForInviter}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.quota.inviter_reward_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label={t('setting.operation.quota.invitee_reward')}
|
||||
name='QuotaForInvitee'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForInvitee}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.quota.invitee_reward_placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('quota').then();
|
||||
}}>
|
||||
{t('setting.operation.quota.buttons.save')}
|
||||
</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>
|
||||
{t('setting.operation.ratio.title')}
|
||||
</Header>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label={t('setting.operation.ratio.model.title')}
|
||||
name='ModelRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.ModelRatio}
|
||||
placeholder={t('setting.operation.ratio.model.placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label={t('setting.operation.ratio.completion.title')}
|
||||
name='CompletionRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.CompletionRatio}
|
||||
placeholder={t('setting.operation.ratio.completion.placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label={t('setting.operation.ratio.group.title')}
|
||||
name='GroupRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.GroupRatio}
|
||||
placeholder={t('setting.operation.ratio.group.placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('ratio').then();
|
||||
}}>
|
||||
{t('setting.operation.ratio.buttons.save')}
|
||||
</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>{t('setting.operation.log.title')}</Header>
|
||||
<Form.Group inline>
|
||||
<Form.Checkbox
|
||||
checked={inputs.LogConsumeEnabled === 'true'}
|
||||
label={t('setting.operation.log.enable_consume')}
|
||||
name='LogConsumeEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths={4}>
|
||||
<Form.Input
|
||||
label='充值链接'
|
||||
label={t('setting.operation.log.target_time')}
|
||||
value={historyTimestamp}
|
||||
type='datetime-local'
|
||||
name='history_timestamp'
|
||||
onChange={(e, { name, value }) => {
|
||||
setHistoryTimestamp(value);
|
||||
}}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
deleteHistoryLogs().then();
|
||||
}}>
|
||||
{t('setting.operation.log.buttons.clean')}
|
||||
</Form.Button>
|
||||
|
||||
<Divider />
|
||||
<Header as='h3'>{t('setting.operation.monitor.title')}</Header>
|
||||
<Form.Group widths={3}>
|
||||
<Form.Input
|
||||
label={t('setting.operation.monitor.max_response_time')}
|
||||
name='ChannelDisableThreshold'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.ChannelDisableThreshold}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.monitor.max_response_time_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label={t('setting.operation.monitor.quota_reminder')}
|
||||
name='QuotaRemindThreshold'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaRemindThreshold}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder={t('setting.operation.monitor.quota_reminder_placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group inline>
|
||||
<Form.Checkbox
|
||||
checked={inputs.AutomaticDisableChannelEnabled === 'true'}
|
||||
label={t('setting.operation.monitor.auto_disable')}
|
||||
name='AutomaticDisableChannelEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Checkbox
|
||||
checked={inputs.AutomaticEnableChannelEnabled === 'true'}
|
||||
label={t('setting.operation.monitor.auto_enable')}
|
||||
name='AutomaticEnableChannelEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('monitor').then();
|
||||
}}>
|
||||
{t('setting.operation.monitor.buttons.save')}
|
||||
</Form.Button>
|
||||
|
||||
<Divider />
|
||||
<Header as='h3'>{t('setting.operation.general.title')}</Header>
|
||||
<Form.Group widths={4}>
|
||||
<Form.Input
|
||||
label={t('setting.operation.general.topup_link')}
|
||||
name='TopUpLink'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.TopUpLink}
|
||||
type='link'
|
||||
placeholder='例如发卡网站的购买链接'
|
||||
placeholder={t('setting.operation.general.topup_link_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label='聊天页面链接'
|
||||
label={t('setting.operation.general.chat_link')}
|
||||
name='ChatLink'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.ChatLink}
|
||||
type='link'
|
||||
placeholder='例如 ChatGPT Next Web 的部署地址'
|
||||
placeholder={t('setting.operation.general.chat_link_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label='单位美元额度'
|
||||
label={t('setting.operation.general.quota_per_unit')}
|
||||
name='QuotaPerUnit'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaPerUnit}
|
||||
type='number'
|
||||
step='0.01'
|
||||
placeholder='一单位货币能兑换的额度'
|
||||
placeholder={t('setting.operation.general.quota_per_unit_placeholder')}
|
||||
/>
|
||||
<Form.Input
|
||||
label='失败重试次数'
|
||||
label={t('setting.operation.general.retry_times')}
|
||||
name='RetryTimes'
|
||||
type={'number'}
|
||||
step='1'
|
||||
@ -200,186 +364,34 @@ const OperationSetting = () => {
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.RetryTimes}
|
||||
placeholder='失败重试次数'
|
||||
placeholder={t('setting.operation.general.retry_times_placeholder')}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group inline>
|
||||
<Form.Checkbox
|
||||
checked={inputs.DisplayInCurrencyEnabled === 'true'}
|
||||
label='以货币形式显示额度'
|
||||
label={t('setting.operation.general.display_in_currency')}
|
||||
name='DisplayInCurrencyEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Checkbox
|
||||
checked={inputs.DisplayTokenStatEnabled === 'true'}
|
||||
label='Billing 相关 API 显示令牌额度而非用户额度'
|
||||
label={t('setting.operation.general.display_token_stat')}
|
||||
name='DisplayTokenStatEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Checkbox
|
||||
checked={inputs.ApproximateTokenEnabled === 'true'}
|
||||
label='使用近似的方式估算 token 数以减少计算量'
|
||||
label={t('setting.operation.general.approximate_token')}
|
||||
name='ApproximateTokenEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('general').then();
|
||||
}}>保存通用设置</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>
|
||||
日志设置
|
||||
</Header>
|
||||
<Form.Group inline>
|
||||
<Form.Checkbox
|
||||
checked={inputs.LogConsumeEnabled === 'true'}
|
||||
label='启用额度消费日志记录'
|
||||
name='LogConsumeEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths={4}>
|
||||
<Form.Input label='目标时间' value={historyTimestamp} type='datetime-local'
|
||||
name='history_timestamp'
|
||||
onChange={(e, { name, value }) => {
|
||||
setHistoryTimestamp(value);
|
||||
}} />
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
deleteHistoryLogs().then();
|
||||
}}>清理历史日志</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>
|
||||
监控设置
|
||||
</Header>
|
||||
<Form.Group widths={3}>
|
||||
<Form.Input
|
||||
label='最长响应时间'
|
||||
name='ChannelDisableThreshold'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.ChannelDisableThreshold}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道'
|
||||
/>
|
||||
<Form.Input
|
||||
label='额度提醒阈值'
|
||||
name='QuotaRemindThreshold'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaRemindThreshold}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='低于此额度时将发送邮件提醒用户'
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group inline>
|
||||
<Form.Checkbox
|
||||
checked={inputs.AutomaticDisableChannelEnabled === 'true'}
|
||||
label='失败时自动禁用渠道'
|
||||
name='AutomaticDisableChannelEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Form.Checkbox
|
||||
checked={inputs.AutomaticEnableChannelEnabled === 'true'}
|
||||
label='成功时自动启用渠道'
|
||||
name='AutomaticEnableChannelEnabled'
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('monitor').then();
|
||||
}}>保存监控设置</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>
|
||||
额度设置
|
||||
</Header>
|
||||
<Form.Group widths={4}>
|
||||
<Form.Input
|
||||
label='新用户初始额度'
|
||||
name='QuotaForNewUser'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForNewUser}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='例如:100'
|
||||
/>
|
||||
<Form.Input
|
||||
label='请求预扣费额度'
|
||||
name='PreConsumedQuota'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.PreConsumedQuota}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='请求结束后多退少补'
|
||||
/>
|
||||
<Form.Input
|
||||
label='邀请新用户奖励额度'
|
||||
name='QuotaForInviter'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForInviter}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='例如:2000'
|
||||
/>
|
||||
<Form.Input
|
||||
label='新用户使用邀请码奖励额度'
|
||||
name='QuotaForInvitee'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='new-password'
|
||||
value={inputs.QuotaForInvitee}
|
||||
type='number'
|
||||
min='0'
|
||||
placeholder='例如:1000'
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('quota').then();
|
||||
}}>保存额度设置</Form.Button>
|
||||
<Divider />
|
||||
<Header as='h3'>
|
||||
倍率设置
|
||||
</Header>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label='模型倍率'
|
||||
name='ModelRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.ModelRatio}
|
||||
placeholder='为一个 JSON 文本,键为模型名称,值为倍率'
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label='补全倍率'
|
||||
name='CompletionRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.CompletionRatio}
|
||||
placeholder='为一个 JSON 文本,键为模型名称,值为倍率,此处的倍率设置是模型补全倍率相较于提示倍率的比例,使用该设置可强制覆盖 One API 的内部比例'
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group widths='equal'>
|
||||
<Form.TextArea
|
||||
label='分组倍率'
|
||||
name='GroupRatio'
|
||||
onChange={handleInputChange}
|
||||
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||
autoComplete='new-password'
|
||||
value={inputs.GroupRatio}
|
||||
placeholder='为一个 JSON 文本,键为分组名称,值为倍率'
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button onClick={() => {
|
||||
submitConfig('ratio').then();
|
||||
}}>保存倍率设置</Form.Button>
|
||||
}}>
|
||||
{t('setting.operation.general.buttons.save')}
|
||||
</Form.Button>
|
||||
</Form>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
|
Loading…
Reference in New Issue
Block a user