Commit Graph

20957 Commits

Author SHA1 Message Date
Andre Wanlin a07e6a31a4 Typos CLI - initial config and changes
Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixed test typos

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixed docs typos

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixed code comment typos

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixed remaining typos

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Added CI and Config

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixed typo, lol

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Fixes and update API reports

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Updated based on feedback

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Updated test

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Minor corrections

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Removed changesets

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Refactor to make changes non-breaking

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Clean up of new typos

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Use typoed over typo'd

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Added typoed

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Updated API Reports

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Feedback improvement

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Refinements

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Simplify based on feedback

Signed-off-by: Andre Wanlin <awanlin@spotify.com>

Reverted to handle both keys

Signed-off-by: Andre Wanlin <awanlin@spotify.com>
2026-05-19 07:38:06 -05:00
Fredrik Adelöw baeb4431e8 Merge pull request #34278 from backstage/freben/deprecate-immediate-stitching
catalog-backend: deprecate immediate mode stitching
2026-05-19 14:12:30 +02:00
Fredrik Adelöw fdf8f753bc Merge pull request #34301 from backstage/freben/incremental-ingestion-any-array
incremental-ingestion: use ANY(array) instead of IN(...) on Postgres
2026-05-19 14:06:34 +02:00
Patrik Oldsberg dcf850f1f5 Merge pull request #34108 from backstage/rugvip/forward-embedded-pg-config
cli-module-build: forward user config to embedded Postgres
2026-05-19 12:10:05 +02:00
Fredrik Adelöw 32f0dfe7f8 incremental-ingestion: use ANY(array) instead of IN(...) on Postgres
The whereIn('ref', refs) calls on ingestion_mark_entities generated
a unique prepared statement for every distinct array length, bloating
the Postgres query plan cache. On Postgres, use = ANY($1) with a
single array parameter instead. Falls back to regular whereIn on
SQLite/MySQL.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 11:55:30 +02:00
Fredrik Adelöw 8f867a2078 Merge pull request #34272 from backstage/freben/relations-target-index
catalog-backend: add missing index on relations.target_entity_ref
2026-05-19 11:43:39 +02:00
Patrik Oldsberg 9a88d85d50 Merge pull request #34089 from backstage/otel/mcp-tools-call
feat: Instrument MCP tool calls with semantically appropriate span
2026-05-19 10:53:13 +02:00
Fredrik Adelöw bc32c13de6 catalog-backend: add missing index on relations.target_entity_ref
The relations table had indexes on originating_entity_id and
source_entity_ref but none on target_entity_ref. Several query paths
join or filter on this column:

- Orphan deletion (LEFT JOIN relations ON target_entity_ref)
- Entity ancestry (INNER JOIN relations ON target_entity_ref)
- Eager pruning (JOIN relations ON target_entity_ref)

Without an index these queries seq-scan the full table (~3.5M rows,
714 MB heap). On a production replica, a single point lookup takes
~122ms via seq scan. With the index it drops to <1ms.

The index is ~141 MB based on column width (~35 bytes avg) across
~3.5M rows. On PostgreSQL it's created with CONCURRENTLY to avoid
blocking reads/writes.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 10:50:06 +02:00
MT Lewis 2bd0450cb4 feat(catalog-backend-module-msgraph): filter out disabled users by default (#34165)
* feat(catalog-backend-module-msgraph): filter out disabled users by default

The Microsoft Graph provider now always applies an `accountEnabled eq true`
base filter when fetching users. Any custom `user.filter` is combined with
the base filter using `and`, so adopters no longer need to manually add
`accountEnabled eq true` to their configuration.

Also removes the legacy mutual exclusivity check between `userFilter` and
`userGroupMemberFilter` — these serve orthogonal purposes (user-level
filtering vs group selection) and the downstream code already handles
both being set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>

* chore: mark msgraph disabled-user filtering as breaking change

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>

* docs(catalog-backend-module-msgraph): clarify automatic accountEnabled filter in docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>

---------

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 10:30:30 +02:00
Fredrik Adelöw 98f496a1ad Merge pull request #34265 from backstage/freben/stable-multi-org-order
github: stabilize entity order in multi-org provider
2026-05-19 10:23:43 +02:00
Ben Lambert 782a819e4d fix: correct changeset bump level for scaffolder-backend (#34297)
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 10:05:53 +02:00
Ben Lambert 29d398b57c fix(auth-backend): harden default allowed patterns for CIMD and DCR (#34260)
* fix(auth-backend): harden default allowed patterns for CIMD and DCR

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback for OIDC defaults

- narrow CLI client ID pattern to exact cli.json path
- add BREAKING prefix to changeset
- add IPv6 [::1] to docs examples
- add loopback redirect URI tests for IPv6 and 127.0.0.1

Signed-off-by: benjdlambert <ben@blam.sh>

* remove dead ['*'] fallback when features are disabled

The restrictive defaults are now always used regardless of the enabled
flag, since the patterns are only consulted on code paths that require
the feature to be enabled.

Signed-off-by: benjdlambert <ben@blam.sh>

* add default pattern tests and fix docs cli example

Signed-off-by: benjdlambert <ben@blam.sh>

* use URL constructor for CLI client ID

Signed-off-by: benjdlambert <ben@blam.sh>

* use string templating for cliClientId to match OidcRouter

Signed-off-by: benjdlambert <ben@blam.sh>

* fix docs: remove misleading CLI client_id URL example

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-19 09:45:31 +02:00
Fredrik Adelöw 50d97e714e Merge pull request #34258 from backstage/freben/mock-credentials-version
backend-test-utils: add version field to mock credentials
2026-05-19 09:24:41 +02:00
Fredrik Adelöw d325ee31d0 Merge pull request #34225 from backstage/fix/filter-predicate-mixed-operator-keys
fix(filter-predicates): reject operator keys mixed with other keys
2026-05-19 09:24:31 +02:00
Patrik Oldsberg 5f14aba359 Merge pull request #34285 from backstage/rugvip/cimd-metadata-size-cap
auth-backend: cap CIMD metadata response size
2026-05-18 17:53:32 +02:00
Ben Lambert 07ec25de2c fix(catalog-backend): move generateStableHash out of shared util to fix Storybook build (#34284)
* fix(catalog-backend): move generateStableHash out of shared util to fix Storybook build

The util.ts file mixed Node.js-only code (createHash from node:crypto)
with pure constants. Since InMemoryCatalogClient reaches into
buildEntitySearch via a relative import, and buildEntitySearch imports
from util.ts, the node:crypto dependency leaked into Vite's browser
bundle causing the Storybook build to fail.

Signed-off-by: benjdlambert <ben@blam.sh>

* add changeset

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-18 16:57:26 +02:00
Patrik Oldsberg 9f269d73ed auth-backend: cap CIMD metadata response size
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 16:38:46 +02:00
Fredrik Adelöw 97515d8356 Merge pull request #33788 from benjidotsh/app/fix-disabled-nav-items
fix(app): add check for disabled nav items to discovery of pages
2026-05-18 16:04:24 +02:00
Eric Peterson b70f13990b Bring tracing service more in line with upstream APIs
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
2026-05-18 15:20:09 +02:00
Fredrik Adelöw 17a9550f13 catalog-backend: deprecate immediate mode stitching
Mark immediate mode stitching as deprecated in config.d.ts, the
StitchingStrategy type, and log a warning on startup when it is
detected. This is a precursor to removing immediate mode entirely
in the next release.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-18 14:19:57 +02:00
Fredrik Adelöw aa313f099c github: stabilize entity order in multi-org provider
When using GithubMultiOrgEntityProvider with alwaysUseDefaultNamespace
and teams with identical slugs across orgs, the emitted entity order
was non-deterministic. Since the catalog's upsert path uses last-write-
wins for duplicate entity refs, this caused the winning org to flip
randomly on every refresh cycle, producing constant unnecessary
stitching and flickering entity data.

Sort the emitted entities by entity ref (primary) and location
annotation (tiebreaker) so that the same org consistently wins when
duplicate refs exist.

Fixes #34263

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-18 11:36:30 +02:00
Patrik Oldsberg 735af6c8c0 Merge pull request #34142 from backstage/session/suspicious-heron-9w2p
feat(auth-backend): validate catalog user existence on refresh token usage
2026-05-18 11:17:21 +02:00
Eric Peterson 6209065f00 Add support for async context propagation and baggage in tracing service.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
2026-05-18 10:28:09 +02:00
Eric Peterson 8916f83bee Instrument MCP tool calls with semantically appropriate span
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
2026-05-18 10:28:09 +02:00
Fredrik Adelöw ada7df7929 backend-test-utils: add version field to mock credentials
The mock credentials created by mockCredentials.none(), .user(), and
.service() were missing the internal version: 'v1' field. This caused
toInternalBackstageCredentials() to throw when used with mock
credentials in tests.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-16 17:39:31 +02:00
Fredrik Adelöw eab8f7a510 Merge pull request #34256 from backstage/cursor/ui-field-flex
fix(ui): allow fields to grow in flex layouts
2026-05-16 16:53:46 +02:00
Fredrik Adelöw e51af8cced Merge pull request #33602 from elaine-mattos/feat/allow-empty-commits 2026-05-16 10:13:59 +02:00
Fredrik Adelöw 379c3a8264 Merge pull request #34113 from its-mitesh-kumar/fix/user-settings-theme-toggle-i18n-priority
fix(user-settings): Prioritize i18n translation for built-in theme names
2026-05-15 20:31:13 +02:00
Fredrik Adelöw c667c2bf90 Merge pull request #34262 from backstage/chore/upgrade-storybook-10.4 2026-05-15 19:10:05 +02:00
Charles de Dreuille 18aa6e4d56 Merge pull request #34151 from backstage/password
Style PasswordField like TextField
2026-05-15 14:22:17 +01:00
Charles de Dreuille b67a862f8e chore: add storybook ui changeset
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
2026-05-15 10:35:24 +01:00
Charles de Dreuille 5520e07992 fix(ui): allow fields to grow in flex layouts
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
2026-05-14 15:39:41 +01:00
Fredrik Adelöw ac07705ac9 Merge pull request #34232 from backstage/cursor/header-container-alignment
fix(ui): align header sections with container
2026-05-13 21:17:40 +02:00
Fredrik Adelöw e477bdc83b Merge pull request #34229 from backstage/freben/rel
exit prerelease mode
2026-05-13 20:57:10 +02:00
Charles de Dreuille 3e0ff6c240 fix(ui): align header sections with container
Add container layout to Header sections so the title, actions, tags, metadata, and tabs align with surrounding page content.

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
2026-05-13 17:44:07 +01:00
Fredrik Adelöw d701652b4c exit prerelease mode
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-13 17:41:10 +02:00
Andre Wanlin 86c6e5abf6 Merge pull request #34027 from adobejmong/feat-add-util-to-get-octokit-client
feat: add util to get octokit client which support retries via octokit/plugin-retry
2026-05-13 10:33:03 -05:00
Fredrik Adelöw 691da8dcd0 add changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-05-13 16:02:45 +02:00
github-actions[bot] 42a2f56e61 Version Packages (next) 2026-05-12 18:28:01 +00:00
Fredrik Adelöw add5d1ace7 catalog-backend: drive paginated entity ordering from search-by-key (#34162)
* draft: restructure entities() ordering to drive from search-by-key

When a sort field is specified, build the query so the search table
filtered by that key is the driving relation, instead of left-joining
search onto final_entities and sorting after. The planner can then walk
the (key, value, entity_id) index in already-sorted order and short
circuit on LIMIT.

Measured against a production replica, the catalog UI's default
"first page of components ordered by metadata.name" query goes from
~940 ms to ~8 ms. See PR description for the full numbers.

Known caveats this draft does not yet address:
- Entities lacking the order field are excluded; the previous shape
  put them at the end with NULLS LAST. A UNION ALL pattern can
  preserve the old semantics.
- Multi-field order falls back to the OLD shape (only the first field
  is taken when present today; subsequent fields acted as
  tie-breakers). Restoring tie-breakers needs additional joins or a
  CTE.
- queryEntities (/entities/by-query) is left untouched; the same
  optimization applies but the CTE/cursor structure makes the rewrite
  more involved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>

* two-phase entities() ordering: fast path + NULLs-last fallback

When an order field is specified, run a fast path first that drives
from the search-by-key index (excluding entities without the field).
If that path doesn't produce enough rows to cover offset+limit+1, run
a fallback that picks up the no-field entities in entity_id order.
This preserves NULLs-LAST semantics while keeping the fast plan for
the common case where every entity has the order field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>

* fix: multi-field order fallback + MySQL quoting in entities()

Fall back to the original LEFT JOIN shape when multiple order fields
are specified, since tie-breaking on secondary fields inherently
requires materialization. The fast INNER-JOIN-driven path is used only
for single-field order (the typical UI case).

Fix the phase 2 NOT EXISTS clause to use knex's ?? identifier escaping
instead of hardcoded double-quotes, which broke on MySQL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>

* catalog-backend: fix phase 2 ordering and update changeset

Fix two issues raised in review:

- Phase 2 (entities lacking the sort field) now always sorts by
  entity_id ASC regardless of the primary sort direction, matching the
  original NULLS-LAST behaviour where the NULL group was always
  entity_id ASC.

- Update changeset to describe the actual two-phase behaviour (NULLS
  LAST preserved) instead of the stale description that said entities
  without the field are excluded.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* catalog-backend: apply offset when limit is undefined in runOrderedEntitiesQuery

Previously the fast-path returned the full combined array when no limit
was specified, silently ignoring any pagination offset. The old
implementation always pushed offset to SQL independently of limit.
Restore parity by slicing the combined array by the offset even when
limit is absent.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* catalog-backend: add pagination and phase-boundary tests for entities() ordering

Add two new test cases that cover the parts of runOrderedEntitiesQuery not
exercised before:

- "paginates correctly through single-field ordering": exercises limit, offset,
  and hasNextPage through the fast path (Phase 1 only) across all DB engines.

- "paginates across the Phase 1 / Phase 2 boundary": exercises the case where
  the requested page straddles entities that have the sort field (Phase 1) and
  those that do not (Phase 2), and verifies that Phase 2 entities are always
  ordered ASC by entity_id regardless of the primary sort direction.

Also fixes a double-space caught by prettier in DefaultEntitiesCatalog.ts.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* catalog-backend: treat null sort-field value the same as a missing sort field

buildEntitySearch stores value=NULL for entity fields that are explicitly
null or exceed MAX_VALUE_LENGTH. Previously, Phase 1 included those rows via
the INNER JOIN (key matches, value IS NULL), causing them to sort ahead of
entities that have no row for the key at all — changing semantics vs the old
LEFT JOIN shape where both cases landed in the same NULLS-LAST bucket.

Fix Phase 1 to require order_0.value IS NOT NULL, and fix Phase 2's NOT EXISTS
to check for no non-null value (value IS NOT NULL) so that both null-valued
and missing-key entities are collected in Phase 2 and ordered together by
entity_id ASC.

Adds a regression test covering an entity with spec.b=null alongside one with
no spec.b, asserting both appear after sorted entities regardless of direction.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 20:20:14 +02:00
Fredrik Adelöw ab690eea30 Merge pull request #34190 from backstage/freben/facets-count-optimization
fix(catalog-backend): simplify facets COUNT(DISTINCT) to COUNT(*)
2026-05-12 15:32:08 +02:00
Fredrik Adelöw c2de113030 draft(catalog-backend): drive queryEntities ordering from search-by-key
Replace the LEFT OUTER JOIN + DISTINCT in the queryEntities CTE with
an INNER JOIN that drives from the search table for the sort field's
key. Entities lacking the sort field are excluded from both the result
and the count, aligning totalItems with navigable entities.

Removes DISTINCT (prerequisite: search table dedup migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
2026-05-12 14:35:36 +02:00
Fredrik Adelöw 387ea7dd75 fix(catalog-backend): simplify facets COUNT(DISTINCT) to COUNT(*)
The UNIQUE constraint on (entity_id, key, value) from the search
indices migration guarantees each entity appears at most once per
(key, original_value) group, making DISTINCT unnecessary. Removing
it lets the database use a simpler aggregation plan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-12 14:29:01 +02:00
Fredrik Adelöw 3be2ee90b6 Merge pull request #34177 from backstage/freben/search-indices-migration
feat(catalog-backend): search table dedup, covering indices, and UNIQUE constraint
2026-05-12 14:19:53 +02:00
Ben Lambert cde3643387 fix(catalog-backend): add missing description to unregister-entity MCP action parameter (#34196)
Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-12 13:34:27 +02:00
Ben Lambert d09c21cb84 feat(scaffolder): config-driven template groups and swappable TemplateCard (#34147)
* feat(scaffolder): config-driven template groups and swappable TemplateCard

Signed-off-by: benjdlambert <ben@blam.sh>

* refactor(scaffolder): keep createGroupsWithOther internal

Signed-off-by: benjdlambert <ben@blam.sh>

* docs(scaffolder): fix sub-page extension ID in changeset

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback

Signed-off-by: benjdlambert <ben@blam.sh>

* split TemplateCard swappable contract from legacy props

Signed-off-by: benjdlambert <ben@blam.sh>

* address review feedback: dedupe tags, defensive groups copy, doc clarifications

Signed-off-by: benjdlambert <ben@blam.sh>

* regenerate api reports

Signed-off-by: benjdlambert <ben@blam.sh>

* align docs and changeset with actual default group titles

Signed-off-by: benjdlambert <ben@blam.sh>

* regen api reports after rebase

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-12 12:29:44 +02:00
Fredrik Adelöw 92dfe61e79 Merge pull request #34087 from backstage/otel/tracing-service
feat: `TracingService` to match `MetricService`
2026-05-12 12:15:30 +02:00
Erik Hughes d726bcd842 feat(ui): add DatePicker component (#34184)
* feat(ui): add DatePicker component

Add a single-date picker built on React Aria's DatePicker, mirroring the
existing DateRangePicker implementation. Includes the date field with
segmented input, calendar popover, BUI design tokens, bg consumer
pattern, and full keyboard/screen reader accessibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Erik Hughes <erikh@spotify.com>

* fix(ui): address DatePicker PR feedback

- Remove unused dataAttributes spread from DatePickerGroup
- Mark DatePickerGroupDefinition and DatePickerCalendarDefinition as
  public so CSS class name changes appear in API reports
- Add Affected components line to changeset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Erik Hughes <erikh@spotify.com>

* fix(ui): restore dataAttributes spread in DatePickerGroup

The bg: 'consumer' config on DatePickerGroupDefinition emits
data-on-bg attributes via useDefinition. Without spreading
dataAttributes onto <Group>, the CSS [data-on-bg] selectors
never match and background auto-increment doesn't work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Erik Hughes <erikh@spotify.com>

---------

Signed-off-by: Erik Hughes <erikh@spotify.com>
Co-authored-by: Erik Hughes <erikh@spotify.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 10:46:46 +02:00
Ben Lambert dbeb7aab3e feat(scaffolder): add BUI theme for scaffolder forms (#33053)
* feat(scaffolder): add BUI theme for scaffolder forms

Add a Backstage UI (BUI) form theme as an alternative to the Material
UI theme. Toggled via formProps.theme or enableBackstageUi page config.

Includes BUI widgets, templates, field extension variants, and a ported
React Aria Autocomplete component.

Signed-off-by: benjdlambert <ben@blam.sh>

* refactor(scaffolder): use BUI Combobox and CheckboxGroup for form widgets

Signed-off-by: benjdlambert <ben@blam.sh>

* chore(scaffolder): enable BUI form flag and add kitchen sink demo template

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(scaffolder): use outlined input style for BUI form widgets

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(scaffolder): address BUI form PR feedback

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(scaffolder): format CSS and regen API reports

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-12 10:35:21 +02:00
Ben Lambert 728629cf64 fix(catalog): show not-found instead of falling back to first route on unknown entity sub-paths (#34081)
* fix(catalog): show not-found instead of falling back to first route on unknown entity sub-paths

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(catalog): address PR review feedback

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(core-compat-api): update entity page conversion test for new not-found behavior

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(catalog): use NotFoundErrorPage and drop redundant route sort

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(catalog): split slash trimming into two replacements for clarity

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(catalog): comment normalizeRoutePath regex and memoize routes

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(catalog): preserve explicit trailing wildcards in route paths

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-05-12 09:57:28 +02:00