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 }} + `, @@ -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