### What problem does this PR solve? Feat: Show agent embed dialog #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| // 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 }; |
| <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} |
| <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} |
| 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); |
| 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, | |||||
| }; | |||||
| }; |
| 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'; | ||||
| 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'; | ||||
| ...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, | ||||
| 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) { | ||||
| } | } | ||||
| }, [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'}> | |||||
| <EllipsisVertical /> | |||||
| <Button variant={'secondary'}> | |||||
| <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> | ||||
| onOk={onFileUploadOk} | onOk={onFileUploadOk} | ||||
| ></UploadAgentDialog> | ></UploadAgentDialog> | ||||
| )} | )} | ||||
| {embedVisible && ( | |||||
| <EmbedDialog | |||||
| visible={embedVisible} | |||||
| hideModal={hideEmbedModal} | |||||
| token={id!} | |||||
| form={SharedFrom.Agent} | |||||
| beta={beta} | |||||
| isAgent | |||||
| ></EmbedDialog> | |||||
| )} | |||||
| </section> | </section> | ||||
| ); | ); | ||||
| } | } |