fix(designer): Extract useRawInputsOutputs hook to fix portal freeze#9129
fix(designer): Extract useRawInputsOutputs hook to fix portal freeze#9129Elaina-Lee merged 1 commit intomainfrom
Conversation
The previous fix (inline placeholderData object) caused infinite re-renders in the portal because TanStack Query returns placeholderData as data immediately (isLoading=false), and a new inline object reference each render triggers the useEffect → dispatch → Redux update → re-render cycle endlessly. Fix: Port v2's useRawInputsOutputs hook pattern to v1: - Module-level emptyData constant (stable reference, no re-render loop) - Stable query key with actionTrackingId/startTime/endTime - No refetch() on runMetaData change (key change handles invalidation) - Always calls getActionLinks for fresh API data (no infinite nesting) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR fixes a portal browser-freeze regression by extracting raw inputs/outputs fetching into a dedicated React Query hook with stable placeholderData, avoiding infinite re-render/dispatch loops.
Changes:
- Added
useRawInputsOutputshook with module-levelemptyDataplaceholder and a stable query key. - Updated
MonitoringPanelto use the new hook instead of an inline React Query call. - Moved/adjusted unit tests to cover the hook behavior and simplified MonitoringTab tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/useRawInputsOutputs.ts | Introduces shared hook for fetching raw action inputs/outputs with stable placeholder data. |
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/tabs/monitoringTab/monitoringTab.tsx | Replaces inline query logic with the new hook and keeps binding initialization via effect. |
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/tabs/monitoringTab/test/monitoringTab.spec.tsx | Updates tests to mock the new hook and removes direct React Query/RunService assertions. |
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/test/useRawInputsOutputs.spec.ts | Adds hook-level tests for query key, placeholder stability, and RunService fetching behavior. |
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
✅ Risk Level
✅ What & Why
✅ Impact of Change
✅ Test Plan
✅ Contributors
|
| Section | Status | Recommendation |
|---|---|---|
| Title | ✅ | Good — descriptive and conventional commit style. |
| Commit Type | ✅ | Correctly marked as fix. |
| Risk Level | ✅ | Medium chosen and label present — consistent. |
| What & Why | ✅ | Well-documented; clear root cause and fix. |
| Impact of Change | ✅ | Clear user/developer/system impact described. |
| Test Plan | ✅ | Unit tests present in diff; manual test coverage described. |
| Contributors | ✅ | Contributors listed. |
| Screenshots/Videos | N/A — acceptable for behavioral fix. |
Summary
The PR follows the required PR body template, includes unit tests that address the regression, and the selected risk level matches the repo label. I recommend removing the needs-pr-update label (it remains on the PR) once you are ready for final review/merge, since the PR body appears complete and test coverage is added.
Quick actionable suggestions (optional):
- Remove the
needs-pr-updatelabel prior to merge if no further changes are expected. - Confirm CI passed for the new unit tests (they are present in the diff and should be picked up by your test pipeline).
- If the new hook is intended to be consumed outside the nodeDetailsPanel folder in other packages, explicitly document or export it in the package index (only if intended).
Please update labels / run CI if needed and proceed — this PR passes review for title & body compliance.
Last updated: Fri, 01 May 2026 00:49:38 GMT
📊 Coverage Check🎉 All changed files have adequate test coverage! |
…9132) fix(designer): Extract useRawInputsOutputs hook to fix portal freeze (#9129) The previous fix (inline placeholderData object) caused infinite re-renders in the portal because TanStack Query returns placeholderData as data immediately (isLoading=false), and a new inline object reference each render triggers the useEffect → dispatch → Redux update → re-render cycle endlessly. Fix: Port v2's useRawInputsOutputs hook pattern to v1: - Module-level emptyData constant (stable reference, no re-render loop) - Stable query key with actionTrackingId/startTime/endTime - No refetch() on runMetaData change (key change handles invalidation) - Always calls getActionLinks for fresh API data (no infinite nesting) Co-authored-by: Krrish Mittal <11722204+takyyon@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Commit Type
Risk Level
What & Why
Problem
Follow-up to PR #9123. The inline
placeholderDatafix for infinite recursive nesting worked correctly in the Standalone designer, but caused the portal to freeze completely when opening any action in monitoring view. The browser tab becomes unresponsive and must be force-killed.Root Cause
The fix in #9123 used an inline object literal for
placeholderData:In the portal environment, TanStack Query returns
placeholderDataasdataimmediately (isLoading=false). Because a new object reference is created each render, this triggers an infinite re-render loop:{ inputs: {}, outputs: {} }creates new object referencedata(sinceisLoadingis false withplaceholderData)useEffectfires ondatachange → dispatchesinitializeInputsOutputsBindingThis did not surface in Standalone because the Standalone app initializes the query cache differently (fresh mount vs portal's persistent extension host).
Fix
Extract a dedicated
useRawInputsOutputshook, porting the proven pattern from designer-v2:emptyDataconstant —const emptyData: RawInputsOutputs = { inputs: {}, outputs: {} }at module scope provides a stable reference.placeholderData: emptyDatanever creates a new object, breaking the re-render loop.useRawInputsOutputs.ts) — encapsulates the query logic in a reusable hook with a typedRawInputsOutputsinterface, matching designer-v2's pattern.monitoringTab.tsxnow delegates all data fetching to the hook, reducing its responsibility to layout and dispatch.Why designer-v2 is unaffected
designer-v2's
useRawInputsOutputshook already uses a module-level empty constant. This fix aligns v1 with that pattern.Impact of Change
useRawInputsOutputshook exported fromnodeDetailsPanel/— can be shared across any panel that needs raw action inputs/outputs.Test Plan
Test details:
useRawInputsOutputs.spec.ts— 7 new unit tests covering:should use stable query key with actionTrackingId, startTime, and endTime— verifies cache key stabilityshould use a stable placeholderData reference (prevents infinite re-render)— the core regression test — assertsplaceholderDatais referentially identical across rendersshould always call getActionLinks even when runData has existing inputs/outputs— verifies no shortcutshould not re-feed already-bound BoundParameters as raw inputs (regression)— regression from fix(designer): Fix infinite recursive nesting in monitoring run history values #9123should return empty inputs/outputs when getActionLinks returns nullish values— null safetyshould handle getActionLinks returning null/undefined entirely— edge caseshould pass enabled option when provided— API contractmonitoringTab.spec.tsx— updated to mockuseRawInputsOutputsinstead ofuseQuerydirectly, testing integration points (nodeId passing, loading state, error state)Contributors
@takyyon
Screenshots/Videos
N/A — behavioral fix (unfreezes browser), no visual changes