diff --git a/web/src/assets/svg/chat-star.svg b/web/src/assets/svg/chat-star.svg index eb34c34b3..03b048f42 100644 --- a/web/src/assets/svg/chat-star.svg +++ b/web/src/assets/svg/chat-star.svg @@ -1,11 +1,11 @@ - + + stroke="currentColor" stroke-width="1.68874" stroke-linecap="round" stroke-linejoin="round" /> - + diff --git a/web/src/assets/svg/file-management.svg b/web/src/assets/svg/file-management.svg new file mode 100644 index 000000000..9617c7520 --- /dev/null +++ b/web/src/assets/svg/file-management.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web/src/assets/svg/knowledge-base.svg b/web/src/assets/svg/knowledge-base.svg new file mode 100644 index 000000000..b756e3274 --- /dev/null +++ b/web/src/assets/svg/knowledge-base.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web/src/assets/svg/knowledge-configration.svg b/web/src/assets/svg/knowledge-configration.svg new file mode 100644 index 000000000..ed5d52c81 --- /dev/null +++ b/web/src/assets/svg/knowledge-configration.svg @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/web/src/assets/svg/knowledge-dataset.svg b/web/src/assets/svg/knowledge-dataset.svg new file mode 100644 index 000000000..7b3edfc60 --- /dev/null +++ b/web/src/assets/svg/knowledge-dataset.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/web/src/assets/svg/knowledge-testing.svg b/web/src/assets/svg/knowledge-testing.svg new file mode 100644 index 000000000..22ab9335c --- /dev/null +++ b/web/src/assets/svg/knowledge-testing.svg @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/web/src/assets/svg/moon.svg b/web/src/assets/svg/moon.svg new file mode 100644 index 000000000..14d49b700 --- /dev/null +++ b/web/src/assets/svg/moon.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/web/src/assets/svg/translation.svg b/web/src/assets/svg/translation.svg new file mode 100644 index 000000000..4ba0c1420 --- /dev/null +++ b/web/src/assets/svg/translation.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/web/src/constants/knowledge.ts b/web/src/constants/knowledge.ts new file mode 100644 index 000000000..52fae77a8 --- /dev/null +++ b/web/src/constants/knowledge.ts @@ -0,0 +1,5 @@ +export enum KnowledgeRouteKey { + Dataset = 'dataset', + Testing = 'testing', + Configration = 'configration', +} diff --git a/web/src/layouts/components/header/index.less b/web/src/layouts/components/header/index.less index b396f0739..f27b0720b 100644 --- a/web/src/layouts/components/header/index.less +++ b/web/src/layouts/components/header/index.less @@ -26,9 +26,14 @@ } .radioGroup { - background: rgba(249, 249, 249, 1) !important; & > label { + height: 40px; + line-height: 40px; border: 0 !important; + background-color: rgba(249, 249, 249, 1); + font-weight: @fontWeight700; + font-family: 'Nunito Sans'; + color: rgba(29, 25, 41, 1); &::before { display: none !important; } diff --git a/web/src/layouts/components/header/index.tsx b/web/src/layouts/components/header/index.tsx index fab3ee416..9d69a4464 100644 --- a/web/src/layouts/components/header/index.tsx +++ b/web/src/layouts/components/header/index.tsx @@ -1,12 +1,14 @@ import { ReactComponent as StarIon } from '@/assets/svg/chat-star.svg'; +import { ReactComponent as FileIcon } from '@/assets/svg/file-management.svg'; +import { ReactComponent as KnowledgeBaseIcon } from '@/assets/svg/knowledge-base.svg'; import { ReactComponent as Logo } from '@/assets/svg/logo.svg'; import { Layout, Radio, Space, theme } from 'antd'; +import Toolbar from '../right-toolbar'; import styles from './index.less'; import { useMemo } from 'react'; import { useLocation, useNavigate } from 'umi'; -import User from '../user'; const { Header } = Layout; @@ -18,13 +20,15 @@ const RagHeader = () => { const { pathname } = useLocation(); const tagsData = [ - { path: '/knowledge', name: 'knowledge' }, - { path: '/chat', name: 'chat' }, - { path: '/file', name: 'file' }, + { path: '/knowledge', name: 'Knowledge Base', icon: KnowledgeBaseIcon }, + { path: '/chat', name: 'Chat', icon: StarIon }, + { path: '/file', name: 'File Management', icon: FileIcon }, ]; const currentPath = useMemo(() => { - return tagsData.find((x) => x.path === pathname)?.name || 'knowledge'; + return ( + tagsData.find((x) => pathname.startsWith(x.path))?.name || 'knowledge' + ); }, [pathname]); const handleChange = (path: string) => { @@ -57,16 +61,20 @@ const RagHeader = () => { handleChange(item.path)} + key={item.name} > - + {item.name} ))} - + ); }; diff --git a/web/src/layouts/components/right-toolbar/index.less b/web/src/layouts/components/right-toolbar/index.less new file mode 100644 index 000000000..9f9b9ebc3 --- /dev/null +++ b/web/src/layouts/components/right-toolbar/index.less @@ -0,0 +1,17 @@ +.toolbarWrapper { + :global(.ant-avatar) { + background-color: rgba(242, 243, 245, 1); + } +} + +.circle { + display: inline-block; + line-height: 32px; + width: 32px; + text-align: center; + height: 32px; + border-radius: 50%; + background-color: rgba(242, 243, 245, 1); + vertical-align: middle; + cursor: pointer; +} diff --git a/web/src/layouts/components/right-toolbar/index.tsx b/web/src/layouts/components/right-toolbar/index.tsx new file mode 100644 index 000000000..02b516814 --- /dev/null +++ b/web/src/layouts/components/right-toolbar/index.tsx @@ -0,0 +1,39 @@ +import { ReactComponent as MoonIcon } from '@/assets/svg/moon.svg'; +import { ReactComponent as TranslationIcon } from '@/assets/svg/translation.svg'; +import { BellOutlined, GithubOutlined } from '@ant-design/icons'; +import { Space } from 'antd'; +import React from 'react'; +import User from '../user'; +import styled from './index.less'; + +const Circle = ({ children }: React.PropsWithChildren) => { + return
{children}
; +}; + +const handleGithubCLick = () => { + window.open('https://github.com/infiniflow/infinity', 'target'); +}; + +const RightToolBar = () => { + return ( +
+ + + + + + + + + + + + + + + +
+ ); +}; + +export default RightToolBar; diff --git a/web/src/layouts/components/user/index.tsx b/web/src/layouts/components/user/index.tsx index 51d20eb90..519e1c69b 100644 --- a/web/src/layouts/components/user/index.tsx +++ b/web/src/layouts/components/user/index.tsx @@ -1,6 +1,6 @@ import authorizationUtil from '@/utils/authorizationUtil'; import type { MenuProps } from 'antd'; -import { Button, Dropdown } from 'antd'; +import { Avatar, Button, Dropdown } from 'antd'; import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { history } from 'umi'; @@ -39,14 +39,12 @@ const App: React.FC = () => { }, []); return ( - <> - - - - + + + ); }; diff --git a/web/src/less/variable.less b/web/src/less/variable.less index 37fe53bc7..4820d07f6 100644 --- a/web/src/less/variable.less +++ b/web/src/less/variable.less @@ -1 +1,14 @@ @fontWeight600: 600; +@fontWeight700: 700; + +@gray2: rgba(29, 25, 41, 1); +@gray3: rgba(52, 48, 62, 1); +@gray8: rgba(165, 163, 169, 1); +@gray11: rgba(232, 232, 234, 1); + +@fontSize12: 12px; +@fontSize14: 14px; +@fontSize16: 16px; +@fontSize18: 18px; + +@fontFamilyNunitoSans: 'Nunito Sans'; diff --git a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx index dfda40474..16f304d6c 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx @@ -1,3 +1,4 @@ +import { KnowledgeRouteKey } from '@/constants/knowledge'; import { getOneNamespaceEffectsLoading } from '@/utils/stroreUtil'; import { DownOutlined } from '@ant-design/icons'; import type { MenuProps } from 'antd'; @@ -158,8 +159,9 @@ const KnowledgeFile: React.FC = ({ kb_id }) => { }, ]; const toChunk = (id: string) => { - console.log(id); - navigate(`/knowledge/add/setting?activeKey=file&id=${kb_id}&doc_id=${id}`); + navigate( + `/knowledge/${KnowledgeRouteKey.Dataset}?id=${kb_id}&doc_id=${id}`, + ); }; const columns: ColumnsType = [ { diff --git a/web/src/pages/add-knowledge/components/knowledge-setting/index.tsx b/web/src/pages/add-knowledge/components/knowledge-setting/index.tsx index e7b5659c9..0a43c527f 100644 --- a/web/src/pages/add-knowledge/components/knowledge-setting/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-setting/index.tsx @@ -1,7 +1,9 @@ +import { KnowledgeRouteKey } from '@/constants/knowledge'; import { Button, Form, Input, Radio, Select, Space, Tag } from 'antd'; import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch, useNavigate, useSelector } from 'umi'; import styles from './index.less'; + const { CheckableTag } = Tag; const layout = { labelCol: { span: 8 }, @@ -67,7 +69,7 @@ const KnowledgeSetting: React.FC = ({ kb_id }) => { }, }); retcode === 0 && - navigate(`/knowledge/add/setting?activeKey=file&id=${kb_id}`); + navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${kb_id}`); } } catch (error) { console.warn(error); diff --git a/web/src/pages/add-knowledge/components/knowledge-sidebar/index.less b/web/src/pages/add-knowledge/components/knowledge-sidebar/index.less new file mode 100644 index 000000000..435e1261b --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-sidebar/index.less @@ -0,0 +1,63 @@ +.sidebarWrapper { + max-width: 288px; + padding: 32px 24px 24px 24px; + flex-direction: column; + + .sidebarTop { + text-align: center; + .knowledgeLogo { + } + .knowledgeTitle { + font-family: 'Nunito Sans'; + font-size: 16px; + line-height: 24px; + font-weight: @fontWeight700; + color: @gray2; + margin-bottom: 6px; + } + .knowledgeDescription { + font-family: 'Nunito Sans'; + font-size: 12px; + font-weight: @fontWeight600; + color: @gray8; + margin: 0; + } + padding-bottom: 20px; + } + .divider { + height: 2px; + background-image: linear-gradient( + to right, + @gray11 0%, + @gray11 50%, + transparent 50% + ); + background-size: 10px 2px; + background-repeat: repeat-x; + } + + .menuWrapper { + padding-top: 10px; + + .menu { + border: none; + font-size: @fontSize14; + font-weight: @fontWeight600; + } + + .defaultWidth { + width: 240px; + } + + .minWidth { + width: 50px; + } + + .menuText { + color: @gray3; + font-family: @fontFamilyNunitoSans; + font-size: @fontSize14; + font-weight: @fontWeight700; + } + } +} diff --git a/web/src/pages/add-knowledge/components/knowledge-sidebar/index.tsx b/web/src/pages/add-knowledge/components/knowledge-sidebar/index.tsx new file mode 100644 index 000000000..fda6c3da0 --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-sidebar/index.tsx @@ -0,0 +1,118 @@ +import { ReactComponent as ConfigrationIcon } from '@/assets/svg/knowledge-configration.svg'; +import { ReactComponent as DatasetIcon } from '@/assets/svg/knowledge-dataset.svg'; +import { ReactComponent as TestingIcon } from '@/assets/svg/knowledge-testing.svg'; +import { getWidth } from '@/utils'; +import { AntDesignOutlined } from '@ant-design/icons'; +import { Avatar, Menu, MenuProps, Space } from 'antd'; +import classNames from 'classnames'; +import { useEffect, useMemo, useState } from 'react'; +import { useNavigate, useParams, useSelector } from 'umi'; +import { KnowledgeRouteKey, routeMap } from '../../constant'; +import styles from './index.less'; + +const KnowledgeSidebar = () => { + const kAModel = useSelector((state: any) => state.kAModel); + const { id } = kAModel; + let navigate = useNavigate(); + const params = useParams(); + const activeKey = params.module || KnowledgeRouteKey.Dataset; + + const [windowWidth, setWindowWidth] = useState(getWidth()); + const [collapsed, setCollapsed] = useState(false); + + const handleSelect: MenuProps['onSelect'] = (e) => { + navigate(`/knowledge/${e.key}?id=${id}`); + }; + + type MenuItem = Required['items'][number]; + + function getItem( + label: React.ReactNode, + key: React.Key, + icon?: React.ReactNode, + disabled?: boolean, + children?: MenuItem[], + type?: 'group', + ): MenuItem { + return { + key, + icon, + children, + label, + type, + disabled, + } as MenuItem; + } + const items: MenuItem[] = useMemo(() => { + return [ + getItem( + routeMap[KnowledgeRouteKey.Dataset], // TODO: Change icon color when selected + KnowledgeRouteKey.Dataset, + , + ), + getItem( + routeMap[KnowledgeRouteKey.Testing], + KnowledgeRouteKey.Testing, + , + ), + getItem( + routeMap[KnowledgeRouteKey.Configration], + KnowledgeRouteKey.Configration, + , + ), + ]; + }, [id]); + + useEffect(() => { + if (windowWidth.width > 957) { + setCollapsed(false); + } else { + setCollapsed(true); + } + }, [windowWidth.width]); + + // 标记一下 + useEffect(() => { + const widthSize = () => { + const width = getWidth(); + console.log(width); + + setWindowWidth(width); + }; + window.addEventListener('resize', widthSize); + return () => { + window.removeEventListener('resize', widthSize); + }; + }, []); + + return ( +
+
+ + } /> +
Cloud Computing
+
+

+ A scalable, secure cloud-based database optimized for high-performance + computing and data storage. +

+
+
+
+ 957, + [styles.minWidth]: windowWidth.width <= 957, + })} + inlineCollapsed={collapsed} + items={items} + onSelect={handleSelect} + /> +
+
+ ); +}; + +export default KnowledgeSidebar; diff --git a/web/src/pages/add-knowledge/constant.ts b/web/src/pages/add-knowledge/constant.ts new file mode 100644 index 000000000..c918a3af6 --- /dev/null +++ b/web/src/pages/add-knowledge/constant.ts @@ -0,0 +1,9 @@ +import { KnowledgeRouteKey } from '@/constants/knowledge'; + +export const routeMap = { + [KnowledgeRouteKey.Dataset]: 'Dataset', + [KnowledgeRouteKey.Testing]: 'Retrieval testing', + [KnowledgeRouteKey.Configration]: 'Configuration', +}; + +export * from '@/constants/knowledge'; diff --git a/web/src/pages/add-knowledge/index.less b/web/src/pages/add-knowledge/index.less index d60a41d85..d94c573ab 100644 --- a/web/src/pages/add-knowledge/index.less +++ b/web/src/pages/add-knowledge/index.less @@ -1,19 +1,15 @@ .container { - display: flex; - - .menu { - .defaultWidth { - width: 256px; - } - - .minWidth { - width: 50px - } - } - - .content { - flex: 1; - overflow-x: auto; - height: 100%; - } -} \ No newline at end of file + display: flex; + height: 100%; + .contentWrapper { + flex: 1; + overflow-x: auto; + height: 100%; + background-color: rgba(247, 248, 250, 1); + padding: 16px 20px 28px 40px; + } + .content { + background-color: white; + margin-top: 16px; + } +} diff --git a/web/src/pages/add-knowledge/index.tsx b/web/src/pages/add-knowledge/index.tsx index d2386a771..74942e7b3 100644 --- a/web/src/pages/add-knowledge/index.tsx +++ b/web/src/pages/add-knowledge/index.tsx @@ -1,39 +1,46 @@ -import { getWidth } from '@/utils'; -import { BarsOutlined, SearchOutlined, ToolOutlined } from '@ant-design/icons'; -import type { MenuProps } from 'antd'; -import { Menu } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { useDispatch, useLocation, useNavigate, useSelector } from 'umi'; +import { Breadcrumb } from 'antd'; +import { useEffect, useMemo } from 'react'; +import { + useDispatch, + useLocation, + useNavigate, + useParams, + useSelector, +} from 'umi'; import Chunk from './components/knowledge-chunk'; import File from './components/knowledge-file'; import Search from './components/knowledge-search'; import Setting from './components/knowledge-setting'; +import Siderbar from './components/knowledge-sidebar'; +import { KnowledgeRouteKey, routeMap } from './constant'; import styles from './index.less'; const KnowledgeAdding = () => { const dispatch = useDispatch(); const kAModel = useSelector((state: any) => state.kAModel); - const { id, activeKey, doc_id } = kAModel; + const navigate = useNavigate(); + const { id, doc_id } = kAModel; - const [collapsed, setCollapsed] = useState(false); - const [windowWidth, setWindowWidth] = useState(getWidth()); - let navigate = useNavigate(); const location = useLocation(); + const params = useParams(); + const activeKey: KnowledgeRouteKey = + (params.module as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset; - // 标记一下 - console.log(doc_id, '>>>>>>>>>>>>>doc_id'); - useEffect(() => { - const widthSize = () => { - const width = getWidth(); - console.log(width); + const gotoList = () => { + navigate('/knowledge'); + }; + + const breadcrumbItems = useMemo(() => { + return [ + { + title: Knowledge Base, + }, + { + title: routeMap[activeKey], + }, + ]; + }, [activeKey]); - setWindowWidth(width); - }; - window.addEventListener('resize', widthSize); - return () => { - window.removeEventListener('resize', widthSize); - }; - }, []); useEffect(() => { const search: string = location.search.slice(1); const map = search.split('&').reduce>((obj, cur) => { @@ -51,66 +58,24 @@ const KnowledgeAdding = () => { }); }, [location]); - useEffect(() => { - if (windowWidth.width > 957) { - setCollapsed(false); - } else { - setCollapsed(true); - } - }, [windowWidth.width]); - - type MenuItem = Required['items'][number]; - - function getItem( - label: React.ReactNode, - key: React.Key, - icon?: React.ReactNode, - disabled?: boolean, - children?: MenuItem[], - type?: 'group', - ): MenuItem { - return { - key, - icon, - children, - label, - type, - disabled, - } as MenuItem; - } - const items: MenuItem[] = useMemo(() => { - const disabled = !id; - return [ - getItem('配置', 'setting', ), - getItem('知识库', 'file', , disabled), - getItem('搜索测试', 'search', , disabled), - ]; - }, [id]); - - const handleSelect: MenuProps['onSelect'] = (e) => { - navigate(`/knowledge/add/setting?activeKey=${e.key}&id=${id}`); - }; - return ( <>
-
- 957 ? styles.defaultWidth : styles.minWidth - } - inlineCollapsed={collapsed} - items={items} - onSelect={handleSelect} - /> -
-
- {activeKey === 'file' && !doc_id && } - {activeKey === 'setting' && } - {activeKey === 'search' && } - {activeKey === 'file' && !!doc_id && } + +
+ +
+ {activeKey === KnowledgeRouteKey.Dataset && !doc_id && ( + + )} + {activeKey === KnowledgeRouteKey.Configration && ( + + )} + {activeKey === KnowledgeRouteKey.Testing && } + {activeKey === KnowledgeRouteKey.Dataset && !!doc_id && ( + + )} +
diff --git a/web/src/pages/add-knowledge/model.ts b/web/src/pages/add-knowledge/model.ts index 082074925..accfd7bc4 100644 --- a/web/src/pages/add-knowledge/model.ts +++ b/web/src/pages/add-knowledge/model.ts @@ -3,7 +3,6 @@ export interface kAModelState { isShowPSwModal: boolean; isShowTntModal: boolean; tenantIfo: any; - activeKey: string; id: string; doc_id: string; } @@ -14,7 +13,6 @@ const model: DvaModel = { isShowPSwModal: false, isShowTntModal: false, tenantIfo: {}, - activeKey: 'setting', id: '', doc_id: '', }, diff --git a/web/src/pages/knowledge/index.tsx b/web/src/pages/knowledge/index.tsx index 44734dace..234a9a408 100644 --- a/web/src/pages/knowledge/index.tsx +++ b/web/src/pages/knowledge/index.tsx @@ -20,7 +20,7 @@ const Knowledge = () => { }, []); const handleAddKnowledge = () => { - navigate(`add/setting?activeKey=setting`); + navigate(`add/setting`); }; useEffect(() => { diff --git a/web/src/pages/knowledge/knowledge-card/index.tsx b/web/src/pages/knowledge/knowledge-card/index.tsx index 2536641c0..31aaa3ca1 100644 --- a/web/src/pages/knowledge/knowledge-card/index.tsx +++ b/web/src/pages/knowledge/knowledge-card/index.tsx @@ -1,13 +1,13 @@ import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg'; +import { KnowledgeRouteKey } from '@/constants/knowledge'; import { formatDate } from '@/utils/date'; import { - AntDesignOutlined, CalendarOutlined, DeleteOutlined, FileTextOutlined, UserOutlined, } from '@ant-design/icons'; -import { Avatar, Card, Dropdown, MenuProps, Space, Tooltip } from 'antd'; +import { Avatar, Card, Dropdown, MenuProps, Space } from 'antd'; import { MouseEvent } from 'react'; import { useDispatch, useNavigate } from 'umi'; @@ -47,7 +47,7 @@ const KnowledgeCard = ({ item }: IProps) => { }; const handleCardClick = () => { - navigate(`add/setting?activeKey=file&id=${item.id}`); + navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${item.id}`); }; const onConfirmDelete = (e?: MouseEvent) => { @@ -97,7 +97,7 @@ const KnowledgeCard = ({ item }: IProps) => { {formatDate(item.update_date)}
- + {/* K @@ -112,7 +112,7 @@ const KnowledgeCard = ({ item }: IProps) => { style={{ backgroundColor: '#1677ff' }} icon={} /> - + */} diff --git a/web/src/routes.ts b/web/src/routes.ts index 547404bd2..8e2e5b104 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -16,7 +16,7 @@ const routes = [ component: '@/pages/knowledge', }, { - path: '/knowledge/add/*', + path: '/knowledge/:module', component: '@/pages/add-knowledge', }, {