projects/storefrontlib/cms-components/myaccount/my-interests/my-interests.component.ts
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | cx-my-interests |
| templateUrl | ./my-interests.component.html |
Properties |
Methods |
|
constructor(productInterestService: UserInterestsService, translationService: TranslationService, productService: ProductService)
|
||||||||||||
|
Parameters :
|
| Private getProduct | ||||||
getProduct(interest: ProductInterestEntryRelation)
|
||||||
|
Parameters :
Returns :
Observable<Product>
|
| Private getSortLabels |
getSortLabels()
|
|
Returns :
Observable<literal type>
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| pageChange | ||||||
pageChange(page: number)
|
||||||
|
Parameters :
Returns :
void
|
| removeInterest | ||||
removeInterest(relation)
|
||||
|
Parameters :
Returns :
void
|
| sortChange | ||||||
sortChange(sort: string)
|
||||||
|
Parameters :
Returns :
void
|
| Private DEFAULT_PAGE_SIZE |
Type : number
|
Default value : 10
|
| getInterestsloading$ |
Type : Observable<boolean>
|
| interests$ |
Type : Observable<ProductInterestSearchResultUI>
|
| isRemoveDisabled$ |
Type : Observable<boolean>
|
| pagination |
Type : PaginationModel
|
| sort |
Type : string
|
Default value : 'byNameAsc'
|
| sortLabels |
Type : Observable<literal type>
|
| Private sortMapping |
Type : object
|
Default value : {
byNameAsc: 'name:asc',
byNameDesc: 'name:desc',
}
|
| sortOptions |
Type : []
|
Default value : [
{
code: 'byNameAsc',
selected: false,
},
{
code: 'byNameDesc',
selected: false,
},
]
|
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import { combineLatest, Observable } from 'rxjs';
import {
PaginationModel,
Product,
ProductInterestEntryRelation,
ProductInterestSearchResult,
ProductScope,
ProductService,
TranslationService,
UserInterestsService,
} from '@spartacus/core';
import { map, tap } from 'rxjs/operators';
interface ProductInterestSearchResultUI extends ProductInterestSearchResult {
results?: (ProductInterestEntryRelation & {
product$?: Observable<Product>;
})[];
}
@Component({
selector: 'cx-my-interests',
templateUrl: './my-interests.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyInterestsComponent implements OnInit, OnDestroy {
private DEFAULT_PAGE_SIZE = 10;
private sortMapping = {
byNameAsc: 'name:asc',
byNameDesc: 'name:desc',
};
sort = 'byNameAsc';
sortOptions = [
{
code: 'byNameAsc',
selected: false,
},
{
code: 'byNameDesc',
selected: false,
},
];
pagination: PaginationModel;
interests$: Observable<ProductInterestSearchResultUI>;
isRemoveDisabled$: Observable<boolean>;
getInterestsloading$: Observable<boolean>;
sortLabels: Observable<{ byNameAsc: string; byNameDesc: string }>;
constructor(
private productInterestService: UserInterestsService,
private translationService: TranslationService,
private productService: ProductService
) {}
ngOnInit() {
this.interests$ = this.productInterestService
.getAndLoadProductInterests(this.DEFAULT_PAGE_SIZE)
.pipe(
tap(
(interests) =>
(this.pagination = {
currentPage: interests.pagination.page,
pageSize: interests.pagination.count,
totalPages: interests.pagination.totalPages,
totalResults: interests.pagination.totalCount,
sort: 'byNameAsc',
})
),
map((interest) => ({
...interest,
results: interest.results
? interest.results.map((result) => ({
...result,
product$: this.getProduct(result),
}))
: interest.results,
}))
);
this.getInterestsloading$ =
this.productInterestService.getProdutInterestsLoading();
this.isRemoveDisabled$ = combineLatest([
this.getInterestsloading$,
this.productInterestService.getRemoveProdutInterestLoading(),
]).pipe(map(([getLoading, removeLoading]) => getLoading || removeLoading));
this.sortLabels = this.getSortLabels();
}
private getSortLabels(): Observable<{
byNameAsc: string;
byNameDesc: string;
}> {
return combineLatest([
this.translationService.translate('myInterests.sorting.byNameAsc'),
this.translationService.translate('myInterests.sorting.byNameDesc'),
]).pipe(
map(([asc, desc]) => {
return {
byNameAsc: asc,
byNameDesc: desc,
};
})
);
}
private getProduct(
interest: ProductInterestEntryRelation
): Observable<Product> {
return this.productService.get(interest.product.code, ProductScope.DETAILS);
}
removeInterest(
relation: ProductInterestEntryRelation & {
product$?: Observable<Product>;
}
): void {
this.productInterestService.removeProdutInterest({
product: relation.product,
productInterestEntry: relation.productInterestEntry,
});
}
sortChange(sort: string): void {
this.sort = sort;
this.productInterestService.loadProductInterests(
this.DEFAULT_PAGE_SIZE,
0,
this.sortMapping[sort]
);
}
pageChange(page: number): void {
this.productInterestService.loadProductInterests(
this.DEFAULT_PAGE_SIZE,
page,
this.sortMapping[this.sort]
);
}
ngOnDestroy(): void {
this.productInterestService.clearProductInterests();
this.productInterestService.resetRemoveInterestState();
}
}
<div *ngIf="interests$ | async as interests" class="container">
<div class="cx-product-interests-title h3">
<h3>{{ 'myInterests.header' | cxTranslate }}</h3>
</div>
<div
class="cx-product-interests-body"
*ngIf="!(getInterestsloading$ | async); else loading"
>
<ng-container *ngIf="interests.pagination.totalCount > 0; else noInterest">
<div class="cx-product-interests-sort top row">
<label
class="
cx-product-interests-form-group
form-group
col-sm-12 col-md-4 col-lg-4
"
><span>{{ 'myInterests.sortBy' | cxTranslate }}</span>
<cx-sorting
[sortOptions]="sortOptions"
[sortLabels]="sortLabels | async"
(sortListEvent)="sortChange($event)"
[selectedOption]="sort"
placeholder="{{ 'myInterests.sortBy' | cxTranslate }}"
>
</cx-sorting>
</label>
<div
class="
cx-product-interests-pagination cx-product-interests-thead-mobile
"
>
<cx-pagination
[pagination]="pagination"
(viewPageEvent)="pageChange($event)"
></cx-pagination>
</div>
</div>
<table class="table cx-product-interests-table">
<thead class="cx-product-interests-thead-mobile">
<th scope="col">
{{ 'myInterests.item' | cxTranslate }}
</th>
<th scope="col"></th>
<th scope="col">
{{ 'myInterests.price' | cxTranslate }}
</th>
<th scope="col">
{{ 'myInterests.notifications' | cxTranslate }}
</th>
<th scope="col"></th>
</thead>
<tbody>
<tr
*ngFor="let interest of interests.results"
class="cx-product-interests-product-item"
>
<ng-container *ngIf="interest.product$ | async as product">
<td>
<div class="cx-product-interests-label">
<a
class="cx-product-interests-product-image-link"
tabindex="-1"
[routerLink]="
{ cxRoute: 'product', params: product } | cxUrl
"
>
<cx-media
[container]="product.images?.PRIMARY"
format="thumbnail"
></cx-media>
</a>
</div>
</td>
<td>
<div class="cx-info col-10">
<div class="cx-info-container row">
<div>
<div *ngIf="product.name" class="cx-name">
<a
class="cx-link cx-product-interests-product-code-link"
[routerLink]="
{ cxRoute: 'product', params: product } | cxUrl
"
>
{{ product.name }}
</a>
</div>
<div *ngIf="product.code" class="cx-code">
<span>{{
'myInterests.productId'
| cxTranslate: { code: product.code }
}}</span>
</div>
<ng-container
*ngFor="let baseOptions of product.baseOptions"
>
<div
*ngFor="
let variant of baseOptions.selected
?.variantOptionQualifiers
"
class="cx-property"
>
<div
class="cx-label cx-product-interests-variant-name"
>
{{ variant.name }}
</div>
<div
class="cx-value cx-product-interests-variant-value"
>
{{ variant.value }}
</div>
</div>
</ng-container>
<div
class="cx-property"
*ngIf="product.stock.stockLevelStatus === 'outOfStock'"
>
<div
class="cx-label cx-product-interests-product-stock"
>
{{ 'myInterests.outOfStock' | cxTranslate }}
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div class="cx-product-interests-product-price">
<div class="d-md-none cx-product-interests-label">
{{ 'myInterests.price' | cxTranslate }}
</div>
<span>{{ product.price.formattedValue }}</span>
</div>
</td>
<td>
<div class="cx-product-interests-subscriptions">
<div class="d-md-none cx-product-interests-label">
{{ 'myInterests.notifications' | cxTranslate }}
</div>
<div
class="cx-product-interests-notification"
*ngFor="let interestEntry of interest.productInterestEntry"
>
<span class="cx-product-interests-type">
{{
'myInterests.' + interestEntry.interestType
| cxTranslate
}}
</span>
<span class="cx-product-interests-expiration-date">
{{
'myInterests.expirationDate'
| cxTranslate
: {
expirationDate:
interestEntry.expirationDate | date
}
}}
</span>
</div>
</div>
</td>
<td>
<div class="cx-actions cx-product-interests-remove-button">
<button
type="button"
class="link cx-product-interests-remove-btn"
[disabled]="isRemoveDisabled$ | async"
(click)="removeInterest(interest)"
>
{{ 'myInterests.remove' | cxTranslate }}
</button>
</div>
</td>
</ng-container>
</tr>
</tbody>
</table>
<div class="cx-product-interests-sort bottom row">
<label
class="
cx-product-interests-form-group cx-product-interests-thead-mobile
form-group
col-sm-12 col-md-4 col-lg-4
"
><span>{{ 'myInterests.sortBy' | cxTranslate }}</span>
<cx-sorting
[sortOptions]="sortOptions"
[sortLabels]="sortLabels | async"
(sortListEvent)="sortChange($event)"
[selectedOption]="sort"
placeholder="{{ 'myInterests.sortBy' | cxTranslate }}"
>
</cx-sorting>
</label>
<div class="cx-product-interests-pagination">
<cx-pagination
[pagination]="pagination"
(viewPageEvent)="pageChange($event)"
></cx-pagination>
</div>
</div>
</ng-container>
</div>
</div>
<ng-template #noInterest>
<div class="cx-product-interests-message">
{{ 'myInterests.noInterests' | cxTranslate }}
</div>
</ng-template>
<ng-template #loading>
<div class="cx-spinner">
<cx-spinner></cx-spinner>
</div>
</ng-template>