a127e2dffd
* feat(review): navigate to code-review findings from the Changes panel The findings count in the review top bar was a passive badge, so a user had to scroll the diff to hunt for each inline finding. Turn it into a navigator: it opens a popover listing every open finding grouped by file (most-severe first), and clicking one jumps to the finding's card in the diff, scrolls it into view, and briefly flashes it. - lib/review/navigation.ts: navigateToFinding selects the finding's file, emits an event, then polls across frames (files render lazily) for the card and scrolls + flashes it. Reuses the composite <repo>\x00<path> key so cross-repo same-named files stay distinct. - review-findings-overview + review-findings-button: the grouped list and its click-to-open popover trigger, mirroring the FixCommentsButton / ReviewCommentsOverview pattern. The badge moves out of ReviewRunButton into the top bar, keeping the review-open-count testid and copy. - inline-review-finding: stamps data-review-finding-id + scroll margin so navigation can target the card. - unanchored-findings-banner: auto-expands when a navigation targets one of its stale findings so that card renders and can be scrolled to. - globals.css: review-finding-flash highlight, respecting reduced motion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(review): harden finding navigation from code-review feedback Address automated review of the findings navigator: - navigation.ts: scope the finding lookup to the open review dialog so a duplicate card rendered by the Changes panel behind it is not scrolled to instead; re-emit the navigate event each poll frame so a lazily mounted stale-findings banner still expands (a one-shot event fired before the section rendered was missed); honor prefers-reduced-motion for the scroll, matching the flash animation. - review-dialog-surface: clear the sidebar file filter before selecting a finding's file, so a finding in a filtered-out file still mounts. - review-findings-button: surface a warning when the card can't be reached instead of discarding the promise silently. - review-findings-overview: compute the file directory once per row. - Tests: unit coverage for the banner auto-expand and the findings button (null render + navigate), plus a mobile-* e2e that taps the navigator and verifies the target card is reached. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useAppStore } from "@/components/state-provider";
|
|
import { useFindingActions } from "@/hooks/domains/review/use-finding-actions";
|
|
import { useSendFindingToAgent } from "@/hooks/domains/review/use-send-finding-to-agent";
|
|
import { FINDING_DOM_ATTR } from "@/lib/review/navigation";
|
|
import type { TaskReviewFinding } from "@/lib/types/review";
|
|
import { ReviewFindingCard } from "./review-finding-card";
|
|
|
|
/**
|
|
* One review finding rendered inline at its anchored diff line.
|
|
*
|
|
* This container wires its own actions from the store rather than taking them as
|
|
* props: an inline finding annotation only exists when the active task has
|
|
* findings, so the store is always present, and threading four callbacks through
|
|
* FileDiffViewer → DiffViewer → the annotation renderer would add plumbing that
|
|
* every other diff consumer would have to carry.
|
|
*/
|
|
export function InlineReviewFinding({
|
|
finding,
|
|
staleReason,
|
|
}: {
|
|
finding: TaskReviewFinding;
|
|
staleReason?: string;
|
|
}) {
|
|
const taskId = useAppStore((s) => s.tasks.activeTaskId);
|
|
const sessionId = useAppStore((s) => s.tasks.activeSessionId);
|
|
const { resolveFinding, dismissFinding, reopenFinding } = useFindingActions(taskId);
|
|
const sendToAgent = useSendFindingToAgent({ taskId, sessionId });
|
|
|
|
return (
|
|
<div className="my-1 scroll-mt-24 px-2 rounded-md" {...{ [FINDING_DOM_ATTR]: finding.id }}>
|
|
<ReviewFindingCard
|
|
finding={finding}
|
|
staleReason={staleReason}
|
|
onResolve={resolveFinding}
|
|
onDismiss={dismissFinding}
|
|
onReopen={reopenFinding}
|
|
onSendToAgent={sessionId ? sendToAgent : undefined}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|