From 596740c86fef06451e39d15efa0d53f999fda80d Mon Sep 17 00:00:00 2001 From: poduck Date: Tue, 30 Dec 2025 10:31:59 -0500 Subject: [PATCH] Simplify embedded mode navigation to stay within iframe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the complex token-passing logic for new tabs in embedded mode. Instead, navigation now stays within the iframe for a simpler UX. - Remove handleNewWindowClick auth handler from sidebar items - Simplify useNewWindow hook to navigate within iframe when embedded - Fix authenticate route to use saveResponse instead of saveToken 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../components/sidebar/ap-sidebar-item.tsx | 18 -------------- .../src/app/routes/authenticate/index.tsx | 2 +- .../react-ui/src/lib/navigation-utils.tsx | 24 +++++-------------- frontend/src/pages/Automations.tsx | 2 +- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/activepieces-fork/packages/react-ui/src/app/components/sidebar/ap-sidebar-item.tsx b/activepieces-fork/packages/react-ui/src/app/components/sidebar/ap-sidebar-item.tsx index cb26231a..64f83f91 100644 --- a/activepieces-fork/packages/react-ui/src/app/components/sidebar/ap-sidebar-item.tsx +++ b/activepieces-fork/packages/react-ui/src/app/components/sidebar/ap-sidebar-item.tsx @@ -36,26 +36,10 @@ export type SidebarItemType = { export const ApSidebarItem = (item: SidebarItemType) => { const location = useLocation(); const { state } = useSidebar(); - const { embedState } = useEmbedding(); const isLinkActive = location.pathname.startsWith(item.to) || item.isActive?.(location.pathname); const isCollapsed = state === 'collapsed'; - // Handle new window clicks with authentication in embedded mode - const handleNewWindowClick = (e: React.MouseEvent) => { - if (item.newWindow && embedState.isEmbedded) { - e.preventDefault(); - const token = authenticationSession.getToken(); - if (token) { - const encodedRedirect = encodeURIComponent(item.to); - const authUrl = `/authenticate?token=${encodeURIComponent(token)}&redirect=${encodedRedirect}`; - window.open(authUrl, '_blank', 'noopener'); - } else { - window.open(item.to, '_blank', 'noopener noreferrer'); - } - } - }; - return ( e.stopPropagation()} @@ -69,7 +53,6 @@ export const ApSidebarItem = (item: SidebarItemType) => { to={item.to} target={item.newWindow ? '_blank' : ''} rel={item.newWindow ? 'noopener noreferrer' : undefined} - onClick={handleNewWindowClick} className={cn( buttonVariants({ variant: 'ghost', size: 'icon' }), isLinkActive && 'bg-sidebar-accent hover:!bg-sidebar-accent', @@ -102,7 +85,6 @@ export const ApSidebarItem = (item: SidebarItemType) => { to={item.to} target={item.newWindow ? '_blank' : ''} rel={item.newWindow ? 'noopener noreferrer' : undefined} - onClick={handleNewWindowClick} >
diff --git a/activepieces-fork/packages/react-ui/src/app/routes/authenticate/index.tsx b/activepieces-fork/packages/react-ui/src/app/routes/authenticate/index.tsx index 95057530..f830e710 100644 --- a/activepieces-fork/packages/react-ui/src/app/routes/authenticate/index.tsx +++ b/activepieces-fork/packages/react-ui/src/app/routes/authenticate/index.tsx @@ -21,7 +21,7 @@ const AuthenticatePage = () => { } else if (token) { // Handle standalone JWT token (from embedded mode new tab) // Save token directly to localStorage for persistence in new tabs - authenticationSession.saveToken(token); + authenticationSession.saveResponse({ token }, false); navigate(redirectTo); } }, [response, token, redirectTo, navigate]); diff --git a/activepieces-fork/packages/react-ui/src/lib/navigation-utils.tsx b/activepieces-fork/packages/react-ui/src/lib/navigation-utils.tsx index 128a0c59..69156e34 100644 --- a/activepieces-fork/packages/react-ui/src/lib/navigation-utils.tsx +++ b/activepieces-fork/packages/react-ui/src/lib/navigation-utils.tsx @@ -8,24 +8,12 @@ export const useNewWindow = () => { const { embedState } = useEmbedding(); const navigate = useNavigate(); if (embedState.isEmbedded) { - // In embedded mode, open new tab with authentication token - return (route: string, searchParams?: string) => { - const token = authenticationSession.getToken(); - const fullRoute = `${route}${searchParams ? '?' + searchParams : ''}`; - - if (token) { - // Pass token for auto-authentication in new tab - const encodedRedirect = encodeURIComponent(fullRoute); - const authUrl = `/authenticate?token=${encodeURIComponent(token)}&redirect=${encodedRedirect}`; - window.open(authUrl, '_blank', 'noopener'); - } else { - // Fallback to in-iframe navigation if no token - navigate({ - pathname: route, - search: searchParams, - }); - } - }; + // In embedded mode, navigate within the iframe (don't open new tabs) + return (route: string, searchParams?: string) => + navigate({ + pathname: route, + search: searchParams, + }); } else { return (route: string, searchParams?: string) => window.open( diff --git a/frontend/src/pages/Automations.tsx b/frontend/src/pages/Automations.tsx index b72e4fff..f7cc698d 100644 --- a/frontend/src/pages/Automations.tsx +++ b/frontend/src/pages/Automations.tsx @@ -1,7 +1,7 @@ import { useState, useEffect, useRef, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery } from '@tanstack/react-query'; -import { Bot, RefreshCw, AlertTriangle, Loader2, Sparkles, RotateCcw, ChevronDown } from 'lucide-react'; +import { Bot, RefreshCw, AlertTriangle, Loader2, ExternalLink, Sparkles, RotateCcw, ChevronDown } from 'lucide-react'; import api from '../api/client'; import { usePlanFeatures } from '../hooks/usePlanFeatures'; import { UpgradePrompt } from '../components/UpgradePrompt';