Problem
surfsense_web/components/citation-panel/citation-panel.tsx has stale local state when the user opens a different citation without closing the panel.
// Lines 31–35
export const CitationPanelContent: FC<CitationPanelContentProps> = ({ chunkId, onClose }) => {
const openEditorPanel = useSetAtom(openEditorPanelAtom);
const [expanded, setExpanded] = useState(false);
useEffect(() => {
setExpanded(false);
}, []); // <-- empty deps; runs only on mount
This component is rendered conditionally inside RightPanel.tsx:251:
{effectiveTab === "citation" && citationOpen && citationState.chunkId != null && (
<CitationPanelContent chunkId={citationState.chunkId} onClose={closeCitation} />
)}
The panel is not keyed on chunkId, so when the user clicks a different citation in the chat, the same component instance is reused with a new chunkId prop — React does not remount it. The reset effect with [] deps never fires again.
Repro:
- Click citation "[1]" → panel opens with default 5-chunk window.
- Click "More context" →
expanded=true, fetches 50-chunk window for chunk 1.
- Click citation "[2]" in the chat.
- Panel now shows the 50-chunk window for chunk 2 — the user did not request this.
Files
surfsense_web/components/citation-panel/citation-panel.tsx (lines 33–35)
What to do
Change the effect deps so it actually resets when the citation changes:
- useEffect(() => {
- setExpanded(false);
- }, []);
+ useEffect(() => {
+ setExpanded(false);
+ }, [chunkId]);
That's the entire fix. The useQuery already has chunkId and chunkWindow in its queryKey (line 40), so it'll correctly refetch the default window when expanded flips back to false.
Alternative (also acceptable): key the rendered component on chunkId in RightPanel.tsx:
<CitationPanelContent key={citationState.chunkId} chunkId={citationState.chunkId} onClose={closeCitation} />
This remounts on chunk change, getting the same effect. The useEffect fix is more local and preferred.
Why this matters
- Real UX bug: opening a new citation should not show a 50-chunk window the user never asked for.
- Removes a hidden invariant from
CitationPanelContent's interface: callers no longer need to know "remount me when chunkId changes."
- One-line fix.
Acceptance criteria
Difficulty
Good first issue — 1-line change.
Problem
surfsense_web/components/citation-panel/citation-panel.tsxhas stale local state when the user opens a different citation without closing the panel.This component is rendered conditionally inside
RightPanel.tsx:251:The panel is not keyed on
chunkId, so when the user clicks a different citation in the chat, the same component instance is reused with a newchunkIdprop — React does not remount it. The reset effect with[]deps never fires again.Repro:
expanded=true, fetches 50-chunk window for chunk 1.Files
surfsense_web/components/citation-panel/citation-panel.tsx(lines 33–35)What to do
Change the effect deps so it actually resets when the citation changes:
That's the entire fix. The
useQueryalready haschunkIdandchunkWindowin itsqueryKey(line 40), so it'll correctly refetch the default window whenexpandedflips back tofalse.Alternative (also acceptable): key the rendered component on
chunkIdinRightPanel.tsx:This remounts on chunk change, getting the same effect. The
useEffectfix is more local and preferred.Why this matters
CitationPanelContent's interface: callers no longer need to know "remount me when chunkId changes."Acceptance criteria
useEffectdeps updated to[chunkId]Difficulty
Good first issue — 1-line change.