Skip to content

Fix/orchestrator plugins#2518

Merged
lokanandaprabhu merged 2 commits intoworkspace/orchestratorfrom
fix/orchestrator-plugins
Mar 11, 2026
Merged

Fix/orchestrator plugins#2518
lokanandaprabhu merged 2 commits intoworkspace/orchestratorfrom
fix/orchestrator-plugins

Conversation

@karthikjeeyar
Copy link
Copy Markdown
Member

This is a manual cherry pick of d6dff3b and 309547d

lokanandaprabhu and others added 2 commits March 11, 2026 21:44
…#2386)

* feat(orchestrator): add card height mode config

Expose a workflow instance page option to switch between fixed card
heights and content-based sizing, with a new hook and changeset entry.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(orchestrator): simplify layout and warn on invalid mode

Refactor the workflow instance layout to reuse card components and
rename the height mode flag for clarity, and warn when config values
are unexpected before falling back to fixed mode.

Made-with: Cursor

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…t retrigger (#2279)

* fix: show spinner on ActiveText retrigger

* fix(orchestrator-form-widgets): keep spinner until ActiveText eval completes

* Merge upstream/main

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(changeset): mention clearOnRetrigger

Document the new fetch:clearOnRetrigger behavior in the existing
changeset for the ActiveText retrigger spinner update.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(orchestrator-form-widgets): dedupe clearOnRetrigger

Extract shared clear-on-retrigger behavior into a reusable hook and
reuse it across ActiveTextInput, ActiveDropdown, and ActiveMultiSelect.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(orchestrator-form-widgets): guard retrigger races

Ignore stale fetch responses when retrigger values change and
avoid reapplying cached data while a retriggered fetch is loading.
Use layout effect for clearOnRetrigger to reduce UI flicker.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Add card height mode config and fix retrigger spinner timing in orchestrator

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Add card height mode config for workflow instance page layout
• Show spinner immediately on ActiveText retrigger to prevent stale values
• Clear widget values when fetch:retrigger dependencies change
• Guard against stale fetch responses with request ID tracking
• Extract reusable clearOnRetrigger hook for form widgets
Diagram
flowchart LR
  A["Config: cardHeightMode"] -->|"fixed or content"| B["useWorkflowInstanceCardHeightMode"]
  B -->|"applies layout"| C["WorkflowInstancePageContent"]
  D["fetch:clearOnRetrigger prop"] -->|"enables"| E["useClearOnRetrigger hook"]
  E -->|"clears on change"| F["ActiveTextInput/Dropdown/MultiSelect"]
  G["useFetch hook"] -->|"tracks requestId"| H["Prevents stale responses"]
  H -->|"guards setData/setError"| I["Consistent widget state"]
Loading

Grey Divider

File Changes

1. workspaces/orchestrator/plugins/orchestrator-common/config.d.ts ⚙️ Configuration changes +14/-0

Add workflowInstancePage cardHeightMode config option

workspaces/orchestrator/plugins/orchestrator-common/config.d.ts


2. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/uiPropTypes.ts ✨ Enhancement +1/-0

Add fetch:clearOnRetrigger UI property type

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/uiPropTypes.ts


3. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/index.ts ✨ Enhancement +1/-0

Export new useClearOnRetrigger hook utility

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/index.ts


View more (11)
4. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useClearOnRetrigger.ts ✨ Enhancement +52/-0

New hook to clear values on retrigger dependency changes

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useClearOnRetrigger.ts


5. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts 🐞 Bug fix +74/-4

Guard stale responses and show spinner on retrigger

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts


6. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetchAndEvaluate.ts 🐞 Bug fix +26/-0

Keep spinner visible during debounce after retrigger

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetchAndEvaluate.ts


7. workspaces/orchestrator/plugins/orchestrator/src/hooks/useWorkflowInstanceCardHeightMode.ts ✨ Enhancement +32/-0

New hook to read and validate card height mode config

workspaces/orchestrator/plugins/orchestrator/src/hooks/useWorkflowInstanceCardHeightMode.ts


8. workspaces/orchestrator/.changeset/active-text-retrigger-spinner.md 📝 Documentation +5/-0

Changeset for retrigger spinner and clearOnRetrigger feature

workspaces/orchestrator/.changeset/active-text-retrigger-spinner.md


9. workspaces/orchestrator/.changeset/workflow-instance-card-height.md 📝 Documentation +6/-0

Changeset for card height mode configuration

workspaces/orchestrator/.changeset/workflow-instance-card-height.md


10. workspaces/orchestrator/docs/orchestratorFormWidgets.md 📝 Documentation +2/-0

Document fetch:clearOnRetrigger property and behavior

workspaces/orchestrator/docs/orchestratorFormWidgets.md


11. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveDropdown.tsx ✨ Enhancement +12/-0

Integrate useClearOnRetrigger hook into dropdown widget

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveDropdown.tsx


12. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveMultiSelect.tsx ✨ Enhancement +14/-0

Integrate useClearOnRetrigger hook into multi-select widget

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveMultiSelect.tsx


13. workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveTextInput.tsx ✨ Enhancement +18/-0

Integrate useClearOnRetrigger hook into text input widget

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/ActiveTextInput.tsx


14. workspaces/orchestrator/plugins/orchestrator/src/components/WorkflowInstancePage/WorkflowInstancePageContent.tsx ✨ Enhancement +92/-54

Refactor layout to support fixed and content-based card heights

workspaces/orchestrator/plugins/orchestrator/src/components/WorkflowInstancePage/WorkflowInstancePageContent.tsx


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge Bot commented Mar 11, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Stale request clears loading 🐞 Bug ⛯ Reliability
Description
In useFetch, when fetch:retrigger changes you set loading=true immediately (to show a spinner
during the debounce window), but any in-flight request from the previous retrigger can still run its
catch/finally and call setError / setLoading(false) because those paths are guarded only by
requestId. Since requestIdRef is incremented only when the next debounced fetch starts, the old
request remains “current” during the debounce delay and can remove the spinner and/or display an
error for stale inputs.
Code

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[R143-147]

+        const requestId = ++requestIdRef.current;
+        const retriggerSnapshot = retrigger;
        try {
          setError(undefined);
          if (typeof evaluatedFetchUrl !== 'string') {
Evidence
useFetch explicitly sets loading=true on dependency changes to cover the debounce period, but
requestIdRef is only incremented at the start of the next fetch. During the (1s) debounce delay,
an older in-flight request still satisfies requestId === requestIdRef.current and can execute
setError(...) and setLoading(false) even though retrigger inputs have already changed, which
contradicts the intended “spinner during debounce” behavior and can surface stale errors.

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[104-128]
workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[142-197]
workspaces/orchestrator/plugins/orchestrator-form-widgets/src/widgets/constants.ts[16-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`useFetch` intends to show a spinner immediately on `fetch:retrigger` changes (during the debounce window), but an older in-flight request can still call `setError(...)` / `setLoading(false)` while the next request is waiting for the debounce delay.

## Issue Context
`requestIdRef.current` is incremented only when a debounced fetch actually starts. If retrigger changes while a request is in-flight, that request is still considered current until the next fetch begins, so its `catch/finally` updates can override the immediate `setLoading(true)` effect.

## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[80-128]
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[142-197]

## Implementation notes
- Increment/invalidate `requestIdRef.current` (or a separate &quot;generation&quot; ref) inside the retrigger-change effect so any older request becomes non-current immediately.
- Alternatively/additionally, gate `setError` and `setLoading(false)` with the same `(requestId === current &amp;&amp; isEqual(retriggerSnapshot, latestRetriggerRef.current))` check used for `setData`.
- Consider aborting the previous request (if `fetchApi.fetch` supports `signal`) to avoid wasted work and simplify state consistency.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link
Copy Markdown
Member

@lokanandaprabhu lokanandaprabhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@sonarqubecloud
Copy link
Copy Markdown

@lokanandaprabhu lokanandaprabhu merged commit 546ccb2 into workspace/orchestrator Mar 11, 2026
2 of 3 checks passed
Comment on lines +143 to 147
const requestId = ++requestIdRef.current;
const retriggerSnapshot = retrigger;
try {
setError(undefined);
if (typeof evaluatedFetchUrl !== 'string') {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Stale request clears loading 🐞 Bug ⛯ Reliability

In useFetch, when fetch:retrigger changes you set loading=true immediately (to show a spinner
during the debounce window), but any in-flight request from the previous retrigger can still run its
catch/finally and call setError / setLoading(false) because those paths are guarded only by
requestId. Since requestIdRef is incremented only when the next debounced fetch starts, the old
request remains “current” during the debounce delay and can remove the spinner and/or display an
error for stale inputs.
Agent Prompt
## Issue description
`useFetch` intends to show a spinner immediately on `fetch:retrigger` changes (during the debounce window), but an older in-flight request can still call `setError(...)` / `setLoading(false)` while the next request is waiting for the debounce delay.

## Issue Context
`requestIdRef.current` is incremented only when a debounced fetch actually starts. If retrigger changes while a request is in-flight, that request is still considered current until the next fetch begins, so its `catch/finally` updates can override the immediate `setLoading(true)` effect.

## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[80-128]
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useFetch.ts[142-197]

## Implementation notes
- Increment/invalidate `requestIdRef.current` (or a separate "generation" ref) inside the retrigger-change effect so any older request becomes non-current immediately.
- Alternatively/additionally, gate `setError` and `setLoading(false)` with the same `(requestId === current && isEqual(retriggerSnapshot, latestRetriggerRef.current))` check used for `setData`.
- Consider aborting the previous request (if `fetchApi.fetch` supports `signal`) to avoid wasted work and simplify state consistency.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants