Skip to content

chore(app-defaults): create app-defaults modules and move implementation and extensions from app-react#3447

Open
christoph-jerolimov wants to merge 2 commits into
redhat-developer:mainfrom
christoph-jerolimov:app-defaults/new-app-defaults-module
Open

chore(app-defaults): create app-defaults modules and move implementation and extensions from app-react#3447
christoph-jerolimov wants to merge 2 commits into
redhat-developer:mainfrom
christoph-jerolimov:app-defaults/new-app-defaults-module

Conversation

@christoph-jerolimov

Copy link
Copy Markdown
Member

Hey, I just made a Pull Request!

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
@rhdh-gh-app

rhdh-gh-app Bot commented Jun 18, 2026

Copy link
Copy Markdown

Missing Changesets

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

  • @red-hat-developer-hub/backstage-plugin-app-defaults
  • @red-hat-developer-hub/backstage-plugin-app-react

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

Changed Packages

Package Name Package Path Changeset Bump Current Version
app workspaces/app-defaults/packages/app none v0.0.0
@red-hat-developer-hub/backstage-plugin-app-defaults workspaces/app-defaults/plugins/app-defaults none v0.0.0
@red-hat-developer-hub/backstage-plugin-app-react workspaces/app-defaults/plugins/app-react none v0.0.5

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

Create app-defaults module and move drawer wiring out of app-react
✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

Description

• Add new app-defaults frontend module to own default app extension wiring (drawer).
• Update example app to consume app-defaults instead of app-react/alpha module.
• Slim app-react to public drawer APIs (hook/store/blueprints) and update docs accordingly.
Diagram

graph TD
  A["RHDH App (createApp)"] --> B(["app-defaults module"]) --> C["appDrawerExtensions"] --> D["ApplicationDrawer wrapper"] --> E["app-react drawer APIs"]
  F["Plugins: drawer content"] --> C
  G[("app-config overrides")] --> D
  subgraph Legend
    direction LR
    _pkg["Package/Component"] ~~~ _mod(["Frontend module"]) ~~~ _cfg[("Config")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep drawer module in app-react (/alpha)
  • ➕ No new package/module to version and depend on
  • ➕ Fewer moving parts for app integrators already using app-react/alpha
  • ➖ Continues mixing public API surface with concrete app wiring
  • ➖ Harder to evolve defaults independently from API guarantees
2. Split defaults by feature (e.g., app-defaults-drawer)
  • ➕ Even clearer ownership boundaries and smaller install surface
  • ➕ Lets apps adopt only the defaults they want
  • ➖ More packages to manage/publish
  • ➖ More confusing onboarding than a single 'defaults' module initially
3. Rely solely on feature auto-discovery instead of explicit module import
  • ➕ Less manual wiring in App.tsx
  • ➕ Aligns with Backstage discovery patterns
  • ➖ Less explicit; harder to see what defaults are enabled
  • ➖ Still requires a module/package that provides the extensions

Recommendation: The PR’s direction (app-defaults owns concrete extension wiring; app-react retains reusable APIs) is the cleanest long-term split. The main follow-up to verify is the published entrypoint ergonomics: the example app uses a default import (import appDefaultsModule from ...), so the module package should export a default (or the app should use a named import). Also fix the installation snippet/package name typo in the new README to prevent copy/paste breakage.

Files changed (25) +243 / -96

Enhancement (6) +89 / -2
App.tsxSwitch app feature registration to app-defaults module +2/-2

Switch app feature registration to app-defaults module

• Replaces the previous app-react alpha drawer module registration with the new app-defaults module in the app's createApp feature list.

workspaces/app-defaults/packages/app/src/App.tsx

package.jsonCreate new app-defaults frontend-plugin-module package +45/-0

Create new app-defaults frontend-plugin-module package

• Introduces a new publishable package definition for @red-hat-developer-hub/backstage-plugin-app-defaults, including Backstage module metadata, dependencies, and build/test scripts.

workspaces/app-defaults/plugins/app-defaults/package.json

DrawerPanel.tsxAdd/move DrawerPanel implementation into app-defaults package +0/-0

Add/move DrawerPanel implementation into app-defaults package

• Includes changes for the DrawerPanel component implementation as part of relocating drawer UI components into app-defaults.

workspaces/app-defaults/plugins/app-defaults/src/drawer/components/DrawerPanel.tsx

index.tsAdd app-defaults package entrypoint +16/-0

Add app-defaults package entrypoint

• Adds the top-level index that re-exports module-level exports from ./module.

workspaces/app-defaults/plugins/app-defaults/src/index.ts

module.tsxDefine appDefaults frontend module composing drawer extensions +25/-0

Define appDefaults frontend module composing drawer extensions

• Creates the appDefaults frontend module via createFrontendModule and re-exports appDrawerExtensions for manual installation. Note: consider aligning exports with how the app imports the module (default vs named).

workspaces/app-defaults/plugins/app-defaults/src/module.tsx

useAppDrawer.tsxExpose reset action on useAppDrawer API +1/-0

Expose reset action on useAppDrawer API

• Adds a reset method to the useAppDrawer return object, delegating to drawerStore.reset.

workspaces/app-defaults/plugins/app-react/src/drawer/hooks/useAppDrawer.tsx

Refactor (6) +15 / -41
index.tsxUse stable AppDrawerContentBlueprint import path +1/-1

Use stable AppDrawerContentBlueprint import path

• Updates the drawer demo module to import AppDrawerContentBlueprint from the app-react main entry instead of /alpha, aligning with the new packaging/export approach.

workspaces/app-defaults/packages/app/src/modules/drawer-demo/index.tsx

ApplicationDrawer.tsxWire ApplicationDrawer to app-react hook/types +3/-2

Wire ApplicationDrawer to app-react hook/types

• Updates the ApplicationDrawer component to use the app-react exported useAppDrawer hook and AppDrawerContent type, decoupling it from local drawer API implementations.

workspaces/app-defaults/plugins/app-defaults/src/drawer/components/ApplicationDrawer.tsx

extensions.tsxExport drawer wrapper extension + extension list (no module here) +6/-18

Export drawer wrapper extension + extension list (no module here)

• Refactors drawer extension wiring to export the wrapper extension and an appDrawerExtensions array. Removes the local createFrontendModule usage in favor of composing a module at the package root.

workspaces/app-defaults/plugins/app-defaults/src/drawer/extensions.tsx

index.tsRe-export drawer extension list from drawer entrypoint +1/-7

Re-export drawer extension list from drawer entrypoint

• Simplifies the drawer package entry to export appDrawerExtensions (instead of exporting the previous drawer API surface).

workspaces/app-defaults/plugins/app-defaults/src/drawer/index.ts

index.tsNarrow app-react drawer exports to API/store + contribution primitives +3/-7

Narrow app-react drawer exports to API/store + contribution primitives

• Stops exporting drawer UI components/module wiring and instead exports the contribution dataRef/blueprint along with useAppDrawer and drawerStore for state/control.

workspaces/app-defaults/plugins/app-react/src/drawer/index.ts

index.tsRe-export drawer surface from app-react root entrypoint +1/-6

Re-export drawer surface from app-react root entrypoint

• Simplifies the root entrypoint to export everything from ./drawer, matching the new intended public surface.

workspaces/app-defaults/plugins/app-react/src/index.ts

Tests (3) +22 / -3
ApplicationDrawer.test.tsxUpdate drawer tests to consume app-react public APIs +6/-3

Update drawer tests to consume app-react public APIs

• Refactors the ApplicationDrawer tests to import useAppDrawer, drawerStore, and AppDrawerContent from the app-react package instead of local module internals.

workspaces/app-defaults/plugins/app-defaults/src/drawer/components/ApplicationDrawer.test.tsx

DrawerPanel.test.tsxAdd/move DrawerPanel tests into app-defaults package +0/-0

Add/move DrawerPanel tests into app-defaults package

• Includes changes for DrawerPanel unit tests as part of moving drawer UI implementation into app-defaults.

workspaces/app-defaults/plugins/app-defaults/src/drawer/components/DrawerPanel.test.tsx

setupTests.tsAdd Jest DOM test setup for app-defaults package +16/-0

Add Jest DOM test setup for app-defaults package

• Adds a setupTests entry to enable @testing-library/jest-dom matchers in package tests.

workspaces/app-defaults/plugins/app-defaults/src/setupTests.ts

Documentation (2) +88 / -33
README.mdDocument app-defaults module usage and drawer behavior +79/-0

Document app-defaults module usage and drawer behavior

• Adds initial documentation describing what the app-defaults module provides, how to install/register it, and how drawer config overrides work. Note: the yarn add snippet appears to reference a singular package name (likely a typo).

workspaces/app-defaults/plugins/app-defaults/README.md

README.mdUpdate app-react docs to point apps to app-defaults module +9/-33

Update app-react docs to point apps to app-defaults module

• Removes app integration instructions for registering the drawer module from app-react and updates examples to use stable imports. Clarifies that apps should install/register app-defaults to enable drawers.

workspaces/app-defaults/plugins/app-react/README.md

Other (8) +29 / -17
knip-report.mdUpdate Knip unused-dependency report after dependency shift +5/-6

Update Knip unused-dependency report after dependency shift

• Adjusts reported unused dependency locations/counts due to package.json line shifts and dependency changes. Reflects removal of one unused devDependency entry in the report.

workspaces/app-defaults/packages/app/knip-report.md

package.jsonDepend on new app-defaults plugin module +1/-0

Depend on new app-defaults plugin module

• Adds @red-hat-developer-hub/backstage-plugin-app-defaults as an app dependency so the app can register the new defaults module.

workspaces/app-defaults/packages/app/package.json

knip-report.mdAdd Knip report for app-auth workspace plugin +9/-0

Add Knip report for app-auth workspace plugin

• Introduces a Knip report file listing unused devDependencies for the app-auth plugin package.

workspaces/app-defaults/plugins/app-auth/knip-report.md

.eslintrc.jsAdd ESLint factory config for new app-defaults package +1/-0

Add ESLint factory config for new app-defaults package

• Adds a standard Backstage CLI eslint-factory configuration file for the new plugin module package.

workspaces/app-defaults/plugins/app-defaults/.eslintrc.js

knip-report.mdAdd placeholder Knip report for new app-defaults package +2/-0

Add placeholder Knip report for new app-defaults package

• Adds an initial Knip report file for the new app-defaults module package.

workspaces/app-defaults/plugins/app-defaults/knip-report.md

knip-report.mdAdd Knip report for app-integrations workspace plugin +9/-0

Add Knip report for app-integrations workspace plugin

• Introduces a Knip report file listing unused devDependencies for the app-integrations plugin package.

workspaces/app-defaults/plugins/app-integrations/knip-report.md

knip-report.mdRefresh app-react Knip report after dependency cleanup +1/-7

Refresh app-react Knip report after dependency cleanup

• Updates the Knip report to reflect removal of unused dependencies and shifted line locations for devDependencies.

workspaces/app-defaults/plugins/app-react/knip-report.md

package.jsonRemove now-unused UI/runtime deps from app-react package +1/-4

Remove now-unused UI/runtime deps from app-react package

• Drops dependencies that are no longer needed after moving concrete drawer UI wiring out of app-react, leaving a slimmer API-focused dependency set.

workspaces/app-defaults/plugins/app-react/package.json

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jun 18, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Invalid default module import ✓ Resolved 🐞 Bug ≡ Correctness
Description
workspaces/app-defaults/packages/app/src/App.tsx default-imports
@red-hat-developer-hub/backstage-plugin-app-defaults and registers it as a feature, but the
package only exports a named appDefaults module (no default export). This will fail type-checking
and/or register the wrong value in features, preventing the defaults module (drawer wrapper) from
being installed.
Code

workspaces/app-defaults/packages/app/src/App.tsx[R21-24]

+import appDefaultsModule from '@red-hat-developer-hub/backstage-plugin-app-defaults';
import {
  globalHeaderModule,
  globalHeaderTranslationsModule,
Relevance

⭐⭐⭐ High

Team previously accepted fixing wrong entrypoint import causing export/type failures (e.g., switch
to /alpha).

PR-#2526

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The app registers appDefaultsModule from a default import, while the new app-defaults package only
provides a named appDefaults export via export * re-exports, meaning there is no default export
to import.

workspaces/app-defaults/packages/app/src/App.tsx[17-39]
workspaces/app-defaults/plugins/app-defaults/src/module.tsx[16-25]
workspaces/app-defaults/plugins/app-defaults/src/index.ts[16-16]

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

## Issue description
`App.tsx` uses a default import for `@red-hat-developer-hub/backstage-plugin-app-defaults`, but that package only exports named symbols (`appDefaults`, `appDrawerExtensions`). This causes compilation failure or a wrong runtime value passed to `createApp({ features: [...] })`.

## Issue Context
- `@red-hat-developer-hub/backstage-plugin-app-defaults` currently exports `appDefaults` as a named `createFrontendModule(...)`.
- The app is importing it as `import appDefaultsModule from ...`.

## Fix Focus Areas
- workspaces/app-defaults/packages/app/src/App.tsx[17-39]
- workspaces/app-defaults/plugins/app-defaults/src/module.tsx[16-25]
- workspaces/app-defaults/plugins/app-defaults/src/index.ts[16-16]

## Suggested fix
Pick one approach and make it consistent across app + docs:
1) **Preferred (named export):**
  - Change the app to `import { appDefaults } from '@red-hat-developer-hub/backstage-plugin-app-defaults';`
  - Register `appDefaults` in the `features` array.

2) **Alternative (provide a default export):**
  - In `workspaces/app-defaults/plugins/app-defaults/src/module.tsx` (or `src/index.ts`), add `export default appDefaults;` (or rename `appDefaults` to `appDefaultsModule` and default-export it).
  - Keep `App.tsx` default import, but ensure the package actually has a default export.

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


2. Broken app-react alpha imports 🐞 Bug ≡ Correctness
Description
Other workspaces still import appDrawerModule / AppDrawerContentBlueprint from
@red-hat-developer-hub/backstage-plugin-app-react/alpha, but the app-react package no longer
exposes appDrawerModule from its drawer barrel and its package.json points ./alpha to a
missing src/alpha.ts. This will break TypeScript/module resolution for those consumers.
Code

workspaces/app-defaults/plugins/app-react/src/drawer/index.ts[R17-23]

export { appDrawerContentDataRef } from './extensions/appDrawerContentDataRef';
export { AppDrawerContentBlueprint } from './extensions/AppDrawerContentBlueprint';
-export { appDrawerModule } from './extensions/appDrawerModule';

-export type { ApplicationDrawerProps } from './components/ApplicationDrawer';
-export type { DrawerPanelProps } from './components/DrawerPanel';
+export { useAppDrawer } from './hooks/useAppDrawer';
+export { drawerStore } from './utils/drawerStore';
+
export type { AppDrawerContent, AppDrawerApi } from './types';
Relevance

⭐⭐⭐ High

Repo has merged fixes adding/repairing ./alpha exports + typesVersions to prevent resolution
failures.

PR-#1605
PR-#1566
PR-#1606

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
app-react/package.json still maps ./alpha to src/alpha.ts, while downstream workspaces import
from that path; additionally, the updated drawer/index.ts no longer exports appDrawerModule,
making it impossible to satisfy those imports without restoring/migrating the alpha entrypoint.

workspaces/app-defaults/plugins/app-react/package.json[8-21]
workspaces/app-defaults/plugins/app-react/src/drawer/index.ts[17-23]
workspaces/lightspeed/packages/app/src/App.tsx[17-36]
workspaces/quickstart/packages/app/src/App.tsx[16-39]
workspaces/lightspeed/plugins/lightspeed/src/alpha/index.tsx[28-35]
workspaces/quickstart/plugins/quickstart/src/alpha/index.tsx[17-25]

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

## Issue description
Multiple workspaces still depend on `@red-hat-developer-hub/backstage-plugin-app-react/alpha` for `appDrawerModule` and `AppDrawerContentBlueprint`, but `@…/app-react` now:
- no longer exports `appDrawerModule` from `src/drawer/index.ts`, and
- still declares an `./alpha` export to `./src/alpha.ts` even though `src/alpha.ts` is missing in this branch.

This combination breaks existing imports in `lightspeed` and `quickstart`.

## Issue Context
You introduced a new `@red-hat-developer-hub/backstage-plugin-app-defaults` module to host the drawer module. That’s fine, but either backward compatibility must be preserved (`/alpha` continues to work), or all internal consumers must be migrated in the same PR and the `/alpha` export removed.

## Fix Focus Areas
- workspaces/app-defaults/plugins/app-react/src/drawer/index.ts[17-23]
- workspaces/app-defaults/plugins/app-react/package.json[8-21]
- workspaces/lightspeed/packages/app/src/App.tsx[17-36]
- workspaces/quickstart/packages/app/src/App.tsx[16-39]
- workspaces/lightspeed/plugins/lightspeed/src/alpha/index.tsx[28-35]
- workspaces/quickstart/plugins/quickstart/src/alpha/index.tsx[17-25]

## Suggested fix
Choose one:
1) **Backward compatible:**
  - Re-introduce `workspaces/app-defaults/plugins/app-react/src/alpha.ts` and make it re-export the previous alpha API surface (`appDrawerModule`, `AppDrawerContentBlueprint`, `appDrawerContentDataRef`, etc.), potentially by importing from the new app-defaults package where appropriate.
  - Ensure `appDrawerModule` exists again for alpha consumers.

2) **Full migration + cleanup (breaking change controlled inside repo):**
  - Update all internal consumers (`lightspeed`, `quickstart`, etc.) to stop importing from `/alpha` and to register the new app-defaults module instead.
  - Remove `./alpha` from `exports` and `typesVersions` in `app-react/package.json` (or provide a stub that clearly errors), and update API reports accordingly.

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



Remediation recommended

3. Wrong README package name 🐞 Bug ⚙ Maintainability
Description
The new app-defaults README instructs installing
@red-hat-developer-hub/backstage-plugin-app-default (missing trailing s), which will not match
the actual package name and will cause failed installs for users following the docs.
Code

workspaces/app-defaults/plugins/app-defaults/README.md[R8-12]

+Add the package as a dependency in your app:
+
+```bash
+yarn add @red-hat-developer-hub/backstage-plugin-app-default
+```
Relevance

⭐⭐⭐ High

Docs/README correctness fixes are typically accepted (e.g., README endpoint/usage corrections were
accepted).

PR-#2341
PR-#1952

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The README’s install command has a different package name than the package being introduced/used
(…app-defaults).

workspaces/app-defaults/plugins/app-defaults/README.md[8-12]
workspaces/app-defaults/plugins/app-defaults/package.json[1-5]

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 README install snippet uses the wrong package name (missing trailing `s`), so users will install a non-existent/different package.

## Issue Context
The actual package name (per `package.json`) is `@red-hat-developer-hub/backstage-plugin-app-defaults`.

## Fix Focus Areas
- workspaces/app-defaults/plugins/app-defaults/README.md[8-12]

## Suggested fix
Update the install command to:
```bash
yarn add @red-hat-developer-hub/backstage-plugin-app-defaults
```

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


Grey Divider

Qodo Logo

Move ApplicationDrawer and DrawerPanel components into app-defaults and
re-export appDrawerExtensions from the new module. The app-react package
now only exposes the public API surface (hooks, blueprints, data refs,
types) while app-defaults owns the concrete extension wiring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
@christoph-jerolimov christoph-jerolimov force-pushed the app-defaults/new-app-defaults-module branch from db9990d to d1f7395 Compare June 18, 2026 10:18
@rhdh-qodo-merge rhdh-qodo-merge Bot added documentation Improvements or additions to documentation enhancement New feature or request Tests labels Jun 18, 2026
@sonarqubecloud

Copy link
Copy Markdown

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/app-defaults

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant