diff --git a/src/app/core/facades/shopping.facade.ts b/src/app/core/facades/shopping.facade.ts index 96e1a704dd..771489bc41 100644 --- a/src/app/core/facades/shopping.facade.ts +++ b/src/app/core/facades/shopping.facade.ts @@ -75,7 +75,7 @@ export class ShoppingFacade { } navigationCategory$(categoryRef: string, limit?: number) { - this.store.dispatch(loadCategoryTree({ categoryRef })); + this.store.dispatch(loadCategoryTree({ categoryRef, limit })); return this.store.pipe(select(getNavigationCategory(categoryRef))); } diff --git a/src/app/core/store/shopping/categories/categories.actions.ts b/src/app/core/store/shopping/categories/categories.actions.ts index ae8e170d40..8596abc7a5 100644 --- a/src/app/core/store/shopping/categories/categories.actions.ts +++ b/src/app/core/store/shopping/categories/categories.actions.ts @@ -14,7 +14,7 @@ export const loadTopLevelCategoriesSuccess = createAction( export const loadCategoryTree = createAction( '[Categories Internal] Load a specific category tree', - payload<{ categoryRef: string }>() + payload<{ categoryRef: string; limit: number }>() ); export const loadCategoryTreeFail = createAction('[Categories API] Load a specific category tree fail', httpError()); diff --git a/src/app/core/store/shopping/categories/categories.effects.ts b/src/app/core/store/shopping/categories/categories.effects.ts index 919fc7eaff..8a36fb0ceb 100644 --- a/src/app/core/store/shopping/categories/categories.effects.ts +++ b/src/app/core/store/shopping/categories/categories.effects.ts @@ -13,9 +13,11 @@ import { selectRouteParam } from 'ish-core/store/core/router'; import { setBreadcrumbData } from 'ish-core/store/core/viewconf'; import { personalizationStatusDetermined } from 'ish-core/store/customer/user'; import { loadMoreProducts } from 'ish-core/store/shopping/product-listing'; +import { log } from 'ish-core/utils/dev/operators'; import { HttpStatusCodeService } from 'ish-core/utils/http-status-code/http-status-code.service'; import { mapErrorToAction, + mapToPayload, mapToPayloadProperty, useCombinedObservableOnAction, whenTruthy, @@ -121,9 +123,11 @@ export class CategoriesEffects { loadCategoryTree$ = createEffect(() => this.actions$.pipe( useCombinedObservableOnAction(this.actions$.pipe(ofType(loadCategoryTree)), personalizationStatusDetermined), - mapToPayloadProperty('categoryRef'), - switchMap(categoryRef => - this.categoryService.getCategoryTree(categoryRef).pipe( + log('nach der Action'), + mapToPayload(), + log('payload'), + switchMap(({ categoryRef, limit }) => + this.categoryService.getCategoryTree(categoryRef, limit).pipe( map(categories => loadCategoryTreeSuccess({ categories })), mapErrorToAction(loadCategoryTreeFail) ) diff --git a/src/app/shared/cms/cms.module.ts b/src/app/shared/cms/cms.module.ts index 7c33b2a77a..49304a4f28 100644 --- a/src/app/shared/cms/cms.module.ts +++ b/src/app/shared/cms/cms.module.ts @@ -6,6 +6,7 @@ import { CMSDialogComponent } from './components/cms-dialog/cms-dialog.component import { CMSFreestyleComponent } from './components/cms-freestyle/cms-freestyle.component'; import { CMSImageEnhancedComponent } from './components/cms-image-enhanced/cms-image-enhanced.component'; import { CMSImageComponent } from './components/cms-image/cms-image.component'; +import { CMSNavigationCategoryComponent } from './components/cms-navigation-category/cms-navigation-category.component'; import { CMSNavigationLinkComponent } from './components/cms-navigation-link/cms-navigation-link.component'; import { CMSNavigationPageComponent } from './components/cms-navigation-page/cms-navigation-page.component'; import { CMSProductListCategoryComponent } from './components/cms-product-list-category/cms-product-list-category.component'; @@ -139,6 +140,14 @@ import { CMS_COMPONENT } from './configurations/injection-keys'; }, multi: true, }, + { + provide: CMS_COMPONENT, + useValue: { + definitionQualifiedName: 'app_sf_base_cm:component.navigation.category.pagelet2-Component', + class: CMSNavigationCategoryComponent, + }, + multi: true, + }, ], }) export class CMSModule {} diff --git a/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.html b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.html new file mode 100644 index 0000000000..72b4b4e80b --- /dev/null +++ b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.html @@ -0,0 +1,26 @@ + +
  • + + +
    +
    +
    + + {{ category.name }} + + + + +
  • +
    diff --git a/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.spec.ts b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.spec.ts new file mode 100644 index 0000000000..105c0054c6 --- /dev/null +++ b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.spec.ts @@ -0,0 +1,31 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { instance, mock } from 'ts-mockito'; + +import { ShoppingFacade } from 'ish-core/facades/shopping.facade'; + +import { CMSNavigationCategoryComponent } from './cms-navigation-category.component'; + +describe('Cms Navigation Category Component', () => { + let component: CMSNavigationCategoryComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CMSNavigationCategoryComponent], + providers: [{ provide: ShoppingFacade, useFactory: () => instance(mock(ShoppingFacade)) }], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CMSNavigationCategoryComponent); + component = fixture.componentInstance; + element = fixture.nativeElement; + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + expect(element).toBeTruthy(); + expect(() => fixture.detectChanges()).not.toThrow(); + }); +}); diff --git a/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.ts b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.ts new file mode 100644 index 0000000000..3794f119a0 --- /dev/null +++ b/src/app/shared/cms/components/cms-navigation-category/cms-navigation-category.component.ts @@ -0,0 +1,42 @@ +import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; +import { Observable } from 'rxjs'; + +import { ShoppingFacade } from 'ish-core/facades/shopping.facade'; +import { ContentPageletView } from 'ish-core/models/content-view/content-view.model'; +import { NavigationCategory } from 'ish-core/models/navigation-category/navigation-category.model'; +import { CMSComponent } from 'ish-shared/cms/models/cms-component/cms-component.model'; + +@Component({ + selector: 'ish-cms-navigation-category', + templateUrl: './cms-navigation-category.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CMSNavigationCategoryComponent implements CMSComponent, OnChanges { + @Input() pagelet: ContentPageletView; + + category$: Observable; + + constructor(private shoppingFacade: ShoppingFacade) {} + + ngOnChanges(): void { + if (this.pagelet?.hasParam('NavigationCategory')) { + this.category$ = this.shoppingFacade.navigationCategory$( + this.pagelet.stringParam('NavigationCategory'), + this.pagelet.numberParam('SubNavigationDepth') + ); + } + } + + showSubMenu() { + return this.pagelet?.hasParam('SubNavigationDepth') && this.pagelet.numberParam('SubNavigationDepth') === 0 + ? false + : true; + } + + subMenuShow(subMenu: HTMLElement) { + subMenu.classList.add('hover'); + } + subMenuHide(subMenu: HTMLElement) { + subMenu.classList.remove('hover'); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index d04fa50ad2..ad1137fa0f 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -21,6 +21,7 @@ import { IconModule } from 'ish-core/icon.module'; import { PipesModule } from 'ish-core/pipes.module'; import { RoleToggleModule } from 'ish-core/role-toggle.module'; import { ModuleLoaderService } from 'ish-core/utils/module-loader/module-loader.service'; +import { ShellModule } from 'ish-shell/shell.module'; import { CaptchaExportsModule } from '../extensions/captcha/exports/captcha-exports.module'; import { CompareExportsModule } from '../extensions/compare/exports/compare-exports.module'; @@ -42,6 +43,7 @@ import { CMSDialogComponent } from './cms/components/cms-dialog/cms-dialog.compo import { CMSFreestyleComponent } from './cms/components/cms-freestyle/cms-freestyle.component'; import { CMSImageEnhancedComponent } from './cms/components/cms-image-enhanced/cms-image-enhanced.component'; import { CMSImageComponent } from './cms/components/cms-image/cms-image.component'; +import { CMSNavigationCategoryComponent } from './cms/components/cms-navigation-category/cms-navigation-category.component'; import { CMSNavigationLinkComponent } from './cms/components/cms-navigation-link/cms-navigation-link.component'; import { CMSNavigationPageComponent } from './cms/components/cms-navigation-page/cms-navigation-page.component'; import { CMSProductListCategoryComponent } from './cms/components/cms-product-list-category/cms-product-list-category.component'; @@ -171,6 +173,7 @@ const importExportModules = [ RecentlyExportsModule, RoleToggleModule, RouterModule, + ShellModule, StoreLocatorExportsModule, SwiperModule, TactonExportsModule, @@ -290,7 +293,7 @@ const exportedComponents = [ @NgModule({ imports: [...importExportModules], - declarations: [...declaredComponents, ...exportedComponents], + declarations: [...declaredComponents, ...exportedComponents, CMSNavigationCategoryComponent], exports: [...exportedComponents, ...importExportModules], }) export class SharedModule { diff --git a/src/app/shell/shell.module.ts b/src/app/shell/shell.module.ts index d97bdfb6c7..91a84de05f 100644 --- a/src/app/shell/shell.module.ts +++ b/src/app/shell/shell.module.ts @@ -37,7 +37,7 @@ import { LazyContentIncludeComponent } from './shared/lazy-content-include/lazy- import { LazyMiniBasketContentComponent } from './shared/lazy-mini-basket-content/lazy-mini-basket-content.component'; import { LazySearchBoxComponent } from './shared/lazy-search-box/lazy-search-box.component'; -const exportedComponents = [CookiesBannerComponent, FooterComponent, HeaderComponent]; +const exportedComponents = [CookiesBannerComponent, FooterComponent, HeaderComponent, SubCategoryNavigationComponent]; @NgModule({ imports: [ @@ -74,7 +74,6 @@ const exportedComponents = [CookiesBannerComponent, FooterComponent, HeaderCompo LazySearchBoxComponent, LoginStatusComponent, MiniBasketComponent, - SubCategoryNavigationComponent, UserInformationMobileComponent, ], exports: [...exportedComponents], diff --git a/src/assets/mock-data/cms/includes/include.header.navigation.pagelet2-Include/get.json b/src/assets/mock-data/cms/includes/include.header.navigation.pagelet2-Include/get.json index 22293bb4e0..c4b27f9edd 100644 --- a/src/assets/mock-data/cms/includes/include.header.navigation.pagelet2-Include/get.json +++ b/src/assets/mock-data/cms/includes/include.header.navigation.pagelet2-Include/get.json @@ -84,6 +84,47 @@ } }, "customAttributes": {} + }, + { + "type": "PageletRO", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.category.pagelet2-Component", + "link": { + "type": "Link", + "uri": "/inSPIRED-inTRONICS_Business-Site/rest/cms/pagelets/cmp_NAVIGATION_CATEGORY", + "title": "NAVIGATION CATEGORY", + "itemId": "cmp_NAVIGATION_CATEGORY" + }, + "displayName": "NAVIGATION CATEGORY", + "id": "cmp_20220912_152120", + "domain": "inSPIRED-inTRONICS_Business-rest", + "configurationParameters": { + "NavigationCategory": { + "value": "Computers@inSPIRED-Computers", + "type": "bc_catalog:types.pagelet2-CategoryBO", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.category.pagelet2-Component-NavigationCategory" + }, + "DisplayName": { + "value": "Category", + "type": "bc_pmc:types.pagelet2-Text", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.category.pagelet2-Component-AlternateNavigationTitle" + }, + "SubNavigationDepth": { + "value": "3", + "type": "bc_pmc:types.pagelet2-Integer", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.category.pagelet2-Component-SubNavigationDepth" + }, + "CSSClass": { + "value": "testing", + "type": "bc_pmc:types.pagelet2-Text", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.category.pagelet2-Component-CSSClass" + }, + "SubNavigationHTML": { + "value": "

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

    ", + "type": "bc_pmc:types.pagelet2-Html", + "definitionQualifiedName": "app_sf_base_cm:component.navigation.link.pagelet2-Component-SubNavigationHTML" + } + }, + "customAttributes": {} } ], "displayName": "Header - Navigation",