refactor(knowledge): enhance CustomCollapse component and improve UI consistency

* Updated CustomCollapse to accept React nodes for labels, allowing for more flexible content.
* Replaced static labels with CollapseLabel component to display item counts.
* Introduced EmptyView component for consistent empty state representation across collapsible sections.
* Removed unnecessary styles and improved button click handling to prevent event propagation.
This commit is contained in:
kangfenmao 2025-03-30 14:32:57 +08:00
parent b363cb06a4
commit 94eb7f3a34
3 changed files with 66 additions and 22 deletions

View File

@ -2,7 +2,7 @@ import { Collapse } from 'antd'
import { FC, memo } from 'react' import { FC, memo } from 'react'
interface CustomCollapseProps { interface CustomCollapseProps {
label: string label: React.ReactNode
extra: React.ReactNode extra: React.ReactNode
children: React.ReactNode children: React.ReactNode
} }
@ -24,7 +24,6 @@ const CustomCollapse: FC<CustomCollapseProps> = ({ label, extra, children }) =>
} }
return ( return (
<Collapse <Collapse
collapsible="header"
bordered={false} bordered={false}
style={CollapseStyle} style={CollapseStyle}
defaultActiveKey={['1']} defaultActiveKey={['1']}

View File

@ -122,7 +122,6 @@ const FileIcon = styled.div`
const FileName = styled.div` const FileName = styled.div`
font-size: 15px; font-size: 15px;
font-weight: bold;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -130,7 +129,6 @@ const FileName = styled.div`
transition: color 0.2s ease; transition: color 0.2s ease;
span { span {
font-size: 15px; font-size: 15px;
font-weight: bold;
} }
&:hover { &:hover {
color: var(--color-primary); color: var(--color-primary);

View File

@ -8,6 +8,7 @@ import {
SettingOutlined SettingOutlined
} from '@ant-design/icons' } from '@ant-design/icons'
import Ellipsis from '@renderer/components/Ellipsis' import Ellipsis from '@renderer/components/Ellipsis'
import { HStack } from '@renderer/components/Layout'
import PromptPopup from '@renderer/components/Popups/PromptPopup' import PromptPopup from '@renderer/components/Popups/PromptPopup'
import TextEditPopup from '@renderer/components/Popups/TextEditPopup' import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
@ -17,7 +18,7 @@ import { getProviderName } from '@renderer/services/ProviderService'
import { FileType, FileTypes, KnowledgeBase, KnowledgeItem } from '@renderer/types' import { FileType, FileTypes, KnowledgeBase, KnowledgeItem } from '@renderer/types'
import { formatFileSize } from '@renderer/utils' import { formatFileSize } from '@renderer/utils'
import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant' import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant'
import { Alert, Button, Divider, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd' import { Alert, Button, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import VirtualList from 'rc-virtual-list' import VirtualList from 'rc-virtual-list'
import { FC } from 'react' import { FC } from 'react'
@ -237,9 +238,16 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
)} )}
<CustomCollapse <CustomCollapse
label={t('files.title')} label={<CollapseLabel label={t('files.title')} count={fileItems.length} />}
extra={ extra={
<Button type="text" icon={<PlusOutlined />} onClick={handleAddFile} disabled={disabled}> <Button
type="text"
icon={<PlusOutlined />}
onClick={(e) => {
e.stopPropagation()
handleAddFile()
}}
disabled={disabled}>
{t('knowledge.add_file')} {t('knowledge.add_file')}
</Button> </Button>
}> }>
@ -257,7 +265,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<FlexColumn> <FlexColumn>
{fileItems.length === 0 ? ( {fileItems.length === 0 ? (
<Empty /> <EmptyView />
) : ( ) : (
<VirtualList <VirtualList
data={fileItems.reverse()} data={fileItems.reverse()}
@ -315,14 +323,21 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</CustomCollapse> </CustomCollapse>
<CustomCollapse <CustomCollapse
label={t('knowledge.directories')} label={<CollapseLabel label={t('knowledge.directories')} count={directoryItems.length} />}
extra={ extra={
<Button type="text" icon={<PlusOutlined />} onClick={handleAddDirectory} disabled={disabled}> <Button
type="text"
icon={<PlusOutlined />}
onClick={(e) => {
e.stopPropagation()
handleAddDirectory()
}}
disabled={disabled}>
{t('knowledge.add_directory')} {t('knowledge.add_directory')}
</Button> </Button>
}> }>
<FlexColumn> <FlexColumn>
{directoryItems.length === 0 && <Empty />} {directoryItems.length === 0 && <EmptyView />}
{directoryItems.reverse().map((item) => ( {directoryItems.reverse().map((item) => (
<FileItem <FileItem
key={item.id} key={item.id}
@ -358,14 +373,21 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</CustomCollapse> </CustomCollapse>
<CustomCollapse <CustomCollapse
label={t('knowledge.urls')} label={<CollapseLabel label={t('knowledge.urls')} count={urlItems.length} />}
extra={ extra={
<Button type="text" icon={<PlusOutlined />} onClick={handleAddUrl} disabled={disabled}> <Button
type="text"
icon={<PlusOutlined />}
onClick={(e) => {
e.stopPropagation()
handleAddUrl()
}}
disabled={disabled}>
{t('knowledge.add_url')} {t('knowledge.add_url')}
</Button> </Button>
}> }>
<FlexColumn> <FlexColumn>
{urlItems.length === 0 && <Empty />} {urlItems.length === 0 && <EmptyView />}
{urlItems.reverse().map((item) => ( {urlItems.reverse().map((item) => (
<FileItem <FileItem
key={item.id} key={item.id}
@ -421,14 +443,21 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</CustomCollapse> </CustomCollapse>
<CustomCollapse <CustomCollapse
label={t('knowledge.sitemaps')} label={<CollapseLabel label={t('knowledge.sitemaps')} count={sitemapItems.length} />}
extra={ extra={
<Button type="text" icon={<PlusOutlined />} onClick={handleAddSitemap} disabled={disabled}> <Button
type="text"
icon={<PlusOutlined />}
onClick={(e) => {
e.stopPropagation()
handleAddSitemap()
}}
disabled={disabled}>
{t('knowledge.add_sitemap')} {t('knowledge.add_sitemap')}
</Button> </Button>
}> }>
<FlexColumn> <FlexColumn>
{sitemapItems.length === 0 && <Empty />} {sitemapItems.length === 0 && <EmptyView />}
{sitemapItems.reverse().map((item) => ( {sitemapItems.reverse().map((item) => (
<FileItem <FileItem
key={item.id} key={item.id}
@ -467,14 +496,21 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</CustomCollapse> </CustomCollapse>
<CustomCollapse <CustomCollapse
label={t('knowledge.notes')} label={<CollapseLabel label={t('knowledge.notes')} count={noteItems.length} />}
extra={ extra={
<Button type="text" icon={<PlusOutlined />} onClick={handleAddNote} disabled={disabled}> <Button
type="text"
icon={<PlusOutlined />}
onClick={(e) => {
e.stopPropagation()
handleAddNote()
}}
disabled={disabled}>
{t('knowledge.add_note')} {t('knowledge.add_note')}
</Button> </Button>
}> }>
<FlexColumn> <FlexColumn>
{noteItems.length === 0 && <Empty />} {noteItems.length === 0 && <EmptyView />}
{noteItems.reverse().map((note) => ( {noteItems.reverse().map((note) => (
<FileItem <FileItem
key={note.id} key={note.id}
@ -501,8 +537,6 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
))} ))}
</FlexColumn> </FlexColumn>
</CustomCollapse> </CustomCollapse>
<Divider style={{ margin: '10px 0' }} />
<ModelInfo> <ModelInfo>
<div className="model-header"> <div className="model-header">
<label>{t('knowledge.model_info')}</label> <label>{t('knowledge.model_info')}</label>
@ -548,6 +582,19 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
) )
} }
const EmptyView = () => <Empty style={{ margin: 0 }} styles={{ image: { display: 'none' } }} />
const CollapseLabel = ({ label, count }: { label: string; count: number }) => {
return (
<HStack alignItems="center" gap={10}>
<label>{label}</label>
<Tag style={{ borderRadius: 100, padding: '0 10px' }} color={count ? 'green' : 'default'}>
{count}
</Tag>
</HStack>
)
}
const MainContent = styled(Scrollbar)` const MainContent = styled(Scrollbar)`
display: flex; display: flex;
width: 100%; width: 100%;