Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/gh 13807 layout changes #13949

Merged
merged 10 commits into from
Oct 5, 2021
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CmsConfig, provideDefaultConfig } from '@spartacus/core';
import { provideDefaultConfig } from '@spartacus/core';
import {
CmsPageGuard,
HamburgerMenuModule,
LayoutConfig,
PageLayoutComponent,
} from '@spartacus/storefront';
import { defaultCpqInteractiveRoutingConfig } from './default-cpq-interactive-routing-config';
Expand All @@ -30,7 +31,7 @@ import { defaultCpqInteractiveRoutingConfig } from './default-cpq-interactive-ro
],
providers: [
provideDefaultConfig(defaultCpqInteractiveRoutingConfig),
provideDefaultConfig(<CmsConfig>{
provideDefaultConfig(<LayoutConfig>{
layoutSlots: {
CpqConfigurationTemplate: {
header: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { NgModule } from '@angular/core';
import { provideDefaultConfig } from '@spartacus/core';
import { LayoutConfig, PAGE_LAYOUT_HANDLER } from '@spartacus/storefront';
import { CpqConfiguratorPageLayoutHandler } from './cpq-configurator-page-layout-handler';

/**
* Contains the layout configuration for the CPQ configurator pages. This configuration is
* optional as of version 4.2, and reduces the components that are rendered in the header section.
* It needs to be explicitly imported, otherwise the default configuration
* from VariantConfiguratorInteractiveModule is active
*/
@NgModule({
providers: [
provideDefaultConfig(<LayoutConfig>{
layoutSlots: {
CpqConfigurationTemplate: {
header: {
md: {
slots: ['SiteLogo', 'MiniCart'],
},
xs: {
slots: ['SiteLogo', 'MiniCart'],
},
},

navigation: {
lg: { slots: [] },
slots: ['CpqConfigMenu'],
},

lg: {
slots: [
'CpqConfigHeader',
'CpqConfigBanner',
'CpqConfigMenu',
'CpqConfigContent',
'CpqConfigOverviewBanner',
'CpqConfigOverviewContent',
'CpqConfigBottombar',
],
},

slots: [
'CpqConfigHeader',
'CpqConfigBanner',
'CpqConfigContent',
'CpqConfigOverviewBanner',
'CpqConfigOverviewContent',
'CpqConfigBottombar',
],
},
},
}),

{
provide: PAGE_LAYOUT_HANDLER,
useExisting: CpqConfiguratorPageLayoutHandler,
multi: true,
},
],
})
export class CpqConfiguratorLayoutModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Type } from '@angular/core';
import { TestBed, waitForAsync } from '@angular/core/testing';
import {
ConfiguratorModelUtils,
ConfiguratorRouter,
ConfiguratorRouterExtractorService,
} from '@spartacus/product-configurator/common';
import { cold } from 'jasmine-marbles';
import { Observable, of } from 'rxjs';

import { CpqConfiguratorPageLayoutHandler } from './cpq-configurator-page-layout-handler';

const standardRouterData: ConfiguratorRouter.Data = {
owner: ConfiguratorModelUtils.createInitialOwner(),
};
let routerData: ConfiguratorRouter.Data;
class MockRouterExtractorService {
extractRouterData(): Observable<ConfiguratorRouter.Data> {
return of(routerData);
}
}
const headerSlots = ['SiteLogo', 'MiniCart'];
const headerSlotsIncludingPreHeader = ['PreHeader', 'SiteLogo', 'MiniCart'];
const contentSlots = [
'CpqConfigHeader',
'CpqConfigBanner',
'CpqConfigMenu',
'CpqConfigContent',
'CpqConfigOverviewBanner',
'CpqConfigOverviewContent',
'CpqConfigBottombar',
];
const pageTemplateCpq = 'CpqConfigurationTemplate';
const pageTemplateOther = 'OtherTemplate';
const sectionHeader = 'header';
const sectionContent = 'content';

describe('CpqConfiguratorPageLayoutHandler', () => {
let serviceUnderTest: CpqConfiguratorPageLayoutHandler;
ChristophHi marked this conversation as resolved.
Show resolved Hide resolved

beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
providers: [
{
provide: ConfiguratorRouterExtractorService,
useClass: MockRouterExtractorService,
},
],
}).compileComponents();
})
);
beforeEach(() => {
serviceUnderTest = TestBed.inject(
CpqConfiguratorPageLayoutHandler as Type<CpqConfiguratorPageLayoutHandler>
);
});

it('should create service', () => {
expect(serviceUnderTest).toBeDefined();
});

it('should not touch slots for section different than header', () => {
let slots$ = cold('-a', {
a: contentSlots,
});
const handledSlots$ = serviceUnderTest.handle(
slots$,
pageTemplateCpq,
sectionContent
);
expect(handledSlots$).toBeObservable(slots$);
});

it('should change slots for header section in cpq template in case we are on configuration page', () => {
routerData = {
...standardRouterData,
pageType: ConfiguratorRouter.PageType.CONFIGURATION,
};
let slots$ = cold('-a-a', {
a: headerSlots,
});
const handledSlots$ = serviceUnderTest.handle(
slots$,
pageTemplateCpq,
sectionHeader
);
expect(handledSlots$).toBeObservable(
cold('-a-a', {
a: headerSlotsIncludingPreHeader,
})
);
});

it('should not change slots for header section in cpq template in case we are on overview page', () => {
routerData = {
...standardRouterData,
pageType: ConfiguratorRouter.PageType.OVERVIEW,
};
let slots$ = cold('-aaa', {
a: headerSlots,
});
const handledSlots$ = serviceUnderTest.handle(
slots$,
pageTemplateCpq,
sectionHeader
);
expect(handledSlots$).toBeObservable(slots$);
});

it('should not change slots for header section in other template', () => {
routerData = {
...standardRouterData,
pageType: ConfiguratorRouter.PageType.CONFIGURATION,
};
let slots$ = cold('-a-a', {
a: headerSlots,
});
const handledSlots$ = serviceUnderTest.handle(
slots$,
pageTemplateOther,
sectionHeader
);
expect(handledSlots$).toBeObservable(slots$);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Injectable } from '@angular/core';
import { PageLayoutHandler } from '@spartacus/storefront';
import {
ConfiguratorRouter,
ConfiguratorRouterExtractorService,
} from '@spartacus/product-configurator/common';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class CpqConfiguratorPageLayoutHandler implements PageLayoutHandler {
constructor(
protected configuratorRouterExtractorService: ConfiguratorRouterExtractorService
) {}
handle(
slots$: Observable<string[]>,
pageTemplate?: string,
section?: string
) {
if (pageTemplate === 'CpqConfigurationTemplate' && section === 'header') {
this.configuratorRouterExtractorService
.extractRouterData()
.pipe(take(1))
.subscribe((routerData) => {
if (
routerData.pageType === ConfiguratorRouter.PageType.CONFIGURATION
) {
slots$ = slots$.pipe(
map((slots) => {
const extendedSlots = ['PreHeader'];
extendedSlots.push(...slots);
return extendedSlots;
})
);
}
});
}

return slots$;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './cpq-configurator-interactive.module';
export * from './cpq-configurator-overview.module';
export * from './cpq-configurator-root.module';
export * from './cpq-configurator-layout.module';
export * from './interceptor/index';
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './variant-configurator-interactive.module';
export * from './variant-configurator-overview.module';
export * from './variant-configurator-interactive-layout.module';
export * from './variant-configurator-overview-layout.module';
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { NgModule } from '@angular/core';

import { provideDefaultConfig } from '@spartacus/core';
import { LayoutConfig } from '@spartacus/storefront';

/**
* Contains the layout configuration for the interactive configuration page. This configuration is
* optional as of version 4.2, and reduces the components that are rendered in the header section.
* It needs to be explicitly imported, otherwise the default configuration
* from VariantConfiguratorInteractiveModule is active
*/
@NgModule({
providers: [
provideDefaultConfig(<LayoutConfig>{
layoutSlots: {
VariantConfigurationTemplate: {
header: {
md: {
slots: ['PreHeader', 'SiteLogo', 'MiniCart'],
},
xs: {
slots: ['PreHeader', 'SiteLogo', 'MiniCart'],
},
},

navigation: {
lg: { slots: [] },
slots: ['VariantConfigMenu'],
},

lg: {
slots: [
'VariantConfigHeader',
'VariantConfigMenu',
'VariantConfigContent',
'VariantConfigBottombar',
],
},

slots: [
'VariantConfigHeader',
'VariantConfigContent',
'VariantConfigBottombar',
],
},
},
}),
],
})
export class VariantConfiguratorInteractiveLayoutModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { NgModule } from '@angular/core';
import { provideDefaultConfig } from '@spartacus/core';
import { LayoutConfig } from '@spartacus/storefront';

/**
* Contains the layout configuration for the overview configuration page. This configuration is
* optional as of version 4.2, and reduces the components that are rendered in the header section.
* It needs to be explicitly imported, otherwise the default configuration
* from VariantConfiguratorOverviewModule is active
*/
@NgModule({
providers: [
provideDefaultConfig(<LayoutConfig>{
layoutSlots: {
VariantConfigurationOverviewTemplate: {
header: {
md: {
slots: ['SiteLogo', 'MiniCart'],
},
xs: {
slots: ['SiteLogo', 'MiniCart'],
},
},
slots: [
'VariantConfigOverviewHeader',
'VariantConfigOverviewBanner',
'VariantConfigOverviewContent',
'VariantConfigOverviewBottombar',
],
},
},
}),
],
})
export class VariantConfiguratorOverviewLayoutModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ import {
PRODUCT_CONFIGURATOR_RULEBASED_FEATURE,
RulebasedConfiguratorRootModule,
} from '@spartacus/product-configurator/rulebased/root';
import { VariantConfiguratorInteractiveLayoutModule } from '@spartacus/product-configurator/rulebased/root';
import { VariantConfiguratorOverviewLayoutModule } from '@spartacus/product-configurator/rulebased/root';
import { CpqConfiguratorLayoutModule } from '@spartacus/product-configurator/rulebased/root';

@NgModule({
imports: [RulebasedConfiguratorRootModule, CpqConfiguratorRootModule],
imports: [
RulebasedConfiguratorRootModule,
VariantConfiguratorInteractiveLayoutModule,
VariantConfiguratorOverviewLayoutModule,
CpqConfiguratorRootModule,
CpqConfiguratorLayoutModule,
],
providers: [
provideConfig({
featureModules: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ import {
PRODUCT_CONFIGURATOR_RULEBASED_FEATURE,
RulebasedConfiguratorRootModule,
} from '@spartacus/product-configurator/rulebased/root';
import { VariantConfiguratorInteractiveLayoutModule } from '@spartacus/product-configurator/rulebased/root';
import { VariantConfiguratorOverviewLayoutModule } from '@spartacus/product-configurator/rulebased/root';

@NgModule({
imports: [RulebasedConfiguratorRootModule],
imports: [
RulebasedConfiguratorRootModule,
VariantConfiguratorInteractiveLayoutModule,
VariantConfiguratorOverviewLayoutModule,
],
providers: [
provideConfig({
featureModules: {
Expand Down