Skip to content

chore(header): upgrade backstage, nfs app & app-legacy setup#2608

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

chore(header): upgrade backstage, nfs app & app-legacy setup#2608
rohitkrai03 wants to merge 1 commit intoredhat-developer:mainfrom
rohitkrai03:nfs-header

Conversation

@rohitkrai03
Copy link
Copy Markdown
Contributor

@rohitkrai03 rohitkrai03 commented Mar 25, 2026

Hey, I just made a Pull Request!

Fixes - https://redhat.atlassian.net/browse/RHIDP-12833
This PR is the first step in migrating global-header plugin to new frontend system.

  • Upgraded to latest Backstage version.
  • Added NFS app package.
  • Moved app to app-legacy.
  • Moved e2e-tests folder out to root.

@rohitkrai03 rohitkrai03 requested review from a team, ciiay and divyanshiGupta as code owners March 25, 2026 15:42
@rhdh-gh-app
Copy link
Copy Markdown

rhdh-gh-app bot commented Mar 25, 2026

Missing Changesets

The following package(s) are changed by this PR but do not have a changeset:

  • @red-hat-developer-hub/backstage-plugin-global-header-test
  • @red-hat-developer-hub/backstage-plugin-global-header

See CONTRIBUTING.md for more information about how to add changesets.

Changed Packages

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

@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Migrate global-header plugin to new Backstage frontend system with dual-mode support

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Upgraded Backstage from v1.45.2 to v1.49.2 with dependency updates
• Created new frontend system (NFS) app package alongside legacy app
• Restructured e2e tests to root level with dual-mode testing support
• Refactored app to use new frontend plugin API and modular architecture
Diagram
flowchart LR
  A["Backstage v1.45.2"] -->|"Upgrade"| B["Backstage v1.49.2"]
  C["Legacy App"] -->|"Parallel"| D["NFS App"]
  E["Nested e2e-tests"] -->|"Relocate"| F["Root e2e-tests"]
  D -->|"Uses"| G["Frontend Plugin API"]
  C -->|"Uses"| H["App Defaults API"]
  F -->|"Supports"| I["APP_MODE env var"]
Loading

Grey Divider

File Changes

1. workspaces/global-header/backstage.json Dependencies +1/-1

Upgrade Backstage version to 1.49.2

workspaces/global-header/backstage.json


2. workspaces/global-header/package.json ⚙️ Configuration changes +9/-4

Add legacy start script and e2e test modes

workspaces/global-header/package.json


3. workspaces/global-header/playwright.config.ts ✨ Enhancement +15/-4

Support dual-mode e2e testing with APP_MODE

workspaces/global-header/playwright.config.ts


View more (37)
4. workspaces/global-header/tsconfig.json ⚙️ Configuration changes +3/-1

Include root-level e2e-tests in TypeScript config

workspaces/global-header/tsconfig.json


5. workspaces/global-header/.eslintignore ⚙️ Configuration changes +1/-0

Ignore root e2e-tests directory

workspaces/global-header/.eslintignore


6. workspaces/global-header/e2e-tests/utils/translations.ts Miscellaneous +6/-6

Update import paths for relocated e2e tests

workspaces/global-header/e2e-tests/utils/translations.ts


7. workspaces/global-header/packages/app/package.json Dependencies +24/-40

Update to new frontend system dependencies

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


8. workspaces/global-header/packages/app/src/App.tsx ✨ Enhancement +5/-149

Refactor to new frontend plugin API architecture

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


9. workspaces/global-header/packages/app/src/index.tsx ✨ Enhancement +1/-2

Update app initialization for new frontend system

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


10. workspaces/global-header/packages/app/src/App.test.tsx 🧪 Tests +1/-2

Update test to use new app API

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


11. workspaces/global-header/packages/app/src/modules/nav/index.ts ✨ Enhancement +22/-0

Create navigation module for new frontend system

workspaces/global-header/packages/app/src/modules/nav/index.ts


12. workspaces/global-header/packages/app/src/modules/nav/Sidebar.tsx ✨ Enhancement +66/-0

Implement sidebar navigation component

workspaces/global-header/packages/app/src/modules/nav/Sidebar.tsx


13. workspaces/global-header/packages/app/src/modules/nav/SidebarLogo.tsx ✨ Enhancement +51/-0

Create responsive sidebar logo component

workspaces/global-header/packages/app/src/modules/nav/SidebarLogo.tsx


14. workspaces/global-header/packages/app/src/modules/nav/LogoFull.tsx ✨ Enhancement +43/-0

Add full logo SVG component for sidebar

workspaces/global-header/packages/app/src/modules/nav/LogoFull.tsx


15. workspaces/global-header/packages/app/src/modules/nav/LogoIcon.tsx ✨ Enhancement +43/-0

Add icon logo SVG component for sidebar

workspaces/global-header/packages/app/src/modules/nav/LogoIcon.tsx


16. workspaces/global-header/packages/app-legacy/package.json ✨ Enhancement +87/-0

Create legacy app package with old API

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


17. workspaces/global-header/packages/app-legacy/src/App.tsx ✨ Enhancement +166/-0

Implement legacy app with traditional architecture

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


18. workspaces/global-header/packages/app-legacy/src/index.tsx ✨ Enhancement +22/-0

Initialize legacy app entry point

workspaces/global-header/packages/app-legacy/src/index.tsx


19. workspaces/global-header/packages/app-legacy/src/App.test.tsx 🧪 Tests +44/-0

Add tests for legacy app component

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


20. workspaces/global-header/packages/app-legacy/src/setupTests.ts ⚙️ Configuration changes +17/-0

Configure test environment for legacy app

workspaces/global-header/packages/app-legacy/src/setupTests.ts


21. workspaces/global-header/packages/app-legacy/public/index.html ✨ Enhancement +60/-0

Create HTML template for legacy app

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


22. workspaces/global-header/packages/app-legacy/public/manifest.json ⚙️ Configuration changes +15/-0

Add web app manifest for legacy app

workspaces/global-header/packages/app-legacy/public/manifest.json


23. workspaces/global-header/packages/app-legacy/public/robots.txt ⚙️ Configuration changes +2/-0

Add robots.txt for legacy app

workspaces/global-header/packages/app-legacy/public/robots.txt


24. workspaces/global-header/packages/app-legacy/.eslintrc.js ⚙️ Configuration changes +1/-0

Configure ESLint for legacy app

workspaces/global-header/packages/app-legacy/.eslintrc.js


25. workspaces/global-header/packages/app-legacy/.eslintignore ⚙️ Configuration changes +1/-0

Ignore public directory in legacy app

workspaces/global-header/packages/app-legacy/.eslintignore


26. workspaces/global-header/packages/backend/package.json Dependencies +28/-28

Update backend dependencies to latest versions

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


27. workspaces/global-header/plugins/global-header/package.json Dependencies +23/-23

Update plugin dependencies to latest versions

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


28. workspaces/global-header/plugins/global-header-test/package.json Dependencies +8/-8

Update test plugin dependencies to latest versions

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


29. workspaces/global-header/e2e-tests/globalHeader.test.ts Additional files +0/-0

...

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


30. workspaces/global-header/e2e-tests/utils/accessibility.ts Additional files +0/-0

...

workspaces/global-header/e2e-tests/utils/accessibility.ts


31. workspaces/global-header/e2e-tests/utils/globalHeaderHelper.ts Additional files +0/-0

...

workspaces/global-header/e2e-tests/utils/globalHeaderHelper.ts


32. workspaces/global-header/e2e-tests/utils/localeSkip.ts Additional files +0/-0

...

workspaces/global-header/e2e-tests/utils/localeSkip.ts


33. workspaces/global-header/packages/app-legacy/src/apis.ts Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/apis.ts


34. workspaces/global-header/packages/app-legacy/src/components/Root/LogoFull.tsx Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/Root/LogoFull.tsx


35. workspaces/global-header/packages/app-legacy/src/components/Root/LogoIcon.tsx Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/Root/LogoIcon.tsx


36. workspaces/global-header/packages/app-legacy/src/components/Root/Root.tsx Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/Root/Root.tsx


37. workspaces/global-header/packages/app-legacy/src/components/Root/index.ts Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/Root/index.ts


38. workspaces/global-header/packages/app-legacy/src/components/catalog/EntityPage.tsx Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/catalog/EntityPage.tsx


39. workspaces/global-header/packages/app-legacy/src/components/search/SearchPage.tsx Additional files +0/-0

...

workspaces/global-header/packages/app-legacy/src/components/search/SearchPage.tsx


40. workspaces/global-header/packages/app/src/setupTests.ts Additional files +0/-1

...

workspaces/global-header/packages/app/src/setupTests.ts


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge bot commented Mar 25, 2026

Code Review by Qodo

🐞 Bugs (6) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. NFS e2e tests fail 🐞 Bug ✓ Correctness
Description
When APP_MODE=nfs, Playwright starts the new NFS app, but that app does not mount the global
header or provide the UI flow the e2e suite depends on, causing deterministic runtime failures
(e.g., missing 'Enter' button / #global-header).
Code

workspaces/global-header/packages/app/src/App.tsx[R16-22]

+import { createApp } from '@backstage/frontend-defaults';
+import catalogPlugin from '@backstage/plugin-catalog/alpha';
+import { navModule } from './modules/nav';

-// eslint-disable-next-line no-restricted-imports
-import { GlobalStyles } from '@mui/material';
-import { Navigate, Route } from 'react-router-dom';
-import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
-import {
-  CatalogEntityPage,
-  CatalogIndexPage,
-  catalogPlugin,
-} from '@backstage/plugin-catalog';
-import {
-  CatalogImportPage,
-  catalogImportPlugin,
-} from '@backstage/plugin-catalog-import';
-import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder';
-import { orgPlugin } from '@backstage/plugin-org';
-import { SearchPage } from '@backstage/plugin-search';
-import {
-  TechDocsIndexPage,
-  techdocsPlugin,
-  TechDocsReaderPage,
-} from '@backstage/plugin-techdocs';
-import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
-import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
-import { UserSettingsPage } from '@backstage/plugin-user-settings';
-import { apis } from './apis';
-import { entityPage } from './components/catalog/EntityPage';
-import { searchPage } from './components/search/SearchPage';
-import { Root } from './components/Root';
-
-import {
-  AlertDisplay,
-  OAuthRequestDialog,
-  SignInPage,
-} from '@backstage/core-components';
-import { createApp } from '@backstage/app-defaults';
-import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
-import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
-import { RequirePermission } from '@backstage/plugin-permission-react';
-import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
-import { SignalsDisplay } from '@backstage/plugin-signals';
-import { NotificationsPage } from '@backstage/plugin-notifications';
-import { githubAuthApiRef } from '@backstage/core-plugin-api';
-
-import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme';
-import { globalHeaderTranslations } from '@red-hat-developer-hub/backstage-plugin-global-header';
-import ManageAccounts from '@mui/icons-material/ManageAccountsOutlined';
-import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined';
-import Logout from '@mui/icons-material/LogoutOutlined';
-
-const app = createApp({
-  icons: {
-    manageAccounts: ManageAccounts,
-    account: AccountCircleOutlinedIcon,
-    logout: Logout,
-  },
-  apis,
-  __experimentalTranslations: {
-    availableLanguages: ['en', 'de', 'es', 'fr', 'it', 'ja'],
-    resources: [globalHeaderTranslations],
-  },
-  bindRoutes({ bind }) {
-    bind(catalogPlugin.externalRoutes, {
-      createComponent: scaffolderPlugin.routes.root,
-      viewTechDoc: techdocsPlugin.routes.docRoot,
-      createFromTemplate: scaffolderPlugin.routes.selectedTemplate,
-    });
-    bind(apiDocsPlugin.externalRoutes, {
-      registerApi: catalogImportPlugin.routes.importPage,
-    });
-    bind(scaffolderPlugin.externalRoutes, {
-      registerComponent: catalogImportPlugin.routes.importPage,
-      viewTechDoc: techdocsPlugin.routes.docRoot,
-    });
-    bind(orgPlugin.externalRoutes, {
-      catalogIndex: catalogPlugin.routes.catalogIndex,
-    });
-  },
-  components: {
-    SignInPage: props => (
-      <SignInPage
-        {...props}
-        auto
-        providers={[
-          'guest',
-          {
-            id: 'github-auth-provider',
-            title: 'GitHub',
-            message: 'Sign in using GitHub',
-            apiRef: githubAuthApiRef,
-          },
-        ]}
-      />
-    ),
-  },
-  themes: getAllThemes(),
+export default createApp({
+  features: [catalogPlugin, navModule],
});
-
-const routes = (
-  <FlatRoutes>
-    <Route path="/" element={<Navigate to="catalog" />} />
-    <Route path="/catalog" element={<CatalogIndexPage />} />
-    <Route
-      path="/catalog/:namespace/:kind/:name"
-      element={<CatalogEntityPage />}
-    >
-      {entityPage}
-    </Route>
-    <Route path="/docs" element={<TechDocsIndexPage />} />
-    <Route
-      path="/docs/:namespace/:kind/:name/*"
-      element={<TechDocsReaderPage />}
-    >
-      <TechDocsAddons>
-        <ReportIssue />
-      </TechDocsAddons>
-    </Route>
-    <Route path="/create" element={<ScaffolderPage />} />
-    <Route path="/api-docs" element={<ApiExplorerPage />} />
-    <Route path="/notifications" element={<NotificationsPage />} />
-    <Route
-      path="/catalog-import"
-      element={
-        <RequirePermission permission={catalogEntityCreatePermission}>
-          <CatalogImportPage />
-        </RequirePermission>
-      }
-    />
-    <Route path="/search" element={<SearchPage />}>
-      {searchPage}
-    </Route>
-    <Route path="/settings" element={<UserSettingsPage />} />
-    <Route path="/catalog-graph" element={<CatalogGraphPage />} />
-  </FlatRoutes>
-);
-
-export default app.createRoot(
-  <>
-    <GlobalStyles
-      styles={{
-        html: { overflowY: 'hidden' },
-      }}
-    />
-    <AlertDisplay />
-    <OAuthRequestDialog />
-    <SignalsDisplay />
-    <AppRouter>
-      <Root>{routes}</Root>
-    </AppRouter>
-  </>,
-);
Evidence
The NFS app only enables [catalogPlugin, navModule] and does not include the global-header plugin
or any header mounting. Meanwhile the e2e suite explicitly clicks a sign-in 'Enter' button and then
queries #global-header and global-header-* test IDs, which are provided by the legacy Root
component mounting <GlobalHeaderComponent />. Additionally, test:e2e:nfs is wired to run the
same suite against the NFS app, so it will fail.

workspaces/global-header/packages/app/src/App.tsx[16-22]
workspaces/global-header/e2e-tests/globalHeader.test.ts[35-82]
workspaces/global-header/packages/app-legacy/src/components/Root/Root.tsx[114-122]
workspaces/global-header/package.json[23-26]
workspaces/global-header/playwright.config.ts[21-24]

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

### Issue description
`APP_MODE=nfs` runs the same global-header e2e suite against the new NFS app, but the NFS app does not include/mount the global header or the same sign-in flow. This makes `test:e2e:nfs` / `test:e2e:all` fail deterministically.

### Issue Context
The legacy app mounts the global header via `<GlobalHeaderComponent />` in the `Root` layout and provides the DOM/testIds the suite asserts. The NFS app currently only enables catalog + nav.

### Fix Focus Areas
Choose one:
- Make NFS app include/mount global header (and translations) so the same e2e suite passes.
- OR split/guard e2e tests: run global-header assertions only for legacy mode, and create a separate NFS-focused suite.

- workspaces/global-header/packages/app/src/App.tsx[16-22]
- workspaces/global-header/e2e-tests/globalHeader.test.ts[35-82]
- workspaces/global-header/package.json[23-26]
- workspaces/global-header/playwright.config.ts[21-24]
- workspaces/global-header/packages/app-legacy/src/components/Root/Root.tsx[114-122]

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


2. E2E imports target missing .js 🐞 Bug ✓ Correctness
Description
The moved e2e tests import src/translations/*.js, but the plugin translation sources in this repo
are *.ts only, so typechecking/bundling can fail depending on TS moduleResolution/loader settings.
Code

workspaces/global-header/e2e-tests/utils/translations.ts[R19-24]

+import { globalHeaderMessages } from '../../plugins/global-header/src/translations/ref.js';
+import globalHeaderTranslationDe from '../../plugins/global-header/src/translations/de.js';
+import globalHeaderTranslationEs from '../../plugins/global-header/src/translations/es.js';
+import globalHeaderTranslationFr from '../../plugins/global-header/src/translations/fr.js';
+import globalHeaderTranslationIt from '../../plugins/global-header/src/translations/it.js';
+import globalHeaderTranslationJa from '../../plugins/global-header/src/translations/ja.js';
Evidence
workspaces/global-header/e2e-tests/utils/translations.ts now imports
.../src/translations/ref.js, de.js, etc. The actual files under
workspaces/global-header/plugins/global-header/src/translations/ are ref.ts, de.ts, etc. There
are no *.js files at those paths in the repo checkout, so these imports cannot resolve at runtime
without a build step that emits JS into src/ (which is not present here).

workspaces/global-header/e2e-tests/utils/translations.ts[17-25]
workspaces/global-header/plugins/global-header/src/translations/ref.ts[1-1]

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

### Issue description
e2e translation helper imports `*.js` files that do not exist in the repo tree.

### Issue Context
Plugin translations are authored as `*.ts` in `plugins/global-header/src/translations/`. The e2e tests run directly from TS sources.

### Fix Focus Areas
Pick one consistent approach:
- Change the imports to target the TS sources (e.g. `ref.ts`, `de.ts`, etc) and adjust lint suppression accordingly.
- OR ensure the referenced `*.js` files exist by building/compiling translations to a known location and update imports to point there.

- workspaces/global-header/e2e-tests/utils/translations.ts[17-25]
- workspaces/global-header/plugins/global-header/src/translations/*[1-200]

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



Remediation recommended

3. Playwright wrapper arg check 🐞 Bug ⛯ Reliability
Description
The playwright script’s bash conditional uses $@ incorrectly, so `yarn playwright test --
<args> will not route to yarn test:e2e:legacy` as intended and can misbehave with multi-arg
invocations.
Code

workspaces/global-header/package.json[R23-27]

+    "test:e2e": "yarn test:e2e:legacy",
+    "test:e2e:legacy": "APP_MODE=legacy playwright test",
+    "test:e2e:nfs": "APP_MODE=nfs playwright test",
+    "test:e2e:all": "yarn test:e2e:legacy && yarn test:e2e:nfs",
+    "playwright": "bash -c 'if [[ $@ == test ]]; then yarn test:e2e:legacy; else npx playwright \"$@\"; fi' _",
Evidence
The script checks [[ $@ == test ]], which becomes a multi-word string comparison once additional
args are present (e.g., test --headed), causing the condition to be false and bypassing the
intended redirect. The repo has similar wrappers elsewhere, indicating this is a used pattern, but
the robust check should be on $1 and $#.

workspaces/global-header/package.json[23-27]
workspaces/bulk-import/package.json[27-31]

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 `playwright` wrapper script does not reliably detect the `test` subcommand when extra arguments are passed.

### Issue Context
`$@` expands to multiple words; using it in `[[ ... == test ]]` breaks when there are additional args.

### Fix Focus Areas
Update the conditional to check the first arg and optionally arg count, e.g.:
- `if [[ "$1" == "test" ]]; then ... fi`
- or `if [[ $# -ge 1 && "$1" == "test" ]]; then ... fi`

- workspaces/global-header/package.json[23-27]

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


4. Legacy start config likely ignored 🐞 Bug ⛯ Reliability
Description
The Playwright webServer command appends --config <...>/app-config.yaml after yarn start:legacy,
but start:legacy uses backstage-cli repo start packages/app-legacy packages/backend, which may
treat trailing CLI flags as package names rather than Backstage CLI options, resulting in the config
not being applied during e2e runs.
Code

workspaces/global-header/playwright.config.ts[R22-30]

+const appMode = process.env.APP_MODE || 'legacy';
+const startCommand = appMode === 'legacy' ? 'yarn start:legacy' : 'yarn start';
+
+// Config paths (absolute to work from any cwd)
+const baseConfig = `${__dirname}/app-config.yaml`;
+
export default defineConfig({
  timeout: 2 * 60 * 1000,
Evidence
In this repo other Playwright configs pass yarn start --config ... (no explicit package paths), or
when using startCommand they append multiple --config flags but rely on a start command that
already supports CLI flags. Here, start:legacy includes explicit package paths
(packages/app-legacy packages/backend), which makes it ambiguous whether --config is still
parsed as a CLI option or interpreted as another package selector. There are no other examples in
the repo of repo start <packagePaths> --config ... to confirm it works.

workspaces/global-header/playwright.config.ts[21-42]
workspaces/global-header/package.json[11-13]
workspaces/adoption-insights/playwright.config.ts[19-48]
workspaces/quickstart/playwright.config.ts[14-27]

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

### Issue description
Appending `--config ...` after `repo start packages/...` is ambiguous and may not apply the config in e2e runs.

### Issue Context
`start:legacy` selects packages explicitly. The Playwright config appends `--config` flags to that command.

### Fix Focus Areas
Make the config handling unambiguous by moving the `--config` flags into dedicated scripts, e.g.:
- Add `start:legacy:e2e` that includes the `--config` arguments in the correct position for backstage-cli.
- Or change `startCommand` to `backstage-cli repo start --config ... packages/...` (if the CLI expects flags first).
Also consider adding a readiness `url` instead of only `port` to ensure the server is actually ready.

- workspaces/global-header/package.json[11-13]
- workspaces/global-header/playwright.config.ts[21-42]

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


5. NFS app lacks user-settings feature 🐞 Bug ✓ Correctness
Description
The NFS app’s sidebar renders links for page:user-settings and routes to /settings, but the app
does not enable the user-settings plugin feature, so these items may be missing and /settings may
404.
Code

workspaces/global-header/packages/app/src/modules/nav/Sidebar.tsx[R54-61]

+          <SidebarGroup
+            label="Settings"
+            icon={<UserSettingsSignInAvatar />}
+            to="/settings"
+          >
+            {nav.take('page:app-visualizer')}
+            {nav.take('page:user-settings')}
+          </SidebarGroup>
Evidence
The sidebar expects nav items like page:user-settings and includes a Settings group pointing to
/settings. Unlike other NFS apps in this repo, the global-header NFS app does not include
@backstage/plugin-user-settings/alpha (feature) in features: [...], so the nav item and route
may not exist.

workspaces/global-header/packages/app/src/modules/nav/Sidebar.tsx[54-61]
workspaces/global-header/packages/app/src/App.tsx[16-22]
workspaces/adoption-insights/packages/app/src/App.tsx[16-34]

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

### Issue description
Sidebar references settings-related nav items and `/settings`, but the app doesn’t enable the corresponding feature.

### Issue Context
Other NFS apps include `userSettingsPlugin` in `features` when they expose settings.

### Fix Focus Areas
- Add `userSettingsPlugin` (alpha) to `features` or remove settings links/items from sidebar until supported.

- workspaces/global-header/packages/app/src/App.tsx[16-22]
- workspaces/global-header/packages/app/src/modules/nav/Sidebar.tsx[54-61]

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



Advisory comments

6. E2E tests ignored by ESLint 🐞 Bug ⚙ Maintainability
Description
Adding e2e-tests/ to .eslintignore disables linting for the entire e2e suite, increasing the
chance of broken imports/types reaching CI only at runtime.
Code

workspaces/global-header/.eslintignore[R1-2]

playwright.config.ts
+e2e-tests/
Evidence
The PR moves e2e tests to workspaces/global-header/e2e-tests and then ignores that directory in
ESLint, removing static feedback for a critical test suite (including the translation import paths
changed in this PR).

workspaces/global-header/.eslintignore[1-2]

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

### Issue description
`e2e-tests/` is fully excluded from ESLint.

### Issue Context
e2e tests include complex selectors/imports and benefit from linting.

### Fix Focus Areas
- Remove the broad ignore and instead add targeted rule overrides (e.g., allow relative monorepo imports only in the translations helper).

- workspaces/global-header/.eslintignore[1-2]
- workspaces/global-header/e2e-tests/utils/translations.ts[17-25]

ⓘ 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

@rohitkrai03 rohitkrai03 force-pushed the nfs-header branch 3 times, most recently from 1ff521a to 0d6e36c Compare March 25, 2026 18:21
Copy link
Copy Markdown
Contributor

@HusneShabbir HusneShabbir left a comment

Choose a reason for hiding this comment

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

Please add the below to the .gitignore file

**/e2e-test-report*/
**/test-results/
**/playwright-report/

Copy link
Copy Markdown
Contributor

@HusneShabbir HusneShabbir left a comment

Choose a reason for hiding this comment

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

/lgtm, fine with the e2e file changes.

Signed-off-by: Rohit Rai <rohitkrai03@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
24.8% Duplication on New Code (required ≤ 3%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants