Make 'Open in canvas' on the lead mini-card actually do something#16
Make 'Open in canvas' on the lead mini-card actually do something#16jerelvelarde wants to merge 1 commit into
Conversation
Clicking the LeadMiniCard's "Open in canvas" was setting selectedLeadId on agent state — which only added a faint lavender ring to the matching kanban card. If the lead was filtered out or scrolled out of view, the click looked like a no-op. Now the click also clears any active filter, sets the lead as highlighted (triggers the existing 2s pulse), and PipelineBoard scrolls the matching DraggableLeadCard into view via useEffect on `selected`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request implements a feature to automatically scroll lead cards into view when selected, specifically targeting the 'Open in canvas' action. The changes include clearing filters and highlighting the selected lead in the state. Feedback suggests stabilizing the ref merger with useCallback to avoid performance overhead and refining the scrolling logic to use block: 'nearest' for manual board clicks to prevent jarring UI movements. It is also recommended to include highlightedLeadIds in the scroll effect's dependency array to ensure consistent behavior on repeated actions.
| "use client"; | ||
|
|
||
| import { useState } from "react"; | ||
| import { useEffect, useRef, useState } from "react"; |
| useEffect(() => { | ||
| if (!selected) return; | ||
| const node = containerRef.current; | ||
| if (!node) return; | ||
| node.scrollIntoView({ behavior: "smooth", block: "center" }); | ||
| }, [selected]); |
There was a problem hiding this comment.
The current implementation scrolls the card to the center of the viewport whenever it is selected. While this is effective for the 'Open in canvas' action from chat, it can be jarring for manual clicks on the board where the card is already visible.
Consider using block: "nearest" to avoid unnecessary movement for visible cards, or conditionally use "center" only when the lead is also highlighted (which distinguishes the chat action from a manual board click).
Additionally, adding highlightedLeadIds to the dependency array ensures that clicking 'Open in canvas' multiple times for the same lead still triggers the scroll if the user has manually scrolled away in between (since onSelect in page.tsx creates a new array reference on every click).
useEffect(() => {
if (!selected) return;
const node = containerRef.current;
if (!node) return;
// Use 'center' for intentional 'Open in canvas' actions (highlighted),
// but 'nearest' for manual board selections to avoid jarring jumps.
node.scrollIntoView({
behavior: "smooth",
block: highlighted ? "center" : "nearest",
});
}, [selected, highlighted, highlightedLeadIds]);
| ref={(node) => { | ||
| setNodeRef(node); | ||
| containerRef.current = node; | ||
| }} |
There was a problem hiding this comment.
Using an inline function for the ref prop causes React to call the ref callback twice (once with null and once with the element) on every re-render of the component. This can lead to unnecessary overhead and potential issues with dnd-kit's internal tracking. It is better to stabilize the ref merger using useCallback.
| ref={(node) => { | |
| setNodeRef(node); | |
| containerRef.current = node; | |
| }} | |
| ref={useCallback((node: HTMLDivElement | null) => { | |
| setNodeRef(node); | |
| containerRef.current = node; | |
| }, [setNodeRef])} |
Summary
<LeadMiniCard>was only settingselectedLeadId— a faint lavender ring on the matching kanban card. If the lead was filtered out or scrolled below the fold, the click looked like a no-op.PipelineBoardscrolls theDraggableLeadCardinto view via auseEffectonselected.Test plan
setFilter({workshops: ["Deploying Agents (prod)"]})if Ada isn't in that bucket).🤖 Generated with Claude Code