feat(project-editor): add Navigation tab for header/flat footer nav

This commit is contained in:
sdarbinyan
2026-07-13 08:57:42 +04:00
parent 4d65386052
commit 16a134ca42
11 changed files with 232 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import { Injectable, computed, inject, signal } from '@angular/core';
import { take } from 'rxjs/operators';
import { BootstrapConfig, DEFAULT_CATALOG_CONFIG, DEFAULT_HEADER_CONFIG, DEFAULT_PRODUCT_PAGE_CONFIG, DEFAULT_USER_EXPERIENCE_CONFIG } from '../../../shared/models/config';
import { NavigationItemConfig } from '../../../shared/models/config';
import { ConfigService } from '../../../core/config/config.service';
import { ProjectEditorIoService } from '../services/project-editor-io.service';
import { ProjectEditorPreviewService } from '../services/project-editor-preview.service';
@@ -88,6 +89,79 @@ export class ProjectEditorFacade {
}));
}
addNavLink(target: 'header' | 'footer'): void {
this.updateBootstrap(current => {
const list = current.navigation[target];
if (!this.isFlatNavList(list)) {
return current;
}
const items = list as NavigationItemConfig[];
const newItem: NavigationItemConfig = {
id: `nav-${Date.now()}`,
label: 'New link',
route: '/',
order: items.length + 1,
visible: true,
};
return { ...current, navigation: { ...current.navigation, [target]: [...items, newItem] } };
});
}
removeNavLink(target: 'header' | 'footer', id: string): void {
this.updateBootstrap(current => {
const list = current.navigation[target];
if (!this.isFlatNavList(list)) {
return current;
}
return {
...current,
navigation: { ...current.navigation, [target]: (list as NavigationItemConfig[]).filter(item => item.id !== id) },
};
});
}
updateNavLink(target: 'header' | 'footer', id: string, patch: Partial<NavigationItemConfig>): void {
this.updateBootstrap(current => {
const list = current.navigation[target];
if (!this.isFlatNavList(list)) {
return current;
}
return {
...current,
navigation: {
...current.navigation,
[target]: (list as NavigationItemConfig[]).map(item => (item.id !== id ? item : { ...item, ...patch })),
},
};
});
}
reorderNavLink(target: 'header' | 'footer', id: string, direction: -1 | 1): void {
this.updateBootstrap(current => {
const list = current.navigation[target];
if (!this.isFlatNavList(list)) {
return current;
}
const items = [...(list as NavigationItemConfig[])].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
const index = items.findIndex(item => item.id === id);
const nextIndex = index + direction;
if (index < 0 || nextIndex < 0 || nextIndex >= items.length) {
return current;
}
const tmp = items[index];
items[index] = items[nextIndex];
items[nextIndex] = tmp;
return {
...current,
navigation: { ...current.navigation, [target]: items.map((item, order) => ({ ...item, order: order + 1 })) },
};
});
}
private isFlatNavList(list: NavigationItemConfig[] | { items: unknown }[]): list is NavigationItemConfig[] {
return list.length === 0 || !('items' in list[0]);
}
private normalize(config: BootstrapConfig): BootstrapConfig {
return {
...config,