Skip to content

Commit 4b5188d

Browse files
ragingwindlizable
authored andcommitted
add agent iframe page for external links
1 parent d65ad92 commit 4b5188d

3 files changed

Lines changed: 53 additions & 49 deletions

File tree

react/src/App.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const SessionDetailAndContainerLogOpenerLegacy = React.lazy(
7979
const ChatPage = React.lazy(() => import('./pages/ChatPage'));
8080

8181
const AIAgentPage = React.lazy(() => import('./pages/AIAgentPage'));
82+
const AIAgentIFramePage = React.lazy(() => import('./pages/AIAgentIFramePage'));
8283

8384
interface CustomHandle {
8485
title?: string;
@@ -514,6 +515,15 @@ const router = createBrowserRouter([
514515
);
515516
},
516517
},
518+
{
519+
path: '/ai-agent/external',
520+
handle: { labelKey: 'webui.menu.AIAgents' },
521+
Component: () => (
522+
<Suspense fallback={<Skeleton active />}>
523+
<AIAgentIFramePage />
524+
</Suspense>
525+
),
526+
},
517527
],
518528
},
519529
]);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Skeleton, theme } from 'antd';
2+
import React, { Suspense } from 'react';
3+
import { StringParam, useQueryParams } from 'use-query-params';
4+
5+
const AIAgentIFramePage: React.FC = () => {
6+
const { token } = theme.useToken();
7+
const [{ url }] = useQueryParams({
8+
url: StringParam,
9+
});
10+
11+
return (
12+
<Suspense
13+
fallback={<Skeleton active style={{ padding: token.paddingMD }} />}
14+
>
15+
{url && (
16+
<iframe
17+
src={url}
18+
title="AI Agent Content"
19+
style={{
20+
width: '100%',
21+
height: '100vh',
22+
border: 'none',
23+
borderRadius: token.borderRadius,
24+
}}
25+
/>
26+
)}
27+
</Suspense>
28+
);
29+
};
30+
31+
export default AIAgentIFramePage;

react/src/pages/AIAgentPage.tsx

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -111,62 +111,25 @@ const AIAgentPage: React.FC = () => {
111111
const { token } = theme.useToken();
112112
const { agents } = useAIAgent();
113113
const webuiNavigate = useWebUINavigate();
114-
const [iframeUrl, setIframeUrl] = React.useState<string | undefined>(
115-
undefined,
116-
);
117-
118-
React.useEffect(() => {
119-
const handlePopState = () => {
120-
if (iframeUrl) {
121-
setIframeUrl(undefined);
122-
}
123-
};
124-
125-
window.addEventListener('popstate', handlePopState);
126-
127-
return () => {
128-
window.removeEventListener('popstate', handlePopState);
129-
};
130-
}, [iframeUrl]);
131114

132115
return (
133116
<Suspense
134117
fallback={<Skeleton active style={{ padding: token.paddingMD }} />}
135118
>
136-
{iframeUrl ? (
137-
<iframe
138-
src={iframeUrl}
139-
title="AI Agent Content"
140-
style={{
141-
width: '100%',
142-
height: '100vh',
143-
border: 'none',
144-
borderRadius: token.borderRadius,
145-
}}
146-
onLoad={() => {
147-
window.history.pushState(
148-
null,
149-
'',
150-
window.location.href + '#iframe',
151-
);
119+
<Flex direction="column" align="stretch" justify="center" gap="lg">
120+
<AIAgentCardList
121+
agents={agents}
122+
onClickAgent={(agent) => {
123+
if (agent.type === 'external') {
124+
webuiNavigate(`/ai-agent/external?url=${agent.config.url}`);
125+
} else {
126+
webuiNavigate(
127+
`/chat?endpointId=${agent.endpoint_id}&agentId=${agent.id}`,
128+
);
129+
}
152130
}}
153131
/>
154-
) : (
155-
<Flex direction="column" align="stretch" justify="center" gap="lg">
156-
<AIAgentCardList
157-
agents={agents}
158-
onClickAgent={(agent) => {
159-
if (agent.type === 'external') {
160-
setIframeUrl(agent.config.url);
161-
} else {
162-
webuiNavigate(
163-
`/chat?endpointId=${agent.endpoint_id}&agentId=${agent.id}`,
164-
);
165-
}
166-
}}
167-
/>
168-
</Flex>
169-
)}
132+
</Flex>
170133
</Suspense>
171134
);
172135
};

0 commit comments

Comments
 (0)