* fix: preserve cmd+click on tracked domain rows
Tracked-domain rows used <div role="button" onClick={navigate(...)}>,
which prevented standard browser open-in-new-tab behavior (cmd+click,
middle-click, right-click → open). Use TanStack Router's <Link> as a
stretched overlay so the row is a real <a href> while the archive
button stays interactive.
* fix: use <Link> for tab toggles and history navigation
Replace onClick={() => navigate(...)} / setSearchParams patterns with
TanStack Router's <Link> across surfaces that change the URL on click.
<Link> renders a real <a href> and only intercepts plain left-clicks,
so cmd/ctrl+click, middle-click, and right-click → open-in-new-tab
all work natively.
- Audit: history "View" button + Pages/Performance tab toggles.
- Domain overview: Top Keywords / Top Pages tab toggles. The keyword-
only sort fallback now happens in the Link's search updater.
- Backlinks: history items, Backlinks/Domains/Pages tab toggles, and
"Recent searches" back-link. Removes now-unused
navigateToBacklinksHistory / navigateToBacklinksTab helpers.
Keyword research and domain history items, and AI search histories,
are not converted: those pages don't trigger their data fetch from
URL params alone, so a plain link target wouldn't reproduce the
current click behavior without a deeper refactor.
* refactor: unify search-page state around URL-driven fetching
Drive Keyword Research, Brand Lookup, and Prompt Explorer from URL
search params so a search is reproducible from a link alone. With
that, all three history surfaces become <Link>s and cmd+click /
right-click → "open in new tab" work natively.
- Shared SearchHistorySection now takes a renderItemLink slot so
callers wrap history items in a <Link> with the right destination.
- Prompt Explorer: added URL search params (q, models, web, cc, hb)
via promptExplorerSearchSchema; switched the explore mutation to
useQuery keyed on the URL params; addSearch now fires from a
success effect; "Recent searches" back-button is a <Link>.
- Brand Lookup: history items + "Recent searches" back-button are
<Link>s; local form state stays in sync with URL via an effect.
- Keyword Research: form submit still navigates+kicks off a search
for the same-URL re-submit case, but the controller also runs an
URL-driven search trigger (with a dedup ref against the form path).
Direct URLs, cmd+click on history, and browser back/forward all
reproduce the same fetch. "Recent searches" back-button and the
history items are <Link>s; the bespoke resetView path is gone.
Also drops now-unused clearKeywordSearchParams,
navigateToBacklinksHistory/Tab helpers' last consumers, and the
PromptExplorerPage's onQueryChange/onSelectHistoryItem callbacks.
* format
* refactor: replace useMutation with manual state in keyword research
---------
Co-authored-by: Claude <noreply@anthropic.com>
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { Link } from "@tanstack/react-router";
|
|
import { MessageSquare } from "lucide-react";
|
|
import {
|
|
HISTORY_ITEM_LINK_CLASS,
|
|
SearchHistorySection,
|
|
} from "@/client/features/ai-search/components/SearchHistorySection";
|
|
import { formatModelLabel } from "@/client/features/ai-search/platformLabels";
|
|
import type { PromptExplorerSearchHistoryItem } from "@/client/hooks/usePromptExplorerSearchHistory";
|
|
|
|
type Props = {
|
|
projectId: string;
|
|
history: PromptExplorerSearchHistoryItem[];
|
|
historyLoaded: boolean;
|
|
onRemoveHistoryItem: (timestamp: number) => void;
|
|
};
|
|
|
|
export function PromptExplorerHistorySection({ projectId, ...props }: Props) {
|
|
return (
|
|
<SearchHistorySection
|
|
{...props}
|
|
emptyIcon={MessageSquare}
|
|
emptyMessage="Enter a prompt to compare model answers"
|
|
noun="prompt"
|
|
renderItemLink={(item, content) => (
|
|
<Link
|
|
from="/p/$projectId/prompt-explorer"
|
|
to="/p/$projectId/prompt-explorer"
|
|
params={{ projectId }}
|
|
search={{
|
|
q: item.prompt,
|
|
models: item.models,
|
|
web: item.webSearch ? undefined : false,
|
|
cc:
|
|
item.webSearchCountryCode === "US"
|
|
? undefined
|
|
: item.webSearchCountryCode,
|
|
hb: item.highlightBrand || undefined,
|
|
}}
|
|
replace
|
|
className={HISTORY_ITEM_LINK_CLASS}
|
|
>
|
|
{content}
|
|
</Link>
|
|
)}
|
|
renderItem={(item) => (
|
|
<>
|
|
<p className="font-medium text-base-content truncate">
|
|
{item.prompt}
|
|
</p>
|
|
<p className="text-sm text-base-content/60 truncate">
|
|
{item.models.map(formatModelLabel).join(", ")}
|
|
</p>
|
|
</>
|
|
)}
|
|
/>
|
|
);
|
|
}
|