Merge pull request #622 from Calcium-Ion/i18n-fix
feat: Enhance i18n support
This commit is contained in:
@@ -27,44 +27,15 @@ import Task from "./pages/Task/index.js";
|
|||||||
import Playground from './pages/Playground/Playground.js';
|
import Playground from './pages/Playground/Playground.js';
|
||||||
import OAuth2Callback from "./components/OAuth2Callback.js";
|
import OAuth2Callback from "./components/OAuth2Callback.js";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { StatusContext } from './context/Status';
|
||||||
|
import { setStatusData } from './helpers/data.js';
|
||||||
|
import { API, showError } from './helpers';
|
||||||
|
|
||||||
const Home = lazy(() => import('./pages/Home'));
|
const Home = lazy(() => import('./pages/Home'));
|
||||||
const Detail = lazy(() => import('./pages/Detail'));
|
const Detail = lazy(() => import('./pages/Detail'));
|
||||||
const About = lazy(() => import('./pages/About'));
|
const About = lazy(() => import('./pages/About'));
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [userState, userDispatch] = useContext(UserContext);
|
|
||||||
// const [statusState, statusDispatch] = useContext(StatusContext);
|
|
||||||
const { i18n } = useTranslation();
|
|
||||||
|
|
||||||
const loadUser = () => {
|
|
||||||
let user = localStorage.getItem('user');
|
|
||||||
if (user) {
|
|
||||||
let data = JSON.parse(user);
|
|
||||||
userDispatch({ type: 'login', payload: data });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
loadUser();
|
|
||||||
let systemName = getSystemName();
|
|
||||||
if (systemName) {
|
|
||||||
document.title = systemName;
|
|
||||||
}
|
|
||||||
let logo = getLogo();
|
|
||||||
if (logo) {
|
|
||||||
let linkElement = document.querySelector("link[rel~='icon']");
|
|
||||||
if (linkElement) {
|
|
||||||
linkElement.href = logo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 从localStorage获取上次使用的语言
|
|
||||||
const savedLang = localStorage.getItem('i18nextLng');
|
|
||||||
if (savedLang) {
|
|
||||||
i18n.changeLanguage(savedLang);
|
|
||||||
}
|
|
||||||
}, [i18n]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ const ChannelsTable = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '优先级',
|
title: t('优先级'),
|
||||||
dataIndex: 'priority',
|
dataIndex: 'priority',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.children === undefined) {
|
if (record.children === undefined) {
|
||||||
@@ -276,8 +276,8 @@ const ChannelsTable = () => {
|
|||||||
keepFocus={true}
|
keepFocus={true}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
Modal.warning({
|
Modal.warning({
|
||||||
title: '修改子渠道优先级',
|
title: t('修改子渠道优先级'),
|
||||||
content: '确定要修改所有子渠道优先级为 ' + e.target.value + ' 吗?',
|
content: t('确定要修改所有子渠道优先级为 ') + e.target.value + t(' 吗?'),
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
if (e.target.value === '') {
|
if (e.target.value === '') {
|
||||||
return;
|
return;
|
||||||
@@ -298,7 +298,7 @@ const ChannelsTable = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '权重',
|
title: t('权重'),
|
||||||
dataIndex: 'weight',
|
dataIndex: 'weight',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.children === undefined) {
|
if (record.children === undefined) {
|
||||||
@@ -325,8 +325,8 @@ const ChannelsTable = () => {
|
|||||||
keepFocus={true}
|
keepFocus={true}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
Modal.warning({
|
Modal.warning({
|
||||||
title: '修改子渠道权重',
|
title: t('修改子渠道权重'),
|
||||||
content: '确定要修改所有子渠道权重为 ' + e.target.value + ' 吗?',
|
content: t('确定要修改所有子渠道权重为 ') + e.target.value + t(' 吗?'),
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
if (e.target.value === '') {
|
if (e.target.value === '') {
|
||||||
return;
|
return;
|
||||||
@@ -646,25 +646,25 @@ const ChannelsTable = () => {
|
|||||||
|
|
||||||
const copySelectedChannel = async (record) => {
|
const copySelectedChannel = async (record) => {
|
||||||
const channelToCopy = record
|
const channelToCopy = record
|
||||||
channelToCopy.name += '_复制';
|
channelToCopy.name += t('_复制');
|
||||||
channelToCopy.created_time = null;
|
channelToCopy.created_time = null;
|
||||||
channelToCopy.balance = 0;
|
channelToCopy.balance = 0;
|
||||||
channelToCopy.used_quota = 0;
|
channelToCopy.used_quota = 0;
|
||||||
if (!channelToCopy) {
|
if (!channelToCopy) {
|
||||||
showError('渠道未找到,请刷新页面后重试。');
|
showError(t('渠道未找到,请刷新页面后重试。'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const newChannel = { ...channelToCopy, id: undefined };
|
const newChannel = { ...channelToCopy, id: undefined };
|
||||||
const response = await API.post('/api/channel/', newChannel);
|
const response = await API.post('/api/channel/', newChannel);
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
showSuccess('渠道复制成功');
|
showSuccess(t('渠道复制成功'));
|
||||||
await refresh();
|
await refresh();
|
||||||
} else {
|
} else {
|
||||||
showError(response.data.message);
|
showError(response.data.message);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showError('渠道复制失败: ' + error.message);
|
showError(t('渠道复制失败: ') + error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -723,7 +723,7 @@ const ChannelsTable = () => {
|
|||||||
}
|
}
|
||||||
const { success, message } = res.data;
|
const { success, message } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
showSuccess('操作成功完成!');
|
showSuccess(t('操作成功完成!'));
|
||||||
let channel = res.data.data;
|
let channel = res.data.data;
|
||||||
let newChannels = [...channels];
|
let newChannels = [...channels];
|
||||||
if (action === 'delete') {
|
if (action === 'delete') {
|
||||||
|
|||||||
@@ -25,24 +25,6 @@ import { stringToColor } from '../helpers/render';
|
|||||||
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
||||||
import { StyleContext } from '../context/Style/index.js';
|
import { StyleContext } from '../context/Style/index.js';
|
||||||
|
|
||||||
// HeaderBar Buttons
|
|
||||||
let headerButtons = [
|
|
||||||
{
|
|
||||||
text: '关于',
|
|
||||||
itemKey: 'about',
|
|
||||||
to: '/about',
|
|
||||||
icon: <IconHelpCircle />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (localStorage.getItem('chat_link')) {
|
|
||||||
headerButtons.splice(1, 0, {
|
|
||||||
name: '聊天',
|
|
||||||
to: '/chat',
|
|
||||||
icon: 'comments',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const HeaderBar = () => {
|
const HeaderBar = () => {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const [userState, userDispatch] = useContext(UserContext);
|
const [userState, userDispatch] = useContext(UserContext);
|
||||||
|
|||||||
@@ -4,15 +4,65 @@ import SiderBar from './SiderBar.js';
|
|||||||
import App from '../App.js';
|
import App from '../App.js';
|
||||||
import FooterBar from './Footer.js';
|
import FooterBar from './Footer.js';
|
||||||
import { ToastContainer } from 'react-toastify';
|
import { ToastContainer } from 'react-toastify';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import { StyleContext } from '../context/Style/index.js';
|
import { StyleContext } from '../context/Style/index.js';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { API, getLogo, getSystemName, showError } from '../helpers/index.js';
|
||||||
|
import { setStatusData } from '../helpers/data.js';
|
||||||
|
import { UserContext } from '../context/User/index.js';
|
||||||
|
import { StatusContext } from '../context/Status/index.js';
|
||||||
const { Sider, Content, Header, Footer } = Layout;
|
const { Sider, Content, Header, Footer } = Layout;
|
||||||
|
|
||||||
|
|
||||||
const PageLayout = () => {
|
const PageLayout = () => {
|
||||||
|
const [userState, userDispatch] = useContext(UserContext);
|
||||||
|
const [statusState, statusDispatch] = useContext(StatusContext);
|
||||||
const [styleState, styleDispatch] = useContext(StyleContext);
|
const [styleState, styleDispatch] = useContext(StyleContext);
|
||||||
const { t } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
|
const loadUser = () => {
|
||||||
|
let user = localStorage.getItem('user');
|
||||||
|
if (user) {
|
||||||
|
let data = JSON.parse(user);
|
||||||
|
userDispatch({ type: 'login', payload: data });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadStatus = async () => {
|
||||||
|
try {
|
||||||
|
const res = await API.get('/api/status');
|
||||||
|
const { success, data } = res.data;
|
||||||
|
if (success) {
|
||||||
|
statusDispatch({ type: 'set', payload: data });
|
||||||
|
setStatusData(data);
|
||||||
|
} else {
|
||||||
|
showError('Unable to connect to server');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showError('Failed to load status');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadUser();
|
||||||
|
loadStatus().catch(console.error);
|
||||||
|
let systemName = getSystemName();
|
||||||
|
if (systemName) {
|
||||||
|
document.title = systemName;
|
||||||
|
}
|
||||||
|
let logo = getLogo();
|
||||||
|
if (logo) {
|
||||||
|
let linkElement = document.querySelector("link[rel~='icon']");
|
||||||
|
if (linkElement) {
|
||||||
|
linkElement.href = logo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 从localStorage获取上次使用的语言
|
||||||
|
const savedLang = localStorage.getItem('i18nextLng');
|
||||||
|
if (savedLang) {
|
||||||
|
i18n.changeLanguage(savedLang);
|
||||||
|
}
|
||||||
|
}, [i18n]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
<Layout style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
||||||
|
|||||||
@@ -168,31 +168,13 @@ const SiderBar = () => {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const loadStatus = async () => {
|
|
||||||
const res = await API.get('/api/status');
|
|
||||||
if (res === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { success, data } = res.data;
|
|
||||||
if (success) {
|
|
||||||
statusDispatch({ type: 'set', payload: data });
|
|
||||||
setStatusData(data);
|
|
||||||
} else {
|
|
||||||
showError('无法正常连接至服务器!');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadStatus().then(() => {
|
|
||||||
setIsCollapsed(
|
|
||||||
localStorage.getItem('default_collapse_sidebar') === 'true',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
let localKey = window.location.pathname.split('/')[1];
|
let localKey = window.location.pathname.split('/')[1];
|
||||||
if (localKey === '') {
|
if (localKey === '') {
|
||||||
localKey = 'home';
|
localKey = 'home';
|
||||||
}
|
}
|
||||||
setSelectedKeys([localKey]);
|
setSelectedKeys([localKey]);
|
||||||
|
|
||||||
let chatLink = localStorage.getItem('chat_link');
|
let chatLink = localStorage.getItem('chat_link');
|
||||||
if (!chatLink) {
|
if (!chatLink) {
|
||||||
let chats = localStorage.getItem('chats');
|
let chats = localStorage.getItem('chats');
|
||||||
@@ -220,6 +202,8 @@ const SiderBar = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setIsCollapsed(localStorage.getItem('default_collapse_sidebar') === 'true');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -709,7 +709,7 @@
|
|||||||
"密码修改成功!": "Password changed successfully!",
|
"密码修改成功!": "Password changed successfully!",
|
||||||
"划转金额最低为": "The minimum transfer amount is",
|
"划转金额最低为": "The minimum transfer amount is",
|
||||||
"请输入邮箱!": "Please enter your email!",
|
"请输入邮箱!": "Please enter your email!",
|
||||||
"验证码发送成功,请检查<EFBFBD><EFBFBD><EFBFBD>箱!": "The verification code was sent successfully, please check your email!",
|
"验证码发送成功,请检查邮箱!": "The verification code was sent successfully, please check your email!",
|
||||||
"请输入邮箱验证码!": "Please enter the email verification code!",
|
"请输入邮箱验证码!": "Please enter the email verification code!",
|
||||||
"请输入要划转的数量": "Please enter the amount to be transferred",
|
"请输入要划转的数量": "Please enter the amount to be transferred",
|
||||||
"当前余额": "Current balance",
|
"当前余额": "Current balance",
|
||||||
@@ -827,8 +827,8 @@
|
|||||||
"模型消耗分布": "Model consumption distribution",
|
"模型消耗分布": "Model consumption distribution",
|
||||||
"模型调用次数占比": "Proportion of model calls",
|
"模型调用次数占比": "Proportion of model calls",
|
||||||
"用户消耗分布": "User consumption distribution",
|
"用户消耗分布": "User consumption distribution",
|
||||||
"时间粒度": "time granularity",
|
"时间粒度": "Time granularity",
|
||||||
"天": "sky",
|
"天": "day",
|
||||||
"模型概览": "Model overview",
|
"模型概览": "Model overview",
|
||||||
"用户概览": "User overview",
|
"用户概览": "User overview",
|
||||||
"正在策划中": "Under planning",
|
"正在策划中": "Under planning",
|
||||||
@@ -1209,5 +1209,13 @@
|
|||||||
"首页内容已更新": "Home page content updated",
|
"首页内容已更新": "Home page content updated",
|
||||||
"关于已更新": "About updated",
|
"关于已更新": "About updated",
|
||||||
"模型测试": "model test",
|
"模型测试": "model test",
|
||||||
"当前未开启Midjourney回调,部分项目可能无法获得绘图结果,可在运营设置中开启。": "Current Midjourney callback is not enabled, some projects may not be able to obtain drawing results, which can be enabled in the operation settings."
|
"当前未开启Midjourney回调,部分项目可能无法获得绘图结果,可在运营设置中开启。": "Current Midjourney callback is not enabled, some projects may not be able to obtain drawing results, which can be enabled in the operation settings.",
|
||||||
|
"Telegram 身份验证": "Telegram authentication",
|
||||||
|
"Linux DO 身份验证": "Linux DO authentication",
|
||||||
|
"协议": "License",
|
||||||
|
"修改子渠道权重": "Modify sub-channel weight",
|
||||||
|
"确定要修改所有子渠道权重为 ": "Confirm to modify all sub-channel weights to ",
|
||||||
|
" 吗?": "?",
|
||||||
|
"修改子渠道优先级": "Modify sub-channel priority",
|
||||||
|
"确定要修改所有子渠道优先级为 ": "Confirm to modify all sub-channel priorities to "
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,10 @@ import { API, showError, showNotice, timestamp2string } from '../../helpers';
|
|||||||
import { StatusContext } from '../../context/Status';
|
import { StatusContext } from '../../context/Status';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
import { StyleContext } from '../../context/Style/index.js';
|
import { StyleContext } from '../../context/Style/index.js';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [statusState] = useContext(StatusContext);
|
const [statusState] = useContext(StatusContext);
|
||||||
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
|
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
|
||||||
const [homePageContent, setHomePageContent] = useState('');
|
const [homePageContent, setHomePageContent] = useState('');
|
||||||
@@ -52,7 +54,8 @@ const Home = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
displayNotice().then();
|
displayNotice().then();
|
||||||
displayHomePageContent().then();
|
displayHomePageContent().then();
|
||||||
}, []);
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{homePageContentLoaded && homePageContent === '' ? (
|
{homePageContentLoaded && homePageContent === '' ? (
|
||||||
@@ -60,13 +63,13 @@ const Home = () => {
|
|||||||
<Card
|
<Card
|
||||||
bordered={false}
|
bordered={false}
|
||||||
headerLine={false}
|
headerLine={false}
|
||||||
title='系统状况'
|
title={t('系统状况')}
|
||||||
bodyStyle={{ padding: '10px 20px' }}
|
bodyStyle={{ padding: '10px 20px' }}
|
||||||
>
|
>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Card
|
<Card
|
||||||
title='系统信息'
|
title={t('系统信息')}
|
||||||
headerExtraContent={
|
headerExtraContent={
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
@@ -74,19 +77,19 @@ const Home = () => {
|
|||||||
color: 'var(--semi-color-text-1)',
|
color: 'var(--semi-color-text-1)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
系统信息总览
|
{t('系统信息总览')}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p>名称:{statusState?.status?.system_name}</p>
|
<p>{t('名称')}:{statusState?.status?.system_name}</p>
|
||||||
<p>
|
<p>
|
||||||
版本:
|
{t('版本')}:
|
||||||
{statusState?.status?.version
|
{statusState?.status?.version
|
||||||
? statusState?.status?.version
|
? statusState?.status?.version
|
||||||
: 'unknown'}
|
: 'unknown'}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
源码:
|
{t('源码')}:
|
||||||
<a
|
<a
|
||||||
href='https://github.com/Calcium-Ion/new-api'
|
href='https://github.com/Calcium-Ion/new-api'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
@@ -96,7 +99,7 @@ const Home = () => {
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
协议:
|
{t('协议')}:
|
||||||
<a
|
<a
|
||||||
href='https://www.apache.org/licenses/LICENSE-2.0'
|
href='https://www.apache.org/licenses/LICENSE-2.0'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
@@ -105,12 +108,12 @@ const Home = () => {
|
|||||||
Apache-2.0 License
|
Apache-2.0 License
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>启动时间:{getStartTimeString()}</p>
|
<p>{t('启动时间')}:{getStartTimeString()}</p>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Card
|
<Card
|
||||||
title='系统配置'
|
title={t('系统配置')}
|
||||||
headerExtraContent={
|
headerExtraContent={
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
@@ -118,45 +121,45 @@ const Home = () => {
|
|||||||
color: 'var(--semi-color-text-1)',
|
color: 'var(--semi-color-text-1)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
系统配置总览
|
{t('系统配置总览')}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
邮箱验证:
|
{t('邮箱验证')}:
|
||||||
{statusState?.status?.email_verification === true
|
{statusState?.status?.email_verification === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
GitHub 身份验证:
|
{t('GitHub 身份验证')}:
|
||||||
{statusState?.status?.github_oauth === true
|
{statusState?.status?.github_oauth === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
微信身份验证:
|
{t('微信身份验证')}:
|
||||||
{statusState?.status?.wechat_login === true
|
{statusState?.status?.wechat_login === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Turnstile 用户校验:
|
{t('Turnstile 用户校验')}:
|
||||||
{statusState?.status?.turnstile_check === true
|
{statusState?.status?.turnstile_check === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Telegram 身份验证:
|
{t('Telegram 身份验证')}:
|
||||||
{statusState?.status?.telegram_oauth === true
|
{statusState?.status?.telegram_oauth === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Linux DO 身份验证:
|
{t('Linux DO 身份验证')}:
|
||||||
{statusState?.status?.linuxdo_oauth === true
|
{statusState?.status?.linuxdo_oauth === true
|
||||||
? '已启用'
|
? t('已启用')
|
||||||
: '未启用'}
|
: t('未启用')}
|
||||||
</p>
|
</p>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -97,32 +97,29 @@ const Playground = () => {
|
|||||||
let res = await API.get(`/api/user/self/groups`);
|
let res = await API.get(`/api/user/self/groups`);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
// return data is a map, key is group name, value is group description
|
|
||||||
// label is group description, value is group name
|
|
||||||
let localGroupOptions = Object.keys(data).map((group) => ({
|
let localGroupOptions = Object.keys(data).map((group) => ({
|
||||||
label: data[group],
|
label: data[group],
|
||||||
value: group,
|
value: group,
|
||||||
}));
|
}));
|
||||||
// handleInputChange('group', localGroupOptions[0].value);
|
|
||||||
|
|
||||||
if (localGroupOptions.length > 0) {
|
if (localGroupOptions.length === 0) {
|
||||||
// set user group at first
|
localGroupOptions = [{
|
||||||
if (userState.user && userState.user.group) {
|
label: t('用户分组'),
|
||||||
let userGroup = userState.user.group;
|
value: '',
|
||||||
// Find and move user's group to the front
|
}];
|
||||||
|
} else {
|
||||||
|
const localUser = JSON.parse(localStorage.getItem('user'));
|
||||||
|
const userGroup = (userState.user && userState.user.group) || (localUser && localUser.group);
|
||||||
|
|
||||||
|
if (userGroup) {
|
||||||
const userGroupIndex = localGroupOptions.findIndex(g => g.value === userGroup);
|
const userGroupIndex = localGroupOptions.findIndex(g => g.value === userGroup);
|
||||||
if (userGroupIndex > -1) {
|
if (userGroupIndex > -1) {
|
||||||
const userGroupOption = localGroupOptions.splice(userGroupIndex, 1)[0];
|
const userGroupOption = localGroupOptions.splice(userGroupIndex, 1)[0];
|
||||||
localGroupOptions.unshift(userGroupOption);
|
localGroupOptions.unshift(userGroupOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
localGroupOptions = [{
|
|
||||||
label: t('用户分组'),
|
|
||||||
value: '',
|
|
||||||
}];
|
|
||||||
setGroups(localGroupOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setGroups(localGroupOptions);
|
setGroups(localGroupOptions);
|
||||||
handleInputChange('group', localGroupOptions[0].value);
|
handleInputChange('group', localGroupOptions[0].value);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user