From 2673be8bc1503ffd81edea28b6f70a14ceea33fa Mon Sep 17 00:00:00 2001 From: balibabu <cike8899@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:44:09 +0800 Subject: [PATCH] remove showDeleteConfirm function and center the Empty of knowledge list and extract the text of the login page to en.json (#203) feat: remove showDeleteConfirm function feat: center the Empty of knowledge list feat: extract the text of the login page to en.json #204 --- web/src/app.tsx | 18 ++++---- .../components/deleting-confirm/index.less | 0 web/src/components/deleting-confirm/index.tsx | 39 ---------------- web/src/components/svg-icon.tsx | 1 - .../hooks/{commonHooks.ts => commonHooks.tsx} | 45 ++++++++++++++++++- web/src/hooks/knowledgeHook.ts | 6 ++- web/src/layouts/components/header/index.tsx | 8 ++-- web/src/locales/en.json | 31 ++++++++++++- .../components/knowledge-file/model.ts | 2 - .../parsing-action-cell/index.tsx | 3 +- web/src/pages/chat/hooks.ts | 5 ++- web/src/pages/knowledge/index.less | 3 ++ web/src/pages/knowledge/index.tsx | 12 ++--- .../pages/knowledge/knowledge-card/index.tsx | 3 +- .../knowledge-creating-modal/index.tsx | 10 +++-- web/src/pages/login/index.tsx | 45 +++++++++---------- 16 files changed, 134 insertions(+), 97 deletions(-) delete mode 100644 web/src/components/deleting-confirm/index.less delete mode 100644 web/src/components/deleting-confirm/index.tsx rename web/src/hooks/{commonHooks.ts => commonHooks.tsx} (60%) diff --git a/web/src/app.tsx b/web/src/app.tsx index 51ce756..746b649 100644 --- a/web/src/app.tsx +++ b/web/src/app.tsx @@ -1,16 +1,16 @@ -import { ConfigProvider } from 'antd'; -import React, { ReactNode } from 'react'; +import { App, ConfigProvider } from 'antd'; +import { ReactNode } from 'react'; export function rootContainer(container: ReactNode) { - return React.createElement( - ConfigProvider, - { - theme: { + return ( + <ConfigProvider + theme={{ token: { fontFamily: 'Inter', }, - }, - }, - container, + }} + > + <App> {container}</App> + </ConfigProvider> ); } diff --git a/web/src/components/deleting-confirm/index.less b/web/src/components/deleting-confirm/index.less deleted file mode 100644 index e69de29..0000000 diff --git a/web/src/components/deleting-confirm/index.tsx b/web/src/components/deleting-confirm/index.tsx deleted file mode 100644 index bd6377a..0000000 --- a/web/src/components/deleting-confirm/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { ExclamationCircleFilled } from '@ant-design/icons'; -import { Modal } from 'antd'; - -const { confirm } = Modal; - -interface IProps { - onOk?: (...args: any[]) => any; - onCancel?: (...args: any[]) => any; -} - -export const showDeleteConfirm = ({ - onOk, - onCancel, -}: IProps): Promise<number> => { - return new Promise((resolve, reject) => { - confirm({ - title: 'Are you sure delete this item?', - icon: <ExclamationCircleFilled />, - content: 'Some descriptions', - okText: 'Yes', - okType: 'danger', - cancelText: 'No', - async onOk() { - try { - const ret = await onOk?.(); - resolve(ret); - console.info(ret); - } catch (error) { - reject(error); - } - }, - onCancel() { - onCancel?.(); - }, - }); - }); -}; - -export default showDeleteConfirm; diff --git a/web/src/components/svg-icon.tsx b/web/src/components/svg-icon.tsx index c0a625c..f740f2c 100644 --- a/web/src/components/svg-icon.tsx +++ b/web/src/components/svg-icon.tsx @@ -4,7 +4,6 @@ import { IconComponentProps } from '@ant-design/icons/lib/components/Icon'; const importAll = (requireContext: __WebpackModuleApi.RequireContext) => { const list = requireContext.keys().map((key) => { const name = key.replace(/\.\/(.*)\.\w+$/, '$1'); - console.log(name, requireContext(key)); return { name, value: requireContext(key) }; }); return list; diff --git a/web/src/hooks/commonHooks.ts b/web/src/hooks/commonHooks.tsx similarity index 60% rename from web/src/hooks/commonHooks.ts rename to web/src/hooks/commonHooks.tsx index 21e6641..b087fb9 100644 --- a/web/src/hooks/commonHooks.ts +++ b/web/src/hooks/commonHooks.tsx @@ -1,5 +1,8 @@ +import { ExclamationCircleFilled } from '@ant-design/icons'; +import { App } from 'antd'; import isEqual from 'lodash/isEqual'; -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; export const useSetModalState = () => { const [visible, setVisible] = useState(false); @@ -72,3 +75,43 @@ export function useDynamicSVGImport( return { error, loading, SvgIcon: ImportedIconRef.current }; } + +interface IProps { + onOk?: (...args: any[]) => any; + onCancel?: (...args: any[]) => any; +} + +export const useShowDeleteConfirm = () => { + const { modal } = App.useApp(); + const { t } = useTranslation(); + + const showDeleteConfirm = useCallback( + ({ onOk, onCancel }: IProps): Promise<number> => { + return new Promise((resolve, reject) => { + modal.confirm({ + title: t('common.deleteModalTitle'), + icon: <ExclamationCircleFilled />, + // content: 'Some descriptions', + okText: 'Yes', + okType: 'danger', + cancelText: 'No', + async onOk() { + try { + const ret = await onOk?.(); + resolve(ret); + console.info(ret); + } catch (error) { + reject(error); + } + }, + onCancel() { + onCancel?.(); + }, + }); + }); + }, + [t, modal], + ); + + return showDeleteConfirm; +}; diff --git a/web/src/hooks/knowledgeHook.ts b/web/src/hooks/knowledgeHook.ts index 8a0f7a3..e34917b 100644 --- a/web/src/hooks/knowledgeHook.ts +++ b/web/src/hooks/knowledgeHook.ts @@ -1,4 +1,4 @@ -import showDeleteConfirm from '@/components/deleting-confirm'; +import { useShowDeleteConfirm } from '@/hooks/commonHooks'; import { IKnowledge } from '@/interfaces/database/knowledge'; import { useCallback, useEffect, useMemo } from 'react'; import { useDispatch, useSearchParams, useSelector } from 'umi'; @@ -17,6 +17,7 @@ export const useDeleteDocumentById = (): { } => { const dispatch = useDispatch(); const knowledgeBaseId = useKnowledgeBaseId(); + const showDeleteConfirm = useShowDeleteConfirm(); const removeDocument = (documentId: string) => () => { return dispatch({ @@ -79,6 +80,7 @@ export const useDeleteChunkByIds = (): { removeChunk: (chunkIds: string[], documentId: string) => Promise<number>; } => { const dispatch = useDispatch(); + const showDeleteConfirm = useShowDeleteConfirm(); const removeChunk = useCallback( (chunkIds: string[], documentId: string) => () => { @@ -97,7 +99,7 @@ export const useDeleteChunkByIds = (): { (chunkIds: string[], documentId: string): Promise<number> => { return showDeleteConfirm({ onOk: removeChunk(chunkIds, documentId) }); }, - [removeChunk], + [removeChunk, showDeleteConfirm], ); return { diff --git a/web/src/layouts/components/header/index.tsx b/web/src/layouts/components/header/index.tsx index 4dc0191..d0d2827 100644 --- a/web/src/layouts/components/header/index.tsx +++ b/web/src/layouts/components/header/index.tsx @@ -8,6 +8,7 @@ import styles from './index.less'; import { useNavigateWithFromState } from '@/hooks/routeHook'; import { useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; import { useLocation } from 'umi'; const { Header } = Layout; @@ -18,14 +19,15 @@ const RagHeader = () => { } = theme.useToken(); const navigate = useNavigateWithFromState(); const { pathname } = useLocation(); + const { t } = useTranslation('translation', { keyPrefix: 'header' }); const tagsData = useMemo( () => [ - { path: '/knowledge', name: 'Knowledge Base', icon: KnowledgeBaseIcon }, - { path: '/chat', name: 'Chat', icon: StarIon }, + { path: '/knowledge', name: t('knowledgeBase'), icon: KnowledgeBaseIcon }, + { path: '/chat', name: t('chat'), icon: StarIon }, // { path: '/file', name: 'File Management', icon: FileIcon }, ], - [], + [t], ); const currentPath = useMemo(() => { diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 9f0778e..705e7fb 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -1,12 +1,41 @@ { - "login": { "login": "Sign in" }, + "common": { + "delete": "Delete", + "deleteModalTitle": "Are you sure delete this item?" + }, + "login": { + "login": "Sign in", + "signUp": "Sign up", + "loginDescription": "We’re so excited to see you again!", + "registerDescription": "Glad to have you on board!", + "emailLabel": "Email", + "emailPlaceholder": "Please input email", + "passwordLabel": "Password", + "passwordPlaceholder": "Please input password", + "rememberMe": "Remember me", + "signInTip": "Don’t have an account?", + "signUpTip": "Already have an account?", + "nicknameLabel": "Nickname", + "nicknamePlaceholder": "Please input nickname", + "register": "Create an account", + "continue": "Continue" + }, "header": { + "knowledgeBase": "Knowledge Base", + "chat": "Chat", "register": "Register", "signin": "Sign in", "home": "Home", "setting": "用ć·č®ľç˝®", "logout": "登出" }, + "knowledgeList": { + "welcome": "Welcome back", + "description": "Which database are we going to use today?", + "createKnowledgeBase": "Create knowledge base", + "name": "Name", + "namePlaceholder": "Please input name!" + }, "footer": { "detail": "All rights reserved @ React" }, diff --git a/web/src/pages/add-knowledge/components/knowledge-file/model.ts b/web/src/pages/add-knowledge/components/knowledge-file/model.ts index 97a75a5..f946c9d 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/model.ts +++ b/web/src/pages/add-knowledge/components/knowledge-file/model.ts @@ -203,7 +203,6 @@ const model: DvaModel<KFModelState> = { const documentId = payload; try { const ret = yield call(getDocumentFile, documentId); - console.info('fetch_document_file:', ret); return ret; } catch (error) { console.warn(error); @@ -238,7 +237,6 @@ const model: DvaModel<KFModelState> = { payload: { current: 1, pageSize: 10 }, }); } - console.info(location); }); }, }, diff --git a/web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx b/web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx index 55fd93d..480fa15 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx @@ -1,4 +1,4 @@ -import showDeleteConfirm from '@/components/deleting-confirm'; +import { useShowDeleteConfirm } from '@/hooks/commonHooks'; import { useRemoveDocument } from '@/hooks/documentHooks'; import { IKnowledgeFile } from '@/interfaces/database/knowledge'; import { api_host } from '@/utils/api'; @@ -31,6 +31,7 @@ const ParsingActionCell = ({ const isRunning = isParserRunning(record.run); const removeDocument = useRemoveDocument(documentId); + const showDeleteConfirm = useShowDeleteConfirm(); const onRmDocument = () => { if (!isRunning) { diff --git a/web/src/pages/chat/hooks.ts b/web/src/pages/chat/hooks.ts index 725d8aa..c81006e 100644 --- a/web/src/pages/chat/hooks.ts +++ b/web/src/pages/chat/hooks.ts @@ -1,7 +1,6 @@ -import showDeleteConfirm from '@/components/deleting-confirm'; import { MessageType } from '@/constants/chat'; import { fileIconMap } from '@/constants/common'; -import { useSetModalState } from '@/hooks/commonHooks'; +import { useSetModalState, useShowDeleteConfirm } from '@/hooks/commonHooks'; import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; import { IConversation, IDialog } from '@/interfaces/database/chat'; import { IChunk } from '@/interfaces/database/knowledge'; @@ -150,6 +149,7 @@ export const useSelectPromptConfigParameters = (): VariableTableDataType[] => { export const useRemoveDialog = () => { const dispatch = useDispatch(); + const showDeleteConfirm = useShowDeleteConfirm(); const removeDocument = (dialogIds: Array<string>) => () => { return dispatch({ @@ -668,6 +668,7 @@ export const useRemoveConversation = () => { const dispatch = useDispatch(); const { dialogId } = useGetChatSearchParams(); const { handleClickConversation } = useClickConversationCard(); + const showDeleteConfirm = useShowDeleteConfirm(); const removeConversation = (conversationIds: Array<string>) => async () => { const ret = await dispatch<any>({ diff --git a/web/src/pages/knowledge/index.less b/web/src/pages/knowledge/index.less index ba92f65..a132081 100644 --- a/web/src/pages/knowledge/index.less +++ b/web/src/pages/knowledge/index.less @@ -44,4 +44,7 @@ .knowledgeCardContainer { padding: 0 60px; overflow: auto; + .knowledgeEmpty { + width: 100%; + } } diff --git a/web/src/pages/knowledge/index.tsx b/web/src/pages/knowledge/index.tsx index b8a3659..9206c22 100644 --- a/web/src/pages/knowledge/index.tsx +++ b/web/src/pages/knowledge/index.tsx @@ -6,22 +6,22 @@ import { Button, Empty, Flex, Space, Spin } from 'antd'; import KnowledgeCard from './knowledge-card'; import KnowledgeCreatingModal from './knowledge-creating-modal'; +import { useTranslation } from 'react-i18next'; import styles from './index.less'; const Knowledge = () => { const { list, loading } = useFetchKnowledgeList(); const userInfo = useSelectUserInfo(); + const { t } = useTranslation('translation', { keyPrefix: 'knowledgeList' }); return ( <Flex className={styles.knowledge} vertical flex={1}> <div className={styles.topWrapper}> <div> <span className={styles.title}> - Welcome back, {userInfo.nickname} + {t('welcome')}, {userInfo.nickname} </span> - <p className={styles.description}> - Which database are we going to use today? - </p> + <p className={styles.description}>{t('description')}</p> </div> <Space size={'large'}> {/* <Button icon={<FilterIcon />} className={styles.filterButton}> @@ -38,7 +38,7 @@ const Knowledge = () => { }} className={styles.topButton} > - Create knowledge base + {t('createKnowledgeBase')} </Button> <KnowledgeCreatingModal visible={visible} @@ -62,7 +62,7 @@ const Knowledge = () => { ); }) ) : ( - <Empty></Empty> + <Empty className={styles.knowledgeEmpty}></Empty> )} </Flex> </Spin> diff --git a/web/src/pages/knowledge/knowledge-card/index.tsx b/web/src/pages/knowledge/knowledge-card/index.tsx index 4a6a2f6..bc7e337 100644 --- a/web/src/pages/knowledge/knowledge-card/index.tsx +++ b/web/src/pages/knowledge/knowledge-card/index.tsx @@ -1,5 +1,6 @@ import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg'; import { KnowledgeRouteKey } from '@/constants/knowledge'; +import { useShowDeleteConfirm } from '@/hooks/commonHooks'; import { IKnowledge } from '@/interfaces/database/knowledge'; import { formatDate } from '@/utils/date'; import { @@ -11,7 +12,6 @@ import { import { Avatar, Card, Dropdown, MenuProps, Space } from 'antd'; import { useDispatch, useNavigate } from 'umi'; -import showDeleteConfirm from '@/components/deleting-confirm'; import styles from './index.less'; interface IProps { @@ -21,6 +21,7 @@ interface IProps { const KnowledgeCard = ({ item }: IProps) => { const navigate = useNavigate(); const dispatch = useDispatch(); + const showDeleteConfirm = useShowDeleteConfirm(); const removeKnowledge = () => { return dispatch({ diff --git a/web/src/pages/knowledge/knowledge-creating-modal/index.tsx b/web/src/pages/knowledge/knowledge-creating-modal/index.tsx index abb9c25..20eaa06 100644 --- a/web/src/pages/knowledge/knowledge-creating-modal/index.tsx +++ b/web/src/pages/knowledge/knowledge-creating-modal/index.tsx @@ -1,6 +1,7 @@ import { IModalManagerChildrenProps } from '@/components/modal-manager'; import { KnowledgeRouteKey } from '@/constants/knowledge'; import { Form, Input, Modal } from 'antd'; +import { useTranslation } from 'react-i18next'; import { useDispatch, useNavigate, useSelector } from 'umi'; type FieldType = { @@ -17,6 +18,7 @@ const KnowledgeCreatingModal = ({ (state: any) => state.loading.effects['kSModel/createKb'], ); const navigate = useNavigate(); + const { t } = useTranslation('translation', { keyPrefix: 'knowledgeList' }); const handleOk = async () => { const ret = await form.validateFields(); @@ -50,7 +52,7 @@ const KnowledgeCreatingModal = ({ return ( <Modal - title="Create knowledge base" + title={t('createKnowledgeBase')} open={visible} onOk={handleOk} onCancel={handleCancel} @@ -67,11 +69,11 @@ const KnowledgeCreatingModal = ({ form={form} > <Form.Item<FieldType> - label="Name" + label={t('name')} name="name" - rules={[{ required: true, message: 'Please input name!' }]} + rules={[{ required: true, message: t('namePlaceholder') }]} > - <Input /> + <Input placeholder={t('namePlaceholder')} /> </Form.Item> </Form> </Modal> diff --git a/web/src/pages/login/index.tsx b/web/src/pages/login/index.tsx index d494c29..1de7e93 100644 --- a/web/src/pages/login/index.tsx +++ b/web/src/pages/login/index.tsx @@ -1,3 +1,4 @@ +import { useLogin, useRegister } from '@/hooks/loginHooks'; import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; import { rsaPsw } from '@/utils'; import { Button, Checkbox, Form, Input } from 'antd'; @@ -6,7 +7,6 @@ import { useTranslation } from 'react-i18next'; import { Icon, useNavigate } from 'umi'; import RightPanel from './right-panel'; -import { useLogin, useRegister } from '@/hooks/loginHooks'; import styles from './index.less'; const Login = () => { @@ -14,7 +14,7 @@ const Login = () => { const navigate = useNavigate(); const login = useLogin(); const register = useRegister(); - const { t } = useTranslation(); + const { t } = useTranslation('translation', { keyPrefix: 'login' }); // TODO: When the server address request is not accessible, the value of dva-loading always remains true. @@ -75,13 +75,11 @@ const Login = () => { <div className={styles.loginLeft}> <div className={styles.leftContainer}> <div className={styles.loginTitle}> - <div> - {title === 'login' ? t('login.login') : 'Create an account'} - </div> + <div>{title === 'login' ? t('login') : 'Create an account'}</div> <span> {title === 'login' - ? 'We’re so excited to see you again!' - : 'Glad to have you on board!'} + ? t('loginDescription') + : t('registerDescription')} </span> </div> @@ -94,55 +92,52 @@ const Login = () => { <Form.Item {...formItemLayout} name="email" - label="Email" - rules={[{ required: true, message: 'Please input value' }]} + label={t('emailLabel')} + rules={[{ required: true, message: t('emailPlaceholder') }]} > - <Input size="large" placeholder="Please input value" /> + <Input size="large" placeholder={t('emailPlaceholder')} /> </Form.Item> {title === 'register' && ( <Form.Item {...formItemLayout} name="nickname" - label="Nickname" - rules={[ - { required: true, message: 'Please input your nickname' }, - ]} + label={t('nicknameLabel')} + rules={[{ required: true, message: t('nicknamePlaceholder') }]} > - <Input size="large" placeholder="Please input your nickname" /> + <Input size="large" placeholder={t('nicknamePlaceholder')} /> </Form.Item> )} <Form.Item {...formItemLayout} name="password" - label="Password" - rules={[{ required: true, message: 'Please input value' }]} + label={t('passwordLabel')} + rules={[{ required: true, message: t('passwordPlaceholder') }]} > <Input.Password size="large" - placeholder="Please input value" + placeholder={t('passwordPlaceholder')} onPressEnter={onCheck} /> </Form.Item> {title === 'login' && ( <Form.Item name="remember" valuePropName="checked"> - <Checkbox> Remember me</Checkbox> + <Checkbox> {t('rememberMe')}</Checkbox> </Form.Item> )} <div> - {' '} {title === 'login' && ( <div> - Don’t have an account? + {t('signInTip')} <Button type="link" onClick={changeTitle}> - Sign up + {t('signUp')} </Button> </div> )} {title === 'register' && ( <div> - Already have an account? + {t('signUpTip')} <Button type="link" onClick={changeTitle}> - Sign in + {t('login')} </Button> </div> )} @@ -154,7 +149,7 @@ const Login = () => { onClick={onCheck} loading={signLoading} > - {title === 'login' ? 'Sign in' : 'Continue'} + {title === 'login' ? t('login') : t('continue')} </Button> {title === 'login' && ( <> -- GitLab