feat: add 'Open in new tab' button for agents (#13044)

- Add new button in agent management dropdown to open agent in new tab
- Implement token-based authentication for shared agent access
- Add translations for 9 languages (en, zh, zh-tw, de, fr, it, ru,
pt-br, vi)
- Keep existing 'Embed into webpage' functionality intact

### What problem does this PR solve?

This allows users to open agents in a separate tab to work in background
while continuing to use other parts of the application.

<img width="1920" height="1080" alt="image"
src="https://github.com/user-attachments/assets/ca1719c8-2f00-4570-a730-1321fa0bfd57"
/>
<img width="254" height="222" alt="image"
src="https://github.com/user-attachments/assets/b3dd6d9f-b7e7-46b0-83e7-f0ea86e7b156"
/>
<img width="1920" height="1080" alt="image"
src="https://github.com/user-attachments/assets/e94e99f9-9039-43f7-b2d9-862b9448630c"
/>

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
PentaFDevs
2026-02-25 06:39:02 +01:00
committed by GitHub
parent cf6fd6f115
commit 8ad47bf242
12 changed files with 33 additions and 3 deletions

View File

@ -1,6 +1,7 @@
import CopyToClipboard from '@/components/copy-to-clipboard';
import HighLightMarkdown from '@/components/highlight-markdown';
import { SelectWithSearch } from '@/components/originui/select-with-search';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
@ -28,6 +29,7 @@ import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common';
import { Routes } from '@/routes';
import { zodResolver } from '@hookform/resolvers/zod';
import { ExternalLink } from 'lucide-react';
import { memo, useCallback, useMemo } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { z } from 'zod';
@ -146,6 +148,11 @@ function EmbedDialog({
}
}, [generateIframeSrc, values]);
const handleOpenInNewTab = useCallback(() => {
const iframeSrc = generateIframeSrc();
window.open(iframeSrc, '_blank');
}, [generateIframeSrc]);
return (
<Dialog open onOpenChange={hideModal}>
<DialogContent>
@ -280,6 +287,14 @@ function EmbedDialog({
<HighLightMarkdown>{text}</HighLightMarkdown>
</div>
</div>
<Button
onClick={handleOpenInNewTab}
className="w-full"
variant="secondary"
>
<ExternalLink className="mr-2 h-4 w-4" />
{t('openInNewTab', { keyPrefix: 'common' })}
</Button>
<div className=" font-medium mt-4 mb-1">
{t(isAgent ? 'flow' : 'chat', { keyPrefix: 'header' })}
<span className="ml-1 inline-block">ID</span>

View File

@ -48,6 +48,7 @@ export default {
submit: 'Absenden',
clear: 'Leeren',
embedIntoSite: 'In Webseite einbetten',
openInNewTab: 'Chat in neuem Tab',
previousPage: 'Zurück',
nextPage: 'Weiter',
add: 'Hinzufügen',

View File

@ -46,6 +46,7 @@ export default {
submit: 'Submit',
clear: 'Clear',
embedIntoSite: 'Embed into webpage',
openInNewTab: 'Chat in new tab',
previousPage: 'Previous',
nextPage: 'Next',
add: 'Add',

View File

@ -37,6 +37,7 @@ export default {
pleaseInput: 'Veuillez saisir',
submit: 'Soumettre',
embedIntoSite: 'Intégrer dans la page web',
openInNewTab: 'Chat dans un nouvel onglet',
previousPage: 'Précédent',
nextPage: 'Suivant',
add: 'Ajouter',

View File

@ -53,6 +53,7 @@ export default {
submit: 'Invia',
clear: 'Cancella',
embedIntoSite: 'Incorpora nella pagina web',
openInNewTab: 'Chat in una nuova scheda',
previousPage: 'Precedente',
nextPage: 'Successivo',
add: 'Aggiungi',

View File

@ -36,6 +36,7 @@ export default {
pleaseInput: 'Por favor, insira',
submit: 'Enviar',
embedIntoSite: 'Incorporar no site',
openInNewTab: 'Chat em nova aba',
previousPage: 'Anterior',
nextPage: 'Próxima',
},

View File

@ -45,6 +45,7 @@ export default {
submit: 'Отправить',
clear: 'Очистить',
embedIntoSite: 'Встроить на веб-страницу',
openInNewTab: 'Чат в новой вкладке',
previousPage: 'Назад',
nextPage: 'Вперед',
add: 'Добавить',

View File

@ -39,6 +39,7 @@ export default {
spanish: 'Tiếng Tây Ban Nha',
japanese: 'Tiếng Nhật',
embedIntoSite: 'Nhúng vào trang web',
openInNewTab: 'Chat trong tab mới',
nextPage: 'Tới',
previousPage: 'Lùi',
},

View File

@ -36,6 +36,7 @@ export default {
pleaseInput: '請輸入',
submit: '提交',
embedIntoSite: '嵌入網站',
openInNewTab: '在新標籤頁中聊天',
previousPage: '上一頁',
nextPage: '下一頁',
add: '添加',

View File

@ -45,6 +45,7 @@ export default {
submit: '提交',
clear: '清空',
embedIntoSite: '嵌入网站',
openInNewTab: '在新标签页中聊天',
previousPage: '上一页',
nextPage: '下一页',
add: '添加',

View File

@ -17,7 +17,6 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import message from '@/components/ui/message';
import { SharedFrom } from '@/constants/chat';
import { useSetModalState } from '@/hooks/common-hooks';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';