-
Notifications
You must be signed in to change notification settings - Fork 394
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a new component for 'EXIT CONFIGURATION' button to enable an opportunity to leave the configuration any time by navigation to a product detail page Closes #13806
- Loading branch information
1 parent
2579348
commit 0932e90
Showing
16 changed files
with
342 additions
and
7 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
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
12 changes: 12 additions & 0 deletions
12
...uct-configurator/rulebased/components/exit-button/configurator-exit-button.component.html
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,12 @@ | ||
<button | ||
class="cx-config-exit-button" | ||
tabindex="0" | ||
(click)="exitConfiguration()" | ||
> | ||
<ng-container *ngIf="isDesktop() | async"> | ||
{{ 'configurator.button.exit' | cxTranslate }} | ||
</ng-container> | ||
<ng-container *ngIf="isMobile() | async"> | ||
{{ 'configurator.button.exitMobile' | cxTranslate }} | ||
</ng-container> | ||
</button> |
171 changes: 171 additions & 0 deletions
171
...-configurator/rulebased/components/exit-button/configurator-exit-button.component.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,171 @@ | ||
import { Type } from '@angular/core'; | ||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; | ||
import { ReactiveFormsModule } from '@angular/forms'; | ||
import { NgSelectModule } from '@ng-select/ng-select'; | ||
import { | ||
I18nTestingModule, | ||
Product, | ||
ProductService, | ||
RoutingService, | ||
} from '@spartacus/core'; | ||
import { | ||
Configurator, | ||
ConfiguratorCommonsService, | ||
ConfiguratorExitButtonComponent, | ||
} from '@spartacus/product-configurator/rulebased'; | ||
import { BreakpointService } from '@spartacus/storefront'; | ||
import { | ||
CommonConfigurator, | ||
ConfiguratorModelUtils, | ||
ConfiguratorRouter, | ||
ConfiguratorRouterExtractorService, | ||
ConfiguratorType, | ||
} from '@spartacus/product-configurator/common'; | ||
import { Observable, of } from 'rxjs'; | ||
import { ConfiguratorTestUtils } from '../../testing/configurator-test-utils'; | ||
import { CommonConfiguratorTestUtilsService } from '../../../common/testing/common-configurator-test-utils.service'; | ||
|
||
const PRODUCT_CODE = 'CONF_LAPTOP'; | ||
const PRODUCT: Product = { | ||
code: PRODUCT_CODE, | ||
}; | ||
|
||
const mockRouterData: any = { | ||
pageType: ConfiguratorRouter.PageType.CONFIGURATION, | ||
isOwnerCartEntry: false, | ||
owner: { | ||
type: CommonConfigurator.OwnerType.PRODUCT, | ||
id: PRODUCT_CODE, | ||
configuratorType: ConfiguratorType.CPQ, | ||
}, | ||
displayOnly: false, | ||
forceReload: false, | ||
resolveIssues: false, | ||
}; | ||
|
||
let configuration: Configurator.Configuration = | ||
ConfiguratorTestUtils.createConfiguration( | ||
'a', | ||
ConfiguratorModelUtils.createOwner( | ||
CommonConfigurator.OwnerType.PRODUCT, | ||
PRODUCT_CODE | ||
) | ||
); | ||
|
||
class MockConfiguratorRouterExtractorService { | ||
extractRouterData(): Observable<ConfiguratorRouter.Data> { | ||
return of(mockRouterData); | ||
} | ||
} | ||
|
||
class MockConfiguratorCommonsService { | ||
getConfiguration(): Observable<Configurator.Configuration> { | ||
return of(configuration); | ||
} | ||
} | ||
|
||
class MockRoutingService { | ||
go() {} | ||
} | ||
|
||
class MockProductService { | ||
get(): Observable<Product> { | ||
return of(PRODUCT); | ||
} | ||
} | ||
|
||
class MockBreakpointService { | ||
isUp() {} | ||
isDown() {} | ||
} | ||
|
||
describe('ConfiguratorExitButton', () => { | ||
let component: ConfiguratorExitButtonComponent; | ||
let fixture: ComponentFixture<ConfiguratorExitButtonComponent>; | ||
let htmlElem: HTMLElement; | ||
let routingService: RoutingService; | ||
let breakpointService: BreakpointService; | ||
|
||
beforeEach( | ||
waitForAsync(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [I18nTestingModule, ReactiveFormsModule, NgSelectModule], | ||
declarations: [ConfiguratorExitButtonComponent], | ||
providers: [ | ||
{ | ||
provide: ConfiguratorRouterExtractorService, | ||
useClass: MockConfiguratorRouterExtractorService, | ||
}, | ||
{ | ||
provide: ConfiguratorCommonsService, | ||
useClass: MockConfiguratorCommonsService, | ||
}, | ||
{ | ||
provide: ProductService, | ||
useClass: MockProductService, | ||
}, | ||
{ | ||
provide: RoutingService, | ||
useClass: MockRoutingService, | ||
}, | ||
{ | ||
provide: BreakpointService, | ||
useClass: MockBreakpointService, | ||
}, | ||
], | ||
}); | ||
}) | ||
); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(ConfiguratorExitButtonComponent); | ||
component = fixture.componentInstance; | ||
routingService = TestBed.inject(RoutingService as Type<RoutingService>); | ||
breakpointService = TestBed.inject( | ||
BreakpointService as Type<BreakpointService> | ||
); | ||
htmlElem = fixture.nativeElement; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create component', () => { | ||
expect(component).toBeDefined(); | ||
}); | ||
|
||
describe('exit a configuration', () => { | ||
it('should navigate to product detail page', () => { | ||
spyOn(routingService, 'go').and.callThrough(); | ||
component.exitConfiguration(); | ||
expect(routingService.go).toHaveBeenCalledWith({ | ||
cxRoute: 'product', | ||
params: PRODUCT, | ||
}); | ||
}); | ||
}); | ||
|
||
describe('rendering tests', () => { | ||
it('should render short text in mobile mode', () => { | ||
spyOn(breakpointService, 'isDown').and.returnValue(of(true)); | ||
spyOn(breakpointService, 'isUp').and.returnValue(of(false)); | ||
fixture.detectChanges(); | ||
CommonConfiguratorTestUtilsService.expectElementToContainText( | ||
expect, | ||
htmlElem, | ||
'.cx-config-exit-button', | ||
'configurator.button.exitMobile' | ||
); | ||
}); | ||
|
||
it('should render long text in desktop mode', () => { | ||
spyOn(breakpointService, 'isUp').and.returnValue(of(true)); | ||
spyOn(breakpointService, 'isDown').and.returnValue(of(false)); | ||
fixture.detectChanges(); | ||
CommonConfiguratorTestUtilsService.expectElementToContainText( | ||
expect, | ||
htmlElem, | ||
'.cx-config-exit-button', | ||
'configurator.button.exit' | ||
); | ||
}); | ||
}); | ||
}); |
70 changes: 70 additions & 0 deletions
70
...oduct-configurator/rulebased/components/exit-button/configurator-exit-button.component.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,70 @@ | ||
import { Component } from '@angular/core'; | ||
import { | ||
Product, | ||
ProductService, | ||
RoutingService, | ||
WindowRef, | ||
} from '@spartacus/core'; | ||
import { ConfiguratorRouterExtractorService } from '@spartacus/product-configurator/common'; | ||
import { BREAKPOINT, BreakpointService } from '@spartacus/storefront'; | ||
import { Observable } from 'rxjs'; | ||
import { filter, switchMap, take } from 'rxjs/operators'; | ||
import { ConfiguratorCommonsService } from '../../core/facade/configurator-commons.service'; | ||
import { Configurator } from '../../core/model/configurator.model'; | ||
|
||
@Component({ | ||
selector: 'cx-configurator-exit-button', | ||
templateUrl: './configurator-exit-button.component.html', | ||
}) | ||
export class ConfiguratorExitButtonComponent { | ||
product$: Observable<Product>; | ||
|
||
constructor( | ||
protected productService: ProductService, | ||
protected routingService: RoutingService, | ||
protected configRouterExtractorService: ConfiguratorRouterExtractorService, | ||
protected configuratorCommonsService: ConfiguratorCommonsService, | ||
protected breakpointService: BreakpointService, | ||
protected windowRef: WindowRef | ||
) {} | ||
/** | ||
* Navigates to the product detail page of the product that is being configured. | ||
*/ | ||
exitConfiguration() { | ||
this.configRouterExtractorService | ||
.extractRouterData() | ||
.pipe( | ||
switchMap((routerData) => | ||
this.configuratorCommonsService.getConfiguration(routerData.owner) | ||
), | ||
switchMap((configuration: Configurator.Configuration) => | ||
this.productService.get( | ||
configuration.productCode ? configuration.productCode : '' | ||
) | ||
), | ||
filter((product) => product !== undefined), | ||
take(1) | ||
) | ||
.subscribe((product) => | ||
this.routingService.go({ cxRoute: 'product', params: product }) | ||
); | ||
} | ||
|
||
/** | ||
* Verifies whether the current screen size equals or is larger than breakpoint `BREAKPOINT.md`. | ||
* | ||
* @returns {Observable<boolean>} - If the given breakpoint equals or is larger than`BREAKPOINT.md` returns `true`, otherwise `false`. | ||
*/ | ||
isDesktop(): Observable<boolean> { | ||
return this.breakpointService?.isUp(BREAKPOINT.md); | ||
} | ||
|
||
/** | ||
* Verifies whether the current screen size equals or is smaller than breakpoint `BREAKPOINT.sm`. | ||
* | ||
* @returns {Observable<boolean>} - If the given breakpoint equals or is smaller than`BREAKPOINT.sm` returns `true`, otherwise `false`. | ||
*/ | ||
isMobile(): Observable<boolean> { | ||
return this.breakpointService?.isDown(BREAKPOINT.sm); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
.../product-configurator/rulebased/components/exit-button/configurator-exit-button.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,26 @@ | ||
import { CommonModule } from '@angular/common'; | ||
import { NgModule } from '@angular/core'; | ||
import { | ||
CmsConfig, | ||
I18nModule, | ||
provideDefaultConfig, | ||
WindowRef, | ||
} from '@spartacus/core'; | ||
import { ConfiguratorExitButtonComponent } from './configurator-exit-button.component'; | ||
|
||
@NgModule({ | ||
imports: [CommonModule, I18nModule], | ||
providers: [ | ||
provideDefaultConfig(<CmsConfig>{ | ||
cmsComponents: { | ||
ConfiguratorExitButton: { | ||
component: ConfiguratorExitButtonComponent, | ||
}, | ||
}, | ||
}), | ||
WindowRef, | ||
], | ||
declarations: [ConfiguratorExitButtonComponent], | ||
exports: [ConfiguratorExitButtonComponent], | ||
}) | ||
export class ConfiguratorExitButtonModule {} |
2 changes: 2 additions & 0 deletions
2
feature-libs/product-configurator/rulebased/components/exit-button/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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './configurator-exit-button.component'; | ||
export * from './configurator-exit-button.module'; |
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
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
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
Oops, something went wrong.