Skip to content

fix(quickstart): make Quick start help menu item clickable - #4021

Merged
ciiay merged 4 commits into
redhat-developer:mainfrom
ciiay:rhdhbugs-3489-fix-quickstart-in-help-dropdown
Jul 31, 2026
Merged

fix(quickstart): make Quick start help menu item clickable#4021
ciiay merged 4 commits into
redhat-developer:mainfrom
ciiay:rhdhbugs-3489-fix-quickstart-in-help-dropdown

Conversation

@ciiay

@ciiay ciiay commented Jul 28, 2026

Copy link
Copy Markdown
Member

Description

The Quick start item in the global-header help dropdown was visible but not clickable, so the drawer never opened. This change renders a real MUI MenuItem via forwardRef (instead of GlobalHeaderMenuItem without a to prop, which used component={Fragment} in global-header 1.21.0 and dropped click handlers), bumps the global-header dependency, and adds unit coverage.

Root cause

GlobalHeaderMenuItem without a to prop rendered MenuItem component={Fragment} in @red-hat-developer-hub/backstage-plugin-global-header@1.21.0, which discarded onClick and role="menuitem".

Fixed

  • RHDHBUGS-3489 — Quick start menu item in global-header help dropdown is not clickable

UI before changes

Before fix

UI after changes

After fix

Test Plan

  • Start the quickstart NFS app (yarn start in workspaces/quickstart)
  • Open the Help (?) dropdown in the global header
  • Verify "Quick start" appears as a menu item
  • Click "Quick start" and verify the quickstart drawer opens on the right
  • Verify no console warning about ref on React.Fragment
  • Verify the sidebar Quick start control still toggles the drawer

Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

Note

This bug fix was identified and implemented using the bug-fix and raise-pr agent skills. Please verify the fix thoroughly before merging.

Made with Cursor

Fixes: https://redhat.atlassian.net/browse/RHDHBUGS-3489
Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rhdh-gh-app

rhdh-gh-app Bot commented Jul 28, 2026

Copy link
Copy Markdown

Changed Packages

Package Name Package Path Changeset Bump Current Version
app-legacy workspaces/quickstart/packages/app-legacy none v0.0.0
app workspaces/quickstart/packages/app none v0.0.0
@red-hat-developer-hub/backstage-plugin-quickstart workspaces/quickstart/plugins/quickstart patch v1.12.2

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

Fix Quick start help menu item clickability in global-header dropdown

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Render Quick start as a real MUI MenuItem with forwardRef to preserve click/role behavior.
• Replace GlobalHeaderMenuItem usage to avoid Fragment rendering that drops handlers.
• Bump global-header dependency and add unit tests covering click + ref behavior.
Diagram

graph TD
  U["User"] --> M["Help dropdown"] --> Q["QuickstartHelpMenuItem"] --> MI["MUI MenuItem (forwardRef)"] --> D["useAppDrawer.toggleDrawer"] --> DR["Quickstart drawer"]
  Q --> C["handleClose (menu)"ذة]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Upstream-only fix (rely on GlobalHeaderMenuItem)
  • ➕ Keeps quickstart plugin code simpler and aligned with global-header API
  • ➕ Centralizes the fix so other consumers benefit automatically
  • ➖ Requires global-header to definitively fix the Fragment/no-to rendering behavior
  • ➖ Still risks regressions if alpha APIs change or ref handling remains inconsistent
2. Use GlobalHeaderMenuItem with a synthetic `to` (e.g., '#') and preventDefault
  • ➕ Minimal code changes; may preserve MenuItem semantics through link rendering
  • ➖ Hacky and can introduce accessibility/URL side effects
  • ➖ Still couples behavior to global-header internal rendering details

Recommendation: Current approach is appropriate: render a real MUI MenuItem and forwardRef explicitly to satisfy MUI menu focus management and preserve onClick/role semantics, while using MenuItemLink for consistent visuals. Keep the dependency bump to pick up global-header fixes, but avoid relying on its conditional rendering behavior for non-navigation items.

Files changed (6) +183 / -68

Bug fix (1) +41 / -19
QuickstartHelpMenuItem.tsxRender Quick start help entry as a forwardRef MUI MenuItem +41/-19

Render Quick start help entry as a forwardRef MUI MenuItem

• Replaces GlobalHeaderMenuItem (alpha) with a MUI MenuItem wrapper using forwardRef and MenuItemLink content, ensuring click handlers and menuitem role are preserved. Keeps behavior to toggle the quickstart drawer and optionally close the menu.

workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.tsx

Tests (1) +88 / -0
QuickstartHelpMenuItem.test.tsxAdd unit tests for help menu item role, click, and ref forwarding +88/-0

Add unit tests for help menu item role, click, and ref forwarding

• Adds tests verifying the Quick start entry renders as a proper menuitem, toggles the drawer and closes the menu on click, and forwards a ref to the underlying MenuItem element.

workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.test.tsx

Documentation (1) +5 / -0
clickable-menu-refix.mdAdd changeset for Quick start help menu click fix +5/-0

Add changeset for Quick start help menu click fix

• Introduces a patch changeset for the quickstart plugin describing the help dropdown click regression fix.

workspaces/quickstart/.changeset/clickable-menu-refix.md

Other (3) +49 / -49
package.jsonBump global-header dependency in quickstart app workspace +1/-1

Bump global-header dependency in quickstart app workspace

• Updates @red-hat-developer-hub/backstage-plugin-global-header from ^1.21.0 to ^1.21.2 for the quickstart app package.

workspaces/quickstart/packages/app/package.json

package.jsonBump global-header dependency in quickstart plugin workspace +1/-1

Bump global-header dependency in quickstart plugin workspace

• Updates @red-hat-developer-hub/backstage-plugin-global-header from ^1.21.0 to ^1.21.2 for the quickstart plugin package.

workspaces/quickstart/plugins/quickstart/package.json

yarn.lockRefresh lockfile for global-header upgrade and transitive bumps +47/-47

Refresh lockfile for global-header upgrade and transitive bumps

• Updates yarn.lock to reflect the global-header version change (resolving to 1.22.1) and related transitive dependency updates (Backstage packages, scalprum).

workspaces/quickstart/yarn.lock

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.79%. Comparing base (eb13368) to head (d8c24df).
⚠️ Report is 49 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4021      +/-   ##
==========================================
- Coverage   57.80%   57.79%   -0.01%     
==========================================
  Files        2393     2393              
  Lines       95919    95895      -24     
  Branches    26776    26776              
==========================================
- Hits        55448    55426      -22     
+ Misses      38935    38933       -2     
  Partials     1536     1536              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.54% <ø> (ø) Carriedforward from 783ab30
ai-integrations 69.06% <ø> (ø) Carriedforward from 783ab30
app-defaults 69.79% <ø> (ø) Carriedforward from 783ab30
augment 46.67% <ø> (ø) Carriedforward from 783ab30
boost 75.92% <ø> (ø) Carriedforward from 783ab30
bulk-import 72.55% <ø> (ø) Carriedforward from 783ab30
cost-management 13.55% <ø> (ø) Carriedforward from 783ab30
dcm 60.72% <ø> (ø) Carriedforward from 783ab30
extensions 56.48% <ø> (ø) Carriedforward from 783ab30
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 783ab30
global-header 62.17% <ø> (ø) Carriedforward from 783ab30
homepage 47.54% <ø> (ø) Carriedforward from 783ab30
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from 783ab30
intelligent-assistant 74.06% <ø> (ø) Carriedforward from 783ab30
konflux 91.98% <ø> (ø) Carriedforward from 783ab30
lightspeed 69.02% <ø> (ø) Carriedforward from 783ab30
mcp-integrations 83.40% <ø> (ø) Carriedforward from 783ab30
orchestrator 66.79% <ø> (ø) Carriedforward from 783ab30
quickstart 63.74% <ø> (-1.31%) ⬇️
sandbox 79.56% <ø> (ø) Carriedforward from 783ab30
scorecard 84.94% <ø> (ø) Carriedforward from 783ab30
theme 83.89% <ø> (ø) Carriedforward from 783ab30
translations 5.12% <ø> (ø) Carriedforward from 783ab30
x2a 79.31% <ø> (ø) Carriedforward from 783ab30

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eb13368...d8c24df. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@its-mitesh-kumar

Copy link
Copy Markdown
Member

/fs-review

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

Context used
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 11 rules
✅ Cross-repo context
  Explored: repo: redhat-developer/rhdh (sha: 6bcb0141)
  Not relevant to this PR: redhat-developer/rhdh-chart
  Not relevant to this PR: redhat-developer/rhdh-operator
  Not relevant to this PR: redhat-developer/rhdh-local

Grey Divider


Remediation recommended

1. Global-header version skew ✓ Resolved 🔗 Cross-repo conflict ☼ Reliability
Description
The quickstart plugin now depends on @red-hat-developer-hub/backstage-plugin-global-header as
^1.21.2, and in this repo that range already resolves to 1.22.1; meanwhile RHDH’s dynamic-plugin
wrapper pins global-header to 1.21.5. When RHDH upgrades quickstart, this can lead to
global-header minor-version skew unless RHDH constrains/dedupes the version (risking dynamic-plugin
runtime/load issues if two copies or incompatible transitive deps are pulled).
Code

workspaces/quickstart/plugins/quickstart/package.json[R48-50]

    "@red-hat-developer-hub/backstage-plugin-app-react": "^0.1.0",
-    "@red-hat-developer-hub/backstage-plugin-global-header": "^1.21.0",
+    "@red-hat-developer-hub/backstage-plugin-global-header": "^1.21.2",
    "@red-hat-developer-hub/backstage-plugin-theme": "^0.14.11",
Relevance

●●● Strong

Team commonly accepts dependency range alignment/dedupe to prevent duplicate versions and runtime
skew.

PR-#3929
PR-#2547

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR quickstart declares ^1.21.2 and the PR lockfile resolves that range to global-header 1.22.1,
while RHDH pins its global-header wrapper dependency to 1.21.5, demonstrating a concrete
cross-repo version skew risk upon integration.

workspaces/quickstart/plugins/quickstart/package.json[36-52]
workspaces/quickstart/yarn.lock[9882-9888]
External repo: redhat-developer/rhdh, dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json [30-33]

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

## Issue description
Quickstart now permits a newer `@red-hat-developer-hub/backstage-plugin-global-header` minor than what RHDH pins in its wrapper (RHDH: `1.21.5`, quickstart range: `^1.21.2`, which can resolve to `1.22.x`). This creates a cross-repo integration risk when RHDH upgrades quickstart: dependency resolution may drift and produce unexpected global-header versions in the dynamic-plugin set.

## Issue Context
- In this PR repo, the lockfile already resolves `^1.21.2` to `1.22.1`, demonstrating that the caret range will float.
- In RHDH, the global-header wrapper is pinned to `1.21.5`, so RHDH upgrades should either (a) deliberately align to `1.22.1` (or higher) in a coordinated change, or (b) constrain quickstart/global-header resolution to keep a single compatible version.

## Fix Focus Areas
- workspaces/quickstart/plugins/quickstart/package.json[48-50]
- workspaces/quickstart/yarn.lock[9882-9888]
- dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json[30-33]

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



Informational

2. Wrapper version not updated 🔗 Cross-repo conflict ⚙ Maintainability
Description
This PR will publish a patch release of @red-hat-developer-hub/backstage-plugin-quickstart, but
RHDH’s dynamic-plugin wrapper is pinned to quickstart 1.9.6. RHDH will not receive this fix until
a follow-up change bumps the wrapper dependency (and lockfile) in redhat-developer/rhdh.
Code

workspaces/quickstart/.changeset/clickable-menu-refix.md[R1-5]

+---
+'@red-hat-developer-hub/backstage-plugin-quickstart': patch
+---
+
+Fix Quick start help menu item not responding to clicks in the global-header dropdown
Relevance

● Weak

Cross-repo wrapper bump/note requests have been rejected as out-of-scope for this repo’s PRs.

PR-#3896

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR adds a changeset indicating a new patch release of the quickstart package, while RHDH’s
dynamic-plugin wrapper remains pinned to 1.9.6, so RHDH will not consume the fix until it updates
that wrapper dependency.

workspaces/quickstart/.changeset/clickable-menu-refix.md[1-5]
External repo: redhat-developer/rhdh, dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json [45-48]

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

## Issue description
The quickstart fix will ship in a new patch release, but RHDH pins its dynamic-plugin quickstart wrapper to `@red-hat-developer-hub/backstage-plugin-quickstart@1.9.6`. Without updating that wrapper, RHDH deployments will continue to use the old quickstart plugin version.

## Issue Context
This is not a defect in the PR itself, but it is a required downstream coordination step for the fix to land in RHDH.

## Fix Focus Areas
- workspaces/quickstart/.changeset/clickable-menu-refix.md[1-5]
- dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json[45-48]

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


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 28, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:25 AM UTC · Completed 3:42 AM UTC
Commit: e9c3e9e · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Low

  • [architectural-coherence] workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.tsx — The PR bypasses the existing GlobalHeaderMenuItem abstraction and manually composes MenuItem + MenuItemLink. This is justified because GlobalHeaderMenuItem does not support forwardRef (needed for MUI Menu focus management), and the quickstart component is registered as type: 'component' in the blueprint system requiring its own MenuItem wrapping. Long-term, adding forwardRef support to GlobalHeaderMenuItem would let consumers use the abstraction.

  • [click-event-swallowing] workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.tsx:60MenuItemLink from the main entry point is a createComponentExtension lazy-loaded component. In practice, the global-header plugin chunk is already loaded before any dropdown can be opened (the header renders on every page), so the lazy-load race is not a real concern. The outer MenuItem's onClick is independent of the inner component's load state.

  • [mock-reset-idiom] workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.test.tsx:33 — Uses mockToggleDrawer.mockClear() instead of jest.clearAllMocks(), which is the predominant idiom in sibling test files (7 of 8 use clearAllMocks).
    Remediation: Replace mockToggleDrawer.mockClear() with jest.clearAllMocks() in the beforeEach block.

Comment thread workspaces/quickstart/plugins/quickstart/src/QuickstartHelpMenuItem.tsx Outdated
@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Jul 28, 2026
ciiay and others added 2 commits July 29, 2026 00:05
Pin global-header to 1.21.5 to match RHDH and avoid floating to 1.22.x.
Use jest.clearAllMocks() for consistency with sibling tests.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Pin app-legacy to global-header 1.21.5 so the workspace lockfile
no longer carries both 1.21.5 and 1.22.1.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@HusneShabbir HusneShabbir left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

Tested Locally, working as expected

@rohitkrai03 rohitkrai03 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ciiay shouldnt the fix be in global header component if it's not using on click handler properly?

…ementing

The root cause was GlobalHeaderMenuItem using component={Fragment} without
a `to` prop (fixed in global-header 1.21.1+). Keep using that shared API
and rely on the 1.21.5 dependency bump rather than a local MenuItem copy.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci openshift-ci Bot removed the lgtm label Jul 31, 2026
@sonarqubecloud

Copy link
Copy Markdown

@ciiay
ciiay requested a review from rohitkrai03 July 31, 2026 14:37

@debsmita1 debsmita1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tested this on RHDH locally in app-next

Before the changes

Image

With the changes

Image

/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Jul 31, 2026

@rohitkrai03 rohitkrai03 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/approve

@ciiay
ciiay merged commit 03fd5c6 into redhat-developer:main Jul 31, 2026
37 checks passed
JslYoon pushed a commit to JslYoon/rhdh-plugins that referenced this pull request Aug 3, 2026
…veloper#4021)

* fix(quickstart): make Quick start help menu item clickable

Fixes: https://redhat.atlassian.net/browse/RHDHBUGS-3489
Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): align global-header pin and test mock reset

Pin global-header to 1.21.5 to match RHDH and avoid floating to 1.22.x.
Use jest.clearAllMocks() for consistency with sibling tests.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): dedupe global-header to fix CI lockfile check

Pin app-legacy to global-header 1.21.5 so the workspace lockfile
no longer carries both 1.21.5 and 1.22.1.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): consume fixed GlobalHeaderMenuItem instead of reimplementing

The root cause was GlobalHeaderMenuItem using component={Fragment} without
a `to` prop (fixed in global-header 1.21.1+). Keep using that shared API
and rely on the 1.21.5 dependency bump rather than a local MenuItem copy.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
JslYoon pushed a commit to JslYoon/rhdh-plugins that referenced this pull request Aug 3, 2026
…veloper#4021)

* fix(quickstart): make Quick start help menu item clickable

Fixes: https://redhat.atlassian.net/browse/RHDHBUGS-3489
Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): align global-header pin and test mock reset

Pin global-header to 1.21.5 to match RHDH and avoid floating to 1.22.x.
Use jest.clearAllMocks() for consistency with sibling tests.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): dedupe global-header to fix CI lockfile check

Pin app-legacy to global-header 1.21.5 so the workspace lockfile
no longer carries both 1.21.5 and 1.22.1.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(quickstart): consume fixed GlobalHeaderMenuItem instead of reimplementing

The root cause was GlobalHeaderMenuItem using component={Fragment} without
a `to` prop (fixed in global-header 1.21.1+). Keep using that shared API
and rely on the 1.21.5 dependency bump rather than a local MenuItem copy.

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Signed-off-by: Yi Cai <yicai@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

5 participants