Fix (next search): Optimize the search problem interface and related functions #3221 (#9569)

### What problem does this PR solve?

Fix (next search): Optimize the search problem interface and related
functions #3221

-Add search_id to the retrievval_test interface
-Optimize handleSearchStrChange and handleSearch callbacks to determine
whether to enable AI search based on search configuration

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2025-08-19 19:22:07 +08:00
committed by GitHub
parent 00f54c207e
commit e6cb74b27f
10 changed files with 147 additions and 164 deletions

View File

@ -0,0 +1,54 @@
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { Card, CardContent } from '@/components/ui/card';
import { formatDate } from '@/utils/date';
interface IProps {
data: {
name: string;
description?: string;
avatar?: string;
update_time?: string | number;
};
onClick?: () => void;
moreDropdown: React.ReactNode;
}
export function HomeCard({ data, onClick, moreDropdown }: IProps) {
return (
<Card
className="bg-bg-card border-colors-outline-neutral-standard"
onClick={() => {
// navigateToSearch(data?.id);
onClick?.();
}}
>
<CardContent className="p-4 flex gap-2 items-start group h-full">
<div className="flex justify-between mb-4">
<RAGFlowAvatar
className="w-[32px] h-[32px]"
avatar={data.avatar}
name={data.name}
/>
</div>
<div className="flex flex-col justify-between gap-1 flex-1 h-full w-[calc(100%-50px)]">
<section className="flex justify-between">
<div className="text-[20px] font-bold w-80% leading-5">
{data.name}
</div>
{moreDropdown}
</section>
<section className="flex flex-col gap-1 mt-1">
<div className="whitespace-nowrap overflow-hidden text-ellipsis">
{data.description}
</div>
<div>
<p className="text-sm opacity-80">
{formatDate(data.update_time)}
</p>
</div>
</section>
</div>
</CardContent>
</Card>
);
}

View File

@ -1,10 +1,7 @@
import { HomeCard } from '@/components/home-card';
import { MoreButton } from '@/components/more-button';
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { SharedBadge } from '@/components/shared-badge';
import { Card, CardContent } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { IFlow } from '@/interfaces/database/agent';
import { formatDate } from '@/utils/date';
import { AgentDropdown } from './agent-dropdown';
import { useRenameAgent } from './use-rename-agent';
@ -16,36 +13,16 @@ export function AgentCard({ data, showAgentRenameModal }: DatasetCardProps) {
const { navigateToAgent } = useNavigatePage();
return (
<Card key={data.id} className="w-40" onClick={navigateToAgent(data.id)}>
<CardContent className="p-2.5 pt-2 group">
<section className="flex justify-between mb-2">
<div className="flex gap-2 items-center">
<RAGFlowAvatar
className="size-6 rounded-lg"
avatar={data.avatar}
name={data.title || 'CN'}
></RAGFlowAvatar>
<SharedBadge>{data.nickname}</SharedBadge>
</div>
<AgentDropdown
showAgentRenameModal={showAgentRenameModal}
agent={data}
>
<MoreButton></MoreButton>
</AgentDropdown>
</section>
<div className="flex justify-between items-end">
<div className="w-full">
<h3 className="text-lg font-semibold mb-2 line-clamp-1">
{data.title}
</h3>
<p className="text-xs text-text-secondary">{data.description}</p>
<p className="text-xs text-text-secondary">
{formatDate(data.update_time)}
</p>
</div>
</div>
</CardContent>
</Card>
<HomeCard
data={{ ...data, name: data.title, description: data.description || '' }}
moreDropdown={
<AgentDropdown showAgentRenameModal={showAgentRenameModal} agent={data}>
<MoreButton></MoreButton>
</AgentDropdown>
}
onClick={() => {
navigateToAgent(data?.id);
}}
/>
);
}

View File

@ -46,7 +46,7 @@ export default function Agents() {
</ListFilterBar>
</div>
<div className="flex-1 overflow-auto">
<div className="flex flex-wrap gap-4 px-8">
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[78vh] overflow-auto px-8">
{data.map((x) => {
return (
<AgentCard

View File

@ -1,10 +1,8 @@
import { HomeCard } from '@/components/home-card';
import { MoreButton } from '@/components/more-button';
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { IKnowledge } from '@/interfaces/database/knowledge';
import { formatDate } from '@/utils/date';
import { ChevronRight } from 'lucide-react';
import { DatasetDropdown } from './dataset-dropdown';
import { useDisplayOwnerName } from './use-display-owner';
@ -24,47 +22,20 @@ export function DatasetCard({
const owner = displayOwnerName(dataset.tenant_id, dataset.nickname);
return (
<Card
key={dataset.id}
className="w-40"
onClick={navigateToDataset(dataset.id)}
>
<CardContent className="p-2.5 pt-2 group">
<section className="flex justify-between mb-2">
<div className="flex gap-2 items-center">
<RAGFlowAvatar
className="size-6 rounded-lg"
avatar={dataset.avatar}
name={dataset.name || 'CN'}
></RAGFlowAvatar>
{owner && (
<Badge className="h-5 rounded-sm px-1 bg-background-badge text-text-badge">
{owner}
</Badge>
)}
</div>
<DatasetDropdown
showDatasetRenameModal={showDatasetRenameModal}
dataset={dataset}
>
<MoreButton></MoreButton>
</DatasetDropdown>
</section>
<div className="flex justify-between items-end">
<div className="w-full">
<h3 className="text-lg font-semibold mb-2 line-clamp-1">
{dataset.name}
</h3>
<p className="text-xs text-text-secondary">
{dataset.doc_num} files
</p>
<p className="text-xs text-text-secondary">
{formatDate(dataset.update_time)}
</p>
</div>
</div>
</CardContent>
</Card>
<HomeCard
data={{ ...dataset, description: `${dataset.doc_num} files` }}
moreDropdown={
<DatasetDropdown
showDatasetRenameModal={showDatasetRenameModal}
dataset={dataset}
>
<MoreButton></MoreButton>
</DatasetDropdown>
}
onClick={() => {
navigateToDataset(dataset.id);
}}
/>
);
}

View File

@ -70,7 +70,7 @@ export default function Datasets() {
</Button>
</ListFilterBar>
<div className="flex-1">
<div className="flex flex-wrap gap-4 max-h-[78vh] overflow-auto px-8">
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[78vh] overflow-auto px-8">
{kbs.map((dataset) => {
return (
<DatasetCard

View File

@ -1,9 +1,7 @@
import { HomeCard } from '@/components/home-card';
import { MoreButton } from '@/components/more-button';
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { Card, CardContent } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { IDialog } from '@/interfaces/database/chat';
import { formatDate } from '@/utils/date';
import { ChatDropdown } from './chat-dropdown';
import { useRenameChat } from './hooks/use-rename-chat';
@ -15,32 +13,21 @@ export function ChatCard({ data, showChatRenameModal }: IProps) {
const { navigateToChat } = useNavigatePage();
return (
<Card key={data.id} className="w-40" onClick={navigateToChat(data.id)}>
<CardContent className="p-2.5 pt-2 group">
<section className="flex justify-between mb-2">
<div className="flex gap-2 items-center">
<RAGFlowAvatar
className="size-6 rounded-lg"
avatar={data.icon}
name={data.name || 'CN'}
></RAGFlowAvatar>
</div>
<ChatDropdown chat={data} showChatRenameModal={showChatRenameModal}>
<MoreButton></MoreButton>
</ChatDropdown>
</section>
<div className="flex justify-between items-end">
<div className="w-full">
<h3 className="text-lg font-semibold mb-2 line-clamp-1 truncate">
{data.name}
</h3>
<p className="text-xs text-text-secondary">{data.description}</p>
<p className="text-xs text-text-secondary">
{formatDate(data.update_time)}
</p>
</div>
</div>
</CardContent>
</Card>
<HomeCard
data={{
name: data.name,
description: data.description,
avatar: data.icon,
update_time: data.update_time,
}}
moreDropdown={
<ChatDropdown chat={data} showChatRenameModal={showChatRenameModal}>
<MoreButton></MoreButton>
</ChatDropdown>
}
onClick={() => {
navigateToChat(data?.id);
}}
/>
);
}

View File

@ -49,7 +49,7 @@ export default function ChatList() {
</ListFilterBar>
</div>
<div className="flex-1 overflow-auto">
<div className="flex flex-wrap gap-4 px-8">
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[84vh] overflow-auto px-8">
{data.dialogs.map((x) => {
return (
<ChatCard

View File

@ -288,20 +288,23 @@ export const useSendQuestion = (
const { pagination, setPagination } = useGetPaginationWithRouter();
const sendQuestion = useCallback(
(question: string) => {
(question: string, enableAI: boolean = true) => {
const q = trim(question);
if (isEmpty(q)) return;
setPagination({ page: 1 });
setIsFirstRender(false);
setCurrentAnswer({} as IAnswer);
setSendingLoading(true);
send({ kb_ids: kbIds, question: q, tenantId, search_id: searchId });
if (enableAI) {
setSendingLoading(true);
send({ kb_ids: kbIds, question: q, tenantId, search_id: searchId });
}
testChunk({
kb_id: kbIds,
highlight: true,
question: q,
page: 1,
size: pagination.pageSize,
search_id: searchId,
});
if (related_search) {
@ -327,12 +330,13 @@ export const useSendQuestion = (
}, []);
const handleClickRelatedQuestion = useCallback(
(question: string) => () => {
if (sendingLoading) return;
(question: string, enableAI: boolean = true) =>
() => {
if (sendingLoading) return;
setSearchStr(question);
sendQuestion(question);
},
setSearchStr(question);
sendQuestion(question, enableAI);
},
[sendQuestion, sendingLoading],
);
@ -348,6 +352,7 @@ export const useSendQuestion = (
doc_ids: documentIds ?? selectedDocumentIds,
page,
size,
search_id: searchId,
});
testChunkAll({
@ -357,6 +362,7 @@ export const useSendQuestion = (
doc_ids: [],
page,
size,
search_id: searchId,
});
},
[
@ -366,6 +372,7 @@ export const useSendQuestion = (
kbIds,
selectedDocumentIds,
testChunkAll,
searchId,
],
);
@ -430,7 +437,6 @@ export const useSearching = ({
const handleSearchStrChange = useCallback(
(value: string) => {
console.log('handleSearchStrChange', value);
setSearchStr(value);
},
[setSearchStr],
@ -442,10 +448,16 @@ export const useSearching = ({
useEffect(() => {
if (searchText) {
setSearchStr(searchText);
sendQuestion(searchText);
sendQuestion(searchText, searchData.search_config.summary);
setSearchText?.('');
}
}, [searchText, sendQuestion, setSearchStr, setSearchText]);
}, [
searchText,
sendQuestion,
setSearchStr,
setSearchText,
searchData.search_config.summary,
]);
const {
mindMapVisible,
@ -462,11 +474,16 @@ export const useSearching = ({
const handleSearch = useCallback(
(value: string) => {
sendQuestion(value);
sendQuestion(value, searchData.search_config.summary);
setSearchStr?.(value);
hideMindMapModal();
},
[setSearchStr, sendQuestion, hideMindMapModal],
[
setSearchStr,
sendQuestion,
hideMindMapModal,
searchData.search_config.summary,
],
);
const { pagination, setPagination } = useGetPaginationWithRouter();

View File

@ -252,7 +252,10 @@ export default function SearchingView({
key={idx}
variant="transparent"
className="bg-bg-card text-text-secondary"
onClick={handleClickRelatedQuestion(x)}
onClick={handleClickRelatedQuestion(
x,
searchData.search_config.summary,
)}
>
{x}
</Button>

View File

@ -1,8 +1,6 @@
import { HomeCard } from '@/components/home-card';
import { MoreButton } from '@/components/more-button';
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { Card, CardContent } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { formatDate } from '@/utils/date';
import { ISearchAppProps } from './hooks';
import { SearchDropdown } from './search-dropdown';
@ -14,43 +12,19 @@ export function SearchCard({ data, showSearchRenameModal }: IProps) {
const { navigateToSearch } = useNavigatePage();
return (
<Card
className="bg-bg-card border-colors-outline-neutral-standard"
<HomeCard
data={data}
moreDropdown={
<SearchDropdown
dataset={data}
showSearchRenameModal={showSearchRenameModal}
>
<MoreButton></MoreButton>
</SearchDropdown>
}
onClick={() => {
navigateToSearch(data?.id);
}}
>
<CardContent className="p-4 flex gap-2 items-start group h-full">
<div className="flex justify-between mb-4">
<RAGFlowAvatar
className="w-[32px] h-[32px]"
avatar={data.avatar}
name={data.name}
/>
</div>
<div className="flex flex-col justify-between gap-1 flex-1 h-full">
<section className="flex justify-between">
<div className="text-[20px] font-bold w-80% leading-5">
{data.name}
</div>
<SearchDropdown
dataset={data}
showSearchRenameModal={showSearchRenameModal}
>
<MoreButton></MoreButton>
</SearchDropdown>
</section>
<section className="flex flex-col gap-1 mt-1">
<div>{data.description}</div>
<div>
<p className="text-sm opacity-80">
{formatDate(data.update_time)}
</p>
</div>
</section>
</div>
</CardContent>
</Card>
/>
);
}