Browse Source

feat(quick-23): memoize InlineParameterPanel and simplify toggle handlers

- Wrap InlineParameterPanel in React.memo
- Simplify handleToggleParams in all 5 generate nodes
- Use local isParamsExpanded instead of re-querying store
- Eliminates O(n) nodes.find() on every toggle click

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 4 months ago
parent
commit
3a73ebc80f
  1. 7
      src/components/nodes/Generate3DNode.tsx
  2. 7
      src/components/nodes/GenerateAudioNode.tsx
  3. 7
      src/components/nodes/GenerateImageNode.tsx
  4. 7
      src/components/nodes/GenerateVideoNode.tsx
  5. 7
      src/components/nodes/InlineParameterPanel.tsx
  6. 7
      src/components/nodes/LLMGenerateNode.tsx

7
src/components/nodes/Generate3DNode.tsx

@ -95,11 +95,8 @@ export function Generate3DNode({ id, data, selected }: NodeProps<Generate3DNodeT
const isParamsExpanded = nodeData.parametersExpanded ?? true; // default expanded
const handleToggleParams = useCallback(() => {
const nodes = useWorkflowStore.getState().nodes;
const node = nodes.find(n => n.id === id);
const currentExpanded = (node?.data as Generate3DNodeData)?.parametersExpanded ?? true;
updateNodeData(id, { parametersExpanded: !currentExpanded });
}, [id, updateNodeData]);
updateNodeData(id, { parametersExpanded: !isParamsExpanded });
}, [id, isParamsExpanded, updateNodeData]);
// Track previous status to detect error transitions
const prevStatusRef = useRef(nodeData.status);

7
src/components/nodes/GenerateAudioNode.tsx

@ -198,11 +198,8 @@ export function GenerateAudioNode({ id, data, selected }: NodeProps<GenerateAudi
const isParamsExpanded = nodeData.parametersExpanded ?? true; // default expanded
const handleToggleParams = useCallback(() => {
const nodes = useWorkflowStore.getState().nodes;
const node = nodes.find(n => n.id === id);
const currentExpanded = (node?.data as GenerateAudioNodeData)?.parametersExpanded ?? true;
updateNodeData(id, { parametersExpanded: !currentExpanded });
}, [id, updateNodeData]);
updateNodeData(id, { parametersExpanded: !isParamsExpanded });
}, [id, isParamsExpanded, updateNodeData]);
// Dynamic handles based on inputSchema
const dynamicHandles = useMemo(() => {

7
src/components/nodes/GenerateImageNode.tsx

@ -151,11 +151,8 @@ export function GenerateImageNode({ id, data, selected }: NodeProps<NanoBananaNo
const isParamsExpanded = nodeData.parametersExpanded ?? true; // default expanded
const handleToggleParams = useCallback(() => {
const nodes = useWorkflowStore.getState().nodes;
const node = nodes.find(n => n.id === id);
const currentExpanded = (node?.data as NanoBananaNodeData)?.parametersExpanded ?? true;
updateNodeData(id, { parametersExpanded: !currentExpanded });
}, [id, updateNodeData]);
updateNodeData(id, { parametersExpanded: !isParamsExpanded });
}, [id, isParamsExpanded, updateNodeData]);
// Handle provider change
const handleProviderChange = useCallback(

7
src/components/nodes/GenerateVideoNode.tsx

@ -131,11 +131,8 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
const isParamsExpanded = nodeData.parametersExpanded ?? true; // default expanded
const handleToggleParams = useCallback(() => {
const nodes = useWorkflowStore.getState().nodes;
const node = nodes.find(n => n.id === id);
const currentExpanded = (node?.data as GenerateVideoNodeData)?.parametersExpanded ?? true;
updateNodeData(id, { parametersExpanded: !currentExpanded });
}, [id, updateNodeData]);
updateNodeData(id, { parametersExpanded: !isParamsExpanded });
}, [id, isParamsExpanded, updateNodeData]);
// Handle provider change
const handleProviderChange = useCallback(

7
src/components/nodes/InlineParameterPanel.tsx

@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import React, { ReactNode } from "react";
interface InlineParameterPanelProps {
expanded: boolean;
@ -13,7 +13,7 @@ interface InlineParameterPanelProps {
* Collapsible parameter container for inline display within generation nodes.
* Provides a chevron toggle button and instant expand/collapse.
*/
export function InlineParameterPanel({
function InlineParameterPanelInner({
expanded,
onToggle,
children,
@ -57,3 +57,6 @@ export function InlineParameterPanel({
</>
);
}
// Memoized export to prevent unnecessary re-renders
export const InlineParameterPanel = React.memo(InlineParameterPanelInner);

7
src/components/nodes/LLMGenerateNode.tsx

@ -71,11 +71,8 @@ export function LLMGenerateNode({ id, data, selected }: NodeProps<LLMGenerateNod
const isParamsExpanded = nodeData.parametersExpanded ?? true; // default expanded
const handleToggleParams = useCallback(() => {
const nodes = useWorkflowStore.getState().nodes;
const node = nodes.find(n => n.id === id);
const currentExpanded = (node?.data as LLMGenerateNodeData)?.parametersExpanded ?? true;
updateNodeData(id, { parametersExpanded: !currentExpanded });
}, [id, updateNodeData]);
updateNodeData(id, { parametersExpanded: !isParamsExpanded });
}, [id, isParamsExpanded, updateNodeData]);
// LLM parameter handlers
const handleProviderChange = useCallback(

Loading…
Cancel
Save