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