mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged in bugfix/HIMA-1144-Product-Details-Page-Dont-Show-Previous-Product-On-Load (pull request #1260)
Bugfix/HIMA-1144 Product Details Page Dont Show Previous Product On Load
This commit is contained in:
@@ -1,8 +1,23 @@
|
||||
import { Component, OnInit, Input, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ElementRef, HostListener } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
} from '@angular/core';
|
||||
import { FeedCard } from '../../../../core/models/feed-card.model';
|
||||
import { Breadcrumb } from '../../../../core/models/breadcrumb.model';
|
||||
import { AddBreadcrumb } from '../../../../core/store/actions/breadcrumb.actions';
|
||||
import { ChangeCurrentRoute, AddProcess } from '../../../../core/store/actions/process.actions';
|
||||
import {
|
||||
AddBreadcrumb,
|
||||
PopBreadcrumbsBeforeCurrent,
|
||||
} from '../../../../core/store/actions/breadcrumb.actions';
|
||||
import {
|
||||
ChangeCurrentRoute,
|
||||
AddProcess,
|
||||
} from '../../../../core/store/actions/process.actions';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { Router } from '@angular/router';
|
||||
import { Process } from '../../../../core/models/process.model';
|
||||
@@ -14,7 +29,7 @@ import { WindowRef } from 'apps/sales/src/app/core/services/window-ref.service';
|
||||
selector: 'app-book-card',
|
||||
templateUrl: './book-card.component.html',
|
||||
styleUrls: ['./book-card.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BookCardComponent implements OnInit {
|
||||
@ViewChild('books', { read: ElementRef }) public books: ElementRef<any>;
|
||||
@@ -29,7 +44,12 @@ export class BookCardComponent implements OnInit {
|
||||
showBackContainer = false;
|
||||
offset: number;
|
||||
|
||||
constructor(private store: Store, private router: Router, private cdrf: ChangeDetectorRef, private windowRef: WindowRef) {}
|
||||
constructor(
|
||||
private store: Store,
|
||||
private router: Router,
|
||||
private cdrf: ChangeDetectorRef,
|
||||
private windowRef: WindowRef
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.isIPad = this.isIPadEnv();
|
||||
@@ -45,26 +65,38 @@ export class BookCardComponent implements OnInit {
|
||||
}
|
||||
|
||||
details(ean: string, name: string) {
|
||||
const processExist = this.store.selectSnapshot(ProcessSelectors.getProcesses).length > 0;
|
||||
const processExist =
|
||||
this.store.selectSnapshot(ProcessSelectors.getProcesses).length > 0;
|
||||
if (!processExist) {
|
||||
this.createProcess();
|
||||
}
|
||||
|
||||
const newBread: Breadcrumb = {
|
||||
name: name.substring(0, 12) + (name.length > 12 ? '...' : ''),
|
||||
path: '/product/details/' + ean,
|
||||
queryParams: { type: 'ean' }
|
||||
const dashboardBread = {
|
||||
name: 'Dashboard',
|
||||
path: '/dashboard',
|
||||
};
|
||||
|
||||
const path = '/product/details/' + ean;
|
||||
const queryParams = { type: 'ean' };
|
||||
const newBread: Breadcrumb = {
|
||||
name: name.substring(0, 12) + (name.length > 12 ? '...' : ''),
|
||||
path,
|
||||
queryParams,
|
||||
};
|
||||
|
||||
this.store.dispatch(new PopBreadcrumbsBeforeCurrent('product'));
|
||||
this.store.dispatch(new AddBreadcrumb(dashboardBread, 'product'));
|
||||
this.store.dispatch(new AddBreadcrumb(newBread, 'product'));
|
||||
this.store.dispatch(new ChangeCurrentRoute('/product/details/' + ean, false, { type: 'ean' }));
|
||||
this.router.navigate(['/product/details/' + ean], { queryParams: { type: 'ean' } });
|
||||
this.store.dispatch(new ChangeCurrentRoute(path, false, queryParams));
|
||||
this.router.navigate([path], {
|
||||
queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
createProcess() {
|
||||
const newProcess = <Process>{
|
||||
id: 1,
|
||||
name: 'Vorgang 1'
|
||||
name: 'Vorgang 1',
|
||||
};
|
||||
this.store.dispatch(new AddProcess(newProcess));
|
||||
}
|
||||
@@ -79,7 +111,11 @@ export class BookCardComponent implements OnInit {
|
||||
|
||||
hideFowardIcon(event) {
|
||||
const e = event.toElement || event.relatedTarget;
|
||||
if (e && e.classList && (e.classList[0] === 'icon' || e.classList[0] === 'ng-star-inserted')) {
|
||||
if (
|
||||
e &&
|
||||
e.classList &&
|
||||
(e.classList[0] === 'icon' || e.classList[0] === 'ng-star-inserted')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.showForward = false;
|
||||
@@ -91,7 +127,11 @@ export class BookCardComponent implements OnInit {
|
||||
|
||||
hideBackIcon(event) {
|
||||
const e = event.toElement || event.relatedTarget;
|
||||
if (e && e.classList && (e.classList[0] === 'icon' || e.classList[0] === 'ng-star-inserted')) {
|
||||
if (
|
||||
e &&
|
||||
e.classList &&
|
||||
(e.classList[0] === 'icon' || e.classList[0] === 'ng-star-inserted')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.showBack = false;
|
||||
@@ -100,13 +140,19 @@ export class BookCardComponent implements OnInit {
|
||||
scrollForward(event) {
|
||||
if (event) {
|
||||
event.stopPropagation();
|
||||
const newScrollLeftPosition = this.books.nativeElement.scrollLeft + 102 * 3;
|
||||
const newScrollLeftPosition =
|
||||
this.books.nativeElement.scrollLeft + 102 * 3;
|
||||
const scrollLeft =
|
||||
newScrollLeftPosition + this.offset * 2 > this.books.nativeElement.scrollWidth
|
||||
newScrollLeftPosition + this.offset * 2 >
|
||||
this.books.nativeElement.scrollWidth
|
||||
? this.books.nativeElement.scrollWidth
|
||||
: newScrollLeftPosition;
|
||||
this.books.nativeElement.scrollTo({ left: scrollLeft, behavior: 'smooth' });
|
||||
this.showForwarContainer = scrollLeft + this.offset * 2 < this.books.nativeElement.scrollWidth;
|
||||
this.books.nativeElement.scrollTo({
|
||||
left: scrollLeft,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
this.showForwarContainer =
|
||||
scrollLeft + this.offset * 2 < this.books.nativeElement.scrollWidth;
|
||||
this.showBackContainer = true;
|
||||
this.showBack = false;
|
||||
}
|
||||
@@ -115,10 +161,18 @@ export class BookCardComponent implements OnInit {
|
||||
scrollBack(event) {
|
||||
if (event) {
|
||||
event.stopPropagation();
|
||||
const newScrollLeftPosition = this.books.nativeElement.scrollLeft - 102 * 3;
|
||||
const scrollLeft = newScrollLeftPosition + this.offset * 2 < 0 ? this.books.nativeElement.scrollWidth : newScrollLeftPosition;
|
||||
this.books.nativeElement.scrollTo({ left: scrollLeft, behavior: 'smooth' });
|
||||
this.showBackContainer = this.books.nativeElement.scrollLeft - this.offset > 0;
|
||||
const newScrollLeftPosition =
|
||||
this.books.nativeElement.scrollLeft - 102 * 3;
|
||||
const scrollLeft =
|
||||
newScrollLeftPosition + this.offset * 2 < 0
|
||||
? this.books.nativeElement.scrollWidth
|
||||
: newScrollLeftPosition;
|
||||
this.books.nativeElement.scrollTo({
|
||||
left: scrollLeft,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
this.showBackContainer =
|
||||
this.books.nativeElement.scrollLeft - this.offset > 0;
|
||||
this.showForwarContainer = true;
|
||||
this.showForward = false;
|
||||
}
|
||||
@@ -136,7 +190,9 @@ export class BookCardComponent implements OnInit {
|
||||
this.showBackContainer = false;
|
||||
}
|
||||
this.showBack = false;
|
||||
this.showForwarContainer = this.books.nativeElement.scrollLeft + this.offset * 2 < this.books.nativeElement.scrollWidth;
|
||||
this.showForwarContainer =
|
||||
this.books.nativeElement.scrollLeft + this.offset * 2 <
|
||||
this.books.nativeElement.scrollWidth;
|
||||
this.showForward = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,42 @@
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectorRef, ElementRef, HostListener } from '@angular/core';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
OnDestroy,
|
||||
ChangeDetectorRef,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
} from '@angular/core';
|
||||
import { ProductService } from '../../../../core/services/product.service';
|
||||
import { ItemDTO, ReviewDTO } from 'swagger';
|
||||
import { Observable, of, Subject, forkJoin } from 'rxjs';
|
||||
import { Observable, of, Subject, forkJoin, combineLatest } from 'rxjs';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { PhotoGalleryComponent, ButtonComponent } from '@libs/ui';
|
||||
import { map, delay, takeUntil, switchMap, catchError, tap, filter, take } from 'rxjs/operators';
|
||||
import {
|
||||
map,
|
||||
delay,
|
||||
takeUntil,
|
||||
switchMap,
|
||||
catchError,
|
||||
tap,
|
||||
filter,
|
||||
take,
|
||||
} from 'rxjs/operators';
|
||||
import { ProductReview } from '../../../../core/models/product-review.model';
|
||||
import { ProductDisplay } from '../../../../core/models/product-display.model';
|
||||
import { AddBreadcrumb, UpdateCurrentBreadcrumbName } from '../../../../core/store/actions/breadcrumb.actions';
|
||||
import {
|
||||
AddBreadcrumb,
|
||||
UpdateCurrentBreadcrumbName,
|
||||
} from '../../../../core/store/actions/breadcrumb.actions';
|
||||
import { ProductCheckoutComponent } from '../../components/product-checkout/product-checkout.component';
|
||||
import { ProductReviewComponent } from '../../components/product-review/product-review.component';
|
||||
import { OtherFormats } from '../../../../core/models/other-formats.model';
|
||||
import { shrinkTitleAnimation, shrinkSecondaryAnimation, shrinkMainCard } from '../product-details/shrink.animation';
|
||||
import {
|
||||
shrinkTitleAnimation,
|
||||
shrinkSecondaryAnimation,
|
||||
shrinkMainCard,
|
||||
} from '../product-details/shrink.animation';
|
||||
import { ProductAvailabilityService } from '../../../../core/services/product-availability.service';
|
||||
import { AvailabilityDTO } from 'swagger/lib/availability/models/availability-dto';
|
||||
import { BranchSelectors } from '../../../../core/store/selectors/branch.selector';
|
||||
@@ -40,10 +64,11 @@ import { allowedAvailabilityStatusCodes } from 'apps/sales/src/app/core/utils/pr
|
||||
selector: 'app-product-details',
|
||||
templateUrl: './product-details.component.html',
|
||||
styleUrls: ['./product-details.component.scss'],
|
||||
animations: [shrinkTitleAnimation, shrinkSecondaryAnimation, shrinkMainCard]
|
||||
animations: [shrinkTitleAnimation, shrinkSecondaryAnimation, shrinkMainCard],
|
||||
})
|
||||
export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('productDetailContainer', { read: ElementRef }) private productDetailContainer: ElementRef<any>;
|
||||
@ViewChild('productDetailContainer', { read: ElementRef })
|
||||
private productDetailContainer: ElementRef<any>;
|
||||
@ViewChild('checkout') checkoutDialog: ProductCheckoutComponent;
|
||||
@ViewChild('photoGallery') photoGallery: PhotoGalleryComponent;
|
||||
@ViewChild('productReview') productReview: ProductReviewComponent;
|
||||
@@ -53,7 +78,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('addtocart') addToCartBtn: ButtonComponent;
|
||||
@ViewChild('recommendations') recommendations: RecommendationsComponent;
|
||||
@ViewChild('otherformats') elOtherformats: ProductOtherFormatsComponent;
|
||||
@ViewChild('panformatsel', { read: ElementRef }) public formats: ElementRef<any>;
|
||||
@ViewChild('panformatsel', { read: ElementRef }) public formats: ElementRef<
|
||||
any
|
||||
>;
|
||||
expanded = true;
|
||||
id: number;
|
||||
item: ItemDTO;
|
||||
@@ -95,7 +122,8 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
fullyLoaded = false;
|
||||
|
||||
private errorMessage = 'Verfügbarkeitsabfrage konnte nicht durchgeführt werden.';
|
||||
private errorMessage =
|
||||
'Verfügbarkeitsabfrage konnte nicht durchgeführt werden.';
|
||||
|
||||
get storeError$() {
|
||||
return of(this.storeError);
|
||||
@@ -132,7 +160,10 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get takeNowAvailable() {
|
||||
if (this.availability.filter(t => t.type === CheckoutType.takeNow).length > 0) {
|
||||
if (
|
||||
this.availability.filter((t) => t.type === CheckoutType.takeNow).length >
|
||||
0
|
||||
) {
|
||||
return of(true);
|
||||
}
|
||||
return of(false);
|
||||
@@ -141,9 +172,10 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
get storeAvailable() {
|
||||
if (
|
||||
this.availability.filter(
|
||||
t =>
|
||||
(t) =>
|
||||
t.type === CheckoutType.store &&
|
||||
(allowedAvailabilityStatusCodes(t.status) || (t.av && t.av.ssc === '830' && t.av.supplier === 'G'))
|
||||
(allowedAvailabilityStatusCodes(t.status) ||
|
||||
(t.av && t.av.ssc === '830' && t.av.supplier === 'G'))
|
||||
).length > 0
|
||||
) {
|
||||
return of(true);
|
||||
@@ -152,14 +184,23 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get shippingAvailable() {
|
||||
if (this.availability.filter(t => t.type === CheckoutType.delivery && allowedAvailabilityStatusCodes(t.status)).length > 0) {
|
||||
if (
|
||||
this.availability.filter(
|
||||
(t) =>
|
||||
t.type === CheckoutType.delivery &&
|
||||
allowedAvailabilityStatusCodes(t.status)
|
||||
).length > 0
|
||||
) {
|
||||
return of(true);
|
||||
}
|
||||
return of(false);
|
||||
}
|
||||
|
||||
get downloadAvailable() {
|
||||
if (this.availability.filter(t => t.type === CheckoutType.donwload).length > 0) {
|
||||
if (
|
||||
this.availability.filter((t) => t.type === CheckoutType.donwload).length >
|
||||
0
|
||||
) {
|
||||
return of(true);
|
||||
}
|
||||
return of(false);
|
||||
@@ -167,8 +208,11 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
get showAvLoading() {
|
||||
if (
|
||||
((!this.storeAvLoaded || !this.shippingAvLoaded) && this.product.formatIcon !== 'EB' && this.product.formatIcon !== 'DL') ||
|
||||
(!this.downloadLoaded && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL'))
|
||||
((!this.storeAvLoaded || !this.shippingAvLoaded) &&
|
||||
this.product.formatIcon !== 'EB' &&
|
||||
this.product.formatIcon !== 'DL') ||
|
||||
(!this.downloadLoaded &&
|
||||
(this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL'))
|
||||
) {
|
||||
return of(true);
|
||||
}
|
||||
@@ -176,7 +220,10 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get isDownload() {
|
||||
if (this.product && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL')) {
|
||||
if (
|
||||
this.product &&
|
||||
(this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL')
|
||||
) {
|
||||
return of(true);
|
||||
}
|
||||
return of(false);
|
||||
@@ -184,11 +231,21 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
get productAvailable() {
|
||||
const availabilityLoaded =
|
||||
this.availability.length > 0 && ((this.storeAvLoaded === true && this.shippingAvLoaded === true) || this.downloadLoaded === true);
|
||||
const hasTakeNow = this.availability.find(t => t.type === CheckoutType.takeNow) !== undefined;
|
||||
const hasStore = this.availability.find(t => t.type === CheckoutType.store) !== undefined;
|
||||
const hasShipping = this.availability.find(t => t.type === CheckoutType.delivery) !== undefined;
|
||||
const hasDownload = this.availability.find(t => t.type === CheckoutType.donwload) !== undefined;
|
||||
this.availability.length > 0 &&
|
||||
((this.storeAvLoaded === true && this.shippingAvLoaded === true) ||
|
||||
this.downloadLoaded === true);
|
||||
const hasTakeNow =
|
||||
this.availability.find((t) => t.type === CheckoutType.takeNow) !==
|
||||
undefined;
|
||||
const hasStore =
|
||||
this.availability.find((t) => t.type === CheckoutType.store) !==
|
||||
undefined;
|
||||
const hasShipping =
|
||||
this.availability.find((t) => t.type === CheckoutType.delivery) !==
|
||||
undefined;
|
||||
const hasDownload =
|
||||
this.availability.find((t) => t.type === CheckoutType.donwload) !==
|
||||
undefined;
|
||||
const canBeBought = hasTakeNow || hasStore || hasShipping || hasDownload;
|
||||
if (canBeBought && availabilityLoaded) {
|
||||
return true;
|
||||
@@ -197,24 +254,32 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get isGiftable() {
|
||||
return this.features.find(fet => fet.key === 'bonus');
|
||||
return this.features.find((fet) => fet.key === 'bonus');
|
||||
}
|
||||
|
||||
get isRecommendation() {
|
||||
return this.features.find(fet => fet.key === 'recommendation');
|
||||
return this.features.find((fet) => fet.key === 'recommendation');
|
||||
}
|
||||
|
||||
get isSubscription() {
|
||||
return this.features.find(fet => fet.key === 'subscription');
|
||||
return this.features.find((fet) => fet.key === 'subscription');
|
||||
}
|
||||
|
||||
get inTheCartButtonDisabled() {
|
||||
if (this.product && !this.product.price) {
|
||||
return true;
|
||||
}
|
||||
const isDownload = this.product && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL');
|
||||
const isDownloadAlreadyAdded = isDownload && this.downloadIds.includes(this.item.id);
|
||||
if (this.cartHasItems && this.cartHasDownload && isDownload && isDownloadAlreadyAdded) {
|
||||
const isDownload =
|
||||
this.product &&
|
||||
(this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL');
|
||||
const isDownloadAlreadyAdded =
|
||||
isDownload && this.downloadIds.includes(this.item.id);
|
||||
if (
|
||||
this.cartHasItems &&
|
||||
this.cartHasDownload &&
|
||||
isDownload &&
|
||||
isDownloadAlreadyAdded
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (isDownload && this.downloadError) {
|
||||
@@ -223,8 +288,12 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
if (
|
||||
isDownload &&
|
||||
this.downloadLoaded &&
|
||||
this.availability.filter(t => t.type === CheckoutType.donwload && t.quantity > 0 && allowedAvailabilityStatusCodes(t.status)).length <
|
||||
1
|
||||
this.availability.filter(
|
||||
(t) =>
|
||||
t.type === CheckoutType.donwload &&
|
||||
t.quantity > 0 &&
|
||||
allowedAvailabilityStatusCodes(t.status)
|
||||
).length < 1
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -233,8 +302,12 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
!isDownload &&
|
||||
this.storeAvLoaded &&
|
||||
this.shippingAvLoaded &&
|
||||
this.availability.filter(t => t.type !== CheckoutType.donwload && t.quantity > 0 && allowedAvailabilityStatusCodes(t.status)).length <
|
||||
1
|
||||
this.availability.filter(
|
||||
(t) =>
|
||||
t.type !== CheckoutType.donwload &&
|
||||
t.quantity > 0 &&
|
||||
allowedAvailabilityStatusCodes(t.status)
|
||||
).length < 1
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -276,7 +349,7 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
private detailInitialize() {
|
||||
this.route.queryParams
|
||||
.pipe(
|
||||
map(params => {
|
||||
map((params) => {
|
||||
if (params['type'] && params['type'] === 'ean') {
|
||||
this.isByEan = true;
|
||||
return true;
|
||||
@@ -284,14 +357,14 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
return false;
|
||||
}),
|
||||
switchMap(ean => {
|
||||
switchMap((ean) => {
|
||||
return this.route.params.pipe(
|
||||
map(params => {
|
||||
map((params) => {
|
||||
return { id: params['id'], ean: ean };
|
||||
})
|
||||
);
|
||||
}),
|
||||
switchMap(data => {
|
||||
switchMap((data) => {
|
||||
this.storeAvLoaded = false;
|
||||
this.shippingAvLoaded = false;
|
||||
this.stockInfoLoaded = false;
|
||||
@@ -322,14 +395,22 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
this.showFeatures = true;
|
||||
}
|
||||
|
||||
if (!this.product.fullDescription || (this.product.fullDescription && this.product.fullDescription.length < 1)) {
|
||||
if (
|
||||
!this.product.fullDescription ||
|
||||
(this.product.fullDescription &&
|
||||
this.product.fullDescription.length < 1)
|
||||
) {
|
||||
this.showNoDescription = true;
|
||||
}
|
||||
|
||||
this.processReviewData(item.reviews);
|
||||
this.loadBranches();
|
||||
|
||||
if (this.product && this.product.formatIcon !== 'EB' && this.product.formatIcon !== 'DL') {
|
||||
if (
|
||||
this.product &&
|
||||
this.product.formatIcon !== 'EB' &&
|
||||
this.product.formatIcon !== 'DL'
|
||||
) {
|
||||
setTimeout(() => {
|
||||
this.loadAvailability(item, item.product.ean);
|
||||
});
|
||||
@@ -348,20 +429,23 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private loadTempData() {
|
||||
this.store
|
||||
.select(SharedSelectors.getProcessSelectedItem)
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
filter(item => !isNullOrUndefined(item))
|
||||
)
|
||||
.subscribe((item: ItemDTO) => {
|
||||
combineLatest(
|
||||
this.store.select(SharedSelectors.getProcessSelectedItem),
|
||||
this.route.params,
|
||||
this.route.queryParams
|
||||
)
|
||||
.pipe(takeUntil(this.destroy$), this.filterTempData)
|
||||
.subscribe((item) => {
|
||||
if (this.productDetailContainer) {
|
||||
this.productDetailContainer.nativeElement.scrollTop = 0;
|
||||
}
|
||||
this.item = item;
|
||||
this.product = this.productDetailMapper(item);
|
||||
this.product.fullDescription =
|
||||
this.product.fullDescription && this.product.fullDescription.length > 0 ? this.product.fullDescription : ' ';
|
||||
this.product.fullDescription &&
|
||||
this.product.fullDescription.length > 0
|
||||
? this.product.fullDescription
|
||||
: ' ';
|
||||
|
||||
if (this.product.features.length > 0) {
|
||||
this.features = this.product.features;
|
||||
@@ -370,22 +454,41 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private filterTempData = (
|
||||
obs: Observable<[ItemDTO, Params, Params]>
|
||||
): Observable<ItemDTO> => {
|
||||
return obs.pipe(
|
||||
filter(([item, params, queryParams]) => {
|
||||
if (isNullOrUndefined(item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryParams['type'] && queryParams['type'] === 'ean') {
|
||||
this.isByEan = true;
|
||||
return item.product.ean === params.id;
|
||||
}
|
||||
return item.id === Number(params.id);
|
||||
}),
|
||||
map(([item, _, __]: [ItemDTO, Params, Params]) => item)
|
||||
);
|
||||
};
|
||||
|
||||
private loadCartState() {
|
||||
this.store
|
||||
.select(SharedSelectors.cartHasItems)
|
||||
.pipe(
|
||||
filter(data => !isNullOrUndefined(data) && data === true),
|
||||
filter((data) => !isNullOrUndefined(data) && data === true),
|
||||
take(1)
|
||||
)
|
||||
.subscribe(hasItems => (this.cartHasItems = hasItems));
|
||||
.subscribe((hasItems) => (this.cartHasItems = hasItems));
|
||||
|
||||
this.store
|
||||
.select(SharedSelectors.cartHasDowloads)
|
||||
.pipe(
|
||||
filter(data => !isNullOrUndefined(data) && data.length > 0),
|
||||
filter((data) => !isNullOrUndefined(data) && data.length > 0),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(donwloadArticles => {
|
||||
.subscribe((donwloadArticles) => {
|
||||
this.cartHasDownload = donwloadArticles && donwloadArticles.length > 0;
|
||||
this.downloadIds = donwloadArticles;
|
||||
});
|
||||
@@ -411,21 +514,21 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
review.length === 0
|
||||
? 0
|
||||
: review
|
||||
.map(t => t.rating)
|
||||
.map((t) => t.rating)
|
||||
.reduce((total, num) => {
|
||||
return total + num;
|
||||
}) / review.length,
|
||||
employeeReviews: review.length,
|
||||
reviews: review.map(t => {
|
||||
reviews: review.map((t) => {
|
||||
return <Review>{
|
||||
id: +t.id,
|
||||
author: t.author,
|
||||
content: t.text,
|
||||
title: t.title,
|
||||
stars: t.rating,
|
||||
date: new Date(t.created)
|
||||
date: new Date(t.created),
|
||||
};
|
||||
})
|
||||
}),
|
||||
};
|
||||
|
||||
// Get review information
|
||||
@@ -444,7 +547,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
private loadReviewData(review: ReviewDTO) {}
|
||||
|
||||
private loadBranches() {
|
||||
this.branches = this.store.selectSnapshot(BranchSelectors.getBranchesIterable);
|
||||
this.branches = this.store.selectSnapshot(
|
||||
BranchSelectors.getBranchesIterable
|
||||
);
|
||||
}
|
||||
|
||||
openBranchesAvailabilityModal() {
|
||||
@@ -499,18 +604,24 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
// text object mapping
|
||||
if (item.texts) {
|
||||
item.texts.forEach(text => {
|
||||
const label = text.label ? '<b>' + text.label + '</b>' + '\n' + '<br>' : '';
|
||||
item.texts.forEach((text) => {
|
||||
const label = text.label
|
||||
? '<b>' + text.label + '</b>' + '\n' + '<br>'
|
||||
: '';
|
||||
const value = text.value ? text.value + '\n' + '<br>' : '';
|
||||
fullDescription = fullDescription ? fullDescription + label + value : label + value;
|
||||
fullDescription = fullDescription
|
||||
? fullDescription + label + value
|
||||
: label + value;
|
||||
});
|
||||
}
|
||||
|
||||
// specs object mapping
|
||||
if (item.specs) {
|
||||
genre = item.specs.find(s => s.key === this.GENRE) ? item.specs.find(s => s.key === this.GENRE).value : '';
|
||||
recommandedAge = item.specs.find(s => s.key === this.RECOMMANDED_AGE)
|
||||
? item.specs.find(s => s.key === this.RECOMMANDED_AGE).value
|
||||
genre = item.specs.find((s) => s.key === this.GENRE)
|
||||
? item.specs.find((s) => s.key === this.GENRE).value
|
||||
: '';
|
||||
recommandedAge = item.specs.find((s) => s.key === this.RECOMMANDED_AGE)
|
||||
? item.specs.find((s) => s.key === this.RECOMMANDED_AGE).value
|
||||
: '';
|
||||
}
|
||||
|
||||
@@ -524,7 +635,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
if (Array.isArray(item.stockInfos) && item.stockInfos.length > 0) {
|
||||
quantity = item.stockInfos[0].inStock.toString();
|
||||
if (+quantity > 0) {
|
||||
const userBranch = this.store.selectSnapshot(BranchSelectors.getUserBranch);
|
||||
const userBranch = this.store.selectSnapshot(
|
||||
BranchSelectors.getUserBranch
|
||||
);
|
||||
for (let x = 0; x < +quantity; x++) {
|
||||
this.availability.push({
|
||||
itemId: item.id,
|
||||
@@ -532,7 +645,7 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
quantity: +quantity,
|
||||
type: CheckoutType.takeNow,
|
||||
av: item.catalogAvailability,
|
||||
status: 0
|
||||
status: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -540,7 +653,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
if (item.shelfInfos) {
|
||||
assortment = item.shelfInfos[0].assortment ? item.shelfInfos[0].assortment : item.shelfInfos[0].label;
|
||||
assortment = item.shelfInfos[0].assortment
|
||||
? item.shelfInfos[0].assortment
|
||||
: item.shelfInfos[0].label;
|
||||
}
|
||||
|
||||
if (item.family && item.family.length > 0) {
|
||||
@@ -550,8 +665,10 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
ean: t.product.ean,
|
||||
format: t.product.format,
|
||||
formatDetail: t.product.formatDetail,
|
||||
price: !!t.catalogAvailability ? t.catalogAvailability.price.value.value : 0,
|
||||
status: !!t.catalogAvailability ? t.catalogAvailability.status : 0
|
||||
price: !!t.catalogAvailability
|
||||
? t.catalogAvailability.price.value.value
|
||||
: 0,
|
||||
status: !!t.catalogAvailability ? t.catalogAvailability.status : 0,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -562,9 +679,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
const imageCover$ = this.bookImagePipe.transform(imageId);
|
||||
this.images$ = imageCover$.pipe(
|
||||
switchMap(cover => {
|
||||
switchMap((cover) => {
|
||||
if (item.images) {
|
||||
return of([cover, ...item.images.map(t => t.url)]);
|
||||
return of([cover, ...item.images.map((t) => t.url)]);
|
||||
}
|
||||
return of([cover]);
|
||||
})
|
||||
@@ -577,12 +694,12 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
let features: Features[] = [];
|
||||
if (item.features) {
|
||||
features = item.features
|
||||
.filter(t => t.enabled === true)
|
||||
.map(t => {
|
||||
.filter((t) => t.enabled === true)
|
||||
.map((t) => {
|
||||
return <Features>{
|
||||
key: t.key,
|
||||
value: t.value,
|
||||
description: t.description
|
||||
description: t.description,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -610,21 +727,28 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
edition,
|
||||
recommandedAge,
|
||||
otherFormats,
|
||||
features
|
||||
features,
|
||||
};
|
||||
}
|
||||
|
||||
async loadDownloadAvailability(item: ItemDTO, ean: string) {
|
||||
const userBranchNumber = this.store.selectSnapshot(BranchSelectors.getUserBranch);
|
||||
const branch = this.store.selectSnapshot(BranchSelectors.getBranchesIterable).find(t => t.branchNumber === userBranchNumber);
|
||||
const userBranchNumber = this.store.selectSnapshot(
|
||||
BranchSelectors.getUserBranch
|
||||
);
|
||||
const branch = this.store
|
||||
.selectSnapshot(BranchSelectors.getBranchesIterable)
|
||||
.find((t) => t.branchNumber === userBranchNumber);
|
||||
if (!branch) {
|
||||
return true;
|
||||
}
|
||||
this.productAvailabilityService
|
||||
.getShippingAvailabilityWithCheck(item, ean, branch.id)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(response => {
|
||||
if ((response as { error: boolean; message: string; type: CheckoutType }).error) {
|
||||
.subscribe((response) => {
|
||||
if (
|
||||
(response as { error: boolean; message: string; type: CheckoutType })
|
||||
.error
|
||||
) {
|
||||
this.downloadError = true;
|
||||
this.downloadLoaded = true;
|
||||
if (this.addToCartBtn) {
|
||||
@@ -637,10 +761,16 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
av: AvailabilityDTO[];
|
||||
};
|
||||
if (successfulResponse) {
|
||||
const preferredAvailability = successfulResponse.av.find(t => t.preferred === 1 && t.supplier === 'DIG');
|
||||
const preferredAvailability = successfulResponse.av.find(
|
||||
(t) => t.preferred === 1 && t.supplier === 'DIG'
|
||||
);
|
||||
if (preferredAvailability) {
|
||||
this.availabilityStatusText = preferredAvailability.sscText;
|
||||
if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
|
||||
if (
|
||||
preferredAvailability.price &&
|
||||
preferredAvailability.price.value &&
|
||||
preferredAvailability.price.value.value
|
||||
) {
|
||||
this.downloadPrice = preferredAvailability.price.value.value;
|
||||
}
|
||||
this.availability.push({
|
||||
@@ -649,7 +779,7 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
quantity: 1,
|
||||
type: CheckoutType.donwload,
|
||||
av: preferredAvailability,
|
||||
status: +preferredAvailability.status
|
||||
status: +preferredAvailability.status,
|
||||
});
|
||||
this.downloadError = false;
|
||||
this.downloadLoaded = true;
|
||||
@@ -676,10 +806,15 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
async loadAvailability(it: ItemDTO, ean: string): Promise<boolean> {
|
||||
const availabilityObservables: Observable<
|
||||
{ branchId: number; type: CheckoutType; av: AvailabilityDTO[] } | { error: boolean; message: string; type: CheckoutType }
|
||||
| { branchId: number; type: CheckoutType; av: AvailabilityDTO[] }
|
||||
| { error: boolean; message: string; type: CheckoutType }
|
||||
>[] = [];
|
||||
const userBranchNumber = this.store.selectSnapshot(BranchSelectors.getUserBranch);
|
||||
const branch = this.store.selectSnapshot(BranchSelectors.getBranchesIterable).find(t => t.branchNumber === userBranchNumber);
|
||||
const userBranchNumber = this.store.selectSnapshot(
|
||||
BranchSelectors.getUserBranch
|
||||
);
|
||||
const branch = this.store
|
||||
.selectSnapshot(BranchSelectors.getBranchesIterable)
|
||||
.find((t) => t.branchNumber === userBranchNumber);
|
||||
if (!branch) {
|
||||
return true;
|
||||
}
|
||||
@@ -696,7 +831,7 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
forkJoin(availabilityObservables)
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
tap(t => {
|
||||
tap((t) => {
|
||||
t.map(
|
||||
(
|
||||
response:
|
||||
@@ -738,45 +873,64 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
if (item.type === CheckoutType.delivery) {
|
||||
this.deliveryError = null;
|
||||
}
|
||||
const preferredAvailability = this.getPreferedAvailability(item.av);
|
||||
const preferredAvailability = this.getPreferedAvailability(
|
||||
item.av
|
||||
);
|
||||
if (!preferredAvailability) {
|
||||
return;
|
||||
}
|
||||
if (item.type === CheckoutType.store) {
|
||||
this.availabilityStatusText = preferredAvailability.sscText;
|
||||
this.currentPickUpDate = preferredAvailability.at
|
||||
? this.datePipe.transform(new Date(preferredAvailability.at), 'dd.MM.yy')
|
||||
? this.datePipe.transform(
|
||||
new Date(preferredAvailability.at),
|
||||
'dd.MM.yy'
|
||||
)
|
||||
: null;
|
||||
if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
|
||||
if (
|
||||
preferredAvailability.price &&
|
||||
preferredAvailability.price.value &&
|
||||
preferredAvailability.price.value.value
|
||||
) {
|
||||
this.pickUpPrice = preferredAvailability.price.value.value;
|
||||
}
|
||||
}
|
||||
if (item.type === CheckoutType.delivery && preferredAvailability.at) {
|
||||
if (
|
||||
item.type === CheckoutType.delivery &&
|
||||
preferredAvailability.at
|
||||
) {
|
||||
this.currentDeliveryDate = preferredAvailability.at
|
||||
? this.datePipe.transform(new Date(preferredAvailability.at), 'dd.MM.yy')
|
||||
? this.datePipe.transform(
|
||||
new Date(preferredAvailability.at),
|
||||
'dd.MM.yy'
|
||||
)
|
||||
: null;
|
||||
}
|
||||
if (item.type === CheckoutType.delivery) {
|
||||
if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
|
||||
if (
|
||||
preferredAvailability.price &&
|
||||
preferredAvailability.price.value &&
|
||||
preferredAvailability.price.value.value
|
||||
) {
|
||||
this.deliveryPrice = preferredAvailability.price.value.value;
|
||||
}
|
||||
}
|
||||
|
||||
item.av.forEach(av => {
|
||||
item.av.forEach((av) => {
|
||||
this.availability.push({
|
||||
itemId: av.itemId,
|
||||
branchId: item.branchId,
|
||||
quantity: item.av.length,
|
||||
type: item.type,
|
||||
av: preferredAvailability,
|
||||
status: av.status
|
||||
status: av.status,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
)
|
||||
.subscribe(av => {
|
||||
.subscribe((av) => {
|
||||
this.storeAvLoaded = true;
|
||||
this.shippingAvLoaded = true;
|
||||
if (this.addToCartBtn) {
|
||||
@@ -791,27 +945,31 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
.getStockInfo([branchId], [itemId])
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
map(stockInfo => {
|
||||
map((stockInfo) => {
|
||||
if (!stockInfo) {
|
||||
return 0;
|
||||
}
|
||||
if (stockInfo.length === 1) {
|
||||
return stockInfo[0].inStock;
|
||||
}
|
||||
return stockInfo ? stockInfo.map(t => t.inStock).reduce((s1, s2) => s1 + s2) : 0;
|
||||
return stockInfo
|
||||
? stockInfo.map((t) => t.inStock).reduce((s1, s2) => s1 + s2)
|
||||
: 0;
|
||||
})
|
||||
)
|
||||
.subscribe(inStockAv => {
|
||||
.subscribe((inStockAv) => {
|
||||
if (inStockAv) {
|
||||
this.product.quantity = inStockAv + '';
|
||||
this.availability = this.availability.filter(t => t.type !== CheckoutType.takeNow);
|
||||
this.availability = this.availability.filter(
|
||||
(t) => t.type !== CheckoutType.takeNow
|
||||
);
|
||||
this.availability.push({
|
||||
itemId: itemId,
|
||||
branchId: branchId,
|
||||
quantity: inStockAv,
|
||||
type: CheckoutType.takeNow,
|
||||
av: { ...this.item.catalogAvailability, qty: inStockAv },
|
||||
status: 0
|
||||
status: 0,
|
||||
});
|
||||
}
|
||||
this.stockInfoLoaded = true;
|
||||
@@ -826,7 +984,9 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
if (!availability) {
|
||||
return;
|
||||
}
|
||||
const preferredAvailability = availability.find((ava: AvailabilityDTO) => ava.preferred === 1);
|
||||
const preferredAvailability = availability.find(
|
||||
(ava: AvailabilityDTO) => ava.preferred === 1
|
||||
);
|
||||
return preferredAvailability; // ? preferredAvailability : availability[0];
|
||||
}
|
||||
|
||||
@@ -874,7 +1034,12 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
expand() {
|
||||
this.expanded = !this.expanded;
|
||||
this.store.dispatch(new UpdateCurrentBreadcrumbName(this.expanded ? this.product.title : 'Empfehlungen', 'product'));
|
||||
this.store.dispatch(
|
||||
new UpdateCurrentBreadcrumbName(
|
||||
this.expanded ? this.product.title : 'Empfehlungen',
|
||||
'product'
|
||||
)
|
||||
);
|
||||
if (!this.expanded) {
|
||||
this.recommendations.loadReccomendations();
|
||||
}
|
||||
@@ -903,7 +1068,10 @@ export class ProductDetailsComponent implements OnInit, OnDestroy {
|
||||
if (event.target.scrollTop === 0) {
|
||||
this.elOtherformats.calculateTopPosition();
|
||||
}
|
||||
if (event.target.scrollTop === event.target.scrollHeight - event.target.offsetHeight) {
|
||||
if (
|
||||
event.target.scrollTop ===
|
||||
event.target.scrollHeight - event.target.offsetHeight
|
||||
) {
|
||||
this.elOtherformats.calculateTopPosition();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user