Simplify embedded mode navigation to stay within iframe

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

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-30 10:31:59 -05:00
parent 174cc94b42
commit 1d1cfbb164
3 changed files with 7 additions and 37 deletions

View File

@@ -36,26 +36,10 @@ export type SidebarItemType = {
export const ApSidebarItem = (item: SidebarItemType) => { export const ApSidebarItem = (item: SidebarItemType) => {
const location = useLocation(); const location = useLocation();
const { state } = useSidebar(); const { state } = useSidebar();
const { embedState } = useEmbedding();
const isLinkActive = const isLinkActive =
location.pathname.startsWith(item.to) || item.isActive?.(location.pathname); location.pathname.startsWith(item.to) || item.isActive?.(location.pathname);
const isCollapsed = state === 'collapsed'; 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 ( return (
<SidebarMenuItem <SidebarMenuItem
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
@@ -69,7 +53,6 @@ export const ApSidebarItem = (item: SidebarItemType) => {
to={item.to} to={item.to}
target={item.newWindow ? '_blank' : ''} target={item.newWindow ? '_blank' : ''}
rel={item.newWindow ? 'noopener noreferrer' : undefined} rel={item.newWindow ? 'noopener noreferrer' : undefined}
onClick={handleNewWindowClick}
className={cn( className={cn(
buttonVariants({ variant: 'ghost', size: 'icon' }), buttonVariants({ variant: 'ghost', size: 'icon' }),
isLinkActive && 'bg-sidebar-accent hover:!bg-sidebar-accent', isLinkActive && 'bg-sidebar-accent hover:!bg-sidebar-accent',
@@ -102,7 +85,6 @@ export const ApSidebarItem = (item: SidebarItemType) => {
to={item.to} to={item.to}
target={item.newWindow ? '_blank' : ''} target={item.newWindow ? '_blank' : ''}
rel={item.newWindow ? 'noopener noreferrer' : undefined} rel={item.newWindow ? 'noopener noreferrer' : undefined}
onClick={handleNewWindowClick}
> >
<div className="w-full flex items-center justify-between gap-2"> <div className="w-full flex items-center justify-between gap-2">
<div className="flex items-center gap-2 w-full"> <div className="flex items-center gap-2 w-full">

View File

@@ -8,24 +8,12 @@ export const useNewWindow = () => {
const { embedState } = useEmbedding(); const { embedState } = useEmbedding();
const navigate = useNavigate(); const navigate = useNavigate();
if (embedState.isEmbedded) { if (embedState.isEmbedded) {
// In embedded mode, open new tab with authentication token // In embedded mode, navigate within the iframe (don't open new tabs)
return (route: string, searchParams?: string) => { return (route: string, searchParams?: string) =>
const token = authenticationSession.getToken(); navigate({
const fullRoute = `${route}${searchParams ? '?' + searchParams : ''}`; pathname: route,
search: 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,
});
}
};
} else { } else {
return (route: string, searchParams?: string) => return (route: string, searchParams?: string) =>
window.open( window.open(

View File

@@ -1,7 +1,7 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query'; 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 api from '../api/client';
import { usePlanFeatures } from '../hooks/usePlanFeatures'; import { usePlanFeatures } from '../hooks/usePlanFeatures';
import { UpgradePrompt } from '../components/UpgradePrompt'; import { UpgradePrompt } from '../components/UpgradePrompt';