fix: Scroll to exact comment location when clicking sidebar discussions

Adds data-comment-id attributes to comment thread rows so clicking a
discussion in the sidebar scrolls directly to the comment, not just the
file card. Includes a brief ring highlight on the target row.
This commit is contained in:
Lukas May
2026-03-06 11:09:07 +01:00
parent b1233dd013
commit 3fcfa61914
3 changed files with 18 additions and 2 deletions

View File

@@ -134,7 +134,7 @@ export function LineWithComments({
{/* Existing comments on this line */}
{lineComments.length > 0 && (
<tr>
<tr data-comment-id={lineComments.find((c) => !c.parentCommentId)?.id}>
<td
colSpan={3}
className="px-3 py-2 bg-muted/20 border-y border-border/50"

View File

@@ -18,6 +18,7 @@ interface ReviewSidebarProps {
files: FileDiff[];
comments: ReviewComment[];
onFileClick: (filePath: string) => void;
onCommentClick?: (commentId: string) => void;
selectedCommit: string | null;
activeFiles: FileDiff[];
commits: CommitInfo[];
@@ -29,6 +30,7 @@ export function ReviewSidebar({
files,
comments,
onFileClick,
onCommentClick,
selectedCommit,
activeFiles,
commits,
@@ -63,6 +65,7 @@ export function ReviewSidebar({
files={files}
comments={comments}
onFileClick={onFileClick}
onCommentClick={onCommentClick}
selectedCommit={selectedCommit}
activeFiles={activeFiles}
viewedFiles={viewedFiles}
@@ -172,6 +175,7 @@ function FilesView({
files,
comments,
onFileClick,
onCommentClick,
selectedCommit,
activeFiles,
viewedFiles,
@@ -179,6 +183,7 @@ function FilesView({
files: FileDiff[];
comments: ReviewComment[];
onFileClick: (filePath: string) => void;
onCommentClick?: (commentId: string) => void;
selectedCommit: string | null;
activeFiles: FileDiff[];
viewedFiles: Set<string>;
@@ -248,7 +253,7 @@ function FilesView({
transition-colors hover:bg-accent/50
${thread.resolved ? "opacity-50" : ""}
`}
onClick={() => onFileClick(thread.filePath)}
onClick={() => onCommentClick ? onCommentClick(thread.id) : onFileClick(thread.filePath)}
>
<div className="flex items-center gap-1.5 w-full min-w-0">
{thread.resolved ? (

View File

@@ -259,6 +259,16 @@ export function ReviewTab({ initiativeId }: ReviewTabProps) {
}
}, []);
const handleCommentClick = useCallback((commentId: string) => {
const el = document.querySelector(`[data-comment-id="${commentId}"]`);
if (el) {
el.scrollIntoView({ behavior: "smooth", block: "center" });
// Brief highlight flash
el.classList.add("ring-2", "ring-primary/50");
setTimeout(() => el.classList.remove("ring-2", "ring-primary/50"), 1500);
}
}, []);
const handlePhaseSelect = useCallback((id: string) => {
setSelectedPhaseId(id);
setSelectedCommit(null);
@@ -331,6 +341,7 @@ export function ReviewTab({ initiativeId }: ReviewTabProps) {
files={allFiles}
comments={comments}
onFileClick={handleFileClick}
onCommentClick={handleCommentClick}
selectedCommit={selectedCommit}
activeFiles={files}
commits={commits}