diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx index b67f63a39..62d404d7a 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx @@ -26,12 +26,10 @@ interface NodeEntry { /** * Search context for structured output tree. - * Separates stable values from frequently changing currentMatchIndex to avoid re-renders. */ interface SearchContextValue { query: string pathToMatchIndices: Map - currentMatchIndexRef: React.RefObject } const SearchContext = createContext(null) @@ -270,15 +268,18 @@ interface HighlightedTextProps { text: string matchIndices: number[] path: string + currentMatchIndex: number } /** * Renders text with search highlights for non-virtualized mode. + * Accepts currentMatchIndex as prop to ensure re-render when it changes. */ const HighlightedText = memo(function HighlightedText({ text, matchIndices, path, + currentMatchIndex, }: HighlightedTextProps) { const searchContext = useContext(SearchContext) @@ -286,13 +287,7 @@ const HighlightedText = memo(function HighlightedText({ return ( <> - {renderHighlightedSegments( - text, - searchContext.query, - matchIndices, - searchContext.currentMatchIndexRef.current, - path - )} + {renderHighlightedSegments(text, searchContext.query, matchIndices, currentMatchIndex, path)} ) }) @@ -304,6 +299,7 @@ interface StructuredNodeProps { expandedPaths: Set onToggle: (path: string) => void wrapText: boolean + currentMatchIndex: number isError?: boolean } @@ -318,6 +314,7 @@ const StructuredNode = memo(function StructuredNode({ expandedPaths, onToggle, wrapText, + currentMatchIndex, isError = false, }: StructuredNodeProps) { const searchContext = useContext(SearchContext) @@ -381,7 +378,12 @@ const StructuredNode = memo(function StructuredNode({ wrapText ? '[word-break:break-word]' : 'whitespace-nowrap' )} > - + ) : isEmptyValue ? (
{Array.isArray(value) ? '[]' : '{}'}
@@ -395,6 +397,7 @@ const StructuredNode = memo(function StructuredNode({ expandedPaths={expandedPaths} onToggle={onToggle} wrapText={wrapText} + currentMatchIndex={currentMatchIndex} /> )) )} @@ -682,18 +685,9 @@ export const StructuredOutput = memo(function StructuredOutput({ const prevDataRef = useRef(data) const prevIsErrorRef = useRef(isError) const internalRef = useRef(null) - const currentMatchIndexRef = useRef(currentMatchIndex) const listRef = useListRef(null) const [containerHeight, setContainerHeight] = useState(400) - currentMatchIndexRef.current = currentMatchIndex - - // Force re-render when currentMatchIndex changes - const [, forceUpdate] = useState(0) - useEffect(() => { - forceUpdate((n) => n + 1) - }, [currentMatchIndex]) - const setContainerRef = useCallback( (node: HTMLDivElement | null) => { ;(internalRef as React.MutableRefObject).current = node @@ -782,7 +776,7 @@ export const StructuredOutput = memo(function StructuredOutput({ const searchContextValue = useMemo(() => { if (!searchQuery) return null - return { query: searchQuery, pathToMatchIndices, currentMatchIndexRef } + return { query: searchQuery, pathToMatchIndices } }, [searchQuery, pathToMatchIndices]) const visibleRowCount = useMemo( @@ -890,6 +884,7 @@ export const StructuredOutput = memo(function StructuredOutput({ expandedPaths={expandedPaths} onToggle={handleToggle} wrapText={wrapText} + currentMatchIndex={currentMatchIndex} isError /> @@ -909,6 +904,7 @@ export const StructuredOutput = memo(function StructuredOutput({ expandedPaths={expandedPaths} onToggle={handleToggle} wrapText={wrapText} + currentMatchIndex={currentMatchIndex} /> ))}