diff --git a/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx b/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx index 7c938271..b951a7c5 100644 --- a/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx +++ b/frontend/packages/common/src/components/aoplatform/TableBtnWithPermission.tsx @@ -1,10 +1,10 @@ -import { Button, Tooltip } from 'antd' -import { useState, useMemo, useEffect, useCallback } from 'react' -import { useGlobalContext } from '@common/contexts/GlobalStateContext' -import { useNavigate } from 'react-router-dom' import { PERMISSION_DEFINITION } from '@common/const/permissions' -import { Icon } from '@iconify/react/dist/iconify.js' +import { useGlobalContext } from '@common/contexts/GlobalStateContext' import { $t } from '@common/locales' +import { Icon } from '@iconify/react/dist/iconify.js' +import { Button, Tooltip } from 'antd' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { useNavigate } from 'react-router-dom' type TableBtnWithPermissionProps = { btnTitle: string @@ -25,6 +25,7 @@ const TableIconName = { copy: 'ic:baseline-file-copy', view: 'ic:baseline-remove-red-eye', publish: 'ic:baseline-publish', + offline: 'ic:baseline-file-download-off', approval: 'ic:baseline-approval', stop: 'ic:baseline-stop-circle', online: 'ic:baseline-check-circle', @@ -86,7 +87,7 @@ const TableBtnWithPermission = ({ - {type !== 'apiDetail' && ( + {!isAIApiPreview && ( @@ -298,7 +298,7 @@ const AiServiceInsideRouterCreate = () => { spinning={loading} wrapperClassName=" pb-PAGE_INSIDE_B pr-PAGE_INSIDE_X" > - +
{ label={$t('提示词')} name="prompt"> @@ -361,7 +361,7 @@ const AiServiceInsideRouterCreate = () => {
{$t('变量')} diff --git a/frontend/packages/core/src/pages/aiSetting/AiSettingModal.tsx b/frontend/packages/core/src/pages/aiSetting/AiSettingModal.tsx index 9527d009..a81a4c7d 100644 --- a/frontend/packages/core/src/pages/aiSetting/AiSettingModal.tsx +++ b/frontend/packages/core/src/pages/aiSetting/AiSettingModal.tsx @@ -97,9 +97,9 @@ const AiSettingModalContent = forwardRef { if (!isChecked) { - return '保存后供应商状态变为【停用】,使用本供应商的 API 将临时使用负载优先级最高的正常供应商。' + return $t('保存后供应商状态变为【停用】,使用本供应商的 API 将临时使用负载优先级最高的正常供应商。') } - return '保存后供应商状态变为【正常】,恢复调用本供应商的 AI 能力。' + return $t('保存后供应商状态变为【正常】,恢复调用本供应商的 AI 能力。') } useImperativeHandle(ref, () => ({ @@ -177,7 +177,7 @@ const AiSettingModalContent = forwardRef
- 当前调用状态: + {$t('当前调用状态:')} {entity.status === 'enabled' && {$t('正常')}} {entity.status === 'disabled' && {$t('停用')}} {entity.status === 'abnormal' && {$t('异常')}} diff --git a/frontend/packages/core/src/pages/aiSetting/components/ModelCardNode.tsx b/frontend/packages/core/src/pages/aiSetting/components/ModelCardNode.tsx index 99efbe2b..115177e1 100644 --- a/frontend/packages/core/src/pages/aiSetting/components/ModelCardNode.tsx +++ b/frontend/packages/core/src/pages/aiSetting/components/ModelCardNode.tsx @@ -1,6 +1,6 @@ +import { $t } from '@common/locales' import { Icon } from '@iconify/react' import { Handle, Position } from '@xyflow/react' -import { t } from 'i18next' import React from 'react' import { useAiSetting } from '../contexts/AiSettingContext' import { AiSettingListItem, ModelDetailData, ModelStatus } from '../types' @@ -59,7 +59,7 @@ export const ModelCardNode: React.FC<{ data: ModelCardNodeData }> = ({ data }) =
- {t('默认:')} + {$t('默认:')} {defaultLlm}
diff --git a/frontend/packages/core/src/pages/keySettings/index.tsx b/frontend/packages/core/src/pages/keySettings/index.tsx index 49a25e94..3f05d620 100644 --- a/frontend/packages/core/src/pages/keySettings/index.tsx +++ b/frontend/packages/core/src/pages/keySettings/index.tsx @@ -67,7 +67,7 @@ const KeySettings: React.FC = () => { const newEntity = entity as EditAPIKey modal.confirm({ - title: mode === 'add' ? $t(`添加 ${provider?.name} APIKey`) : $t('编辑 APIKey'), + title: mode === 'add' ? $t('添加 (0) APIKey', [provider?.name]) : $t('编辑 APIKey'), content: , onOk: () => { return new Promise((resolve, reject) => { diff --git a/frontend/packages/core/src/pages/logsettings/LogSettings.tsx b/frontend/packages/core/src/pages/logsettings/LogSettings.tsx index 232cc8a5..cf710367 100644 --- a/frontend/packages/core/src/pages/logsettings/LogSettings.tsx +++ b/frontend/packages/core/src/pages/logsettings/LogSettings.tsx @@ -1,93 +1,95 @@ +import InsidePage from '@common/components/aoplatform/InsidePage' +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const' +import { DynamicMenuItem } from '@common/const/type' +import { useGlobalContext } from '@common/contexts/GlobalStateContext' +import { useFetch } from '@common/hooks/http' +import { $t } from '@common/locales' +import { getItem } from '@common/utils/navigation' +import { RouterParams } from '@core/components/aoplatform/RenderRoutes' +import { Menu, MenuProps, Skeleton, message } from 'antd' +import { useEffect, useMemo, useState } from 'react' +import { Link, Outlet, useNavigate, useParams } from 'react-router-dom' -import { Menu, MenuProps, Skeleton, message } from "antd"; -import { Link, Outlet, useNavigate, useParams } from "react-router-dom"; -import InsidePage from "@common/components/aoplatform/InsidePage"; -import { useEffect, useMemo, useState } from "react"; -import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; -import { DynamicMenuItem, } from "@common/const/type"; -import { useFetch } from "@common/hooks/http"; -import { getItem } from "@common/utils/navigation"; -import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; -import { $t } from "@common/locales"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext"; +const LogSettings = () => { + const { moduleId } = useParams() + const [menuItems, setMenuItems] = useState([]) + const [activeMenu, setActiveMenu] = useState() + const { fetchData } = useFetch() + const [loading, setLoading] = useState(true) + const navigateTo = useNavigate() + const { state } = useGlobalContext() -const LogSettings = ()=>{ - const {moduleId} = useParams(); - const [menuItems, setMenuItems ] = useState([]) - const [activeMenu, setActiveMenu] = useState() - const {fetchData} = useFetch() - const [loading, setLoading] = useState(true) - const navigateTo = useNavigate() - const {state} = useGlobalContext() - - const getDynamicMenuList = ()=>{ - return fetchData>(`simple/dynamics/log`,{method:'GET'}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - - setMenuItems(data.dynamics) - if(!activeMenu || activeMenu.length === 0){ - navigateTo(`/logsettings/template/${data.dynamics[0].name}`) - } - return Promise.resolve(data.dynamics) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return Promise.reject(msg || $t(RESPONSE_TIPS.error)) - } - }) - } - - const menuData = useMemo(()=>{ - const newMenu = menuItems?.map((x:DynamicMenuItem)=>{ - return getItem( - {$t(x.title)}, - x.name, - undefined, - undefined, - undefined, - 'system.settings.log_configuration.view') - }) - return newMenu - },[state.language,menuItems]) - - const onMenuClick: MenuProps['onClick'] = ({key}) => { - setActiveMenu(key) - }; - - - useEffect(() => { - setActiveMenu(moduleId) - }, [ moduleId]); - - useEffect(()=>{ - setLoading(true) - Promise.all([getDynamicMenuList()]).finally(()=>setLoading(false)) - },[]) - - return ( - <> - - -
- -
- -
-
-
-
- + const getDynamicMenuList = () => { + return fetchData>(`simple/dynamics/log`, { method: 'GET' }).then( + (response) => { + const { code, data, msg } = response + if (code === STATUS_CODE.SUCCESS) { + setMenuItems(data.dynamics) + if (!activeMenu || activeMenu.length === 0) { + navigateTo(`/logsettings/template/${data.dynamics[0].name}`) + } + return Promise.resolve(data.dynamics) + } else { + message.error(msg || $t(RESPONSE_TIPS.error)) + return Promise.reject(msg || $t(RESPONSE_TIPS.error)) + } + } ) + } + + const menuData = useMemo(() => { + const newMenu = menuItems?.map((x: DynamicMenuItem) => { + return getItem( + {$t(x.title)}, + x.name, + undefined, + undefined, + undefined, + 'system.settings.log_configuration.view' + ) + }) + return newMenu + }, [state.language, menuItems]) + + const onMenuClick: MenuProps['onClick'] = ({ key }) => { + setActiveMenu(key) + } + + useEffect(() => { + setActiveMenu(moduleId) + }, [moduleId]) + + useEffect(() => { + setLoading(true) + Promise.all([getDynamicMenuList()]).finally(() => setLoading(false)) + }, []) + + return ( + <> + + +
+ +
+ +
+
+
+
+ + ) } -export default LogSettings; \ No newline at end of file +export default LogSettings diff --git a/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx b/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx index fe24c935..7928f12d 100644 --- a/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx +++ b/frontend/packages/core/src/pages/resourcesettings/ResourceSettings.tsx @@ -1,95 +1,89 @@ +import InsidePage from '@common/components/aoplatform/InsidePage' +import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const' +import { DynamicMenuItem } from '@common/const/type' +import { useGlobalContext } from '@common/contexts/GlobalStateContext' +import { useFetch } from '@common/hooks/http' +import { $t } from '@common/locales' +import { getItem } from '@common/utils/navigation' +import { RouterParams } from '@core/components/aoplatform/RenderRoutes' +import { Menu, MenuProps, Skeleton, message } from 'antd' +import { useEffect, useMemo, useState } from 'react' +import { Link, Outlet, useNavigate, useParams } from 'react-router-dom' -import { Menu, MenuProps, Skeleton, message } from "antd"; -import { Link, Outlet, useNavigate, useParams } from "react-router-dom"; -import InsidePage from "@common/components/aoplatform/InsidePage"; -import { useEffect, useMemo, useState } from "react"; -import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; -import { DynamicMenuItem } from "@common/const/type"; -import { useFetch } from "@common/hooks/http"; -import { getItem } from "@common/utils/navigation"; -import { RouterParams } from "@core/components/aoplatform/RenderRoutes"; -import { $t } from "@common/locales"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext"; +const LogSettings = () => { + const { moduleId } = useParams() + const [menuItems, setMenuItems] = useState([]) + const [activeMenu, setActiveMenu] = useState() + const { fetchData } = useFetch() + const [loading, setLoading] = useState(true) + const navigateTo = useNavigate() + const { state } = useGlobalContext() -const LogSettings = ()=>{ - const {moduleId} = useParams(); - const [menuItems, setMenuItems ] = useState([]) - const [activeMenu, setActiveMenu] = useState() - const {fetchData} = useFetch() - const [loading, setLoading] = useState(true) - const navigateTo = useNavigate() - const {state} = useGlobalContext() - - const getDynamicMenuList = ()=>{ - setLoading(true) - fetchData>(`simple/dynamics/resource`,{method:'GET'}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - - - setMenuItems(data.dynamics) - if(!activeMenu || activeMenu.length === 0){ - navigateTo(`/resourcesettings/template/${data.dynamics[0].name}`) - } - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }).finally(()=>setLoading(false)) - } + const getDynamicMenuList = () => { + setLoading(true) + fetchData>(`simple/dynamics/resource`, { method: 'GET' }) + .then((response) => { + const { code, data, msg } = response + if (code === STATUS_CODE.SUCCESS) { + setMenuItems(data.dynamics) + if (!activeMenu || activeMenu.length === 0) { + navigateTo(`/resourcesettings/template/${data.dynamics[0].name}`) + } + } else { + message.error(msg || $t(RESPONSE_TIPS.error)) + } + }) + .finally(() => setLoading(false)) + } - - const menuData = useMemo(()=>{ - const newMenu = menuItems?.map((x:DynamicMenuItem)=>{ - - return getItem( - {$t(x.title)}, - x.name, - undefined, - undefined, - undefined, - 'system.settings.log_configuration.view') - }) - return newMenu - },[state.language,menuItems]) + const menuData = useMemo(() => { + const newMenu = menuItems?.map((x: DynamicMenuItem) => { + return getItem( + {$t(x.title)}, + x.name, + undefined, + undefined, + undefined, + 'system.settings.log_configuration.view' + ) + }) + return newMenu + }, [state.language, menuItems]) + const onMenuClick: MenuProps['onClick'] = ({ key }) => { + setActiveMenu(key) + } - const onMenuClick: MenuProps['onClick'] = ({key}) => { - setActiveMenu(key) - }; - - useEffect(() => { - setActiveMenu(moduleId) - }, [ moduleId]); - - useEffect(()=>{ - setLoading(true) - getDynamicMenuList() - },[]) - - - return ( - <> - - -
- -
- -
-
-
-
- - ) + useEffect(() => { + setActiveMenu(moduleId) + }, [moduleId]) + + useEffect(() => { + setLoading(true) + getDynamicMenuList() + }, []) + + return ( + <> + + +
+ +
+ +
+
+
+
+ + ) } -export default LogSettings; \ No newline at end of file +export default LogSettings diff --git a/frontend/prompt/Translate.md b/frontend/prompt/Translate.md new file mode 100644 index 00000000..72fb216d --- /dev/null +++ b/frontend/prompt/Translate.md @@ -0,0 +1,24 @@ +# Translation Workflow in Windsurf + +Follow these steps to manage translations in the project: + +1. **Scan for New Translations** + * Navigate to the `frontend` directory + * Run `pnpm run scan` to detect new translatable content + +2. **Locate New Translation Fields** + * Go to `packages/common/src/locales/scan/newJson` + * Find the language-specific JSON files (e.g., en-US.json, ja-JP.json) + * These files contain the new fields that need translation + +3. **Apply Translations** + * After translating the content, go to `packages/common/src/locales/scan` + * Open the corresponding language JSON file include ja-JP.json,en-US.json,zh-CH.json,zh-TW.json + * Paste the translated content into the appropriate file + +4. **Save and Apply** + * Save the file + * Changes will take effect immediately + * No additional build or restart is required + +Note: Available language files are en-US.json, ja-JP.json, zh-CN.json, and zh-TW.json. \ No newline at end of file