Skip to content

feat(header): add new NFS header#2783

Open
rohitkrai03 wants to merge 1 commit intoredhat-developer:mainfrom
rohitkrai03:nfs-header
Open

feat(header): add new NFS header#2783
rohitkrai03 wants to merge 1 commit intoredhat-developer:mainfrom
rohitkrai03:nfs-header

Conversation

@rohitkrai03
Copy link
Copy Markdown
Contributor

@rohitkrai03 rohitkrai03 commented Apr 15, 2026

Hey, I just made a Pull Request!

Fixes - https://redhat.atlassian.net/browse/RHIDP-11822

  • Added new frontend system (NFS) support for the global header plugin with extension blueprints (GlobalHeaderComponentBlueprint, GlobalHeaderMenuItemBlueprint) that let any plugin contribute toolbar components and dropdown menu items
  • Added config-driven globalHeader.components and globalHeader.menuItems in app-config.yaml so deployers can add toolbar buttons and menu items without writing plugin code
  • Added documentation for the NFS API, including setup, extension authoring, config-driven items, and default override guides
Screen.Recording.2026-04-16.at.2.52.57.AM.mov

✔️ 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)

@rohitkrai03 rohitkrai03 requested review from a team, ciiay and divyanshiGupta as code owners April 15, 2026 21:21
@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge bot commented Apr 15, 2026

Code Review by Qodo

🐞 Bugs (4)   📘 Rule violations (0)   📎 Requirement gaps (2)
🐞\ ≡ Correctness (2) ☼ Reliability (1) ⚙ Maintainability (1)
📎\ ≡ Correctness (1) ⚙ Maintainability (1)

Grey Divider


Action required

1. globalHeader.* bypasses app.extensions 📎
Description
The new NFS implementation reads config from globalHeader.components / globalHeader.menuItems
instead of app.extensions, so header configuration is not migrated to the required extension
config model. This prevents deployers from configuring header items via app.extensions
schema-driven extension configuration as required.
Code

workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.tsx[R30-34]

+export function readConfigComponents(
+  configApi: Config,
+): GlobalHeaderComponentData[] {
+  const items = configApi.getOptionalConfigArray('globalHeader.components');
+  if (!items) return [];
Evidence
PR Compliance ID 4 requires header configuration to be represented under app.extensions and
consumed via an extension config schema. The added code explicitly reads
globalHeader.components/globalHeader.menuItems (not app.extensions) and adds corresponding
config typings under globalHeader, while the component blueprint schema only defines priority
and not other component config fields like title/icon/link.

Header component configuration migrated to app.extensions with schema consumption
workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.tsx[30-34]
workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.ts[26-41]
workspaces/global-header/plugins/global-header/config.d.ts[47-92]
workspaces/global-header/plugins/global-header/src/alpha/extensions/blueprints.tsx[161-173]

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

## Issue description
Header component/menu item configuration is implemented under `globalHeader.components` and `globalHeader.menuItems`, but compliance requires migration of these options into `app.extensions` with schema-backed consumption.

## Issue Context
- `readConfigComponents()` reads `globalHeader.components`.
- `readConfigMenuItems()` reads `globalHeader.menuItems`.
- `GlobalHeaderComponentBlueprint` only defines a `priority` schema, not schema for other config-driven fields expected by the requirement.

## Fix Focus Areas
- workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.tsx[30-55]
- workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.ts[26-42]
- workspaces/global-header/plugins/global-header/config.d.ts[47-92]
- workspaces/global-header/plugins/global-header/src/alpha/extensions/blueprints.tsx[161-173]

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


2. Legacy mount points still used 📎
Description
Legacy Global Header mount-point infrastructure is still present and actively updated in this PR,
indicating the migration has not fully replaced the legacy mountPoints approach with NFS
extensions. This violates the requirement to replace the listed legacy mount points with NFS
extensions without remaining functional dependency.
Code

workspaces/global-header/plugins/global-header/src/defaultMountPoints/defaultMountPoints.tsx[R76-86]

    {
-      Component: CreateDropdown,
+      Component: HeaderIconButton as ComponentType,
      config: {
        priority: 90,
-        layout: {
-          display: {
-            sm: 'none',
-            md: 'block',
-          },
-          mr: 1.5,
-        } as any as CSSProperties, // I don't used MUI v5 specific `sx` types here to allow us changing the implementation later
+        props: {
+          title: 'Self-service',
+          titleKey: 'create.title',
+          icon: 'addCircleOutline',
+          to: '/create',
+        },
      },
Evidence
PR Compliance ID 3 requires replacing the legacy Global Header mountPoints with NFS extensions.
The PR modifies the legacy mount-point defaults (defaultGlobalHeaderComponentsMountPoints) by
adding/updating a mount-point-rendered component (HeaderIconButton) within the mount-point list,
showing ongoing reliance on the mount-point system rather than full replacement.

Legacy mount points replaced by NFS extensions
workspaces/global-header/plugins/global-header/src/defaultMountPoints/defaultMountPoints.tsx[76-86]

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

## Issue description
Legacy Global Header mount-point defaults are still being maintained/updated, which conflicts with the requirement to replace legacy `mountPoints` (`global.header/component`, `global.header/application-launcher`, `global.header/profile`, `global.header/help`) with NFS extensions.

## Issue Context
This PR introduces NFS extensions/blueprints, but also updates legacy mount-point defaults, indicating the legacy mount-point path remains part of the migrated implementation.

## Fix Focus Areas
- workspaces/global-header/plugins/global-header/src/defaultMountPoints/defaultMountPoints.tsx[76-86]

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


3. Wrong NFS import path 🐞
Description
packages/app/src/App.tsx imports a default export and globalHeaderModule from the package root,
but the root entrypoint exports neither, so the app will fail to compile and/or the imports will be
undefined at runtime.
Code

workspaces/global-header/packages/app/src/App.tsx[R23-26]

+import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme/alpha';
+import globalHeaderPlugin, {
+  globalHeaderModule,
+} from '@red-hat-developer-hub/backstage-plugin-global-header';
Evidence
The app uses a default import and named globalHeaderModule from the root package entrypoint, but
the root src/index.ts only re-exports ./plugin and ./translations. globalHeaderModule and
the default export exist only under the /alpha entrypoint.

workspaces/global-header/packages/app/src/App.tsx[17-26]
workspaces/global-header/plugins/global-header/src/index.ts[24-26]
workspaces/global-header/plugins/global-header/src/alpha/index.ts[24-28]

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

### Issue description
`packages/app/src/App.tsx` imports `globalHeaderPlugin` (default) and `globalHeaderModule` from `@red-hat-developer-hub/backstage-plugin-global-header`, but the root entrypoint doesn’t export those.

### Issue Context
- Root entrypoint exports only `./plugin` and `./translations`.
- NFS plugin default export + `globalHeaderModule` are exported from the `/alpha` subpath.

### Fix Focus Areas
- workspaces/global-header/packages/app/src/App.tsx[23-26]

### Suggested fix
Change the import to:
```ts
import globalHeaderPlugin, { globalHeaderModule } from '@red-hat-developer-hub/backstage-plugin-global-header/alpha';
```
Alternatively, if you intentionally want root imports, re-export `default` and `globalHeaderModule` from `workspaces/global-header/plugins/global-header/src/index.ts` (but that changes the intended public surface).

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



Remediation recommended

4. Broken aria-labelledby 🐞
Description
HeaderDropdownComponent sets MenuListProps['aria-labelledby'] to a generated id, but that id is
never assigned to the triggering Button/IconButton, breaking the ARIA relationship between the menu
and its control.
Code

workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx[R80-102]

  const id = useId();

+  const menuId = `${id}-menu`;
+
  const commonButtonProps = {
    ...buttonProps,
    onClick: (event: MouseEvent<HTMLElement>) => {
      onOpen(event);
-      // focus the menu when opened
-      // TODO: investigate why MUI isn't doing this for us
+      // Defer focus until MUI finishes rendering the menu into the DOM.
      setTimeout(() => {
        document
-          .getElementById(`${id}-menu`)
-          ?.getElementsByTagName('a')[0]
+          .getElementById(menuId)
+          ?.querySelector<HTMLElement>('[role="menuitem"]')
          ?.focus();
      }, 0);
    },
    'aria-haspopup': true,
-    'aria-controls': id,
+    'aria-controls': menuId,
    'aria-expanded': anchorEl ? true : undefined,
+    'aria-label': tooltip,
  };

  return (
Evidence
The component generates id = useId() and uses it in MenuListProps as aria-labelledby, but the
trigger buttons only receive commonButtonProps which does not set an id attribute (so the
referenced element doesn’t exist).

workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx[80-113]
workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx[134-138]

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

### Issue description
`MenuListProps.aria-labelledby` references an id (`id = useId()`) that is not applied to the trigger Button/IconButton, so assistive tech cannot associate the opened menu with its trigger.

### Issue Context
The menu uses `menuId` for `aria-controls`, but the separate `id` is only used in `aria-labelledby` and never appears in the DOM.

### Fix Focus Areas
- workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx[80-113]
- workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx[134-138]

### Suggested fix
Add `id` to the trigger element (e.g. include `id` in `commonButtonProps`) and keep `MenuListProps['aria-labelledby']` pointing to that same id.
Example:
```ts
const commonButtonProps = {
 id,
 ...buttonProps,
 ...
}
```

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


5. Legacy layout styling lost 🐞
Description
HeaderIconButton no longer supports the legacy layout prop, but the legacy
GlobalHeaderComponent mountpoint system still relies on passing layout into mountpoint
components; any existing mountpoints that styled HeaderIconButton via layout will now silently
stop applying that styling.
Code

workspaces/global-header/plugins/global-header/src/components/HeaderIconButton/HeaderIconButton.tsx[R35-47]

  size?: 'small' | 'medium' | 'large';
  ariaLabel?: string;
  to: string;
-  layout?: CSSProperties;
}

-// Backstage Link automatically detects external links and emits analytic events.
const Link = (props: any) => (
  <BackstageLink {...props} color="inherit" externalLinkIcon={false} />
);

+/** @public */
export const HeaderIconButton = ({
  title,
  titleKey,
Evidence
The legacy mountpoint type includes layout and the legacy renderer always passes
layout={mountPoint.config?.layout} into each mountpoint component. After this PR,
HeaderIconButtonProps no longer includes layout and the component doesn’t apply layout anywhere,
so legacy layout-based styling for this component is effectively removed.

workspaces/global-header/plugins/global-header/src/components/HeaderIconButton/HeaderIconButton.tsx[26-78]
workspaces/global-header/plugins/global-header/src/types.ts[78-91]
workspaces/global-header/plugins/global-header/src/components/GlobalHeaderComponent.tsx[59-65]

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

### Issue description
Legacy mountpoint rendering passes a `layout` prop to header components, but `HeaderIconButton` no longer consumes it. This breaks legacy mountpoint configurations that depended on `layout` for spacing/responsive display.

### Issue Context
- `GlobalHeaderComponentMountPoint` and `GlobalHeaderComponent` still model/pass `layout`.
- `HeaderIconButton` removed `layout` from its public props and no longer wraps its content in a layout-applied element.

### Fix Focus Areas
- workspaces/global-header/plugins/global-header/src/components/HeaderIconButton/HeaderIconButton.tsx[26-78]
- workspaces/global-header/plugins/global-header/src/components/GlobalHeaderComponent.tsx[59-65]

### Suggested fixes (pick one)
1) Re-introduce `layout?: CSSProperties` on `HeaderIconButtonProps` and apply it to a wrapper element (e.g. a `Box sx={layout}` or `style={layout}`), restoring legacy behavior.

2) Refactor legacy `GlobalHeaderComponent` to apply layout at the container level (wrap each mountpoint with `<Box sx={mountPoint.config?.layout}>...</Box>`), similar to the NFS implementation, and stop passing `layout` into the child component.

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



Advisory comments

6. Route-change close too narrow 🐞
Description
useDropdownManager says it closes on “any route change”, but it only reacts to
location.pathname, so navigations that only change search/hash can leave dropdowns open.
Code

workspaces/global-header/plugins/global-header/src/hooks/useDropdownManager.ts[R33-37]

+  // Close the dropdown on any route change — acts as a safety net when
+  // a Link-based MenuItem navigates before the Menu transition completes.
+  useEffect(() => {
+    setAnchorEl(null);
+  }, [location.pathname]);
Evidence
The effect dependency is [location.pathname], which will not run for ?query or #hash changes
on the same path despite the comment claiming “any route change”.

workspaces/global-header/plugins/global-header/src/hooks/useDropdownManager.ts[17-37]

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

### Issue description
Dropdowns won’t auto-close for URL changes that keep the same pathname (e.g. query string updates).

### Issue Context
The intent is a safety net to close on navigation; depending only on `pathname` doesn’t cover all navigations.

### Fix Focus Areas
- workspaces/global-header/plugins/global-header/src/hooks/useDropdownManager.ts[33-37]

### Suggested fix
Change the effect dependency to include `location.search` and `location.hash`, or use `location.key`:
```ts
}, [location.pathname, location.search, location.hash]);
// or
}, [location.key]);
```

ⓘ 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

@rhdh-gh-app
Copy link
Copy Markdown

rhdh-gh-app bot commented Apr 15, 2026

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
app workspaces/global-header/packages/app none v0.0.0
@red-hat-developer-hub/backstage-plugin-global-header workspaces/global-header/plugins/global-header minor v1.20.3

@rohitkrai03 rohitkrai03 force-pushed the nfs-header branch 2 times, most recently from b1d18a2 to 8ddf68b Compare April 15, 2026 21:28
@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Add New Frontend System support for global header with config-driven extensions and default components

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Introduces comprehensive New Frontend System (NFS) support for the global header plugin with two
  extension blueprints (GlobalHeaderComponentBlueprint and GlobalHeaderMenuItemBlueprint) enabling
  plugins to contribute toolbar components and dropdown menu items
• Implements config-driven toolbar buttons and menu items via globalHeader.components and
  globalHeader.menuItems in app-config.yaml, allowing deployers to extend the header without
  writing plugin code
• Adds three implementation tiers: data-driven (config-based), building blocks (reusable
  components), and fully custom React components for maximum flexibility
• Creates extension data refs, context provider, and hooks (useGlobalHeaderComponents(),
  useGlobalHeaderMenuItems()) for distributing collected extension data throughout the app
• Implements menu item grouping and sorting utilities with priority-based ordering and section-based
  organization
• Adds new NFS components: GlobalHeader, GlobalHeaderDropdown, GlobalHeaderDropdownContent,
  ProfileDropdown, HelpDropdown, ApplicationLauncherDropdown, and MyProfileMenuItem
• Provides 10 default toolbar extensions (company logo, search, spacer, self-service, starred, app
  launcher, help, notifications, divider, profile) and 6 default menu item extensions
• Fixes dropdown auto-close on route navigation and improves accessibility with better focus
  management and ARIA labels
• Updates legacy mount points to use new HeaderIconButton component for self-service button
• Adds comprehensive documentation guide for extending the global header using NFS with setup,
  extension authoring, and customization examples
• Includes extensive test coverage for menu item grouping, config reading, dropdown rendering, and
  context hooks
• Updates package.json with NFS dependencies and proper module exports for ./alpha subpath
Diagram
flowchart LR
  A["app-config.yaml<br/>globalHeader config"] -->|readConfigComponents| B["GlobalHeaderComponentData"]
  A -->|readConfigMenuItems| C["GlobalHeaderMenuItemData"]
  D["Extension<br/>Blueprints"] -->|contribute| B
  D -->|contribute| C
  B -->|collected by| E["globalHeaderModule"]
  C -->|collected by| E
  E -->|provides via| F["GlobalHeaderContext"]
  F -->|consumed by| G["GlobalHeader<br/>Component"]
  G -->|renders| H["Toolbar Items<br/>& Dropdowns"]
  I["Default<br/>Extensions"] -->|registered in| J["globalHeaderPlugin"]
  J -->|provides| D
Loading

Grey Divider

File Changes

1. workspaces/global-header/plugins/global-header/src/alpha/defaults/rhdhLogo.ts ✨ Enhancement +27/-0

Add default RHDH logo SVG data URIs

• Introduces a new file containing default Red Hat Developer Hub logo SVG data URIs
• Exports rhdhLogo object with light and dark theme variants
• Used by the companyLogoExtension toolbar component

workspaces/global-header/plugins/global-header/src/alpha/defaults/rhdhLogo.ts


2. workspaces/global-header/plugins/global-header/src/alpha/utils/menuItemGrouping.test.ts 🧪 Tests +176/-0

Add tests for menu item grouping utilities

• Comprehensive test suite for menu item grouping utilities
• Tests groupBySection function for grouping items by section labels
• Tests buildDropdownEntries function for sorting and organizing dropdown entries
• Validates component mapping, priority handling, and default values

workspaces/global-header/plugins/global-header/src/alpha/utils/menuItemGrouping.test.ts


3. workspaces/global-header/plugins/global-header/config.d.ts ⚙️ Configuration changes +75/-33

Add config-driven global header components and menu items

• Refactors config declaration from module augmentation to direct interface export
• Adds new globalHeader.components config for toolbar icon-button items
• Adds new globalHeader.menuItems config for dropdown menu items
• Includes fields for title, icon, link, section labels, and priority

workspaces/global-header/plugins/global-header/config.d.ts


View more (47)
4. workspaces/global-header/plugins/global-header/src/alpha/utils/menuItemGrouping.ts ✨ Enhancement +99/-0

Implement menu item grouping and sorting utilities

• Implements groupBySection function to group data-driven menu items by section label
• Implements buildDropdownEntries function to combine and sort component and section entries
• Defines SectionGroup and DropdownEntry types for organizing dropdown content
• Handles priority-based sorting and default component assignment

workspaces/global-header/plugins/global-header/src/alpha/utils/menuItemGrouping.ts


5. workspaces/global-header/plugins/global-header/src/alpha/types.ts ✨ Enhancement +89/-0

Define NFS data types for header components and menu items

• Defines GlobalHeaderComponentData interface for toolbar-level items
• Defines GlobalHeaderMenuItemData interface for dropdown menu items
• Supports both component-based and data-driven rendering modes
• Includes fields for titles, icons, links, sections, and click handlers

workspaces/global-header/plugins/global-header/src/alpha/types.ts


6. workspaces/global-header/e2e-tests/globalHeader.test.ts 🧪 Tests +7/-18

Update e2e tests for header navigation changes

• Updates test selectors to use more resilient locator strategies
• Changes self-service button from button to link element
• Simplifies navigation test by removing menu snapshot assertion
• Updates aria snapshot expectations to reflect link-based navigation

workspaces/global-header/e2e-tests/globalHeader.test.ts


7. workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.test.ts 🧪 Tests +100/-0

Add tests for config-driven menu item reading

• Test suite for reading menu items from app configuration
• Validates mapping of config entries to GlobalHeaderMenuItemData objects
• Tests handling of optional fields and multiple items
• Verifies proper extraction of all menu item properties

workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.test.ts


8. workspaces/global-header/plugins/global-header/src/alpha/index.ts ✨ Enhancement +77/-0

Export NFS API surface for global header plugin

• Exports core NFS plugin and module definitions
• Exports extension blueprints for components and menu items
• Exports data refs and context hooks for custom dropdowns
• Exports building block components and default extensions

workspaces/global-header/plugins/global-header/src/alpha/index.ts


9. workspaces/global-header/plugins/global-header/src/alpha/defaults/index.ts ✨ Enhancement +70/-0

Export default toolbar and menu item extensions

• Aggregates all default toolbar and menu item extensions
• Exports defaultToolbarExtensions array with 10 default components
• Exports defaultMenuItemExtensions array with 6 default menu items
• Provides convenient access to all pre-built extensions

workspaces/global-header/plugins/global-header/src/alpha/defaults/index.ts


10. workspaces/global-header/plugins/global-header/src/alpha/plugin.ts ✨ Enhancement +66/-0

Create NFS global header plugin with default extensions

• Creates the main globalHeaderPlugin using NFS createFrontendPlugin
• Registers all default toolbar and menu item extensions
• Provides the plugin entry point for the global header system

workspaces/global-header/plugins/global-header/src/alpha/plugin.ts


11. workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.ts ✨ Enhancement +43/-0

Implement config-driven menu item reading utility

• Implements readConfigMenuItems function to parse app config
• Maps globalHeader.menuItems config array to GlobalHeaderMenuItemData objects
• Handles optional fields and returns empty array when config is absent

workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigMenuItems.ts


12. workspaces/global-header/plugins/global-header/src/hooks/useDropdownManager.ts 🐞 Bug fix +13/-5

Add dropdown auto-close on route navigation

• Adds useCallback hooks to memoize handleOpen and handleClose functions
• Adds useEffect hook to close dropdown on route changes
• Imports useLocation from react-router-dom for route tracking
• Prevents menu from staying open during navigation

workspaces/global-header/plugins/global-header/src/hooks/useDropdownManager.ts


13. workspaces/global-header/plugins/global-header/src/alpha/extensions/dataRefs.ts ✨ Enhancement +44/-0

Create extension data refs for NFS integration

• Defines globalHeaderComponentDataRef for toolbar component data
• Defines globalHeaderMenuItemDataRef for menu item data
• Uses NFS createExtensionDataRef to create typed data references

workspaces/global-header/plugins/global-header/src/alpha/extensions/dataRefs.ts


14. workspaces/global-header/plugins/global-header/src/index.ts Miscellaneous +1/-1

Update main index exports to translations

• Changes export from ./alpha to ./translations
• Maintains existing plugin export
• Adjusts public API surface

workspaces/global-header/plugins/global-header/src/index.ts


15. workspaces/global-header/packages/app/public/index.html Dependencies +4/-0

Add Material Icons font dependency

• Adds link to Material Icons Outlined font from Google Fonts
• Enables icon rendering for header components

workspaces/global-header/packages/app/public/index.html


16. workspaces/global-header/plugins/global-header/report-alpha.api.md 📝 Documentation +1406/-0

Generate API report for NFS global header plugin

• Auto-generated API report documenting the NFS alpha surface
• Documents all exported blueprints, extensions, types, and utilities
• Includes type signatures for components, data refs, and hooks
• Comprehensive reference for the new NFS API

workspaces/global-header/plugins/global-header/report-alpha.api.md


17. workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdownContent.test.tsx 🧪 Tests +145/-0

Add tests for dropdown content rendering

• Test suite for dropdown content rendering component
• Tests rendering of component and section entries
• Validates divider handling and entry ordering
• Tests edge cases like missing components and empty entries

workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdownContent.test.tsx


18. workspaces/global-header/plugins/global-header/src/components/MenuItemLink/MenuItemLink.tsx 📝 Documentation +1/-0

Mark MenuItemLink as public API

• Adds JSDoc @public annotation to MenuItemLink component
• Marks component as part of public API surface

workspaces/global-header/plugins/global-header/src/components/MenuItemLink/MenuItemLink.tsx


19. workspaces/global-header/docs/new-frontend-system.md 📝 Documentation +341/-0

New Frontend System extension guide and API documentation

• Comprehensive guide for extending the global header using the new frontend system (NFS)
• Documents two extension blueprints: GlobalHeaderComponentBlueprint for toolbar items and
 GlobalHeaderMenuItemBlueprint for dropdown menu items
• Provides three implementation tiers: data-driven, building blocks, and fully custom components
• Includes config-driven setup via app-config.yaml and customization of default extensions

workspaces/global-header/docs/new-frontend-system.md


20. workspaces/global-header/plugins/global-header/src/alpha/extensions/blueprints.tsx ✨ Enhancement +254/-0

Extension blueprints for toolbar and menu items

• Defines GlobalHeaderComponentBlueprint for toolbar-level extensions with configurable priority
 and layout
• Defines GlobalHeaderMenuItemBlueprint for dropdown menu items with target routing and section
 grouping
• Implements data-driven component factory that auto-renders HeaderIconButton from icon/title/link
 params
• Supports three tiers: data-driven, building blocks, and fully custom React components

workspaces/global-header/plugins/global-header/src/alpha/extensions/blueprints.tsx


21. workspaces/global-header/plugins/global-header/src/alpha/components/ProfileDropdown.tsx ✨ Enhancement +130/-0

Profile dropdown with user avatar and catalog integration

• New profile dropdown component that displays user avatar and display name
• Fetches user entity from catalog API and extracts display name with fallback logic
• Collects menu items from 'profile' target via GlobalHeaderDropdown
• Handles guest users and missing profile pictures gracefully

workspaces/global-header/plugins/global-header/src/alpha/components/ProfileDropdown.tsx


22. workspaces/global-header/plugins/global-header/src/alpha/extensions/globalHeaderModule.tsx ✨ Enhancement +127/-0

Frontend module wrapper for extension collection and merging

• Creates frontend module that wraps the app root and collects header extensions
• Merges extension-contributed components and menu items with config-driven items from
 app-config.yaml
• Sorts all items by priority (highest first) before rendering
• Provides GlobalHeaderProvider context to distribute collected data to child components

workspaces/global-header/plugins/global-header/src/alpha/extensions/globalHeaderModule.tsx


23. workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdown.tsx ✨ Enhancement +113/-0

Reusable dropdown component for menu item collection

• High-level dropdown building block that collects menu items from a named extension target
• Groups items by section and sorts by priority
• Supports optional empty state rendering and validity tracking
• Forwards ref to underlying MUI MenuList for accessibility and testing

workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdown.tsx


24. workspaces/global-header/plugins/global-header/src/alpha/defaults/toolbarExtensions.tsx ✨ Enhancement +114/-0

Default toolbar component extensions with priorities

• Defines default toolbar component extensions using GlobalHeaderComponentBlueprint
• Exports 10 default extensions: company logo, search, spacer, self-service button, starred
 dropdown, app launcher, help, notifications, divider, and profile
• Each extension has a unique priority value for ordering
• Wraps existing components like SearchComponent, NotificationButton, and new NFS dropdowns

workspaces/global-header/plugins/global-header/src/alpha/defaults/toolbarExtensions.tsx


25. workspaces/global-header/plugins/global-header/src/alpha/defaults/menuItemExtensions.tsx ✨ Enhancement +118/-0

Default dropdown menu item extensions

• Defines default menu item extensions for profile, help, and app-launcher dropdowns
• Includes 6 default items: settings, my-profile, logout, support button, and two app launcher links
• Supports both data-driven items (title/link) and custom component items (LogoutButton,
 SupportButton)
• Uses i18n keys for translatable content

workspaces/global-header/plugins/global-header/src/alpha/defaults/menuItemExtensions.tsx


26. workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx ✨ Enhancement +13/-7

Accessibility improvements for dropdown menu focus and labeling

• Added menuListRef prop to forward ref to underlying MUI MenuList for accessibility
• Improved focus management to defer focus until MUI finishes rendering
• Changed menu item selector from <a> tags to [role="menuitem"] for better accessibility
• Added aria-label to button for improved screen reader support

workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/HeaderDropdownComponent.tsx


27. workspaces/global-header/plugins/global-header/README.md 📝 Documentation +92/-8

Comprehensive plugin README with NFS and legacy documentation

• Completely rewritten README with feature overview and installation instructions
• Added separate sections for new frontend system and legacy mount points usage
• Documented config-driven toolbar buttons and menu items via app-config.yaml
• Added links to comprehensive documentation guides and development instructions

workspaces/global-header/plugins/global-header/README.md


28. workspaces/global-header/plugins/global-header/src/alpha/extensions/GlobalHeaderContext.test.tsx 🧪 Tests +95/-0

Unit tests for global header context hooks

• Tests for useGlobalHeaderComponents() hook verifying component collection and empty state
• Tests for useGlobalHeaderMenuItems(target) hook verifying target filtering and empty states
• Validates provider behavior when no context is present

workspaces/global-header/plugins/global-header/src/alpha/extensions/GlobalHeaderContext.test.tsx


29. workspaces/global-header/plugins/global-header/src/components/HeaderIconButton/HeaderIconButton.tsx ✨ Enhancement +14/-20

Simplification of HeaderIconButton component

• Removed layout prop and Box wrapper to simplify component
• Removed unused CSSProperties import
• Added @public JSDoc tag for API documentation
• Simplified component structure while maintaining tooltip and icon rendering

workspaces/global-header/plugins/global-header/src/components/HeaderIconButton/HeaderIconButton.tsx


30. workspaces/global-header/plugins/global-header/src/alpha/components/MyProfileMenuItem.tsx ✨ Enhancement +82/-0

Custom My Profile menu item with catalog URL resolution

• New custom menu item component for "My Profile" link in profile dropdown
• Dynamically resolves catalog URL from user entity reference
• Returns null for guest users to match legacy behavior
• Parses entity ref and constructs catalog link with namespace and user name

workspaces/global-header/plugins/global-header/src/alpha/components/MyProfileMenuItem.tsx


31. workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.test.tsx 🧪 Tests +76/-0

Unit tests for config-driven toolbar component reading

• Tests for readConfigComponents() utility that reads toolbar items from app-config.yaml
• Validates empty array return when config is absent
• Tests mapping of config entries to component data with priority handling
• Verifies rendered HeaderIconButton has correct props and attributes

workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.test.tsx


32. workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeader.test.tsx 🧪 Tests +67/-0

Unit tests for GlobalHeader component rendering

• Tests for GlobalHeader component rendering from context
• Validates all components are rendered and empty toolbar behavior
• Verifies nav element with id "global-header" is present

workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeader.test.tsx


33. workspaces/global-header/plugins/global-header/src/defaultMountPoints/defaultMountPoints.tsx ✨ Enhancement +9/-11

Legacy mount point update for self-service button

• Replaced CreateDropdown with HeaderIconButton for self-service button in legacy mount points
• Updated config to use HeaderIconButton props instead of layout styling
• Removed unused CSSProperties import
• Maintains backward compatibility with legacy mount point system

workspaces/global-header/plugins/global-header/src/defaultMountPoints/defaultMountPoints.tsx


34. workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdownContent.tsx ✨ Enhancement +73/-0

Dropdown content renderer for grouped and custom items

• New component that renders dropdown content by mapping entries to either standalone components or
 MenuSection
• Handles both custom component items and data-driven grouped items
• Passes handleClose and hideDivider props to child components

workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeaderDropdownContent.tsx


35. workspaces/global-header/plugins/global-header/src/alpha/extensions/GlobalHeaderContext.tsx ✨ Enhancement +78/-0

Context provider and hooks for extension data distribution

• Creates React context for distributing collected header extension data
• Exports GlobalHeaderProvider to wrap app with component and menu item data
• Exports useGlobalHeaderComponents() hook to access all toolbar components
• Exports useGlobalHeaderMenuItems(target) hook to filter menu items by dropdown target

workspaces/global-header/plugins/global-header/src/alpha/extensions/GlobalHeaderContext.tsx


36. workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.tsx ✨ Enhancement +56/-0

Config reader for toolbar components from app-config.yaml

• Utility function that reads globalHeader.components from app-config.yaml
• Maps config entries to GlobalHeaderComponentData with HeaderIconButton rendering
• Supports title, titleKey, icon, link, tooltip, and priority config fields
• Enables deployers to add toolbar buttons without writing plugin code

workspaces/global-header/plugins/global-header/src/alpha/utils/readConfigComponents.tsx


37. workspaces/global-header/plugins/global-header/package.json ⚙️ Configuration changes +17/-0

Package exports and dependencies for NFS support

• Added exports field with main entry and ./alpha subpath for new frontend system
• Added typesVersions for TypeScript type resolution of alpha exports
• Added dependencies: @backstage/frontend-plugin-api and @backstage/plugin-app-react
• Enables proper module resolution for NFS integration

workspaces/global-header/plugins/global-header/package.json


38. workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeader.tsx ✨ Enhancement +54/-0

Main global header AppBar component

• New main header component that renders toolbar items from context in a sticky AppBar
• Uses ErrorBoundary to isolate component failures
• Applies layout overrides from component data via Box wrapper
• Supports custom app bar foreground color from theme

workspaces/global-header/plugins/global-header/src/alpha/components/GlobalHeader.tsx


39. workspaces/global-header/plugins/global-header/src/alpha/components/HelpDropdown.tsx ✨ Enhancement +50/-0

Help dropdown with empty state handling

• New help dropdown component that collects menu items from 'help' target
• Displays help icon button with tooltip
• Shows empty state when no help items are contributed
• Uses trackValidity to hide dropdown when no visible items exist

workspaces/global-header/plugins/global-header/src/alpha/components/HelpDropdown.tsx


40. workspaces/global-header/plugins/global-header/src/alpha/components/ApplicationLauncherDropdown.tsx ✨ Enhancement +51/-0

Application launcher dropdown with empty state

• New application launcher dropdown component that collects menu items from 'app-launcher' target
• Displays apps icon button with tooltip
• Shows empty state with icon when no launcher items are contributed
• Uses trackValidity to conditionally render empty state

workspaces/global-header/plugins/global-header/src/alpha/components/ApplicationLauncherDropdown.tsx


41. workspaces/global-header/packages/app/src/App.tsx ⚙️ Configuration changes +20/-1

Test app integration of global header NFS

• Added globalHeaderModule and globalHeaderPlugin to app features
• Added multiple Backstage plugins: notifications, scaffolder, search, user-settings
• Added rhdhThemeModule for RHDH theming
• Updated app to use new frontend system with proper plugin ordering

workspaces/global-header/packages/app/src/App.tsx


42. workspaces/global-header/packages/app/package.json Dependencies +2/-0

Test app dependencies for global header and theme

• Added @red-hat-developer-hub/backstage-plugin-global-header dependency
• Added @red-hat-developer-hub/backstage-plugin-theme dependency for RHDH theming

workspaces/global-header/packages/app/package.json


43. workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/MenuSection.tsx ✨ Enhancement +16/-3

Menu item onClick handler and styling improvements

• Added onClick optional field to MenuItemConfig interface
• Updated menu item rendering to call onClick handler before handleClose
• Added color: 'inherit' and textDecoration: 'none' sx styling to menu items

workspaces/global-header/plugins/global-header/src/components/HeaderDropdownComponent/MenuSection.tsx


44. workspaces/global-header/docs/index.md 📝 Documentation +10/-3

Documentation index with integration modes overview

• Updated title and description for clarity
• Added section documenting two integration modes: new frontend system and legacy mount points
• Added reference to config-driven menu items feature
• Fixed typo: "enitity" to "entity"

workspaces/global-header/docs/index.md


45. workspaces/global-header/plugins/global-header/src/components/HeaderIcon/HeaderIcon.tsx ✨ Enhancement +10/-1

Material Icons ligature conversion for icon names

• Added toMaterialIconLigature() helper function to convert camelCase icon names to snake_case
• Updated icon rendering to use ligature format for Material Icons
• Enables consistent icon naming across the plugin (e.g., manageAccounts -> manage_accounts)

workspaces/global-header/plugins/global-header/src/components/HeaderIcon/HeaderIcon.tsx


46. workspaces/global-header/plugins/global-header/src/components/LogoutButton/LogoutButton.tsx ✨ Enhancement +6/-2

Logout button divider visibility control

• Added optional hideDivider prop to control divider rendering
• Updated component to conditionally render divider based on prop
• Enables flexible divider display in different dropdown contexts

workspaces/global-header/plugins/global-header/src/components/LogoutButton/LogoutButton.tsx


47. workspaces/global-header/plugins/global-header/report.api.md 📝 Documentation +2/-2

API report updates for component changes

• Removed layout?: CSSProperties from HeaderIconButtonProps interface
• Added onClick?: () => void to MenuItemConfig interface
• Updated API documentation to reflect component changes

workspaces/global-header/plugins/global-header/report.api.md


48. workspaces/global-header/app-config.yaml ⚙️ Configuration changes +8/-0

App config updates for NFS extension discovery

• Added packages: all configuration
• Added extensions section with catalog page extension configuration
• Enables new frontend system extension discovery

workspaces/global-header/app-config.yaml


49. workspaces/global-header/.changeset/famous-bottles-marry.md Miscellaneous +5/-0

Changeset for new frontend system header feature

• Changeset documenting addition of new frontend system based header
• Marks change as minor version bump for the global header plugin

workspaces/global-header/.changeset/famous-bottles-marry.md


50. workspaces/global-header/plugins/global-header/src/alpha.ts Additional files +0/-17

...

workspaces/global-header/plugins/global-header/src/alpha.ts


Grey Divider

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge bot added documentation Improvements or additions to documentation enhancement New feature or request Tests labels Apr 15, 2026
Signed-off-by: Rohit Rai <rohitkrai03@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

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

Labels

documentation Improvements or additions to documentation enhancement New feature or request Tests workspace/global-header

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant