From 7a32e8ba10ef37618486269cde5b83258f52ef0f Mon Sep 17 00:00:00 2001 From: cca313 Date: Sat, 30 Mar 2024 11:16:43 +0800 Subject: [PATCH 1/4] add knowledge base tab --- .../src/app/knowledge/(desktop)/index.tsx | 29 +++++++++++++++++++ .../knowledge/(desktop)/layout.desktop.tsx | 23 +++++++++++++++ frontend/src/app/knowledge/page.tsx | 9 ++++++ frontend/src/features/SideBar/TopActions.tsx | 11 ++++++- .../global/slices/common/initialState.ts | 1 + 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 frontend/src/app/knowledge/(desktop)/index.tsx create mode 100644 frontend/src/app/knowledge/(desktop)/layout.desktop.tsx create mode 100644 frontend/src/app/knowledge/page.tsx diff --git a/frontend/src/app/knowledge/(desktop)/index.tsx b/frontend/src/app/knowledge/(desktop)/index.tsx new file mode 100644 index 00000000..f3dc3fb8 --- /dev/null +++ b/frontend/src/app/knowledge/(desktop)/index.tsx @@ -0,0 +1,29 @@ +'use client'; + +import dynamic from 'next/dynamic'; +import { FC, memo } from 'react'; +import { Flexbox } from 'react-layout-kit'; + +import ResponsiveIndex from '@/components/ResponsiveIndex'; + +import PageTitle from '../features/PageTitle'; +import ChatHeader from './features/ChatHeader'; +import Conversation from './features/Conversation'; +import SideBar from './features/SideBar'; +import Layout from './layout.desktop'; + +const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC; + +const DesktopPage = memo(() => ( + + + + + + + + + + +)); +export default DesktopPage; diff --git a/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx b/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx new file mode 100644 index 00000000..94e2a462 --- /dev/null +++ b/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { PropsWithChildren, memo } from 'react'; +import { Flexbox } from 'react-layout-kit'; + +import AppLayoutDesktop from '@/layout/AppLayout.desktop'; +import { SidebarTabKey } from '@/store/global/initialState'; + + +export default memo(({ children }: PropsWithChildren) => { + return ( + + + {children} + + + ); +}); diff --git a/frontend/src/app/knowledge/page.tsx b/frontend/src/app/knowledge/page.tsx new file mode 100644 index 00000000..2fbc496a --- /dev/null +++ b/frontend/src/app/knowledge/page.tsx @@ -0,0 +1,9 @@ +const Page = () => { + // const mobile = isMobileDevice(); + + // const Page = mobile ? MobilePage : DesktopPage; + + return
321
; +}; + +export default Page; diff --git a/frontend/src/features/SideBar/TopActions.tsx b/frontend/src/features/SideBar/TopActions.tsx index 66f5a0ab..df1a4c07 100644 --- a/frontend/src/features/SideBar/TopActions.tsx +++ b/frontend/src/features/SideBar/TopActions.tsx @@ -1,5 +1,5 @@ import { ActionIcon } from '@lobehub/ui'; -import { Compass, MessageSquare } from 'lucide-react'; +import { Compass, Library, MessageSquare } from 'lucide-react'; import Link from 'next/link'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -43,6 +43,15 @@ const TopActions = memo(({ tab }) => { title={t('tab.market')} /> + + + ); }); diff --git a/frontend/src/store/global/slices/common/initialState.ts b/frontend/src/store/global/slices/common/initialState.ts index dcdb2b82..77a9f0da 100644 --- a/frontend/src/store/global/slices/common/initialState.ts +++ b/frontend/src/store/global/slices/common/initialState.ts @@ -2,6 +2,7 @@ import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.share export enum SidebarTabKey { Chat = 'chat', + Knowledge = 'knowledge', Market = 'market', Setting = 'settings', } From 3d5d1a00faa76ebadbd5e199d762356aa98037f1 Mon Sep 17 00:00:00 2001 From: cca313 Date: Sat, 30 Mar 2024 19:40:03 +0800 Subject: [PATCH 2/4] add knowledge base list --- .../(desktop)/features/KnowledgeCard.tsx | 39 +++++++++++++++++++ .../(desktop)/features/KnowledgeConfig.tsx | 0 .../(desktop)/features/KnowledgeList.tsx | 26 +++++++++++++ .../src/app/knowledge/(desktop)/index.tsx | 19 +++------ .../knowledge/(desktop)/layout.desktop.tsx | 5 +-- frontend/src/app/knowledge/page.tsx | 9 ++++- 6 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx create mode 100644 frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx create mode 100644 frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx new file mode 100644 index 00000000..15e9589d --- /dev/null +++ b/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx @@ -0,0 +1,39 @@ +import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons'; +import { Card, Skeleton } from 'antd'; +import React, { useState } from 'react'; + +const { Meta } = Card; + +interface KnowLedgeCardProps { + intro: string; + name: string; +} +const App: React.FC = (props: KnowLedgeCardProps) => { + const [loading, setLoading] = useState(false); + const { name, intro } = props; + const onChange = (checked: boolean) => { + setLoading(!checked); + }; + + return ( + , + , + , + ]} + bordered={false} + style={{ marginTop: 16, width: 300 }} + > + + } + description={intro} + title={name} + /> + + + ); +}; + +export default App; diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx new file mode 100644 index 00000000..08a9b8b1 --- /dev/null +++ b/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx @@ -0,0 +1,26 @@ +import React, { memo } from 'react'; + +import KnowledgeCard from './KnowledgeCard'; + +const list = [ + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, + { intro: 'aaaaa', name: '321' }, +]; + +const RenderList = memo(() => + list.map((item, index) => { + return ; + }), +); + +const KnowledgeCardList = memo(() => { + return ; +}); + +export default KnowledgeCardList; diff --git a/frontend/src/app/knowledge/(desktop)/index.tsx b/frontend/src/app/knowledge/(desktop)/index.tsx index f3dc3fb8..5caf1ba3 100644 --- a/frontend/src/app/knowledge/(desktop)/index.tsx +++ b/frontend/src/app/knowledge/(desktop)/index.tsx @@ -1,27 +1,20 @@ 'use client'; -import dynamic from 'next/dynamic'; -import { FC, memo } from 'react'; +import { memo } from 'react'; import { Flexbox } from 'react-layout-kit'; import ResponsiveIndex from '@/components/ResponsiveIndex'; -import PageTitle from '../features/PageTitle'; -import ChatHeader from './features/ChatHeader'; -import Conversation from './features/Conversation'; -import SideBar from './features/SideBar'; +import KnowledgeCardList from './features/KnowledgeList'; import Layout from './layout.desktop'; -const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC; +// const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC; const DesktopPage = memo(() => ( - +
321
}> - - - - - + +
diff --git a/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx b/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx index 94e2a462..509fec90 100644 --- a/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx +++ b/frontend/src/app/knowledge/(desktop)/layout.desktop.tsx @@ -6,15 +6,14 @@ import { Flexbox } from 'react-layout-kit'; import AppLayoutDesktop from '@/layout/AppLayout.desktop'; import { SidebarTabKey } from '@/store/global/initialState'; - export default memo(({ children }: PropsWithChildren) => { return ( - + {children} diff --git a/frontend/src/app/knowledge/page.tsx b/frontend/src/app/knowledge/page.tsx index 2fbc496a..fc90ec13 100644 --- a/frontend/src/app/knowledge/page.tsx +++ b/frontend/src/app/knowledge/page.tsx @@ -1,9 +1,16 @@ +import DesktopPage from './(desktop)'; + +// import MobilePage from './(mobile)'; +// import SessionHydration from './components/SessionHydration'; +// import Migration from './features/Migration'; + const Page = () => { // const mobile = isMobileDevice(); // const Page = mobile ? MobilePage : DesktopPage; + const Page = DesktopPage; - return
321
; + return ; }; export default Page; From 14dc3f1394f63ea52cc7d1faff4013e751254004 Mon Sep 17 00:00:00 2001 From: cca313 Date: Wed, 10 Apr 2024 17:54:54 +0800 Subject: [PATCH 3/4] =?UTF-8?q?UI=E8=AE=BE=E8=AE=A1=E5=92=8C=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/CreateKnowledgeBase.tsx | 78 +++++++++++ .../(desktop)/features/KnowledgeConfig.tsx | 0 .../src/app/knowledge/(desktop)/index.tsx | 36 ++++-- .../base/[fileId]/features/ModalSegment.tsx | 17 +++ .../app/knowledge/[id]/base/[fileId]/page.tsx | 70 ++++++++++ .../[id]/base/features/ModalAddFile.tsx | 45 +++++++ frontend/src/app/knowledge/[id]/base/page.tsx | 121 ++++++++++++++++++ .../src/app/knowledge/[id]/config/page.tsx | 62 +++++++++ .../[id]/features/KnowledgeBaseConfig.tsx | 31 +++++ frontend/src/app/knowledge/[id]/layout.tsx | 43 +++++++ frontend/src/app/knowledge/[id]/page.tsx | 11 ++ .../src/app/knowledge/[id]/tabs/TabItem.tsx | 50 ++++++++ .../src/app/knowledge/[id]/tabs/index.tsx | 28 ++++ frontend/src/store/global/initialState.ts | 2 +- .../global/slices/common/initialState.ts | 5 + 15 files changed, 588 insertions(+), 11 deletions(-) create mode 100644 frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx delete mode 100644 frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx create mode 100644 frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx create mode 100644 frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx create mode 100644 frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx create mode 100644 frontend/src/app/knowledge/[id]/base/page.tsx create mode 100644 frontend/src/app/knowledge/[id]/config/page.tsx create mode 100644 frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx create mode 100644 frontend/src/app/knowledge/[id]/layout.tsx create mode 100644 frontend/src/app/knowledge/[id]/page.tsx create mode 100644 frontend/src/app/knowledge/[id]/tabs/TabItem.tsx create mode 100644 frontend/src/app/knowledge/[id]/tabs/index.tsx diff --git a/frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx b/frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx new file mode 100644 index 00000000..737274a0 --- /dev/null +++ b/frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx @@ -0,0 +1,78 @@ +import { Modal, type ModalProps } from '@lobehub/ui'; +import { Form, Input, Select } from 'antd'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Flexbox } from 'react-layout-kit'; + +// export const imageTypeOptions: SegmentedProps['options'] = [ +// { +// label: 'JPG', +// value: ImageType.JPG, +// }, +// { +// label: 'PNG', +// value: ImageType.PNG, +// }, +// { +// label: 'SVG', +// value: ImageType.SVG, +// }, +// { +// label: 'WEBP', +// value: ImageType.WEBP, +// }, +// ]; + +const DEFAULT_FIELD_VALUE = { + // imageType: ImageType.JPG, + withBackground: true, + withFooter: false, + withPluginInfo: false, + withSystemRole: false, +}; + +const CreateKnowledgeBase = memo(({ onClose, open }) => { + const { t } = useTranslation('chat'); + + return ( + +
+ + + + + + + +
+ + + +
+
+ + + +
+
+
+
+ ); +}); + +export default CreateKnowledgeBase; diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeConfig.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/app/knowledge/(desktop)/index.tsx b/frontend/src/app/knowledge/(desktop)/index.tsx index 5caf1ba3..1be83767 100644 --- a/frontend/src/app/knowledge/(desktop)/index.tsx +++ b/frontend/src/app/knowledge/(desktop)/index.tsx @@ -1,22 +1,38 @@ 'use client'; -import { memo } from 'react'; +import { FloatButton } from 'antd'; +import { Plus } from 'lucide-react'; +import dynamic from 'next/dynamic'; +import { memo, useEffect, useState } from 'react'; import { Flexbox } from 'react-layout-kit'; import ResponsiveIndex from '@/components/ResponsiveIndex'; import KnowledgeCardList from './features/KnowledgeList'; +// import CreateKnowledgeBase from './features/createKnowledgeBase'; import Layout from './layout.desktop'; +const CreateKnowledgeBase = dynamic(() => import('./features/CreateKnowledgeBase')); // const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC; -const DesktopPage = memo(() => ( -
321
}> - - - - - -
-)); +const DesktopPage = memo(() => { + const [showModal, setShowModal] = useState(false); + useEffect(() => { + setShowModal(true); + }, []); + const onClose = () => setShowModal(false); + return ( +
321
}> + + + + + + } onClick={() => setShowModal(true)}> + 新建知识库 + + +
+ ); +}); export default DesktopPage; diff --git a/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx b/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx new file mode 100644 index 00000000..c5521a4b --- /dev/null +++ b/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx @@ -0,0 +1,17 @@ +import { Input, Modal } from 'antd'; +import { memo } from 'react'; +import { Center, Flexbox } from 'react-layout-kit'; + +const ModalSegment = memo(() => { + return ( + + +
+ +
+
+
+ ); +}); + +export default ModalSegment; diff --git a/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx b/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx new file mode 100644 index 00000000..f87c3248 --- /dev/null +++ b/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx @@ -0,0 +1,70 @@ +'use client'; + +import { Card, List } from 'antd'; +import { createStyles } from 'antd-style'; +import React, { memo, useState } from 'react'; + +import ModalSegment from './features/ModalSegment'; + +const data = [ + { + title: 'Title 1', + }, + { + title: 'Title 2', + }, + { + title: 'Title 3', + }, + { + title: 'Title 4', + }, + { + title: 'Title 5', + }, + { + title: 'Title 6', + }, +]; +const useStyle = createStyles(({ css, token }) => ({ + card: css` + cursor: pointer; + overflow: hidden; + &:hover { + box-shadow: 0 0 0 1px ${token.colorText}; + } + + &:active { + scale: 0.95; + } + `, +})); + +const App = memo(() => { + const { styles } = useStyle(); + const [isShowModal, setModal] = useState(); + return ( + <> + ( + + console.log(1)}> + Card content + + + )} + size="large" + /> + + + ); +}); + +export default App; diff --git a/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx b/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx new file mode 100644 index 00000000..37df8bec --- /dev/null +++ b/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx @@ -0,0 +1,45 @@ +import { InboxOutlined } from '@ant-design/icons'; +import type { UploadProps } from 'antd'; +import { Modal, Upload, message } from 'antd'; +import React, { memo } from 'react'; + +const { Dragger } = Upload; + +const props: UploadProps = { + action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload', + multiple: true, + name: 'file', + onChange(info) { + const { status } = info.file; + if (status !== 'uploading') { + console.log(info.file, info.fileList); + } + if (status === 'done') { + message.success(`${info.file.name} file uploaded successfully.`); + } else if (status === 'error') { + message.error(`${info.file.name} file upload failed.`); + } + }, + onDrop(e) { + console.log('Dropped files', e.dataTransfer.files); + }, +}; + +const ModalAddFile = memo(() => { + return ( + + +

+ +

+

Click or drag file to this area to upload

+

+ Support for a single or bulk upload. Strictly prohibited from uploading company data or + other banned files. +

+
+
+ ); +}); + +export default ModalAddFile; diff --git a/frontend/src/app/knowledge/[id]/base/page.tsx b/frontend/src/app/knowledge/[id]/base/page.tsx new file mode 100644 index 00000000..603e6625 --- /dev/null +++ b/frontend/src/app/knowledge/[id]/base/page.tsx @@ -0,0 +1,121 @@ +'use client'; + +import { Button, Table } from 'antd'; +import type { TableColumnsType } from 'antd'; +import React, { useState } from 'react'; +import { Flexbox } from 'react-layout-kit'; + +import ModalAddFile from './features/ModalAddFile'; + +interface DataType { + address: string; + age: number; + key: React.Key; + name: string; +} + +const columns: TableColumnsType = [ + { + dataIndex: 'index', + title: '序号', + }, + { + dataIndex: 'name', + title: '文档名称', + }, + { + dataIndex: 'loader', + title: '文档加载器', + }, + { + dataIndex: 'loader', + title: '文档加载器', + }, + { + dataIndex: 'splitter', + title: '分词器', + }, + { + dataIndex: 'source', + title: '源文件', + }, + { + dataIndex: 'vector', + title: '向量库', + }, +]; + +const data: DataType[] = []; +for (let i = 0; i < 46; i++) { + data.push({ + address: `London, Park Lane no. ${i}`, + age: 32, + key: i, + name: `Edward King ${i}`, + }); +} + +const App: React.FC = () => { + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [loading, setLoading] = useState(false); + + const start = () => { + setLoading(true); + // ajax request after empty completing + setTimeout(() => { + setSelectedRowKeys([]); + setLoading(false); + }, 1000); + }; + + const onSelectChange = (newSelectedRowKeys: React.Key[]) => { + console.log('selectedRowKeys changed:', newSelectedRowKeys); + setSelectedRowKeys(newSelectedRowKeys); + }; + + const rowSelection = { + onChange: onSelectChange, + selectedRowKeys, + }; + const hasSelected = selectedRowKeys.length > 0; + + return ( + <> + + + + + + + + + {hasSelected ? `Selected ${selectedRowKeys.length} items` : ''} + + +
+ +
+
+ + + + + ); +}; + +export default App; diff --git a/frontend/src/app/knowledge/[id]/config/page.tsx b/frontend/src/app/knowledge/[id]/config/page.tsx new file mode 100644 index 00000000..6b607537 --- /dev/null +++ b/frontend/src/app/knowledge/[id]/config/page.tsx @@ -0,0 +1,62 @@ +'use client'; + +import { Form, type ItemGroup } from '@lobehub/ui'; +import { Form as AntForm, Input, InputNumber, Slider, Switch } from 'antd'; +import { Settings } from 'lucide-react'; +import { memo, useCallback } from 'react'; + +import { FORM_STYLE } from '@/const/layoutTokens'; + +const KnowledgeBaseConfig = memo(() => { + const [form] = AntForm.useForm(); + + const handleConfigChange = useCallback(() => { + console.log(321); + }, []); + const system: ItemGroup = { + children: [ + { + children: , + desc: '名称', + label: '知识库名称', + name: 'name', + }, + { + children: , + desc: '简介', + label: '知识库简介', + name: 'intro', + }, + { + children: , + desc: '321', + label: '单段文本最大长度', + name: 'paragraphMaxLength', + }, + { + children: , + desc: '321', + label: '相邻文本重合长度', + name: 'paragraphOverlapLength', + }, + { + children: , + desc: '321', + label: '文本匹配条数', + name: 'paragraphMatchCount', + }, + { + children: , + desc: '321', + label: '开启中文标题加强', + name: 'chineseTitleEnhance', + }, + ], + icon: Settings, + title: '知识库设置', + }; + + return
; +}); + +export default KnowledgeBaseConfig; diff --git a/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx b/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx new file mode 100644 index 00000000..2a7af4dd --- /dev/null +++ b/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx @@ -0,0 +1,31 @@ +import { Form, type ItemGroup } from '@lobehub/ui'; +import { Form as AntForm, Input } from 'antd'; +import { AppWindow } from 'lucide-react'; +import { memo, useCallback } from 'react'; + +import { FORM_STYLE } from '@/const/layoutTokens'; + +// 参考settings/llm/Anthropic/index.tsx的代码生成一个名为KnowledgeBaseConfig.tsx的表单组件 +const KnowledgeBaseConfig = memo(() => { + const [form] = AntForm.useForm(); + + const handleConfigChange = useCallback(() => { + console.log(321); + }, []); + const system: ItemGroup = { + children: [ + { + children: , + desc: '知识库名称321', + label: '知识库名称', + name: 'password', + }, + ], + icon: AppWindow, + title: '321', + }; + + return ; +}); + +export default KnowledgeBaseConfig; diff --git a/frontend/src/app/knowledge/[id]/layout.tsx b/frontend/src/app/knowledge/[id]/layout.tsx new file mode 100644 index 00000000..e3efe0b4 --- /dev/null +++ b/frontend/src/app/knowledge/[id]/layout.tsx @@ -0,0 +1,43 @@ +'use client'; + +import { createStyles } from 'antd-style'; +import { PropsWithChildren, memo } from 'react'; +import { Center, Flexbox } from 'react-layout-kit'; + +import AppLayoutDesktop from '@/layout/AppLayout.desktop'; +import { SidebarTabKey } from '@/store/global/initialState'; + +import KnowledgeTabs from './tabs'; + +const useStyles = createStyles(({ stylish, token, css }) => ({ + container: { + paddingLeft: 20, + paddingRight: 20, + position: 'relative', + }, +})); + +export default memo(({ children, params }: PropsWithChildren) => { + console.log(params); + return ( + + + + +
图标占位
+
知识库名称
+
+ +
+ +
{children}
+
+
+
+ ); +}); diff --git a/frontend/src/app/knowledge/[id]/page.tsx b/frontend/src/app/knowledge/[id]/page.tsx new file mode 100644 index 00000000..bbf5adb9 --- /dev/null +++ b/frontend/src/app/knowledge/[id]/page.tsx @@ -0,0 +1,11 @@ +'use client'; + +import dynamic from 'next/dynamic'; +import { memo } from 'react'; + +const KnowledgeBaseConfig = dynamic(() => import('./features/KnowledgeBaseConfig')); +const KnowledgeDetail = memo(() => { + return ; +}); + +export default KnowledgeDetail; diff --git a/frontend/src/app/knowledge/[id]/tabs/TabItem.tsx b/frontend/src/app/knowledge/[id]/tabs/TabItem.tsx new file mode 100644 index 00000000..22fcd99a --- /dev/null +++ b/frontend/src/app/knowledge/[id]/tabs/TabItem.tsx @@ -0,0 +1,50 @@ +import { Icon, List } from '@lobehub/ui'; +import { createStyles, useResponsive } from 'antd-style'; +import { ChevronRight, type LucideIcon } from 'lucide-react'; +import { CSSProperties, ReactNode, memo } from 'react'; + +const { Item } = List; + +const useStyles = createStyles(({ css, token, responsive }) => ({ + container: css` + position: relative; + padding-top: 16px; + padding-bottom: 16px; + border-radius: ${token.borderRadius}px; + ${responsive.mobile} { + border-radius: 0; + } + `, + noHover: css` + pointer-events: none; + `, +})); + +export interface ItemProps { + active?: boolean; + className?: string; + hoverable?: boolean; + icon: LucideIcon; + label: ReactNode; + style?: CSSProperties; +} + +const KnowledgeTabItem = memo( + ({ label, icon, hoverable = true, active = false, style, className }) => { + const { cx, styles } = useStyles(); + const { mobile } = useResponsive(); + return ( + } + className={cx(styles.container, !hoverable && styles.noHover, className)} + style={style} + title={label as string} + > + {mobile && } + + ); + }, +); + +export default KnowledgeTabItem; diff --git a/frontend/src/app/knowledge/[id]/tabs/index.tsx b/frontend/src/app/knowledge/[id]/tabs/index.tsx new file mode 100644 index 00000000..9c036bee --- /dev/null +++ b/frontend/src/app/knowledge/[id]/tabs/index.tsx @@ -0,0 +1,28 @@ +import { Settings2, Webhook } from 'lucide-react'; +import Link from 'next/link'; +import { memo } from 'react'; + +import { KnowledgeTabs } from '@/store/global/initialState'; + +import Item from './TabItem'; + +export interface KnowledgeTabsProps { + activeTab?: KnowledgeTabs; + params: Record; +} + +const KnowledgeTabsBox = memo(({ activeTab, params }) => { + console.log(params); + const items = [ + { icon: Webhook, label: '知识库', value: KnowledgeTabs.Base }, + { icon: Settings2, label: '配置', value: KnowledgeTabs.Config }, + ]; + + return items.map(({ value, icon, label }) => ( + + + + )); +}); + +export default KnowledgeTabsBox; diff --git a/frontend/src/store/global/initialState.ts b/frontend/src/store/global/initialState.ts index 0494ffe9..00d70059 100644 --- a/frontend/src/store/global/initialState.ts +++ b/frontend/src/store/global/initialState.ts @@ -2,7 +2,7 @@ import { GlobalCommonState, initialCommonState } from './slices/common/initialSt import { GlobalPreferenceState, initialPreferenceState } from './slices/preference/initialState'; import { GlobalSettingsState, initialSettingsState } from './slices/settings/initialState'; -export { SettingsTabs, SidebarTabKey } from './slices/common/initialState'; +export { KnowledgeTabs, SettingsTabs, SidebarTabKey } from './slices/common/initialState'; export type GlobalState = GlobalCommonState & GlobalSettingsState & GlobalPreferenceState; diff --git a/frontend/src/store/global/slices/common/initialState.ts b/frontend/src/store/global/slices/common/initialState.ts index 77a9f0da..84540c7b 100644 --- a/frontend/src/store/global/slices/common/initialState.ts +++ b/frontend/src/store/global/slices/common/initialState.ts @@ -15,6 +15,11 @@ export enum SettingsTabs { TTS = 'tts', } +export enum KnowledgeTabs { + Base = 'base', + Config = 'config', +} + export interface Guide { // Topic 引导 topic?: boolean; From 6bd3d20996e2902d7cdafb9b6bc62411c7f3af1c Mon Sep 17 00:00:00 2001 From: cca313 Date: Fri, 12 Apr 2024 21:52:50 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BB=A3=E7=A0=81&=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(desktop)/features/KnowledgeCard.tsx | 24 ++--- .../(desktop)/features/KnowledgeList.tsx | 15 ++- ...ledgeBase.tsx => ModalCreateKnowledge.tsx} | 29 ++--- .../src/app/knowledge/(desktop)/index.tsx | 17 +-- .../base/[fileId]/features/ModalSegment.tsx | 9 +- .../app/knowledge/[id]/base/[fileId]/page.tsx | 13 ++- .../[id]/base/features/ModalAddFile.tsx | 9 +- frontend/src/app/knowledge/[id]/base/page.tsx | 101 ++++++++---------- .../src/app/knowledge/[id]/config/page.tsx | 40 ++++--- .../[id]/features/KnowledgeBaseConfig.tsx | 31 ------ frontend/src/app/knowledge/[id]/layout.tsx | 16 ++- frontend/src/app/knowledge/[id]/page.tsx | 11 -- .../src/app/knowledge/[id]/tabs/index.tsx | 24 +++-- frontend/src/store/global/initialState.ts | 2 +- .../global/slices/common/initialState.ts | 5 - 15 files changed, 147 insertions(+), 199 deletions(-) rename frontend/src/app/knowledge/(desktop)/features/{CreateKnowledgeBase.tsx => ModalCreateKnowledge.tsx} (79%) delete mode 100644 frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx delete mode 100644 frontend/src/app/knowledge/[id]/page.tsx diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx index 15e9589d..428b5e82 100644 --- a/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx +++ b/frontend/src/app/knowledge/(desktop)/features/KnowledgeCard.tsx @@ -1,5 +1,6 @@ -import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons'; +import { DeleteOutlined, EditOutlined } from '@ant-design/icons'; import { Card, Skeleton } from 'antd'; +import { useRouter } from 'next/navigation'; import React, { useState } from 'react'; const { Meta } = Card; @@ -8,32 +9,27 @@ interface KnowLedgeCardProps { intro: string; name: string; } -const App: React.FC = (props: KnowLedgeCardProps) => { +const KnowledgeCard: React.FC = (props: KnowLedgeCardProps) => { const [loading, setLoading] = useState(false); const { name, intro } = props; - const onChange = (checked: boolean) => { - setLoading(!checked); + const router = useRouter(); + const handleCardEditClick = () => { + router.push('/knowledge/1/base'); }; - return ( , - , - , + , + , ]} bordered={false} style={{ marginTop: 16, width: 300 }} > - } - description={intro} - title={name} - /> + ); }; -export default App; +export default KnowledgeCard; diff --git a/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx b/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx index 08a9b8b1..927a8308 100644 --- a/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx +++ b/frontend/src/app/knowledge/(desktop)/features/KnowledgeList.tsx @@ -3,14 +3,13 @@ import React, { memo } from 'react'; import KnowledgeCard from './KnowledgeCard'; const list = [ - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, - { intro: 'aaaaa', name: '321' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, + { intro: '知识库简介', name: '知识库名称' }, ]; const RenderList = memo(() => diff --git a/frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx b/frontend/src/app/knowledge/(desktop)/features/ModalCreateKnowledge.tsx similarity index 79% rename from frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx rename to frontend/src/app/knowledge/(desktop)/features/ModalCreateKnowledge.tsx index 737274a0..34efcb7f 100644 --- a/frontend/src/app/knowledge/(desktop)/features/CreateKnowledgeBase.tsx +++ b/frontend/src/app/knowledge/(desktop)/features/ModalCreateKnowledge.tsx @@ -4,25 +4,6 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { Flexbox } from 'react-layout-kit'; -// export const imageTypeOptions: SegmentedProps['options'] = [ -// { -// label: 'JPG', -// value: ImageType.JPG, -// }, -// { -// label: 'PNG', -// value: ImageType.PNG, -// }, -// { -// label: 'SVG', -// value: ImageType.SVG, -// }, -// { -// label: 'WEBP', -// value: ImageType.WEBP, -// }, -// ]; - const DEFAULT_FIELD_VALUE = { // imageType: ImageType.JPG, withBackground: true, @@ -30,8 +11,10 @@ const DEFAULT_FIELD_VALUE = { withPluginInfo: false, withSystemRole: false, }; - -const CreateKnowledgeBase = memo(({ onClose, open }) => { +interface ModalCreateKnowledgeProps extends ModalProps { + toggleModal: (open: boolean) => void; +} +const CreateKnowledgeBase = memo(({ toggleModal, open }) => { const { t } = useTranslation('chat'); return ( @@ -39,8 +22,8 @@ const CreateKnowledgeBase = memo(({ onClose, open }) => { allowFullscreen centered={false} maxHeight={false} - onCancel={onClose} - onOk={onClose} + onCancel={() => toggleModal(false)} + onOk={() => toggleModal(false)} open={open} title="创建知识库" > diff --git a/frontend/src/app/knowledge/(desktop)/index.tsx b/frontend/src/app/knowledge/(desktop)/index.tsx index 1be83767..eca8c602 100644 --- a/frontend/src/app/knowledge/(desktop)/index.tsx +++ b/frontend/src/app/knowledge/(desktop)/index.tsx @@ -3,36 +3,29 @@ import { FloatButton } from 'antd'; import { Plus } from 'lucide-react'; import dynamic from 'next/dynamic'; -import { memo, useEffect, useState } from 'react'; +import { memo, useState } from 'react'; import { Flexbox } from 'react-layout-kit'; -import ResponsiveIndex from '@/components/ResponsiveIndex'; - import KnowledgeCardList from './features/KnowledgeList'; // import CreateKnowledgeBase from './features/createKnowledgeBase'; import Layout from './layout.desktop'; -const CreateKnowledgeBase = dynamic(() => import('./features/CreateKnowledgeBase')); -// const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC; +const ModalCreateKnowledge = dynamic(() => import('./features/ModalCreateKnowledge')); const DesktopPage = memo(() => { const [showModal, setShowModal] = useState(false); - useEffect(() => { - setShowModal(true); - }, []); - const onClose = () => setShowModal(false); return ( -
321
}> + <> - } onClick={() => setShowModal(true)}> 新建知识库 -
+ + ); }); export default DesktopPage; diff --git a/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx b/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx index c5521a4b..600b69bf 100644 --- a/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx +++ b/frontend/src/app/knowledge/[id]/base/[fileId]/features/ModalSegment.tsx @@ -2,9 +2,14 @@ import { Input, Modal } from 'antd'; import { memo } from 'react'; import { Center, Flexbox } from 'react-layout-kit'; -const ModalSegment = memo(() => { +type ModalSegmentProps = { + open: boolean; + toggleOpen: (open: boolean) => void; +}; + +const ModalSegment = memo(({ open, toggleOpen }) => { return ( - + toggleOpen(false)} open={open} title="知识片段">
diff --git a/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx b/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx index f87c3248..0749f2ff 100644 --- a/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx +++ b/frontend/src/app/knowledge/[id]/base/[fileId]/page.tsx @@ -2,9 +2,10 @@ import { Card, List } from 'antd'; import { createStyles } from 'antd-style'; +import dynamic from 'next/dynamic'; import React, { memo, useState } from 'react'; -import ModalSegment from './features/ModalSegment'; +const ModalSegment = dynamic(() => import('./features/ModalSegment')); const data = [ { @@ -42,7 +43,11 @@ const useStyle = createStyles(({ css, token }) => ({ const App = memo(() => { const { styles } = useStyle(); - const [isShowModal, setModal] = useState(); + const [isModalOpen, toggleOpen] = useState(false); + console.log(toggleOpen); + const handleSegmentCardClick = () => { + toggleOpen(true); + }; return ( <> { }} renderItem={() => ( - console.log(1)}> + Card content )} size="large" /> - + ); }); diff --git a/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx b/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx index 37df8bec..734159bc 100644 --- a/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx +++ b/frontend/src/app/knowledge/[id]/base/features/ModalAddFile.tsx @@ -5,6 +5,11 @@ import React, { memo } from 'react'; const { Dragger } = Upload; +type ModalAddFileProps = { + open: boolean; + setModalOpen: (open: boolean) => void; +}; + const props: UploadProps = { action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload', multiple: true, @@ -25,9 +30,9 @@ const props: UploadProps = { }, }; -const ModalAddFile = memo(() => { +const ModalAddFile = memo(({ open, setModalOpen }) => { return ( - + setModalOpen(false)} open={open} title="添加文件">

diff --git a/frontend/src/app/knowledge/[id]/base/page.tsx b/frontend/src/app/knowledge/[id]/base/page.tsx index 603e6625..94e1d9ea 100644 --- a/frontend/src/app/knowledge/[id]/base/page.tsx +++ b/frontend/src/app/knowledge/[id]/base/page.tsx @@ -2,11 +2,13 @@ import { Button, Table } from 'antd'; import type { TableColumnsType } from 'antd'; +import dynamic from 'next/dynamic'; +import Link from 'next/link'; import React, { useState } from 'react'; import { Flexbox } from 'react-layout-kit'; -import ModalAddFile from './features/ModalAddFile'; - +// import ModalAddFile from './features/ModalAddFile'; +const ModalAddFile = dynamic(() => import('./features/ModalAddFile')); interface DataType { address: string; age: number; @@ -14,94 +16,82 @@ interface DataType { name: string; } -const columns: TableColumnsType = [ - { - dataIndex: 'index', - title: '序号', - }, - { - dataIndex: 'name', - title: '文档名称', - }, - { - dataIndex: 'loader', - title: '文档加载器', - }, - { - dataIndex: 'loader', - title: '文档加载器', - }, - { - dataIndex: 'splitter', - title: '分词器', - }, - { - dataIndex: 'source', - title: '源文件', - }, - { - dataIndex: 'vector', - title: '向量库', - }, -]; - const data: DataType[] = []; for (let i = 0; i < 46; i++) { data.push({ address: `London, Park Lane no. ${i}`, age: 32, + index: i, key: i, name: `Edward King ${i}`, }); } -const App: React.FC = () => { +const App: React.FC<{ params }> = ({ params }) => { const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [loading, setLoading] = useState(false); - - const start = () => { - setLoading(true); - // ajax request after empty completing - setTimeout(() => { - setSelectedRowKeys([]); - setLoading(false); - }, 1000); - }; - + const [isShowModal, setModal] = useState(false); const onSelectChange = (newSelectedRowKeys: React.Key[]) => { console.log('selectedRowKeys changed:', newSelectedRowKeys); setSelectedRowKeys(newSelectedRowKeys); }; - + const columns: TableColumnsType = [ + { + dataIndex: 'index', + title: '序号', + }, + { + dataIndex: 'name', + render: (text) => {text}, + title: '文档名称', + }, + { + dataIndex: 'loader', + title: '文档加载器', + }, + { + dataIndex: 'loader', + title: '文档加载器', + }, + { + dataIndex: 'splitter', + title: '分词器', + }, + { + dataIndex: 'source', + title: '源文件', + }, + { + dataIndex: 'vector', + title: '向量库', + }, + ]; const rowSelection = { onChange: onSelectChange, selectedRowKeys, }; const hasSelected = selectedRowKeys.length > 0; - + console.log(params); return ( <> - - - - - - {hasSelected ? `Selected ${selectedRowKeys.length} items` : ''} -

-
@@ -110,10 +100,11 @@ const App: React.FC = () => { columns={columns} dataSource={data} rowSelection={rowSelection} + size="middle" style={{ width: '100%' }} /> - + ); }; diff --git a/frontend/src/app/knowledge/[id]/config/page.tsx b/frontend/src/app/knowledge/[id]/config/page.tsx index 6b607537..ac67ac9e 100644 --- a/frontend/src/app/knowledge/[id]/config/page.tsx +++ b/frontend/src/app/knowledge/[id]/config/page.tsx @@ -1,53 +1,58 @@ 'use client'; import { Form, type ItemGroup } from '@lobehub/ui'; -import { Form as AntForm, Input, InputNumber, Slider, Switch } from 'antd'; +import { Form as AntForm, Button, Input, InputNumber, Switch } from 'antd'; import { Settings } from 'lucide-react'; import { memo, useCallback } from 'react'; +import { Flexbox } from 'react-layout-kit'; import { FORM_STYLE } from '@/const/layoutTokens'; const KnowledgeBaseConfig = memo(() => { const [form] = AntForm.useForm(); - const handleConfigChange = useCallback(() => { - console.log(321); - }, []); + const handleConfigChange = useCallback(async () => { + try { + const values = await form.validateFields(); + console.log('Success:', values); + } catch (errorInfo) { + console.log('Failed:', errorInfo); + } + }, [form]); const system: ItemGroup = { children: [ { children: , - desc: '名称', label: '知识库名称', name: 'name', + rules: [{ message: '请输入知识库名称', required: true }], }, { children: , - desc: '简介', label: '知识库简介', name: 'intro', + rules: [{ message: '请输入知识库简介', required: true }], }, { children: , - desc: '321', label: '单段文本最大长度', name: 'paragraphMaxLength', + rules: [{ message: '请输入知识库名称', required: true }], }, { children: , - desc: '321', label: '相邻文本重合长度', name: 'paragraphOverlapLength', + rules: [{ message: '请输入知识库名称', required: true }], }, { - children: , - desc: '321', + children: , label: '文本匹配条数', name: 'paragraphMatchCount', + rules: [{ message: '请输入知识库名称', required: true }], }, { - children: , - desc: '321', + children: , label: '开启中文标题加强', name: 'chineseTitleEnhance', }, @@ -56,7 +61,16 @@ const KnowledgeBaseConfig = memo(() => { title: '知识库设置', }; - return ; + return ( + <> + + + + + + ); }); export default KnowledgeBaseConfig; diff --git a/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx b/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx deleted file mode 100644 index 2a7af4dd..00000000 --- a/frontend/src/app/knowledge/[id]/features/KnowledgeBaseConfig.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Form, type ItemGroup } from '@lobehub/ui'; -import { Form as AntForm, Input } from 'antd'; -import { AppWindow } from 'lucide-react'; -import { memo, useCallback } from 'react'; - -import { FORM_STYLE } from '@/const/layoutTokens'; - -// 参考settings/llm/Anthropic/index.tsx的代码生成一个名为KnowledgeBaseConfig.tsx的表单组件 -const KnowledgeBaseConfig = memo(() => { - const [form] = AntForm.useForm(); - - const handleConfigChange = useCallback(() => { - console.log(321); - }, []); - const system: ItemGroup = { - children: [ - { - children: , - desc: '知识库名称321', - label: '知识库名称', - name: 'password', - }, - ], - icon: AppWindow, - title: '321', - }; - - return ; -}); - -export default KnowledgeBaseConfig; diff --git a/frontend/src/app/knowledge/[id]/layout.tsx b/frontend/src/app/knowledge/[id]/layout.tsx index e3efe0b4..a2806266 100644 --- a/frontend/src/app/knowledge/[id]/layout.tsx +++ b/frontend/src/app/knowledge/[id]/layout.tsx @@ -1,6 +1,5 @@ 'use client'; -import { createStyles } from 'antd-style'; import { PropsWithChildren, memo } from 'react'; import { Center, Flexbox } from 'react-layout-kit'; @@ -9,16 +8,12 @@ import { SidebarTabKey } from '@/store/global/initialState'; import KnowledgeTabs from './tabs'; -const useStyles = createStyles(({ stylish, token, css }) => ({ - container: { - paddingLeft: 20, - paddingRight: 20, - position: 'relative', - }, -})); - -export default memo(({ children, params }: PropsWithChildren) => { +interface LayoutProps extends PropsWithChildren { + params: Record; +} +export default memo(({ children, params }) => { console.log(params); + return ( @@ -32,6 +27,7 @@ export default memo(({ children, params }: PropsWithChildren) => {
图标占位
知识库名称
+ diff --git a/frontend/src/app/knowledge/[id]/page.tsx b/frontend/src/app/knowledge/[id]/page.tsx deleted file mode 100644 index bbf5adb9..00000000 --- a/frontend/src/app/knowledge/[id]/page.tsx +++ /dev/null @@ -1,11 +0,0 @@ -'use client'; - -import dynamic from 'next/dynamic'; -import { memo } from 'react'; - -const KnowledgeBaseConfig = dynamic(() => import('./features/KnowledgeBaseConfig')); -const KnowledgeDetail = memo(() => { - return ; -}); - -export default KnowledgeDetail; diff --git a/frontend/src/app/knowledge/[id]/tabs/index.tsx b/frontend/src/app/knowledge/[id]/tabs/index.tsx index 9c036bee..eac91458 100644 --- a/frontend/src/app/knowledge/[id]/tabs/index.tsx +++ b/frontend/src/app/knowledge/[id]/tabs/index.tsx @@ -1,27 +1,35 @@ import { Settings2, Webhook } from 'lucide-react'; -import Link from 'next/link'; -import { memo } from 'react'; - -import { KnowledgeTabs } from '@/store/global/initialState'; +import { useRouter } from 'next/navigation'; +import { memo, useState } from 'react'; import Item from './TabItem'; +export enum KnowledgeTabs { + Base = 'base', + Config = 'config', +} + export interface KnowledgeTabsProps { activeTab?: KnowledgeTabs; params: Record; } -const KnowledgeTabsBox = memo(({ activeTab, params }) => { +const KnowledgeTabsBox = memo(({ params }) => { console.log(params); + const [activeTab, setActiveTab] = useState(KnowledgeTabs.Base); const items = [ { icon: Webhook, label: '知识库', value: KnowledgeTabs.Base }, { icon: Settings2, label: '配置', value: KnowledgeTabs.Config }, ]; - + const router = useRouter(); + const handleTabClick = (value: KnowledgeTabs) => { + setActiveTab(value); + router.push(`/knowledge/${params.id}/${value}`); + }; return items.map(({ value, icon, label }) => ( - +
handleTabClick(value)}> - +
)); }); diff --git a/frontend/src/store/global/initialState.ts b/frontend/src/store/global/initialState.ts index 00d70059..0494ffe9 100644 --- a/frontend/src/store/global/initialState.ts +++ b/frontend/src/store/global/initialState.ts @@ -2,7 +2,7 @@ import { GlobalCommonState, initialCommonState } from './slices/common/initialSt import { GlobalPreferenceState, initialPreferenceState } from './slices/preference/initialState'; import { GlobalSettingsState, initialSettingsState } from './slices/settings/initialState'; -export { KnowledgeTabs, SettingsTabs, SidebarTabKey } from './slices/common/initialState'; +export { SettingsTabs, SidebarTabKey } from './slices/common/initialState'; export type GlobalState = GlobalCommonState & GlobalSettingsState & GlobalPreferenceState; diff --git a/frontend/src/store/global/slices/common/initialState.ts b/frontend/src/store/global/slices/common/initialState.ts index 84540c7b..77a9f0da 100644 --- a/frontend/src/store/global/slices/common/initialState.ts +++ b/frontend/src/store/global/slices/common/initialState.ts @@ -15,11 +15,6 @@ export enum SettingsTabs { TTS = 'tts', } -export enum KnowledgeTabs { - Base = 'base', - Config = 'config', -} - export interface Guide { // Topic 引导 topic?: boolean;