feat(frontend-plugin-api): add titleRouteRef to PageBlueprint

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>
This commit is contained in:
Johan Persson
2026-03-16 17:27:46 +01:00
parent 364d4fe187
commit d66a3ec9ab
11 changed files with 71 additions and 7 deletions
+3 -1
View File
@@ -43,7 +43,9 @@ test('Should render the home page', async ({ page }) => {
await enterButton.click();
// Wait for sign-in to complete
await expect(page.getByRole('link', { name: 'Catalog' })).toBeVisible();
await expect(
page.getByRole('navigation').getByRole('link', { name: 'Catalog' }),
).toBeVisible();
await page.goto('/home');
// The home page should render with the custom homepage grid
+3 -1
View File
@@ -24,7 +24,9 @@ test('the results are rendered as expected', async ({ page }) => {
await enterButton.click();
// Wait for sign-in to complete before navigating
await expect(page.getByRole('link', { name: 'Catalog' })).toBeVisible();
await expect(
page.getByRole('navigation').getByRole('link', { name: 'Catalog' }),
).toBeVisible();
// Set up route interception BEFORE navigating to the search page
await page.route(`**/api/search/query?term=*`, async route => {
+3 -1
View File
@@ -24,6 +24,8 @@ test('App should render the welcome page', async ({ page }) => {
await enterButton.click();
// Verify the sidebar navigation is visible after sign-in
await expect(page.getByRole('link', { name: 'Catalog' })).toBeVisible();
await expect(
page.getByRole('navigation').getByRole('link', { name: 'Catalog' }),
).toBeVisible();
await expect(page.getByRole('link', { name: 'APIs' })).toBeVisible();
});