Add `titleRouteRef` to `PageLayoutProps` so the plugin header title
links back to the plugin root. `PageBlueprint` resolves it from
`plugin.routes.root` with fallback to `params.routeRef`.
- PageLayout swap resolves the title link via a conditional child
component that calls `useRouteRef` only when a route ref exists
- Header actions get stable React keys via `cloneElement`
Signed-off-by: Johan Persson <johanopersson@gmail.com>
The entity page in the new frontend system already renders its own
header through the EntityHeader extension, so the default page layout
header from the PageBlueprint was redundant. This disables it by
passing noHeader: true to the page factory.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* frontend-app-api: add `apis` to specialized app result types
Added `apis: ApiHolder` to both `BootstrapSpecializedApp` and
`FinalizedSpecializedApp` types, and included the APIs in the returned
objects from `getBootstrapApp()`, `finalizeFromSessionState()`, and
`finalizeFromBootstrapError()`.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* Add .patches entry for PR #33445
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
---------
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
The unprocessed entities view is now provided as a DevTools sub-page
directly from the plugin, removing the need for manual wiring. The
standalone page is still available but disabled by default.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the defineParams + createExtensionBlueprintParams pattern with
inline param types on the factory, matching PageBlueprint, SubPageBlueprint,
and other blueprints. Update the app-visualizer usage accordingly.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
For paginated tables, always show the loading indicator since stale
data from a different page would be misleading. The loading
suppression (showing stale data during refresh) only applies to the
non-paginated table where the stale filtered results are still
meaningful.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Wrap the title + spinner in an inline-flex container for vertical
centering, and reduce the spinner to 0.8em so it doesn't affect the
overall box height.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
When filters change and a fetch is in progress but stale data is still
displayed, show a small circular spinner after the title text (e.g.
"Owned Components (5) ⟳") to indicate that updated results are being
loaded.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
The Table component replaces all data rows with a loading spinner when
isLoading is true. This caused a flash of empty table between filter
changes. Now only show the loading state when there's no data to
display yet (initial load), keeping stale results visible during
filter transitions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
The EntityListProvider exposed entities from `outputState` (synced via
useEffect) but `loading` from `useAsyncFn`. When the async function
resolved, `loading` flipped to false one render before `outputState`
updated, causing a flash of stale data between the loading indicator
and the new results.
Use `resolvedValue` directly in the context value when available,
eliminating the extra render lag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>