projects/storefrontlib/cms-components/product/stock-notification/stock-notification.component.ts
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | cx-stock-notification |
| templateUrl | ./stock-notification.component.html |
Properties |
|
Methods |
|
constructor(currentProductService: CurrentProductService, globalMessageService: GlobalMessageService, translationService: TranslationService, interestsService: UserInterestsService, modalService: ModalService, notificationPrefService: UserNotificationPreferenceService, userIdService: UserIdService)
|
||||||||||||||||||||||||
|
Parameters :
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| Private onInterestAddingError |
onInterestAddingError()
|
|
Returns :
void
|
| Private onInterestRemovingSuccess |
onInterestRemovingSuccess()
|
|
Returns :
void
|
| Private openDialog |
openDialog()
|
|
Returns :
void
|
| subscribe |
subscribe()
|
|
Returns :
void
|
| unsubscribe |
unsubscribe()
|
|
Returns :
void
|
| anonymous |
Default value : true
|
| Private enabledPrefs |
Type : NotificationPreference[]
|
Default value : []
|
| hasProductInterests$ |
Type : Observable<boolean>
|
| isRemoveInterestLoading$ |
Type : Observable<boolean>
|
| outOfStock$ |
Type : Observable<boolean>
|
| prefsEnabled$ |
Type : Observable<boolean>
|
| Private productCode |
Type : string
|
| Private subscribeSuccess$ |
Type : Observable<boolean>
|
| Private subscriptions |
Default value : new Subscription()
|
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import {
GlobalMessageService,
GlobalMessageType,
isNotNullable,
NotificationPreference,
NotificationType,
OCC_USER_ID_ANONYMOUS,
Product,
TranslationService,
UserIdService,
UserInterestsService,
UserNotificationPreferenceService,
} from '@spartacus/core';
import { combineLatest, Observable, Subscription } from 'rxjs';
import { filter, first, map, tap } from 'rxjs/operators';
import { ModalService } from '../../../shared/components/modal/modal.service';
import { CurrentProductService } from '../current-product.service';
import { StockNotificationDialogComponent } from './stock-notification-dialog/stock-notification-dialog.component';
@Component({
selector: 'cx-stock-notification',
templateUrl: './stock-notification.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StockNotificationComponent implements OnInit, OnDestroy {
hasProductInterests$: Observable<boolean>;
prefsEnabled$: Observable<boolean>;
outOfStock$: Observable<boolean>;
isRemoveInterestLoading$: Observable<boolean>;
anonymous = true;
private enabledPrefs: NotificationPreference[] = [];
private productCode: string;
private subscribeSuccess$: Observable<boolean>;
private subscriptions = new Subscription();
constructor(
private currentProductService: CurrentProductService,
private globalMessageService: GlobalMessageService,
private translationService: TranslationService,
private interestsService: UserInterestsService,
private modalService: ModalService,
private notificationPrefService: UserNotificationPreferenceService,
private userIdService: UserIdService
) {}
ngOnInit() {
this.outOfStock$ = combineLatest([
this.currentProductService.getProduct().pipe(filter(isNotNullable)),
this.userIdService.getUserId(),
]).pipe(
tap(([product, userId]) => {
this.productCode = product.code;
if (userId !== OCC_USER_ID_ANONYMOUS) {
this.anonymous = false;
this.notificationPrefService.loadPreferences();
this.interestsService.loadProductInterests(
null,
null,
null,
product.code,
NotificationType.BACK_IN_STOCK
);
}
}),
map(
([product]: [Product, String]) =>
!!product.stock && product.stock.stockLevelStatus === 'outOfStock'
)
);
this.hasProductInterests$ = this.interestsService
.getProductInterests()
.pipe(
map(
(interests) => !!interests.results && interests.results.length === 1
)
);
this.subscribeSuccess$ =
this.interestsService.getAddProductInterestSuccess();
this.isRemoveInterestLoading$ =
this.interestsService.getRemoveProdutInterestLoading();
this.prefsEnabled$ = this.notificationPrefService
.getEnabledPreferences()
.pipe(
tap((prefs) => (this.enabledPrefs = prefs)),
map((prefs) => prefs.length > 0)
);
this.subscriptions.add(
this.interestsService.getAddProductInterestError().subscribe((error) => {
if (error) {
this.onInterestAddingError();
}
})
);
this.subscriptions.add(
this.interestsService
.getRemoveProdutInterestSuccess()
.subscribe((success) => {
if (success) {
this.onInterestRemovingSuccess();
}
})
);
}
subscribe() {
this.openDialog();
this.interestsService.addProductInterest(
this.productCode,
NotificationType.BACK_IN_STOCK
);
}
unsubscribe() {
this.interestsService.removeProdutInterest(
{
product: {
code: this.productCode,
},
productInterestEntry: [
{
interestType: NotificationType.BACK_IN_STOCK,
},
],
},
true
);
}
private onInterestRemovingSuccess() {
this.subscriptions.add(
this.translationService
.translate('stockNotification.unsubscribeSuccess')
.pipe(first())
.subscribe((text) =>
this.globalMessageService.add(text, GlobalMessageType.MSG_TYPE_INFO)
)
);
this.interestsService.resetRemoveInterestState();
}
private onInterestAddingError() {
this.modalService.dismissActiveModal();
this.interestsService.resetAddInterestState();
}
private openDialog() {
const modalInstance = this.modalService.open(
StockNotificationDialogComponent,
{
centered: true,
size: 'lg',
}
).componentInstance;
modalInstance.subscribeSuccess$ = this.subscribeSuccess$;
modalInstance.enabledPrefs = this.enabledPrefs;
}
ngOnDestroy(): void {
this.subscriptions.unsubscribe();
this.interestsService.clearProductInterests();
this.notificationPrefService.clearPreferences();
}
}
<ng-container *ngIf="outOfStock$ | async">
<ng-container *ngIf="!(hasProductInterests$ | async); else stopNotify">
<ng-container *ngIf="prefsEnabled$ | async; else disableNotify">
<div class="stock-notification-notes">
<p>{{ 'stockNotification.getNotified' | cxTranslate }}</p>
</div>
<button
class="btn btn-primary btn-block btn-notify"
type="button"
(click)="subscribe()"
>
{{ 'stockNotification.notifyMe' | cxTranslate }}
</button>
</ng-container>
</ng-container>
</ng-container>
<ng-template #disableNotify>
<div class="stock-notification-notes" id="outOfStockMessage">
<p>
<ng-container *ngIf="anonymous; else loggedIn">
<a [routerLink]="{ cxRoute: 'login' } | cxUrl">
{{ 'miniLogin.signInRegister' | cxTranslate }}</a
>
{{ 'stockNotification.getNotifySuffix' | cxTranslate }}<br />
</ng-container>
<ng-template #loggedIn>
{{ 'stockNotification.getNotify' | cxTranslate }}<br />
{{ 'stockNotification.activateChannelsPrefix' | cxTranslate
}}<a [routerLink]="['/my-account/notification-preference']">{{
'stockNotification.channelsLink' | cxTranslate
}}</a
>{{ 'stockNotification.activateChannelsSuffix' | cxTranslate }}
</ng-template>
</p>
</div>
<button
class="btn btn-primary btn-block btn-notify"
type="button"
disabled="true"
aria-describedby="outOfStockMessage"
>
{{ 'stockNotification.notifyMe' | cxTranslate }}
</button>
</ng-template>
<ng-template #stopNotify>
<ng-container *ngIf="!(isRemoveInterestLoading$ | async); else loading">
<div class="stock-notification-notes">
<p>{{ 'stockNotification.notified' | cxTranslate }}</p>
</div>
<button
class="btn btn-primary btn-block btn-stop-notify"
type="button"
(click)="unsubscribe()"
>
{{ 'stockNotification.stopNotify' | cxTranslate }}
</button>
</ng-container>
</ng-template>
<ng-template #loading>
<div class="cx-dialog-body modal-body">
<div class="cx-dialog-row">
<div class="col-sm-12">
<cx-spinner></cx-spinner>
</div>
</div>
</div>
</ng-template>