mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Show agent embed dialog #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
40
web/src/components/originui/underline-tabs.tsx
Normal file
40
web/src/components/originui/underline-tabs.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// registry/default/components/comp-430.tsx
|
||||||
|
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
||||||
|
import React from 'react';
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
|
||||||
|
|
||||||
|
export const UnderlineTabsList = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||||
|
>(function UnderlineTabsList({ className, ...props }, ref) {
|
||||||
|
return (
|
||||||
|
<TabsList
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'text-foreground h-auto gap-2 rounded-none border-b bg-transparent px-0 py-1',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const UnderlineTabsTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||||
|
>(function UnderlineTabsTrigger({ className, ...props }, ref) {
|
||||||
|
return (
|
||||||
|
<TabsTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'hover:bg-accent hover:text-foreground data-[state=active]:after:bg-primary data-[state=active]:hover:bg-accent relative after:absolute after:inset-x-0 after:bottom-0 after:-mb-1 after:h-0.5 data-[state=active]:bg-transparent data-[state=active]:shadow-none',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export { Tabs as UnderlineTabs, TabsContent as UnderlineTabsContent };
|
||||||
@ -38,7 +38,7 @@ const DialogContent = React.forwardRef<
|
|||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-colors-background-neutral-standard p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-2xl translate-x-[-50%] translate-y-[-50%] gap-4 border bg-colors-background-neutral-standard p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef<
|
|||||||
<TabsPrimitive.Trigger
|
<TabsPrimitive.Trigger
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-colors-background-inverse-strong data-[state=active]:text-colors-text-inverse-strong data-[state=active]:shadow-sm',
|
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-colors-background-inverse-strong data-[state=active]:text-text-title data-[state=active]:shadow-sm',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
132
web/src/pages/agent/embed-dialog/index.tsx
Normal file
132
web/src/pages/agent/embed-dialog/index.tsx
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import CopyToClipboard from '@/components/copy-to-clipboard';
|
||||||
|
import HightLightMarkdown from '@/components/highlight-markdown';
|
||||||
|
import {
|
||||||
|
UnderlineTabs,
|
||||||
|
UnderlineTabsContent,
|
||||||
|
UnderlineTabsList,
|
||||||
|
UnderlineTabsTrigger,
|
||||||
|
} from '@/components/originui/underline-tabs';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from '@/components/ui/dialog';
|
||||||
|
import { SharedFrom } from '@/constants/chat';
|
||||||
|
import {
|
||||||
|
LanguageAbbreviation,
|
||||||
|
LanguageAbbreviationMap,
|
||||||
|
} from '@/constants/common';
|
||||||
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
|
import { IModalProps } from '@/interfaces/common';
|
||||||
|
import { memo, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
type IProps = IModalProps<any> & {
|
||||||
|
token: string;
|
||||||
|
form: SharedFrom;
|
||||||
|
beta: string;
|
||||||
|
isAgent: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function EmbedDialog({
|
||||||
|
hideModal,
|
||||||
|
token = '',
|
||||||
|
form,
|
||||||
|
beta = '',
|
||||||
|
isAgent,
|
||||||
|
}: IProps) {
|
||||||
|
const { t } = useTranslate('chat');
|
||||||
|
|
||||||
|
const [visibleAvatar, setVisibleAvatar] = useState(false);
|
||||||
|
const [locale, setLocale] = useState('');
|
||||||
|
|
||||||
|
const languageOptions = useMemo(() => {
|
||||||
|
return Object.values(LanguageAbbreviation).map((x) => ({
|
||||||
|
label: LanguageAbbreviationMap[x],
|
||||||
|
value: x,
|
||||||
|
}));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const generateIframeSrc = () => {
|
||||||
|
let src = `${location.origin}/chat/share?shared_id=${token}&from=${form}&auth=${beta}`;
|
||||||
|
if (visibleAvatar) {
|
||||||
|
src += '&visible_avatar=1';
|
||||||
|
}
|
||||||
|
if (locale) {
|
||||||
|
src += `&locale=${locale}`;
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
};
|
||||||
|
|
||||||
|
const iframeSrc = generateIframeSrc();
|
||||||
|
|
||||||
|
const text = `
|
||||||
|
~~~ html
|
||||||
|
<iframe
|
||||||
|
src="${iframeSrc}"
|
||||||
|
style="width: 100%; height: 100%; min-height: 600px"
|
||||||
|
frameborder="0"
|
||||||
|
>
|
||||||
|
</iframe>
|
||||||
|
~~~
|
||||||
|
`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open onOpenChange={hideModal}>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>
|
||||||
|
{t('embedIntoSite', { keyPrefix: 'common' })}
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<section className="w-full overflow-auto">
|
||||||
|
<UnderlineTabs defaultValue="1" className="w-full">
|
||||||
|
<UnderlineTabsList>
|
||||||
|
<UnderlineTabsTrigger value="1">
|
||||||
|
{t('fullScreenTitle')}
|
||||||
|
</UnderlineTabsTrigger>
|
||||||
|
<UnderlineTabsTrigger value="2">
|
||||||
|
{t('partialTitle')}
|
||||||
|
</UnderlineTabsTrigger>
|
||||||
|
<UnderlineTabsTrigger value="3">
|
||||||
|
{t('extensionTitle')}
|
||||||
|
</UnderlineTabsTrigger>
|
||||||
|
</UnderlineTabsList>
|
||||||
|
<UnderlineTabsContent value="1">
|
||||||
|
<section>
|
||||||
|
<HightLightMarkdown>{text}</HightLightMarkdown>
|
||||||
|
</section>
|
||||||
|
</UnderlineTabsContent>
|
||||||
|
<UnderlineTabsContent value="2">
|
||||||
|
{t('comingSoon')}
|
||||||
|
</UnderlineTabsContent>
|
||||||
|
<UnderlineTabsContent value="3">
|
||||||
|
{t('comingSoon')}
|
||||||
|
</UnderlineTabsContent>
|
||||||
|
</UnderlineTabs>
|
||||||
|
<div className="text-base font-medium mt-4 mb-1">
|
||||||
|
{t(isAgent ? 'flow' : 'chat', { keyPrefix: 'header' })}
|
||||||
|
<span className="ml-1 inline-block">ID</span>
|
||||||
|
</div>
|
||||||
|
<div className="bg-background-card rounded-md p-2 ">
|
||||||
|
{token} <CopyToClipboard text={token}></CopyToClipboard>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
className="pt-3 cursor-pointer text-background-checked inline-block"
|
||||||
|
href={
|
||||||
|
isAgent
|
||||||
|
? 'https://ragflow.io/docs/dev/http_api_reference#create-session-with-agent'
|
||||||
|
: 'https://ragflow.io/docs/dev/http_api_reference#create-session-with-chat-assistant'
|
||||||
|
}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{t('howUseId', { keyPrefix: isAgent ? 'flow' : 'chat' })}
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(EmbedDialog);
|
||||||
179
web/src/pages/agent/hooks/use-show-dialog.ts
Normal file
179
web/src/pages/agent/hooks/use-show-dialog.ts
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import { SharedFrom } from '@/constants/chat';
|
||||||
|
import {
|
||||||
|
useSetModalState,
|
||||||
|
useShowDeleteConfirm,
|
||||||
|
useTranslate,
|
||||||
|
} from '@/hooks/common-hooks';
|
||||||
|
import {
|
||||||
|
useCreateSystemToken,
|
||||||
|
useFetchManualSystemTokenList,
|
||||||
|
useFetchSystemTokenList,
|
||||||
|
useRemoveSystemToken,
|
||||||
|
} from '@/hooks/user-setting-hooks';
|
||||||
|
import { IStats } from '@/interfaces/database/chat';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { message } from 'antd';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
export const useOperateApiKey = (idKey: string, dialogId?: string) => {
|
||||||
|
const { removeToken } = useRemoveSystemToken();
|
||||||
|
const { createToken, loading: creatingLoading } = useCreateSystemToken();
|
||||||
|
const { data: tokenList, loading: listLoading } = useFetchSystemTokenList();
|
||||||
|
|
||||||
|
const showDeleteConfirm = useShowDeleteConfirm();
|
||||||
|
|
||||||
|
const onRemoveToken = (token: string) => {
|
||||||
|
showDeleteConfirm({
|
||||||
|
onOk: () => removeToken(token),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCreateToken = useCallback(() => {
|
||||||
|
createToken({ [idKey]: dialogId });
|
||||||
|
}, [createToken, idKey, dialogId]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
removeToken: onRemoveToken,
|
||||||
|
createToken: onCreateToken,
|
||||||
|
tokenList,
|
||||||
|
creatingLoading,
|
||||||
|
listLoading,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ChartStatsType = {
|
||||||
|
[k in keyof IStats]: Array<{ xAxis: string; yAxis: number }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSelectChartStatsList = (): ChartStatsType => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const data = queryClient.getQueriesData({ queryKey: ['fetchStats'] });
|
||||||
|
const stats: IStats = (data.length > 0 ? data[0][1] : {}) as IStats;
|
||||||
|
|
||||||
|
return Object.keys(stats).reduce((pre, cur) => {
|
||||||
|
const item = stats[cur as keyof IStats];
|
||||||
|
if (item.length > 0) {
|
||||||
|
pre[cur as keyof IStats] = item.map((x) => ({
|
||||||
|
xAxis: x[0] as string,
|
||||||
|
yAxis: x[1] as number,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return pre;
|
||||||
|
}, {} as ChartStatsType);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useShowTokenEmptyError = () => {
|
||||||
|
const { t } = useTranslate('chat');
|
||||||
|
|
||||||
|
const showTokenEmptyError = useCallback(() => {
|
||||||
|
message.error(t('tokenError'));
|
||||||
|
}, [t]);
|
||||||
|
return { showTokenEmptyError };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useShowBetaEmptyError = () => {
|
||||||
|
const { t } = useTranslate('chat');
|
||||||
|
|
||||||
|
const showBetaEmptyError = useCallback(() => {
|
||||||
|
message.error(t('betaError'));
|
||||||
|
}, [t]);
|
||||||
|
return { showBetaEmptyError };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUrlWithToken = (token: string, from: string = 'chat') => {
|
||||||
|
const { protocol, host } = window.location;
|
||||||
|
return `${protocol}//${host}/chat/share?shared_id=${token}&from=${from}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useFetchTokenListBeforeOtherStep = () => {
|
||||||
|
const { showTokenEmptyError } = useShowTokenEmptyError();
|
||||||
|
const { showBetaEmptyError } = useShowBetaEmptyError();
|
||||||
|
|
||||||
|
const { data: tokenList, fetchSystemTokenList } =
|
||||||
|
useFetchManualSystemTokenList();
|
||||||
|
|
||||||
|
let token = '',
|
||||||
|
beta = '';
|
||||||
|
|
||||||
|
if (Array.isArray(tokenList) && tokenList.length > 0) {
|
||||||
|
token = tokenList[0].token;
|
||||||
|
beta = tokenList[0].beta;
|
||||||
|
}
|
||||||
|
|
||||||
|
token =
|
||||||
|
Array.isArray(tokenList) && tokenList.length > 0 ? tokenList[0].token : '';
|
||||||
|
|
||||||
|
const handleOperate = useCallback(async () => {
|
||||||
|
const ret = await fetchSystemTokenList();
|
||||||
|
const list = ret;
|
||||||
|
if (Array.isArray(list) && list.length > 0) {
|
||||||
|
if (!list[0].beta) {
|
||||||
|
showBetaEmptyError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return list[0]?.token;
|
||||||
|
} else {
|
||||||
|
showTokenEmptyError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, [fetchSystemTokenList, showBetaEmptyError, showTokenEmptyError]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
token,
|
||||||
|
beta,
|
||||||
|
handleOperate,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useShowEmbedModal = () => {
|
||||||
|
const {
|
||||||
|
visible: embedVisible,
|
||||||
|
hideModal: hideEmbedModal,
|
||||||
|
showModal: showEmbedModal,
|
||||||
|
} = useSetModalState();
|
||||||
|
|
||||||
|
const { handleOperate, token, beta } = useFetchTokenListBeforeOtherStep();
|
||||||
|
|
||||||
|
const handleShowEmbedModal = useCallback(async () => {
|
||||||
|
const succeed = await handleOperate();
|
||||||
|
if (succeed) {
|
||||||
|
showEmbedModal();
|
||||||
|
}
|
||||||
|
}, [handleOperate, showEmbedModal]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
showEmbedModal: handleShowEmbedModal,
|
||||||
|
hideEmbedModal,
|
||||||
|
embedVisible,
|
||||||
|
embedToken: token,
|
||||||
|
beta,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePreviewChat = (idKey: string) => {
|
||||||
|
const { handleOperate } = useFetchTokenListBeforeOtherStep();
|
||||||
|
|
||||||
|
const open = useCallback(
|
||||||
|
(t: string) => {
|
||||||
|
window.open(
|
||||||
|
getUrlWithToken(
|
||||||
|
t,
|
||||||
|
idKey === 'canvasId' ? SharedFrom.Agent : SharedFrom.Chat,
|
||||||
|
),
|
||||||
|
'_blank',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[idKey],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handlePreview = useCallback(async () => {
|
||||||
|
const token = await handleOperate();
|
||||||
|
if (token) {
|
||||||
|
open(token);
|
||||||
|
}
|
||||||
|
}, [handleOperate, open]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
handlePreview,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -7,13 +7,25 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu';
|
} from '@/components/ui/dropdown-menu';
|
||||||
|
import { SharedFrom } from '@/constants/chat';
|
||||||
import { useSetModalState } from '@/hooks/common-hooks';
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { ReactFlowProvider } from '@xyflow/react';
|
import { ReactFlowProvider } from '@xyflow/react';
|
||||||
import { CodeXml, EllipsisVertical, Forward, Import, Key } from 'lucide-react';
|
import {
|
||||||
|
ChevronDown,
|
||||||
|
CirclePlay,
|
||||||
|
Download,
|
||||||
|
History,
|
||||||
|
Key,
|
||||||
|
Logs,
|
||||||
|
ScreenShare,
|
||||||
|
Upload,
|
||||||
|
} from 'lucide-react';
|
||||||
import { ComponentPropsWithoutRef, useCallback } from 'react';
|
import { ComponentPropsWithoutRef, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useParams } from 'umi';
|
||||||
import AgentCanvas from './canvas';
|
import AgentCanvas from './canvas';
|
||||||
|
import EmbedDialog from './embed-dialog';
|
||||||
import { useHandleExportOrImportJsonFile } from './hooks/use-export-json';
|
import { useHandleExportOrImportJsonFile } from './hooks/use-export-json';
|
||||||
import { useFetchDataOnMount } from './hooks/use-fetch-data';
|
import { useFetchDataOnMount } from './hooks/use-fetch-data';
|
||||||
import { useGetBeginNodeDataQuery } from './hooks/use-get-begin-query';
|
import { useGetBeginNodeDataQuery } from './hooks/use-get-begin-query';
|
||||||
@ -22,6 +34,7 @@ import {
|
|||||||
useSaveGraph,
|
useSaveGraph,
|
||||||
useSaveGraphBeforeOpeningDebugDrawer,
|
useSaveGraphBeforeOpeningDebugDrawer,
|
||||||
} from './hooks/use-save-graph';
|
} from './hooks/use-save-graph';
|
||||||
|
import { useShowEmbedModal } from './hooks/use-show-dialog';
|
||||||
import { BeginQuery } from './interface';
|
import { BeginQuery } from './interface';
|
||||||
import { UploadAgentDialog } from './upload-agent-dialog';
|
import { UploadAgentDialog } from './upload-agent-dialog';
|
||||||
|
|
||||||
@ -30,13 +43,14 @@ function AgentDropdownMenuItem({
|
|||||||
...props
|
...props
|
||||||
}: ComponentPropsWithoutRef<typeof DropdownMenuItem>) {
|
}: ComponentPropsWithoutRef<typeof DropdownMenuItem>) {
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItem className="flex justify-between items-center" {...props}>
|
<DropdownMenuItem className="justify-start" {...props}>
|
||||||
{children}
|
{children}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Agent() {
|
export default function Agent() {
|
||||||
|
const { id } = useParams();
|
||||||
const { navigateToAgentList } = useNavigatePage();
|
const { navigateToAgentList } = useNavigatePage();
|
||||||
const {
|
const {
|
||||||
visible: chatDrawerVisible,
|
visible: chatDrawerVisible,
|
||||||
@ -53,12 +67,9 @@ export default function Agent() {
|
|||||||
hideFileUploadModal,
|
hideFileUploadModal,
|
||||||
} = useHandleExportOrImportJsonFile();
|
} = useHandleExportOrImportJsonFile();
|
||||||
const { saveGraph, loading } = useSaveGraph();
|
const { saveGraph, loading } = useSaveGraph();
|
||||||
|
|
||||||
const { flowDetail } = useFetchDataOnMount();
|
const { flowDetail } = useFetchDataOnMount();
|
||||||
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
||||||
|
|
||||||
const { handleRun } = useSaveGraphBeforeOpeningDebugDrawer(showChatDrawer);
|
const { handleRun } = useSaveGraphBeforeOpeningDebugDrawer(showChatDrawer);
|
||||||
|
|
||||||
const handleRunAgent = useCallback(() => {
|
const handleRunAgent = useCallback(() => {
|
||||||
const query: BeginQuery[] = getBeginNodeDataQuery();
|
const query: BeginQuery[] = getBeginNodeDataQuery();
|
||||||
if (query.length > 0) {
|
if (query.length > 0) {
|
||||||
@ -68,47 +79,58 @@ export default function Agent() {
|
|||||||
}
|
}
|
||||||
}, [getBeginNodeDataQuery, handleRun, showChatDrawer]);
|
}, [getBeginNodeDataQuery, handleRun, showChatDrawer]);
|
||||||
|
|
||||||
|
const { showEmbedModal, hideEmbedModal, embedVisible, beta } =
|
||||||
|
useShowEmbedModal();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="h-full">
|
<section className="h-full">
|
||||||
<PageHeader back={navigateToAgentList} title={flowDetail.title}>
|
<PageHeader back={navigateToAgentList} title={flowDetail.title}>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<ButtonLoading
|
<ButtonLoading
|
||||||
variant={'outline'}
|
variant={'secondary'}
|
||||||
onClick={() => saveGraph()}
|
onClick={() => saveGraph()}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</ButtonLoading>
|
</ButtonLoading>
|
||||||
<Button variant={'outline'} onClick={handleRunAgent}>
|
<Button variant={'secondary'} onClick={handleRunAgent}>
|
||||||
|
<CirclePlay />
|
||||||
Run app
|
Run app
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant={'outline'}>Publish</Button>
|
<Button variant={'secondary'}>
|
||||||
|
<History />
|
||||||
|
History version
|
||||||
|
</Button>
|
||||||
|
<Button variant={'secondary'}>
|
||||||
|
<Logs />
|
||||||
|
Log
|
||||||
|
</Button>
|
||||||
|
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant={'icon'} size={'icon'}>
|
<Button variant={'secondary'}>
|
||||||
<EllipsisVertical />
|
<ChevronDown /> Management
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
<AgentDropdownMenuItem onClick={openDocument}>
|
<AgentDropdownMenuItem onClick={openDocument}>
|
||||||
API
|
|
||||||
<Key />
|
<Key />
|
||||||
|
API
|
||||||
</AgentDropdownMenuItem>
|
</AgentDropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<AgentDropdownMenuItem onClick={handleImportJson}>
|
<AgentDropdownMenuItem onClick={handleImportJson}>
|
||||||
|
<Download />
|
||||||
Import
|
Import
|
||||||
<Import />
|
|
||||||
</AgentDropdownMenuItem>
|
</AgentDropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<AgentDropdownMenuItem onClick={handleExportJson}>
|
<AgentDropdownMenuItem onClick={handleExportJson}>
|
||||||
|
<Upload />
|
||||||
Export
|
Export
|
||||||
<Forward />
|
|
||||||
</AgentDropdownMenuItem>
|
</AgentDropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<AgentDropdownMenuItem>
|
<AgentDropdownMenuItem onClick={showEmbedModal}>
|
||||||
|
<ScreenShare />
|
||||||
{t('common.embedIntoSite')}
|
{t('common.embedIntoSite')}
|
||||||
<CodeXml />
|
|
||||||
</AgentDropdownMenuItem>
|
</AgentDropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@ -126,6 +148,16 @@ export default function Agent() {
|
|||||||
onOk={onFileUploadOk}
|
onOk={onFileUploadOk}
|
||||||
></UploadAgentDialog>
|
></UploadAgentDialog>
|
||||||
)}
|
)}
|
||||||
|
{embedVisible && (
|
||||||
|
<EmbedDialog
|
||||||
|
visible={embedVisible}
|
||||||
|
hideModal={hideEmbedModal}
|
||||||
|
token={id!}
|
||||||
|
form={SharedFrom.Agent}
|
||||||
|
beta={beta}
|
||||||
|
isAgent
|
||||||
|
></EmbedDialog>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user