diff --git a/docs/docs/guides/extending-the-admin-ui/defining-routes/index.md b/docs/docs/guides/extending-the-admin-ui/defining-routes/index.md
index 7db966387c..372cef28fe 100644
--- a/docs/docs/guides/extending-the-admin-ui/defining-routes/index.md
+++ b/docs/docs/guides/extending-the-admin-ui/defining-routes/index.md
@@ -482,6 +482,7 @@ export default [
registerRouteComponent({
component: TestComponent,
title: 'Test',
+ locationId: 'my-location-id'
// highlight-next-line
breadcrumb: 'Test',
}),
diff --git a/docs/docs/guides/extending-the-admin-ui/page-tabs/index.md b/docs/docs/guides/extending-the-admin-ui/page-tabs/index.md
index 9f73d0f85e..185c80e5df 100644
--- a/docs/docs/guides/extending-the-admin-ui/page-tabs/index.md
+++ b/docs/docs/guides/extending-the-admin-ui/page-tabs/index.md
@@ -23,6 +23,22 @@ export default [
![./ui-extensions-tabs.webp](./ui-extensions-tabs.webp)
+If you want to add page tabs to a custom admin page, specify the `locationId` property:
+
+```ts title="src/plugins/my-plugin/ui/routes.ts"
+import { registerRouteComponent } from '@vendure/admin-ui/core';
+import { TestComponent } from './components/test/test.component';
+
+export default [
+ registerRouteComponent({
+ component: TestComponent,
+ title: 'Test',
+ // highlight-next-line
+ locationId: 'my-location-id'
+ }),
+];
+```
+
:::note
Currently it is only possible to define new tabs using Angular components.
:::
diff --git a/docs/docs/reference/admin-ui-api/routes/register-route-component.md b/docs/docs/reference/admin-ui-api/routes/register-route-component.md
index a6dae886de..85d6d3b356 100644
--- a/docs/docs/reference/admin-ui-api/routes/register-route-component.md
+++ b/docs/docs/reference/admin-ui-api/routes/register-route-component.md
@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
## registerRouteComponent
-
+
Registers an Angular standalone component to be rendered in a route.
diff --git a/packages/admin-ui/src/lib/core/src/extension/components/route.component.ts b/packages/admin-ui/src/lib/core/src/extension/components/route.component.ts
index 262dffec4b..b39e187813 100644
--- a/packages/admin-ui/src/lib/core/src/extension/components/route.component.ts
+++ b/packages/admin-ui/src/lib/core/src/extension/components/route.component.ts
@@ -1,4 +1,4 @@
-import { Component, inject, InjectionToken } from '@angular/core';
+import { Component, inject, InjectionToken, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
import { combineLatest, Observable, of, switchMap } from 'rxjs';
@@ -7,6 +7,9 @@ import { BreadcrumbValue } from '../../providers/breadcrumb/breadcrumb.service';
import { SharedModule } from '../../shared/shared.module';
import { PageMetadataService } from '../providers/page-metadata.service';
import { AngularRouteComponentOptions } from '../types';
+import { HeaderTab } from '../../shared/components/page-header-tabs/page-header-tabs.component';
+import { PageService } from '../../providers/page/page.service';
+import { PageLocationId } from '../../common/component-registry-types';
export const ROUTE_COMPONENT_OPTIONS = new InjectionToken(
'ROUTE_COMPONENT_OPTIONS',
@@ -17,6 +20,8 @@ export const ROUTE_COMPONENT_OPTIONS = new InjectionToken
+ {{ description }}
+ 1" [tabs]="headerTabs">
`,
@@ -26,8 +31,14 @@ export const ROUTE_COMPONENT_OPTIONS = new InjectionToken;
+ @Input() protected locationId: PageLocationId;
+ @Input() protected description: string;
+ headerTabs: HeaderTab[] = [];
- constructor(private route: ActivatedRoute) {
+ constructor(
+ private route: ActivatedRoute,
+ private pageService: PageService,
+ ) {
const breadcrumbLabel$ = this.route.data.pipe(
switchMap(data => {
if (data.breadcrumb instanceof Observable) {
@@ -53,5 +64,14 @@ export class RouteComponent {
this.title$ = combineLatest([inject(ROUTE_COMPONENT_OPTIONS).title$, breadcrumbLabel$]).pipe(
map(([title, breadcrumbLabel]) => title ?? breadcrumbLabel),
);
+
+ this.locationId = this.route.snapshot.data.locationId;
+ this.description = this.route.snapshot.data.description;
+ this.headerTabs = this.pageService.getPageTabs(this.locationId).map(tab => ({
+ id: tab.tab,
+ label: tab.tab,
+ icon: tab.tabIcon,
+ route: tab.route ? [tab.route] : ['./'],
+ }));
}
}
diff --git a/packages/admin-ui/src/lib/core/src/extension/register-route-component.ts b/packages/admin-ui/src/lib/core/src/extension/register-route-component.ts
index 7e686dafc8..f286b24765 100644
--- a/packages/admin-ui/src/lib/core/src/extension/register-route-component.ts
+++ b/packages/admin-ui/src/lib/core/src/extension/register-route-component.ts
@@ -25,6 +25,8 @@ export type RegisterRouteComponentOptions<
> = {
component: Type | Component;
title?: string;
+ locationId?: string;
+ description?: string;
breadcrumb?: BreadcrumbValue;
path?: string;
query?: T;
@@ -81,7 +83,7 @@ export function registerRouteComponent<
Field extends keyof ResultOf,
R extends Field,
>(options: RegisterRouteComponentOptions) {
- const { query, entityKey, variables, getBreadcrumbs } = options;
+ const { query, entityKey, variables, getBreadcrumbs, locationId, description } = options;
const breadcrumbSubject$ = new BehaviorSubject(options.breadcrumb ?? '');
const titleSubject$ = new BehaviorSubject(options.title);
@@ -129,6 +131,8 @@ export function registerRouteComponent<
...(options.routeConfig ?? {}),
resolve: { ...(resolveFn ? { detail: resolveFn } : {}), ...(options.routeConfig?.resolve ?? {}) },
data: {
+ locationId,
+ description,
breadcrumb: breadcrumbSubject$,
...(options.routeConfig?.data ?? {}),
...(getBreadcrumbs && query && entityKey
diff --git a/packages/dev-server/example-plugins/ui-extensions-library/ui/providers.ts b/packages/dev-server/example-plugins/ui-extensions-library/ui/providers.ts
index 3badfd25b5..3f8d891aff 100644
--- a/packages/dev-server/example-plugins/ui-extensions-library/ui/providers.ts
+++ b/packages/dev-server/example-plugins/ui-extensions-library/ui/providers.ts
@@ -1,4 +1,5 @@
-import { addNavMenuSection } from '@vendure/admin-ui/core';
+import { PageLocationId, addNavMenuSection, registerPageTab } from '@vendure/admin-ui/core';
+import { AngularUiComponent } from './angular-components/angular-ui/angular-ui.component';
export default [
addNavMenuSection({
@@ -17,4 +18,33 @@ export default [
},
],
}),
+ //Testing page tabs on custom angular components
+ registerPageTab({
+ location: 'angular-ui' as PageLocationId,
+ tab: 'Example Tab 1',
+ route: '/extensions/ui-library/angular-ui',
+ tabIcon: 'star',
+ component: AngularUiComponent,
+ }),
+ registerPageTab({
+ location: 'angular-ui' as PageLocationId,
+ tab: 'Example Tab 2',
+ route: '/extensions/ui-library/angular-ui2',
+ tabIcon: 'star',
+ component: AngularUiComponent,
+ }),
+ registerPageTab({
+ location: 'react-ui' as PageLocationId,
+ tab: 'Example Tab 1',
+ route: '/extensions/ui-library/angular-ui',
+ tabIcon: 'star',
+ component: AngularUiComponent,
+ }),
+ registerPageTab({
+ location: 'react-ui' as PageLocationId,
+ tab: 'Example Tab 2',
+ route: '/extensions/ui-library/angular-ui2',
+ tabIcon: 'star',
+ component: AngularUiComponent,
+ }),
];
diff --git a/packages/dev-server/example-plugins/ui-extensions-library/ui/routes.ts b/packages/dev-server/example-plugins/ui-extensions-library/ui/routes.ts
index 422d7886d4..67c91a6738 100644
--- a/packages/dev-server/example-plugins/ui-extensions-library/ui/routes.ts
+++ b/packages/dev-server/example-plugins/ui-extensions-library/ui/routes.ts
@@ -9,10 +9,22 @@ export default [
path: 'react-ui',
component: ReactUi,
title: 'React UI',
+ description: "Test description",
+ locationId: "react-ui"
}),
registerRouteComponent({
path: 'angular-ui',
component: AngularUiComponent,
title: 'Angular UI',
+ locationId: "angular-ui",
+ description: "Test description 2"
}),
-];
+ //Test page tabs on angular components
+ registerRouteComponent({
+ path: 'angular-ui2',
+ component: AngularUiComponent,
+ title: 'Angular UI 2',
+ locationId: "angular-ui",
+ description: "Test description 2"
+ })
+]
\ No newline at end of file