refactor: finalize bootstrap-driven layout and widget runtime
This commit is contained in:
@@ -5,22 +5,7 @@ import { TranslatePipe } from '../../i18n/translate.pipe';
|
||||
import { LogoComponent } from '../logo/logo.component';
|
||||
import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade';
|
||||
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
|
||||
import { ConfigService } from '../../core/config/config.service';
|
||||
import { StaticPageResolverService } from '../../core/config/static-page-resolver.service';
|
||||
import { BootstrapConfig, FooterNavigationGroupConfig, NavigationConfig, NavigationItemConfig, FooterNavigationItemConfig } from '../../shared/models/config';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
|
||||
interface FooterResolvedItem {
|
||||
id: string;
|
||||
label: string;
|
||||
route: string;
|
||||
}
|
||||
|
||||
interface FooterResolvedGroup {
|
||||
id: string;
|
||||
title: string;
|
||||
items: FooterResolvedItem[];
|
||||
}
|
||||
import { FooterPaymentIcon, FooterResolvedGroup, FooterResolverService } from '../../core/config/footer-resolver.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
@@ -31,19 +16,23 @@ interface FooterResolvedGroup {
|
||||
})
|
||||
export class FooterComponent {
|
||||
readonly footerGroups = signal<FooterResolvedGroup[]>([]);
|
||||
readonly paymentIcons = signal<FooterPaymentIcon[]>([]);
|
||||
readonly copyrightText = signal('');
|
||||
|
||||
constructor(
|
||||
private readonly uiRuntime: UiRuntimeFacade,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly staticPageResolver: StaticPageResolverService,
|
||||
private readonly languageService: LanguageService
|
||||
private readonly footerResolver: FooterResolverService
|
||||
) {
|
||||
this.configService.loadBootstrap().pipe(take(1)).subscribe({
|
||||
next: bootstrap => {
|
||||
this.footerGroups.set(this.resolveFooterGroups(bootstrap));
|
||||
this.footerResolver.resolveFooterModel().pipe(take(1)).subscribe({
|
||||
next: model => {
|
||||
this.footerGroups.set(model.groups);
|
||||
this.paymentIcons.set(model.paymentIcons);
|
||||
this.copyrightText.set(model.copyrightText);
|
||||
},
|
||||
error: () => {
|
||||
this.footerGroups.set([]);
|
||||
this.paymentIcons.set([]);
|
||||
this.copyrightText.set('');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -57,120 +46,4 @@ export class FooterComponent {
|
||||
get contactEmail(): string {
|
||||
return this.uiRuntime.contactEmail();
|
||||
}
|
||||
|
||||
private resolveFooterGroups(bootstrap: BootstrapConfig): FooterResolvedGroup[] {
|
||||
const footer = bootstrap.navigation?.footer ?? [];
|
||||
const lang = this.languageService.currentLanguage();
|
||||
|
||||
if (this.isGroupedFooter(footer)) {
|
||||
return footer
|
||||
.map((group, index) => this.resolveGroupFromConfig(group, bootstrap, lang, index))
|
||||
.filter((group): group is FooterResolvedGroup => group != null && group.items.length > 0);
|
||||
}
|
||||
|
||||
const items = (footer as NavigationItemConfig[])
|
||||
.map(item => this.resolveLegacyItem(item, bootstrap, lang))
|
||||
.filter((item): item is FooterResolvedItem => item != null);
|
||||
|
||||
if (!items.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [{
|
||||
id: 'footer-group-default',
|
||||
title: '',
|
||||
items
|
||||
}];
|
||||
}
|
||||
|
||||
private resolveGroupFromConfig(
|
||||
group: FooterNavigationGroupConfig,
|
||||
bootstrap: BootstrapConfig,
|
||||
lang: string,
|
||||
index: number
|
||||
): FooterResolvedGroup | null {
|
||||
const items = (group.items ?? [])
|
||||
.map(item => this.resolveGroupItem(item, bootstrap, lang))
|
||||
.filter((item): item is FooterResolvedItem => item != null);
|
||||
|
||||
if (!items.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: `footer-group-${index}`,
|
||||
title: this.staticPageResolver.resolveFooterTitle(group.groupTitle, lang),
|
||||
items
|
||||
};
|
||||
}
|
||||
|
||||
private resolveGroupItem(
|
||||
item: FooterNavigationItemConfig,
|
||||
bootstrap: BootstrapConfig,
|
||||
lang: string
|
||||
): FooterResolvedItem | null {
|
||||
if (item.visible === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (item.type === 'staticPage' && item.key) {
|
||||
const staticPage = this.staticPageResolver.resolveByKeyFromBootstrap(bootstrap, item.key, lang);
|
||||
if (!staticPage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: `static-${item.key}`,
|
||||
label: staticPage.title,
|
||||
route: staticPage.route
|
||||
};
|
||||
}
|
||||
|
||||
const label = typeof item.label === 'string'
|
||||
? item.label
|
||||
: this.staticPageResolver.resolveFooterTitle(item.label, lang);
|
||||
|
||||
if (!item.route || !label) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: `${item.type}-${label}`,
|
||||
label,
|
||||
route: item.route
|
||||
};
|
||||
}
|
||||
|
||||
private resolveLegacyItem(item: NavigationItemConfig, bootstrap: BootstrapConfig, lang: string): FooterResolvedItem | null {
|
||||
if (item.visible === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (item.type === 'staticPage' && item.key) {
|
||||
const staticPage = this.staticPageResolver.resolveByKeyFromBootstrap(bootstrap, item.key, lang);
|
||||
if (!staticPage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
label: staticPage.title,
|
||||
route: staticPage.route
|
||||
};
|
||||
}
|
||||
|
||||
if (!item.route) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
label: item.labelKey ?? item.id,
|
||||
route: item.route
|
||||
};
|
||||
}
|
||||
|
||||
private isGroupedFooter(footer: NavigationConfig['footer']): footer is FooterNavigationGroupConfig[] {
|
||||
return Array.isArray(footer) && footer.length > 0 && 'items' in footer[0];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user