feat(iframe): add iframe bridge for ragflow integration
- Implement Penpal-based iframe communication bridge between host and child apps - Add route handling for ragflow integration with '/route-ragflow' prefix - Update navigation hooks to support embedded mode via iframe bridge - Configure build and dependencies for new iframe-bridge package - Adjust nginx config for proper SPA routing in subpath deployments
This commit is contained in:
@@ -2,6 +2,7 @@ import { AgentCategory, AgentQuery } from '@/constants/agent';
|
||||
import { NavigateToDataflowResultProps } from '@/pages/dataflow-result/interface';
|
||||
import { Routes } from '@/routes';
|
||||
import { useCallback } from 'react';
|
||||
import Bridge from '@teres/iframe-bridge';
|
||||
import { useNavigate, useParams, useSearchParams } from 'umi';
|
||||
|
||||
export enum QueryStringMap {
|
||||
@@ -14,106 +15,131 @@ export const useNavigatePage = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const { id } = useParams();
|
||||
|
||||
// 统一由 @teres/iframe-bridge 提供嵌入判断与消息封装
|
||||
|
||||
// 统一的跳转封装:嵌入模式下向父页面发送消息,否则使用内部 navigate
|
||||
const navigateOrPost = useCallback(
|
||||
(to: string, options?: { hostAgents?: boolean }) => {
|
||||
console.log('Bridge: ', Bridge);
|
||||
console.log('Bridge.isEmbedded', Bridge.isEmbedded());
|
||||
if (Bridge.isEmbedded()) {
|
||||
if (options?.hostAgents) {
|
||||
// 返回到宿主应用的 /agents
|
||||
if (typeof Bridge.clientClose === 'function') {
|
||||
Bridge.clientClose();
|
||||
} else {
|
||||
Bridge.clientNavigate(Bridge.toHostPath(Routes.Agents));
|
||||
}
|
||||
return;
|
||||
}
|
||||
Bridge.clientNavigate(Bridge.toHostPath(to));
|
||||
return;
|
||||
}
|
||||
navigate(to);
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const navigateToDatasetList = useCallback(() => {
|
||||
navigate(Routes.Datasets);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.Datasets);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToDataset = useCallback(
|
||||
(id: string) => () => {
|
||||
// navigate(`${Routes.DatasetBase}${Routes.DataSetOverview}/${id}`);
|
||||
navigate(`${Routes.Dataset}/${id}`);
|
||||
navigateOrPost(`${Routes.Dataset}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
const navigateToDatasetOverview = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.DatasetBase}${Routes.DataSetOverview}/${id}`);
|
||||
navigateOrPost(`${Routes.DatasetBase}${Routes.DataSetOverview}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToDataFile = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.DatasetBase}${Routes.DatasetBase}/${id}`);
|
||||
navigateOrPost(`${Routes.DatasetBase}${Routes.DatasetBase}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToHome = useCallback(() => {
|
||||
navigate(Routes.Root);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.Root);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToProfile = useCallback(() => {
|
||||
navigate(Routes.ProfileSetting);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.ProfileSetting);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToOldProfile = useCallback(() => {
|
||||
navigate(Routes.UserSetting);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.UserSetting);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToChatList = useCallback(() => {
|
||||
navigate(Routes.Chats);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.Chats);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToChat = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.Chat}/${id}`);
|
||||
navigateOrPost(`${Routes.Chat}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToAgents = useCallback(() => {
|
||||
navigate(Routes.Agents);
|
||||
}, [navigate]);
|
||||
// 嵌入模式下返回宿主应用的 /agents;独立模式跳转 ragflow 内部 /agents
|
||||
navigateOrPost(Routes.Agents, { hostAgents: true });
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToAgentList = useCallback(() => {
|
||||
navigate(Routes.AgentList);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.AgentList);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToAgent = useCallback(
|
||||
(id: string, category?: AgentCategory) => () => {
|
||||
navigate(`${Routes.Agent}/${id}?${AgentQuery.Category}=${category}`);
|
||||
navigateOrPost(`${Routes.Agent}/${id}?${AgentQuery.Category}=${category}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToDataflow = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.DataFlow}/${id}`);
|
||||
navigateOrPost(`${Routes.DataFlow}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToAgentLogs = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.AgentLogPage}/${id}`);
|
||||
navigateOrPost(`${Routes.AgentLogPage}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToAgentTemplates = useCallback(() => {
|
||||
navigate(Routes.AgentTemplates);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.AgentTemplates);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToSearchList = useCallback(() => {
|
||||
navigate(Routes.Searches);
|
||||
}, [navigate]);
|
||||
navigateOrPost(Routes.Searches);
|
||||
}, [navigateOrPost]);
|
||||
|
||||
const navigateToSearch = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.Search}/${id}`);
|
||||
navigateOrPost(`${Routes.Search}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToChunkParsedResult = useCallback(
|
||||
(id: string, knowledgeId?: string) => () => {
|
||||
navigate(
|
||||
navigateOrPost(
|
||||
`${Routes.ParsedResult}/chunks?id=${knowledgeId}&doc_id=${id}`,
|
||||
// `${Routes.DataflowResult}?id=${knowledgeId}&doc_id=${id}&type=chunk`,
|
||||
);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const getQueryString = useCallback(
|
||||
@@ -134,34 +160,36 @@ export const useNavigatePage = () => {
|
||||
|
||||
const navigateToChunk = useCallback(
|
||||
(route: Routes) => {
|
||||
navigate(
|
||||
navigateOrPost(
|
||||
`${route}/${id}?${QueryStringMap.KnowledgeId}=${getQueryString(QueryStringMap.KnowledgeId)}`,
|
||||
);
|
||||
},
|
||||
[getQueryString, id, navigate],
|
||||
[getQueryString, id, navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToFiles = useCallback(
|
||||
(folderId?: string) => {
|
||||
navigate(`${Routes.Files}?folderId=${folderId}`);
|
||||
navigateOrPost(`${Routes.Files}?folderId=${folderId}`);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
const navigateToDataflowResult = useCallback(
|
||||
(props: NavigateToDataflowResultProps) => () => {
|
||||
let params: string[] = [];
|
||||
Object.keys(props).forEach((key) => {
|
||||
// @ts-ignore
|
||||
if (props[key]) {
|
||||
// @ts-ignore
|
||||
params.push(`${key}=${props[key]}`);
|
||||
}
|
||||
});
|
||||
navigate(
|
||||
navigateOrPost(
|
||||
// `${Routes.ParsedResult}/${id}?${QueryStringMap.KnowledgeId}=${knowledgeId}`,
|
||||
`${Routes.DataflowResult}?${params.join('&')}`,
|
||||
);
|
||||
},
|
||||
[navigate],
|
||||
[navigateOrPost],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user