- Refactor useClosedTabHistory to store full VaultEntry (not stub) for reliable reopening - Add data-tab-path attribute to TabItem for precise Playwright selectors - Add 2 Playwright smoke tests: single close/reopen and empty-history no-op - Update ARCHITECTURE.md and ABSTRACTIONS.md with closed tab history docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import { useCallback, useRef } from 'react'
|
|
import type { VaultEntry } from '../types'
|
|
|
|
export interface ClosedTabEntry {
|
|
path: string
|
|
index: number
|
|
entry: VaultEntry
|
|
}
|
|
|
|
const MAX_HISTORY = 20
|
|
|
|
export function useClosedTabHistory() {
|
|
const stackRef = useRef<ClosedTabEntry[]>([])
|
|
|
|
const push = useCallback((path: string, index: number, entry: VaultEntry) => {
|
|
const stack = stackRef.current
|
|
// Remove any existing entry for this path (dedup)
|
|
const filtered = stack.filter(e => e.path !== path)
|
|
filtered.push({ path, index, entry })
|
|
// Cap at MAX_HISTORY
|
|
if (filtered.length > MAX_HISTORY) {
|
|
filtered.splice(0, filtered.length - MAX_HISTORY)
|
|
}
|
|
stackRef.current = filtered
|
|
}, [])
|
|
|
|
const pop = useCallback((): ClosedTabEntry | null => {
|
|
const stack = stackRef.current
|
|
if (stack.length === 0) return null
|
|
return stack.pop() ?? null
|
|
}, [])
|
|
|
|
const clear = useCallback(() => {
|
|
stackRef.current = []
|
|
}, [])
|
|
|
|
// Getter so callers see live state without re-render
|
|
return {
|
|
push, pop, clear,
|
|
get canReopen() { return stackRef.current.length > 0 },
|
|
}
|
|
}
|