mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-03 06:17:29 +08:00
Feat: Add Explore page (#13043)
### What problem does this PR solve? Feat: Add Explore page ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@@ -95,6 +95,13 @@ export const useNavigatePage = () => {
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const navigateToAgentExplore = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.Agent}/${id}/explore`);
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const navigateToAgentLogs = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.AgentLogPage}/${id}`);
|
||||
@@ -176,7 +183,7 @@ export const useNavigatePage = () => {
|
||||
|
||||
const navigateToDataflowResult = useCallback(
|
||||
(props: NavigateToDataflowResultProps) => () => {
|
||||
let params: string[] = [];
|
||||
const params: string[] = [];
|
||||
Object.keys(props).forEach((key) => {
|
||||
if (props[key as keyof typeof props]) {
|
||||
params.push(`${key}=${props[key as keyof typeof props]}`);
|
||||
@@ -203,6 +210,7 @@ export const useNavigatePage = () => {
|
||||
navigateToChunk,
|
||||
navigateToAgents,
|
||||
navigateToAgent,
|
||||
navigateToAgentExplore,
|
||||
navigateToAgentLogs,
|
||||
navigateToAgentTemplates,
|
||||
navigateToSearchList,
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { FileUploadProps } from '@/components/file-upload';
|
||||
import { useHandleFilterSubmit } from '@/components/list-filter-bar/use-handle-filter-submit';
|
||||
import message from '@/components/ui/message';
|
||||
import { AgentGlobals, initialBeginValues } from '@/constants/agent';
|
||||
import {
|
||||
AgentCategory,
|
||||
AgentGlobals,
|
||||
initialBeginValues,
|
||||
} from '@/constants/agent';
|
||||
import { useFetchTenantInfo } from '@/hooks/use-user-setting-request';
|
||||
import {
|
||||
IAgentLogResponse,
|
||||
IAgentLogsRequest,
|
||||
IAgentLogsResponse,
|
||||
IFlow,
|
||||
@@ -20,7 +26,10 @@ import { BeginId } from '@/pages/agent/constant';
|
||||
import { IInputs } from '@/pages/agent/interface';
|
||||
import { useGetSharedChatSearchParams } from '@/pages/next-chats/hooks/use-send-shared-message';
|
||||
import agentService, {
|
||||
createAgentSession,
|
||||
deleteAgentSession,
|
||||
fetchAgentLogsByCanvasId,
|
||||
fetchAgentLogsById,
|
||||
fetchPipeLineList,
|
||||
fetchTrace,
|
||||
fetchWebhookTrace,
|
||||
@@ -39,6 +48,7 @@ import {
|
||||
|
||||
export const enum AgentApiAction {
|
||||
FetchAgentListByPage = 'fetchAgentListByPage',
|
||||
FetchAllAgentList = 'fetchAllAgentList',
|
||||
FetchAgentList = 'fetchAgentList',
|
||||
UpdateAgentSetting = 'updateAgentSetting',
|
||||
DeleteAgent = 'deleteAgent',
|
||||
@@ -61,6 +71,11 @@ export const enum AgentApiAction {
|
||||
CancelDataflow = 'cancelDataflow',
|
||||
CancelCanvas = 'cancelCanvas',
|
||||
FetchWebhookTrace = 'fetchWebhookTrace',
|
||||
FetchSessionsByCanvasId = 'fetchSessionsByCanvasId',
|
||||
FetchSessionById = 'fetchSessionById',
|
||||
CreateAgentSession = 'createAgentSession',
|
||||
DeleteAgentSession = 'deleteAgentSession',
|
||||
FetchSessionByIdManually = 'fetchSessionByIdManually',
|
||||
}
|
||||
|
||||
export const EmptyDsl = {
|
||||
@@ -194,6 +209,28 @@ export const useFetchAgentListByPage = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export function useFetchAllAgentList() {
|
||||
const { data, isFetching: loading } = useQuery<IFlow[]>({
|
||||
queryKey: [AgentApiAction.FetchAllAgentList],
|
||||
queryFn: async () => {
|
||||
const { data } = await agentService.listCanvas(
|
||||
{
|
||||
params: {
|
||||
page: 1,
|
||||
page_size: 100000,
|
||||
canvas_category: AgentCategory.AgentCanvas,
|
||||
},
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
return data?.data?.canvas;
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading };
|
||||
}
|
||||
|
||||
export const useUpdateAgentSetting = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -627,6 +664,37 @@ export const useFetchAgentLog = (searchParams: IAgentLogsRequest) => {
|
||||
return { data, loading };
|
||||
};
|
||||
|
||||
export const useFetchSessionsByCanvasId = () => {
|
||||
const { id: canvasId } = useParams();
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
|
||||
const { data, isFetching: loading } = useQuery<IAgentLogsResponse>({
|
||||
queryKey: [AgentApiAction.FetchSessionsByCanvasId, canvasId],
|
||||
initialData: { total: 0, sessions: [] } as IAgentLogsResponse,
|
||||
gcTime: 0,
|
||||
enabled: !!canvasId && !isEmpty(tenantInfo),
|
||||
queryFn: async () => {
|
||||
if (!canvasId) {
|
||||
return { total: 0, sessions: [] };
|
||||
}
|
||||
|
||||
const { data } = await fetchAgentLogsByCanvasId(canvasId, {
|
||||
page: 1,
|
||||
page_size: 100000,
|
||||
exp_user_id: tenantInfo.tenant_id,
|
||||
});
|
||||
|
||||
return data?.data ?? { total: 0, sessions: [] };
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
data: data?.sessions ?? [],
|
||||
loading,
|
||||
total: data?.total ?? 0,
|
||||
};
|
||||
};
|
||||
|
||||
export const useFetchExternalAgentInputs = () => {
|
||||
const { sharedId } = useGetSharedChatSearchParams();
|
||||
|
||||
@@ -873,3 +941,82 @@ export const useFetchWebhookTrace = (autoStart: boolean = true) => {
|
||||
currentNextSinceTs,
|
||||
};
|
||||
};
|
||||
|
||||
export function useCreateAgentSession() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: [AgentApiAction.CreateAgentSession],
|
||||
mutationFn: async (payload: { id: string; name: string }) => {
|
||||
const { data } = await createAgentSession(payload);
|
||||
|
||||
if (data.code === 0) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [AgentApiAction.FetchSessionsByCanvasId],
|
||||
});
|
||||
}
|
||||
|
||||
return data?.data ?? {};
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, createAgentSession: mutateAsync };
|
||||
}
|
||||
|
||||
export function useDeleteAgentSession() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: [AgentApiAction.DeleteAgentSession],
|
||||
mutationFn: async ({
|
||||
canvasId,
|
||||
sessionId,
|
||||
}: {
|
||||
canvasId: string;
|
||||
sessionId: string;
|
||||
}) => {
|
||||
const { data } = await deleteAgentSession(canvasId, sessionId);
|
||||
|
||||
if (data.code === 0) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [AgentApiAction.FetchSessionsByCanvasId],
|
||||
});
|
||||
}
|
||||
|
||||
return data?.code ?? -1;
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, deleteAgentSession: mutateAsync };
|
||||
}
|
||||
|
||||
export function useFetchSessionManually() {
|
||||
const { id: canvasId } = useParams();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation<IAgentLogResponse, unknown, string>({
|
||||
mutationKey: [AgentApiAction.FetchSessionByIdManually, canvasId],
|
||||
mutationFn: async (sessionId) => {
|
||||
if (!canvasId || !sessionId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data } = await fetchAgentLogsById(canvasId, sessionId);
|
||||
|
||||
return data?.data;
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, fetchSessionManually: mutateAsync };
|
||||
}
|
||||
|
||||
61
web/src/hooks/use-client-search.ts
Normal file
61
web/src/hooks/use-client-search.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useDebounce } from 'ahooks';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
export interface SearchFilterOptions<T> {
|
||||
data: T[];
|
||||
searchFields: Array<keyof T | ((item: T) => string)>;
|
||||
debounceMs?: number;
|
||||
}
|
||||
|
||||
export function useClientSearch<T>({
|
||||
data,
|
||||
searchFields,
|
||||
debounceMs = 300,
|
||||
}: SearchFilterOptions<T>) {
|
||||
const [searchKeyword, setSearchKeyword] = useState('');
|
||||
|
||||
const debouncedSearchKeyword = useDebounce(searchKeyword, {
|
||||
wait: debounceMs,
|
||||
});
|
||||
|
||||
const handleSearchChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
setSearchKeyword(e.target.value);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const clearSearch = useCallback(() => {
|
||||
setSearchKeyword('');
|
||||
}, []);
|
||||
|
||||
const filteredData = useMemo(() => {
|
||||
if (!debouncedSearchKeyword.trim()) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const keyword = debouncedSearchKeyword.toLowerCase().trim();
|
||||
|
||||
return data.filter((item) => {
|
||||
return searchFields.some((field) => {
|
||||
let value: string;
|
||||
|
||||
if (typeof field === 'function') {
|
||||
value = field(item);
|
||||
} else {
|
||||
value = String(item[field] ?? '');
|
||||
}
|
||||
|
||||
return value?.toLowerCase().includes(keyword);
|
||||
});
|
||||
});
|
||||
}, [data, debouncedSearchKeyword, searchFields]);
|
||||
|
||||
return {
|
||||
filteredData,
|
||||
searchKeyword,
|
||||
handleSearchChange,
|
||||
clearSearch,
|
||||
isSearching: debouncedSearchKeyword !== searchKeyword,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user