Perf: i18n ns (#1441)

* i18n

* fix: handle
This commit is contained in:
Archer
2024-05-10 18:41:41 +08:00
committed by GitHub
parent f351d4ea68
commit 26f4c92124
27 changed files with 1705 additions and 1595 deletions

View File

@@ -6,6 +6,7 @@ import { appWithTranslation } from 'next-i18next';
import QueryClientContext from '@/web/context/QueryClient';
import ChakraUIContext from '@/web/context/ChakraUI';
import I18nContextProvider from '@/web/context/I18n';
import { useInitApp } from '@/web/context/useInitApp';
import '@/web/styles/reset.scss';
@@ -34,11 +35,13 @@ function App({ Component, pageProps }: AppProps) {
{scripts?.map((item, i) => <Script key={i} strategy="lazyOnload" {...item}></Script>)}
<QueryClientContext>
<ChakraUIContext>
<Layout>
<Component {...pageProps} />
</Layout>
</ChakraUIContext>
<I18nContextProvider>
<ChakraUIContext>
<Layout>
<Component {...pageProps} />
</Layout>
</ChakraUIContext>
</I18nContextProvider>
</QueryClientContext>
</>
);

View File

@@ -26,6 +26,7 @@ import { formatTime2HM } from '@fastgpt/global/common/string/time';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext, getWorkflowStore } from '@/components/core/workflow/context';
import { useInterval, useUpdateEffect } from 'ahooks';
import { useI18n } from '@/web/context/I18n';
const ImportSettings = dynamic(() => import('@/components/core/workflow/Flow/ImportSettings'));
const PublishHistories = dynamic(
@@ -56,6 +57,8 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
const theme = useTheme();
const { toast } = useToast();
const { t } = useTranslation();
const { appT } = useI18n();
const { copyData } = useCopyData();
const { openConfirm: openConfigPublish, ConfirmModal } = useConfirm({
content: t('core.app.Publish Confirm')
@@ -177,10 +180,10 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
null,
2
),
t('app.Export Config Successful')
appT('Export Config Successful')
);
}
}, [copyData, flowData2StoreDataAndCheck, t]);
}, [appT, copyData, flowData2StoreDataAndCheck]);
// effect
useBeforeunload({
@@ -254,12 +257,12 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
}
menuList={[
{
label: t('app.Import Configs'),
label: appT('Import Configs'),
icon: 'common/importLight',
onClick: onOpenImport
},
{
label: t('app.Export Configs'),
label: appT('Export Configs'),
icon: 'export',
onClick: onExportWorkflow
}
@@ -316,6 +319,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
isV2Workflow,
t,
saveLabel,
appT,
onOpenImport,
onExportWorkflow,
openConfigPublish,

View File

@@ -33,9 +33,12 @@ import { usePagination } from '@fastgpt/web/hooks/usePagination';
import DateRangePicker, { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
import { formatChatValue2InputType } from '@/components/ChatBox/utils';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { useI18n } from '@/web/context/I18n';
const Logs = ({ appId }: { appId: string }) => {
const { t } = useTranslation();
const { appT } = useI18n();
const { isPc } = useSystemStore();
const [dateRange, setDateRange] = useState<DateRangeType>({
@@ -73,10 +76,10 @@ const Logs = ({ appId }: { appId: string }) => {
{isPc && (
<>
<Box fontWeight={'bold'} fontSize={['md', 'xl']} mb={2}>
{t('app.Chat logs')}
{appT('Chat logs')}
</Box>
<Box color={'myGray.500'} fontSize={'sm'}>
{t('app.Chat Logs Tips')},{' '}
{appT('Chat Logs Tips')},{' '}
<Box
as={'span'}
mr={2}
@@ -97,11 +100,11 @@ const Logs = ({ appId }: { appId: string }) => {
<Thead>
<Tr>
<Th>{t('core.app.logs.Source And Time')}</Th>
<Th>{t('app.Logs Title')}</Th>
<Th>{t('app.Logs Message Total')}</Th>
<Th>{t('app.Feedback Count')}</Th>
<Th>{appT('Logs Title')}</Th>
<Th>{appT('Logs Message Total')}</Th>
<Th>{appT('Feedback Count')}</Th>
<Th>{t('core.app.feedback.Custom feedback')}</Th>
<Th>{t('app.Mark Count')}</Th>
<Th>{appT('Mark Count')}</Th>
</Tr>
</Thead>
<Tbody>
@@ -176,7 +179,7 @@ const Logs = ({ appId }: { appId: string }) => {
<Flex h={'100%'} flexDirection={'column'} alignItems={'center'} pt={'10vh'}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}>
{t('app.Logs Empty')}
{appT('Logs Empty')}
</Box>
</Flex>
)}

View File

@@ -15,11 +15,14 @@ import Avatar from '@/components/Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon';
import TagsEditModal from './TagsEditModal';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useI18n } from '@/web/context/I18n';
const InfoModal = dynamic(() => import('../InfoModal'));
const AppCard = ({ appId }: { appId: string }) => {
const router = useRouter();
const { t } = useTranslation();
const { appT } = useI18n();
const { toast } = useToast();
const { appDetail } = useAppStore();
const { feConfigs } = useSystemStore();
@@ -27,7 +30,7 @@ const AppCard = ({ appId }: { appId: string }) => {
const [TeamTagsSet, setTeamTagsSet] = useState<AppSchema>();
const { openConfirm: openConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({
content: t('app.Confirm Del App Tip'),
content: appT('Confirm Del App Tip'),
type: 'delete'
});

View File

@@ -21,6 +21,7 @@ import { UseFormReturn } from 'react-hook-form';
import { AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
import { useAppStore } from '@/web/core/app/store/useAppStore';
import { form2AppWorkflow } from '@/web/core/app/utils';
import { useI18n } from '@/web/context/I18n';
const ChatTest = ({
editForm,
@@ -30,6 +31,8 @@ const ChatTest = ({
appId: string;
}) => {
const { t } = useTranslation();
const { appT } = useI18n();
const { userInfo } = useUserStore();
const ChatBoxRef = useRef<ComponentRef>(null);
const { appDetail } = useAppStore();
@@ -114,7 +117,7 @@ const ChatTest = ({
>
<Flex px={[2, 5]}>
<Box fontSize={['md', 'xl']} fontWeight={'bold'} flex={1}>
{t('app.Chat Debug')}
{appT('Chat Debug')}
</Box>
<MyTooltip label={t('core.chat.Restart')}>
<IconButton
@@ -160,7 +163,7 @@ const ChatTest = ({
whiteSpace={'pre-wrap'}
textAlign={'center'}
>
<Box>{t('app.Advance App TestTip')}</Box>
<Box>{appT('Advance App TestTip')}</Box>
</Flex>
)}
</Flex>

View File

@@ -29,6 +29,7 @@ import DeleteIcon, { hoverDeleteStyles } from '@fastgpt/web/components/common/Ic
import { TTSTypeEnum } from '@/constants/app';
import { getSystemVariables } from '@/web/core/app/utils';
import { useUpdate } from 'ahooks';
import { useI18n } from '@/web/context/I18n';
const DatasetSelectModal = dynamic(() => import('@/components/core/app/DatasetSelectModal'));
const DatasetParamsModal = dynamic(() => import('@/components/core/app/DatasetParamsModal'));
@@ -61,6 +62,8 @@ const EditForm = ({
const theme = useTheme();
const router = useRouter();
const { t } = useTranslation();
const { appT } = useI18n();
const { publishApp, appDetail } = useAppStore();
const { allDatasets } = useDatasetStore();
@@ -200,7 +203,7 @@ const EditForm = ({
<Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/ai'} w={'20px'} />
<Box ml={2} flex={1}>
{t('app.AI Settings')}
{appT('AI Settings')}
</Box>
</Flex>
<Flex alignItems={'center'} mt={5}>

View File

@@ -17,6 +17,7 @@ import { serviceSideProps } from '@/web/common/utils/i18n';
import { useAppStore } from '@/web/core/app/store/useAppStore';
import Head from 'next/head';
import { useTranslation } from 'next-i18next';
import { useI18n } from '@/web/context/I18n';
const FlowEdit = dynamic(() => import('./components/FlowEdit'), {
loading: () => <Loading />
@@ -34,6 +35,8 @@ enum TabEnum {
const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
const { t } = useTranslation();
const { appT } = useI18n();
const router = useRouter();
const theme = useTheme();
const { feConfigs } = useSystemStore();
@@ -74,10 +77,10 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
id: TabEnum.publish,
icon: 'support/outlink/shareLight'
},
{ label: t('app.Chat logs'), id: TabEnum.logs, icon: 'core/app/logsLight' },
{ label: appT('Chat logs'), id: TabEnum.logs, icon: 'core/app/logsLight' },
{ label: t('core.Start chat'), id: TabEnum.startChat, icon: 'core/chat/chatLight' }
],
[feConfigs?.hide_app_flow, t]
[appT, feConfigs?.hide_app_flow, t]
);
const onCloseFlowEdit = useCallback(() => setCurrentTab(TabEnum.simpleEdit), [setCurrentTab]);
@@ -150,7 +153,7 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
borderRadius={'50%'}
aria-label={''}
/>
{t('app.My Apps')}
{appT('My Apps')}
</Flex>
</Box>
{/* phone tab */}
@@ -193,7 +196,7 @@ export async function getServerSideProps(context: any) {
const currentTab = context?.query?.currentTab || TabEnum.simpleEdit;
return {
props: { currentTab, ...(await serviceSideProps(context)) }
props: { currentTab, ...(await serviceSideProps(context, ['app'])) }
};
}

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState, useEffect } from 'react';
import React, { useCallback } from 'react';
import { Box, Grid, Flex, IconButton, Button, useDisclosure } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useQuery } from '@tanstack/react-query';
@@ -7,7 +7,6 @@ import { delModelById } from '@/web/core/app/api';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { serviceSideProps } from '@/web/common/utils/i18n';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import PageContainer from '@/components/PageContainer';
import Avatar from '@/components/Avatar';
@@ -16,10 +15,12 @@ import CreateModal from './component/CreateModal';
import { useAppStore } from '@/web/core/app/store/useAppStore';
import PermissionIconText from '@/components/support/permission/IconText';
import { useUserStore } from '@/web/support/user/useUserStore';
import { useI18n } from '@/web/context/I18n';
const MyApps = () => {
const { toast } = useToast();
const { t } = useTranslation();
const { appT, commonT } = useI18n();
const router = useRouter();
const { userInfo } = useUserStore();
const { myApps, loadMyApps } = useAppStore();
@@ -62,10 +63,10 @@ const MyApps = () => {
<PageContainer isLoading={isFetching} insertProps={{ px: [5, '48px'] }}>
<Flex pt={[4, '30px']} alignItems={'center'} justifyContent={'space-between'}>
<Box letterSpacing={1} fontSize={['20px', '24px']} color={'myGray.900'}>
{t('app.My Apps')}
{appT('My Apps')}
</Box>
<Button leftIcon={<AddIcon />} variant={'primaryOutline'} onClick={onOpenCreateModal}>
{t('common.New Create')}
{commonT('New Create')}
</Button>
</Flex>
<Grid
@@ -76,7 +77,7 @@ const MyApps = () => {
{myApps.map((app) => (
<MyTooltip
key={app._id}
label={userInfo?.team.canWrite ? t('app.To Settings') : t('app.To Chat')}
label={userInfo?.team.canWrite ? appT('To Settings') : appT('To Chat')}
>
<Box
lineHeight={1.5}
@@ -168,9 +169,6 @@ const MyApps = () => {
</MyTooltip>
))}
</Grid>
{/* (
<ShareBox></ShareBox>
) */}
{myApps.length === 0 && (
<Flex mt={'35vh'} flexDirection={'column'} alignItems={'center'}>
@@ -191,7 +189,7 @@ const MyApps = () => {
export async function getServerSideProps(content: any) {
return {
props: {
...(await serviceSideProps(content))
...(await serviceSideProps(content, ['app']))
}
};
}

View File

@@ -23,6 +23,7 @@ import { useUserStore } from '@/web/support/user/useUserStore';
import { AppListItemType } from '@fastgpt/global/core/app/type';
import { useQuery } from '@tanstack/react-query';
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
import { useI18n } from '@/web/context/I18n';
type HistoryItemType = {
id: string;
@@ -68,6 +69,8 @@ const ChatHistorySlider = ({
const theme = useTheme();
const router = useRouter();
const { t } = useTranslation();
const { appT } = useI18n();
const { isPc } = useSystemStore();
const { userInfo } = useUserStore();
@@ -86,7 +89,8 @@ const ChatHistorySlider = ({
const concatHistory = useMemo<HistoryItemType[]>(
() =>
!activeChatId
? [{ id: activeChatId, title: t('core.chat.New Chat') }].concat(history)
? //@ts-ignore
[{ id: activeChatId, title: t('core.chat.New Chat') }].concat(history)
: history,
[activeChatId, history, t]
);
@@ -115,7 +119,7 @@ const ChatHistorySlider = ({
whiteSpace={'nowrap'}
>
{isPc && (
<MyTooltip label={canRouteToDetail ? t('app.App Detail') : ''} offset={[0, 0]}>
<MyTooltip label={canRouteToDetail ? appT('App Detail') : ''} offset={[0, 0]}>
<Flex
pt={5}
pb={2}

View File

@@ -17,6 +17,7 @@ import {
} from '@/web/core/workflow/utils';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext, getWorkflowStore } from '@/components/core/workflow/context';
import { useI18n } from '@/web/context/I18n';
const ImportSettings = dynamic(() => import('@/components/core/workflow/Flow/ImportSettings'));
@@ -25,6 +26,8 @@ type Props = { plugin: PluginItemSchema; onClose: () => void };
const Header = ({ plugin, onClose }: Props) => {
const theme = useTheme();
const { t } = useTranslation();
const { appT } = useI18n();
const { toast } = useToast();
const { copyData } = useCopyData();
const edges = useContextSelector(WorkflowContext, (v) => v.edges);
@@ -77,10 +80,10 @@ const Header = ({ plugin, onClose }: Props) => {
null,
2
),
t('app.Export Config Successful')
appT('Export Config Successful')
);
}
}, [copyData, flowData2StoreDataAndCheck, t]);
}, [appT, copyData, flowData2StoreDataAndCheck]);
const Render = useMemo(() => {
return (
@@ -118,9 +121,9 @@ const Header = ({ plugin, onClose }: Props) => {
/>
}
menuList={[
{ label: t('app.Import Configs'), icon: 'common/importLight', onClick: onOpenImport },
{ label: appT('Import Configs'), icon: 'common/importLight', onClick: onOpenImport },
{
label: t('app.Export Configs'),
label: appT('Export Configs'),
icon: 'export',
onClick: onCopy
}
@@ -139,6 +142,7 @@ const Header = ({ plugin, onClose }: Props) => {
</>
);
}, [
appT,
isLoading,
isOpenImport,
onClose,