Drop the deprecated NavItemBlueprint from the public API and migrate core
plugins to set title and icon on PageBlueprint instead. AppNav keeps
backward compatibility for legacy nav-item extensions via an internal
core.nav-item.target data ref.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(techdocs): make sidebar positioning configurable via CSS custom properties
Replace hardcoded Backstage app sidebar widths (224px/72px) in the
TechDocs layout CSS with CSS custom properties that inherit through
the shadow DOM boundary, allowing apps with custom sidebar widths
to override the defaults.
- `--techdocs-sidebar-closed-offset-pinned` (default: 224px)
- `--techdocs-sidebar-closed-offset-collapsed` (default: 72px)
- `--techdocs-sidebar-open-translate` (default: 16rem)
Also extract all magic values into named constants.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* Add PR #33908 to patch release
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Extract entityPresentationSnapshot helper to eliminate unsafe `as Entity`
casts when passing CompoundEntityRef to EntityPresentationApi.forEntity(),
which only accepts Entity | string. The helper safely discriminates input
types and stringifies CompoundEntityRef before calling the API.
- Add entityPresentationSnapshot as a public export from catalog-react
- Remove duplicated getEntityTitle/getTitle helpers across 5 files
- Fix useAsync dependency array in TemplateFormPreviewer
- Update TSDoc across all presentation API surfaces to reference the
new helper
- Update entity-presentation.md docs with usage guidance and migration
table
Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
- Consolidate changesets: one for catalog-react (deprecation), one combined
for the remaining 5 plugins
- Add entity-presentation to microsite/sidebars.ts
- Update @deprecated tags to point to useEntityPresentation /
entityPresentationApiRef only, not defaultEntityPresentation
- Use entityPresentationApiRef with .promise in async loaders
(StepPrepareCreatePullRequest, TemplateFormPreviewer)
- Add optional entityPresentation?: EntityPresentationApi param to sync
column factories and use .snapshot when available
(columnFactories, EntityTable/columns, EntityOwnerPicker, CatalogTable)
- Rewrite entity-presentation.md to recommend .snapshot/.promise instead
of defaultEntityPresentation
- Update TSDoc on entityPresentationApiRef, EntityPresentationApi,
defaultEntityPresentation, useEntityPresentation, EntityDisplayName
- Re-export presentation API types from alpha entry point
- Update API reports
- Fix test mocks for entityPresentationApiRef
Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
Migrate all humanizeEntityRef and humanizeEntity usages to the Catalog
Presentation API across catalog, catalog-react, org-react,
catalog-import, scaffolder, and techdocs plugins.
- Use useEntityPresentation hook in React component contexts
(AncestryPage)
- Use defaultEntityPresentation for non-React contexts like sort
comparators, filter functions, and data mappers
- Add @deprecated tags to humanizeEntityRef and humanizeEntity
- Improve TSDoc on entityPresentationApiRef, EntityPresentationApi,
useEntityPresentation, EntityDisplayName, and
defaultEntityPresentation with guidance on which to use when
- Add Entity Presentation docs page with usage examples and migration
guide
Made-with: Cursor
Signed-off-by: Marat Dyatko <maratd@spotify.com>
Switch from real timers to fake timers so state transitions are
deterministic. The test previously relied on a ~100ms real-time window
between the 1000ms buildingTimeout and the 1100ms mock sync delay,
which was too tight for slow CI machines to observe reliably.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
Move jest from dependencies to peer dependencies, allowing users to
choose between Jest 29 and Jest 30.
The CLI now detects the Jest version at runtime and uses the
appropriate environment:
- Jest 29: Uses standard jest-environment-jsdom
- Jest 30: Uses a custom environment based on @jest/environment-jsdom-abstract
with fixes for Web API globals (fetch, streams, Error, etc.)
The cross-fetch polyfill is only injected for Jest 29, as with Jest 30+
our patched Jest environment is used. The network request blocker is made
MSW-compatible by checking if fetch was wrapped before blocking.
Jest 30 (with jsdom v27) fixes `Could not parse CSS stylesheet`
warnings/errors when testing components from @backstage/ui or other
packages using CSS `@layer` declarations.
New peer dependencies (install based on your Jest version):
- jest (required, ^29 or ^30)
- Jest 29 requires: jest-environment-jsdom
- Jest 30 requires: @jest/environment-jsdom-abstract, jsdom
Production code changes for jsdom 27 testability:
- AppIdentityProxy: extract navigateToUrl method for spying
- LiveReloadAddon: export utils.reloadPage for spying
- collect.ts: export internal.resolvePackagePath for mocking
MockFetchApi: evaluate global.fetch at call time instead of construction
time, allowing MSW to patch fetch after MockFetchApi is constructed.
Test adaptations for jsdom 27:
- Use RGB values instead of named colors in CSS assertions
- Update error format expectations (hyphenated type names, SyntaxError
instead of FetchError for JSON parse errors)
- Simplify URL error assertions for cross-version compatibility
- Fix accessible name whitespace handling for external links
- Use history.replaceState for location mocking (non-configurable)
- Use fireEvent.blur for contentEditable elements
- Move async assertions inside waitFor for race conditions
- Remove Blob.prototype.text polyfill (now native)
- Remove test case using credentials in plugin:// URLs
Test adaptations for Jest 30:
- Replace `expect.objectContaining([...])` with direct array equality
- Replace `expect.objectContaining({ length: N })` with
`expect.any(Array)` + separate `toHaveLength()` assertions
- Use child process for native Node.js module resolution in
collect.test.ts to work around Jest 30's resolver behavior
- Update snapshot headers for new Jest format
Also removes the jest-haste-map patch which is no longer needed.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* Replace underscores in techdocs titles
Signed-off-by: Luna Stadler <luc@spreadshirt.net>
* Make techdocs titles similar to component titles
The pattern for components is entity name, page/tab and then app title.
This ordering makes it easier to distinguish tabs at a glance.
Signed-off-by: Luna Stadler <luc@spreadshirt.net>
* Abbreviate nested pages in techdocs
A deeply nested page like `/really/very/deeply/nested/page`, will now
become "Really | ... | Nested | Page".
This should preserve some of the context and support docs whith deeply
nested pages.
Signed-off-by: Luna Stadler <luc@spreadshirt.net>
* Add changeset for TechDocs page title improvements
Signed-off-by: Luna Stadler <luc@spreadshirt.net>
* Display the full title based on all parts of the path
Signed-off-by: Luna Stadler <luc@spreadshirt.net>
---------
Signed-off-by: Luna Stadler <luc@spreadshirt.net>