-
Notifications
You must be signed in to change notification settings - Fork 392
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Provide reduced header layout for configurator pages (#13949)
Provides a reduced layout, which does not contain elements like search and miniCart, in order to not distract the end-user while configuring. This change is optional and needs to explicitly activated in a customer's app module as of 4.x. The internal app activates it by importing the respective layout modules in the VC and CPQ feature modules. closes #13807
- Loading branch information
1 parent
9bd802a
commit bd79df1
Showing
10 changed files
with
338 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
feature-libs/product-configurator/rulebased/root/cpq/cpq-configurator-layout.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} |
126 changes: 126 additions & 0 deletions
126
...libs/product-configurator/rulebased/root/cpq/cpq-configurator-page-layout-handler.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 classUnderTest: CpqConfiguratorPageLayoutHandler; | ||
|
||
beforeEach( | ||
waitForAsync(() => { | ||
TestBed.configureTestingModule({ | ||
providers: [ | ||
{ | ||
provide: ConfiguratorRouterExtractorService, | ||
useClass: MockRouterExtractorService, | ||
}, | ||
], | ||
}).compileComponents(); | ||
}) | ||
); | ||
beforeEach(() => { | ||
classUnderTest = TestBed.inject( | ||
CpqConfiguratorPageLayoutHandler as Type<CpqConfiguratorPageLayoutHandler> | ||
); | ||
}); | ||
|
||
it('should create service', () => { | ||
expect(classUnderTest).toBeDefined(); | ||
}); | ||
|
||
it('should not touch slots for section different than header', () => { | ||
let slots$ = cold('-a', { | ||
a: contentSlots, | ||
}); | ||
const handledSlots$ = classUnderTest.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$ = classUnderTest.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$ = classUnderTest.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$ = classUnderTest.handle( | ||
slots$, | ||
pageTemplateOther, | ||
sectionHeader | ||
); | ||
expect(handledSlots$).toBeObservable(slots$); | ||
}); | ||
}); |
42 changes: 42 additions & 0 deletions
42
feature-libs/product-configurator/rulebased/root/cpq/cpq-configurator-page-layout-handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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$; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; |
2 changes: 2 additions & 0 deletions
2
feature-libs/product-configurator/rulebased/root/variant/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; |
50 changes: 50 additions & 0 deletions
50
...uct-configurator/rulebased/root/variant/variant-configurator-interactive-layout.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} |
35 changes: 35 additions & 0 deletions
35
...roduct-configurator/rulebased/root/variant/variant-configurator-overview-layout.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters