Switch filter query builders from IN (subquery) to EXISTS (correlated
subquery) patterns. This enables PostgreSQL semi-join optimizations
(stops at first match) and replaces NOT IN with NOT EXISTS (faster,
no NULL-semantics pitfalls).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Converts createBinRunner from spawnSync to async spawn, and processes
all CLI packages concurrently with a shared p-limit limiter bounded
by CPU count. Reduces wall-clock time from ~50s to ~12s.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Page components without props don't need to be exported from the
package API surface. Import directly from the component file in
the alpha entry points instead.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the accordion-based actions list with a Table component from
@backstage/ui, providing aligned columns for action name and description
with click-to-expand detail view.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the table-based actions page with an accordion layout using
@backstage/ui components. Each action is listed as an expandable
accordion, letting users browse the full list while expanding
individual actions to see their schema details inline. This avoids
the need to scroll between a table and a detail section.
The search field is kept for filtering actions by name or description.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace dual TParams/TParamKeys type parameters with a single TParamKey,
removing unnecessary complexity while preserving runtime behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
The auditor's severity log level mappings previously used a `zod/v3`
`z.record()` schema with manual fallbacks for defaults and relied on
casting into Zod error internals (`.received`, `.options`) that changed
between v3 and v4. This replaces it with a `z.object()` schema using
`.default()` so that Zod owns the default values and type inference,
and derives the valid values and received input without reaching into
undocumented error properties.
This does not migrate all `zod/v3` imports in the package, as the
remaining usages are tied to public API types (e.g. `AnyZodObject`
from `@backstage/backend-plugin-api`).
Signed-off-by: Jon Koops <jonkoops@gmail.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
Use `paginationOptions: { type: 'none' }` in EntityDataTable instead
of deriving page size from data length, which was 0 during the initial
loading render causing only one row to be displayed.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Add `CompletePaginationOptions` type extending `PaginationOptions`
with a `type` field supporting `'page'` (default) and `'none'`.
When using `mode: 'complete'` with `type: 'none'`, `useTable` skips
data slicing and produces `pagination: { type: 'none' }` in
`tableProps` directly.
Also sync `pageSize` state when `paginationOptions.pageSize` changes
dynamically, fixing cases where the initial value became stale.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
BUI link components with relative hrefs (e.g. `../other`) would
navigate to the wrong URL because React Aria's navigate callback
receives the raw href string and cannot resolve it correctly from
where it is called in Backstage's routing setup.
This adds a `resolveHref` flag to the component definition system.
When enabled, `useDefinition` calls `useHref()` to turn relative
hrefs into absolute paths before they reach the React Aria layer.
A compile-time type guard ensures components with `href` in their
props cannot omit the flag.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Refactor `SignInResolverFactoryOptions` and `createSchemaFromZod` to use
`TSchema extends ZodType` instead of `ZodSchema<Output, Def, Input>`,
avoiding "excessively deep" TypeScript inference errors when multiple
Zod copies are resolved in a project.
Signed-off-by: Jon Koops <jonkoops@gmail.com>
Add `DOM.AsyncIterable` to the shared TypeScript configuration in
`@backstage/cli`, making standard async iteration methods available on
DOM APIs like `FileSystemDirectoryHandle`. This aligns behavior with
TypeScript 6.0, where this lib is included in `DOM` by default.
With the async iterable types now available, replace the custom
`IterableDirectoryHandle` and `WritableFileHandle` types in the scaffolder
plugin with the standard `FileSystemDirectoryHandle` and
`FileSystemFileHandle` DOM types. Add type guard functions for
`FileSystemHandle` since it is not a discriminated union.
Signed-off-by: Jon Koops <jonkoops@gmail.com>
TypeScript 6.0 no longer applies bivariant checking to method-shorthand
functions that don't reference `this`. This causes the `fix` callbacks in
suggestion descriptors to fail type checking when they return `void`
instead of a valid `Fix | null` value.
- Return `null` from non-fixable suggestion `fix` handlers
- Add explicit `SuggestionReportDescriptor[]` type annotation to `suggest`
- Remove redundant `@param` JSDoc annotations now covered by the array type
Signed-off-by: Jon Koops <jonkoops@gmail.com>
Component names in the "Affected components" examples should use
PascalCase (Button, Card, Table) to match actual component names.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
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>
- Register title and icon on the new-frontend createFrontendPlugin export.
- Add NfsDefaultImportPage using @backstage/ui Header with shared grid body.
- Point the alpha PageBlueprint loader at the NFS variant.
- Depend on @backstage/ui and @remixicon/react.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
- Add title, icon, and NfsCatalogGraphPage to the new frontend plugin alpha entry
- Refactor catalog graph page with headerVariant for legacy vs Backstage UI header
- Export NfsCatalogGraphPage from the CatalogGraphPage module
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* feat(ui): add showPaginationLabel to type definitions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* feat(ui): wire showPaginationLabel through useTable and Table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* feat(ui): conditionally render pagination label based on showPaginationLabel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* chore(ui): add changeset and update API reports for showPaginationLabel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* Update .changeset/show-pagination-label.md
Co-authored-by: Johan Persson <johanopersson@gmail.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* docs(ui): document showPaginationLabel prop in docs-ui
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* fix(ui): wrap component names in backticks in changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* fix(ui): move pagination display options to inner useMemo dependency array
Move showPageSizeOptions, getLabel, and showPaginationLabel from the
outer useMemo dependency array to the inner pagination useMemo
dependency array so that changes to these options correctly trigger
a new pagination object reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* chore(ui): remove backticks from changeset
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* Revert "chore(ui): remove backticks from changeset"
This reverts commit 9b7f8bb6e83c28587219b7734676b1c062661a8a.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Johan Persson <johanopersson@gmail.com>
Restructure the FlattenedMessages conditional type to check
`TMessages[TKey] extends string` directly instead of using an
intermediate `infer TValue` pattern, which caused excessive type
instantiation depth in TypeScript 6.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Legacy plugins already render their own headers, so the additional
PageLayout header from the PageBlueprint results in duplicate headers.
Pass noHeader: true in both convertLegacyPageExtension and
collectLegacyRoutes to suppress the outer header.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the RA Tabs/TabList/Tab rendering in the Header component
with a nav-based approach that supports grouped dropdown items via
BUI Menu. Active state is consumer-controlled via a new activeTabId
prop. The indicator system follows the TabsIndicators CSS custom
property pattern for animated active/hover/focus states.
Signed-off-by: Johan Persson <johanopersson@gmail.com>