arch(sprint1): drive widget registry from manifest
This commit is contained in:
@@ -27,7 +27,8 @@ export class PlatformRuntimeService {
|
||||
|
||||
this.configService.loadBootstrap().pipe(take(1)).subscribe({
|
||||
next: (bootstrap) => {
|
||||
this.widgetRegistryBootstrap.registerDefaults();
|
||||
this.widgetRegistryBootstrap.registerFromManifest().subscribe({
|
||||
next: () => {
|
||||
this.themeEngine.applyTheme(bootstrap.theme);
|
||||
this.brandingEngine.applyBranding(bootstrap.branding);
|
||||
this.runtimeState.markInitialized({
|
||||
@@ -37,6 +38,18 @@ export class PlatformRuntimeService {
|
||||
});
|
||||
this.initializing = false;
|
||||
},
|
||||
error: () => {
|
||||
this.themeEngine.applyTheme(bootstrap.theme);
|
||||
this.brandingEngine.applyBranding(bootstrap.branding);
|
||||
this.runtimeState.markInitialized({
|
||||
localization: bootstrap.localization,
|
||||
featureFlags: bootstrap.featureFlags,
|
||||
permissions: bootstrap.permissions
|
||||
});
|
||||
this.initializing = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
error: () => {
|
||||
this.initializing = false;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,59 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, map, of } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { HeroWidgetComponent, FooterNavigationWidgetComponent, ProductCarouselWidgetComponent } from '../ui';
|
||||
import { RegisteredWidget } from '../contracts/widget-component.contract';
|
||||
import { WidgetRegistryService } from './widget-registry.service';
|
||||
|
||||
interface WidgetManifestItem {
|
||||
type: string;
|
||||
version: string;
|
||||
componentKey: string;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
interface WidgetManifest {
|
||||
widgets: WidgetManifestItem[];
|
||||
}
|
||||
|
||||
const APPROVED_WIDGET_COMPONENTS: Record<string, RegisteredWidget['component']> = {
|
||||
'hero': HeroWidgetComponent,
|
||||
'footer-navigation': FooterNavigationWidgetComponent,
|
||||
'product-carousel': ProductCarouselWidgetComponent
|
||||
};
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class WidgetRegistryBootstrapService {
|
||||
constructor(private readonly registry: WidgetRegistryService) {}
|
||||
private readonly manifestUrl = '/assets/mock/bootstrap/widget-manifest.json';
|
||||
|
||||
registerDefaults(): void {
|
||||
this.registry.registerMany([
|
||||
{ type: 'hero', version: '1.0.0', component: HeroWidgetComponent },
|
||||
{ type: 'footer-navigation', version: '1.0.0', component: FooterNavigationWidgetComponent },
|
||||
{ type: 'product-carousel', version: '1.0.0', component: ProductCarouselWidgetComponent }
|
||||
]);
|
||||
constructor(
|
||||
private readonly registry: WidgetRegistryService,
|
||||
private readonly http: HttpClient
|
||||
) {}
|
||||
|
||||
registerFromManifest(): Observable<void> {
|
||||
return this.http.get<WidgetManifest>(this.manifestUrl).pipe(
|
||||
map((manifest) => {
|
||||
const widgets = (manifest.widgets ?? [])
|
||||
.filter((item) => item.enabled !== false)
|
||||
.map((item): RegisteredWidget | null => {
|
||||
const component = APPROVED_WIDGET_COMPONENTS[item.componentKey];
|
||||
if (!component) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: item.type,
|
||||
version: item.version,
|
||||
component
|
||||
};
|
||||
})
|
||||
.filter((item): item is RegisteredWidget => item !== null);
|
||||
|
||||
this.registry.registerMany(widgets);
|
||||
}),
|
||||
catchError(() => of(undefined))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
22
src/assets/mock/bootstrap/widget-manifest.json
Normal file
22
src/assets/mock/bootstrap/widget-manifest.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"widgets": [
|
||||
{
|
||||
"type": "hero",
|
||||
"version": "1.0.0",
|
||||
"componentKey": "hero",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"type": "footer-navigation",
|
||||
"version": "1.0.0",
|
||||
"componentKey": "footer-navigation",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"type": "product-carousel",
|
||||
"version": "1.0.0",
|
||||
"componentKey": "product-carousel",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user