Add a third browser contextual tour step for cookie import.

When new users reach the final browser tour step, open the toolbar menu
and anchor the callout on Import Cookies so they can reuse existing logins.

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
brennanb2025
2026-06-07 15:05:51 -07:00
co-authored by Orca
parent eb62cb6c7a
commit 6bdd69a57b
4 changed files with 49 additions and 5 deletions
@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useEffect, useState } from 'react'
import { Check, Ellipsis, Import, Monitor, Plus, Settings } from 'lucide-react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
@@ -58,6 +58,9 @@ export function BrowserToolbarMenu({
const fetchDetectedBrowsers = useAppStore((s) => s.fetchDetectedBrowsers)
const browserSessionImportState = useAppStore((s) => s.browserSessionImportState)
const setBrowserPageViewportPreset = useAppStore((s) => s.setBrowserPageViewportPreset)
const browserCookieTourStepActive = useAppStore(
(s) => s.activeContextualTourId === 'browser' && s.activeContextualTourStepIndex === 2
)
const applyViewportPreset = (nextId: BrowserViewportPresetId | null): void => {
setBrowserPageViewportPreset(browserPageId, nextId)
@@ -72,8 +75,22 @@ export function BrowserToolbarMenu({
const [pendingSwitchProfileId, setPendingSwitchProfileId] = useState<string | null | undefined>(
undefined
)
const [menuOpen, setMenuOpen] = useState(false)
const mountedRef = useMountedRef()
useEffect(() => {
// Why: step 3 anchors on Import Cookies inside this menu, so open it when
// the browser tour reaches the final step and close it when leaving.
setMenuOpen(browserCookieTourStepActive)
}, [browserCookieTourStepActive])
const handleMenuOpenChange = (open: boolean): void => {
if (browserCookieTourStepActive && !open) {
return
}
setMenuOpen(open)
}
const effectiveProfileId = currentProfileId ?? 'default'
const defaultProfile = browserSessionProfiles.find((p) => p.id === 'default')
@@ -165,7 +182,7 @@ export function BrowserToolbarMenu({
return (
<>
<DropdownMenu>
<DropdownMenu open={menuOpen} onOpenChange={handleMenuOpenChange}>
<DropdownMenuTrigger asChild>
<Button size="icon" variant="ghost" className="h-8 w-8" title="Browser menu">
<Ellipsis className="size-4" />
@@ -211,7 +228,10 @@ export function BrowserToolbarMenu({
}
}}
>
<DropdownMenuSubTrigger disabled={browserSessionImportState?.status === 'importing'}>
<DropdownMenuSubTrigger
disabled={browserSessionImportState?.status === 'importing'}
data-contextual-tour-target="browser-import-cookies-control"
>
<Import className="mr-2 size-3.5" />
Import Cookies
</DropdownMenuSubTrigger>
+3 -2
View File
@@ -1929,7 +1929,8 @@ describe('createUISlice contextual tours', () => {
const store = createUIStore()
const visibleSelectors = [
'[data-contextual-tour-target="browser-grab-control"]',
'[data-contextual-tour-target="browser-annotation-control"]'
'[data-contextual-tour-target="browser-annotation-control"]',
'[data-contextual-tour-target="browser-import-cookies-control"]'
]
stubContextualTourTargets(visibleSelectors)
store.getState().hydratePersistedUI(makeAutoTourEligibleUI())
@@ -1940,7 +1941,7 @@ describe('createUISlice contextual tours', () => {
store.getState().advanceContextualTour()
expect(store.getState().activeContextualTourId).toBe('browser')
expect(store.getState().activeContextualTourStepIndex).toBe(1)
expect(store.getState().activeContextualTourStepIndex).toBe(2)
})
it('advances the active split step when the split command interaction is recorded', () => {
+17
View File
@@ -97,6 +97,23 @@ describe('contextual tour definitions', () => {
})
})
it('orders the browser tour as grab, annotate, then import cookies', () => {
const tour = CONTEXTUAL_TOURS.find((entry) => entry.id === 'browser') as
| ContextualTour
| undefined
expect(tour?.steps.map((step) => step.title)).toEqual([
'Grab page context for agents',
'Mark design feedback in place',
'Stay logged in'
])
expect(tour?.steps[2]).toMatchObject({
body: 'Bring your existing logins into Orca to stay signed in immediately.',
targetSelector: '[data-contextual-tour-target="browser-import-cookies-control"]',
preferredPlacement: 'left'
})
})
it('points the tasks tour at the row workspace action before toolbar fallbacks', () => {
const tour = CONTEXTUAL_TOURS.find((entry) => entry.id === 'tasks') as
| ContextualTour
+6
View File
@@ -110,6 +110,12 @@ export const CONTEXTUAL_TOURS = [
title: 'Mark design feedback in place',
body: 'Annotate elements and send those notes to an agent.',
targetSelector: '[data-contextual-tour-target="browser-annotation-control"]'
},
{
title: 'Stay logged in',
body: 'Bring your existing logins into Orca to stay signed in immediately.',
targetSelector: '[data-contextual-tour-target="browser-import-cookies-control"]',
preferredPlacement: 'left'
}
]
},