@colijnit/product 257.1.12 → 257.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, Injectable, EventEmitter, Component, ViewEncapsulation, Input, Output, Renderer2, ChangeDetectorRef, ViewChild, ElementRef, Pipe, NgModule, ChangeDetectionStrategy, HostListener, HostBinding, SecurityContext, CUSTOM_ELEMENTS_SCHEMA, Inject, PLATFORM_ID, NO_ERRORS_SCHEMA } from '@angular/core';
3
3
  import { __awaiter } from 'tslib';
4
- import { Subject, BehaviorSubject } from 'rxjs';
4
+ import { Subject, BehaviorSubject, combineLatest } from 'rxjs';
5
5
  import { Options } from '@colijnit/ioneconnector/build/model/options';
6
6
  import { ArticleFullObject } from '@colijnit/articleapi/build/model/article-full-object';
7
7
  import { SuperArticle } from '@colijnit/articleapi/build/model/super-article';
@@ -30,8 +30,8 @@ class Version {
30
30
  constructor() {
31
31
  this.name = "@colijnit/product";
32
32
  this.description = "Product detail page project for iOne";
33
- this.symVer = "257.1.12";
34
- this.publishDate = "9-7-2025 14:29:11";
33
+ this.symVer = "257.1.13";
34
+ this.publishDate = "22-8-2025 16:12:09";
35
35
  }
36
36
  }
37
37
 
@@ -202,6 +202,14 @@ class ProductConnectorAdapterService {
202
202
  });
203
203
  });
204
204
  }
205
+ getGeneratedArtDirectly(goodId, showLoader) {
206
+ return __awaiter(this, void 0, void 0, function* () {
207
+ return this.articleConnector.getGeneratedArtDirectly(goodId, showLoader).catch((messages) => {
208
+ this._eventService.errorMessage.next(messages);
209
+ return null;
210
+ });
211
+ });
212
+ }
205
213
  getGoodIdFromArticleNr(sku) {
206
214
  return __awaiter(this, void 0, void 0, function* () {
207
215
  const response = yield this.articleConnector.getGoodIdFromArticleNr(sku);
@@ -569,6 +577,7 @@ class ProductConnectorService {
569
577
  this._adapterService = _adapterService;
570
578
  this._settingsService = _settingsService;
571
579
  this.controllerInitialized = new BehaviorSubject(false);
580
+ this.articleLoaded = new BehaviorSubject(false);
572
581
  this._initializing = false;
573
582
  this._initialized = false;
574
583
  this.connectorOptions = new Options();
@@ -646,6 +655,9 @@ class ProductConnectorService {
646
655
  getJsonArticleFlatTree(goodId, goodType, quantity, externalSource = false, showLoader = true, configuratorStatistics) {
647
656
  return this._adapterService.getJsonArticleFlatTree(goodId, goodType, quantity, externalSource, showLoader, this._instanceId, configuratorStatistics);
648
657
  }
658
+ getGeneratedArtDirectly(goodId, showLoader = true) {
659
+ return this._adapterService.getGeneratedArtDirectly(goodId, showLoader);
660
+ }
649
661
  addWebSessionTransactionLine(transactionUuid, sku, quantity) {
650
662
  return __awaiter(this, void 0, void 0, function* () {
651
663
  return yield this._adapterService.addWebSessionTransactionLine(transactionUuid, sku, quantity);
@@ -967,9 +979,18 @@ class ProductPageComponent {
967
979
  if (this.selections.nativeElement) {
968
980
  this.selections.nativeElement.forceRenderImage();
969
981
  }
970
- }), this.settingsService.settingsLoaded.subscribe(loaded => this._handleSettingsLoaded(loaded)), this._ione.controllerInitialized.subscribe((initialized) => {
971
- this.settingsLoaded = initialized;
972
- }), this.appEventService.onAnswersAvailable.subscribe((answers) => {
982
+ }), this.settingsService.settingsLoaded.subscribe(loaded => this._handleSettingsLoaded(loaded)), this._pageLoadedSubscription = combineLatest([
983
+ this._ione.controllerInitialized,
984
+ this._ione.articleLoaded
985
+ ]).subscribe(([initialized, articleLoaded]) => {
986
+ if (initialized && articleLoaded) {
987
+ this.settingsLoaded = initialized;
988
+ }
989
+ }),
990
+ // this._ione.controllerInitialized.subscribe((initialized: boolean) => {
991
+ // this.settingsLoaded = initialized;
992
+ // }),
993
+ this.appEventService.onAnswersAvailable.subscribe((answers) => {
973
994
  if (answers && this.configurable) {
974
995
  this.showAddToCart = false;
975
996
  }
@@ -1045,6 +1066,7 @@ class ProductPageComponent {
1045
1066
  if (this._initializedSub) {
1046
1067
  this._initializedSub.unsubscribe();
1047
1068
  }
1069
+ this._pageLoadedSubscription.unsubscribe();
1048
1070
  this.configurator = undefined;
1049
1071
  this.selections = undefined;
1050
1072
  this.fullscreenbutton = undefined;
@@ -1076,7 +1098,8 @@ class ProductPageComponent {
1076
1098
  this._ione.getFullArticle(this._sku).then((article) => {
1077
1099
  this.article = article;
1078
1100
  if (this.article) {
1079
- this.configurable = this.article.goodType === 'B';
1101
+ this.configurable = this.article.goodType === 'B' && (this.article.isConfigurable || this.article.isConfigurable === undefined);
1102
+ // this.configurable = this.article.goodType === 'B';
1080
1103
  if (this.configurable) {
1081
1104
  this.showAddToCart = false;
1082
1105
  this.currentView = SelectorType.TwoD;
@@ -1093,6 +1116,7 @@ class ProductPageComponent {
1093
1116
  });
1094
1117
  this._changeDetector.detectChanges();
1095
1118
  }
1119
+ this._ione.articleLoaded.next(true);
1096
1120
  });
1097
1121
  }
1098
1122
  }));
@@ -1109,37 +1133,37 @@ class ProductPageComponent {
1109
1133
  ProductPageComponent.decorators = [
1110
1134
  { type: Component, args: [{
1111
1135
  selector: 'app-product-page',
1112
- template: "<ng-container *ngIf=\"settingsLoaded\">\r\n <div class=\"page-wrapper\">\r\n <div class=\"page-wrapper-content\">\r\n <div class=\"page-wrapper-left\">\r\n <div class=\"product-image-container\">\r\n <div class=\"product-page-block-selector-type\">\r\n <app-product-selector-type class=\"default-padding\"\r\n [(currentType)]=\"currentView\"\r\n [show2D]=\"configurable\"\r\n [show3D]=\"threeD\"\r\n ></app-product-selector-type>\r\n </div>\r\n <div class=\"product-page-block-image default-padding\" [class.full]=\"fullScreen\">\r\n <app-image-carousel [@toggleVisibilityByState]=\"show2D ? 'show' : 'hide'\" [images]=\"article?.images\" [showRefresh]=\"configurable && threeD\"></app-image-carousel>\r\n <ng-container *ngIf=\"settingsLoaded\">\r\n <threed-configurator #configurator class=\"threed-configurator\"\r\n [class.configurator-full-screen]=\"fullScreen\"\r\n [@toggleVisibilityByState]=\"show3D ? 'show' : 'hide'\"\r\n [@toggleFullScreen]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n ></threed-configurator>\r\n </ng-container>\r\n <co-icon #fullscreenbutton class=\"fullscreen-button\" *ngIf=\"show3D\"\r\n [@toggleTopLeft]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n [iconData]=\"iconCache.getIcon(fullScreenIcon)\"\r\n (click)=\"showFullScreen()\"></co-icon>\r\n <co-icon class=\"threed-watermark\" *ngIf=\"show3D && fullScreen\"\r\n [iconData]=\"iconCache.getIcon(icon.Logo)\"></co-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-right\">\r\n <div class=\"product-page-block-description\">\r\n <app-product-description class=\"default-padding\" [article]=\"article\"></app-product-description>\r\n </div>\r\n <div class=\"product-page-block-additional\">\r\n <div class=\"product-page-block-additional-description\">\r\n <app-product-additional-description class=\"default-padding\" [article]=\"article\"></app-product-additional-description>\r\n </div>\r\n <div class=\"product-page-block-price\" [class.full]=\"configuring\">\r\n <app-product-price class=\"s-padding\" *ngIf=\"!configuring\"\r\n [pricing]=\"article?.pricing\"\r\n [configurable]=\"configurable\"\r\n ></app-product-price>\r\n <ng-container *ngIf=\"settingsLoaded\">\r\n <threed-selections #selections class=\"threed-selections\" [class.show-selections]=\"configuring\" [@toggleFullScreenRight]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n [class.default-padding]=\"!fullScreen\"\r\n [class.show-full-screen]=\"fullScreen\"\r\n [class.mini-scrollbar]=\"fullScreen\"\r\n [sku]=\"sku\"\r\n [settings]=\"settings\"\r\n (onUserActionFromThreeD)=\"configuring = true\"\r\n (instanceSet)=\"setInstance($event)\"\r\n (onImageReceived)=\"appEventService.onImageReceived.next($event)\"\r\n (onRenderStarted)=\"appEventService.onRenderStarted.next()\"\r\n (onDraftRenderImageReceived)=\"appEventService.onDraftRenderImageReceived.next($event)\"\r\n (onArticleReceived)=\"appEventService.onArticleReceived.next($event.detail)\"\r\n (onSelectionsReceived)=\"appEventService.onSelectionsReceived.next($event.detail)\"\r\n (onArticleInfoReceived)=\"appEventService.onArticleInfoReceived.next($event.detail)\"\r\n (onAnswersAvailable)=\"appEventService.onAnswersAvailable.next($event.detail)\"\r\n ></threed-selections>\r\n </ng-container>\r\n </div>\r\n <div class=\"product-page-block-addtocart no-padding product-action-buttons\" *ngIf=\"!configuring\" [@toggleTopRight]=\"fullScreen ? 'fullscreen' : 'halfscreen'\">\r\n <app-product-addtocart\r\n [configurable]=\"configurable\"\r\n [createFrozenArticle]=\"createFrozenArticle\"\r\n [configuring]=\"configuring\"\r\n [showAddToCart]=\"showAddToCart\"\r\n [article]=\"article\"\r\n [externalSource]=\"externalSource\"\r\n [isReturn]=\"isReturn\"\r\n (startConfiguration)=\"handleStartConfiguration()\"\r\n (showRelatedPopup)=\"handlePopUpChange($event)\"\r\n ></app-product-addtocart>\r\n </div>\r\n <div class=\"addtocart-reserved product-action-buttons\" *ngIf=\"configuring\" [class.full-screen]=\"fullScreen\">\r\n <app-product-addtocart class=\"default-padding\"\r\n [configurable]=\"false\"\r\n [fullscreen]=\"fullScreen\"\r\n [showAddToCart]=\"showAddToCart\"\r\n [configuring]=\"configuring\"\r\n [article]=\"article\"\r\n [externalSource]=\"externalSource\"\r\n [isReturn]=\"isReturn\"\r\n (startConfiguration)=\"handleStartConfiguration()\"\r\n ></app-product-addtocart>\r\n </div>\r\n <div class=\"product-page-block-variants\">\r\n <app-product-related class=\"no-padding\" *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\" [refType]=\"64\" [label]=\"'VARIANTS' | localize\"></app-product-related>\r\n </div>\r\n <div class=\"product-page-block-stock\">\r\n <app-product-stock class=\"no-padding\" [goodId]=\"article?.goodId\" (openStockEvent)=\"openStock()\"></app-product-stock>\r\n </div>\r\n <div class=\"product-page-block-delivery\">\r\n <app-product-delivery class=\"no-padding\" [stockAndDelivery]=\"stockAndDelivery\"></app-product-delivery>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-content\">\r\n <div class=\"page-wrapper-left\">\r\n <app-product-info-tabs class=\"no-padding\" [article]=\"article\"></app-product-info-tabs>\r\n </div>\r\n <div class=\"page-wrapper-right\">\r\n <div class=\"product-page-block-related s-padding\">\r\n <app-product-related\r\n *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"1\"\r\n [label]=\"'RELATED_PRODUCTS' | localize\">\r\n </app-product-related>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-content no-top-margin\">\r\n <div class=\"page-wrapper-full\">\r\n <div class=\"product-page-block-alternatives s-padding\">\r\n <app-product-related\r\n *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"4\"\r\n [isSmallModus]=\"false\"\r\n [label]=\"'ALTERNATIVE_PRODUCTS' | localize\">\r\n </app-product-related>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"showRelatedProductsPopup\">\r\n <co-product-dialog\r\n [mainArticle]=\"article\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"1\"\r\n (closeRelatedPopup)=\"handlePopUpChange($event)\"\r\n >\r\n </co-product-dialog>\r\n\r\n<!-- <app-product-related class=\"no-padding\" *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"-->\r\n<!-- [articles]=\"article?.relatedArticles\" [refType]=\"64\" [label]=\"'VARIANTS' | localize\"></app-product-related>-->\r\n </div>\r\n\r\n\r\n </div>\r\n</ng-container>\r\n",
1136
+ template: "<ng-container *ngIf=\"settingsLoaded\">\r\n <div class=\"page-wrapper\">\r\n <div class=\"page-wrapper-content\">\r\n <div class=\"page-wrapper-left\">\r\n <div class=\"product-image-container\">\r\n <div class=\"product-page-block-selector-type\">\r\n <app-product-selector-type class=\"default-padding\"\r\n [(currentType)]=\"currentView\"\r\n [show2D]=\"configurable\"\r\n [show3D]=\"threeD\"\r\n ></app-product-selector-type>\r\n </div>\r\n <div class=\"product-page-block-image default-padding\" [class.full]=\"fullScreen\">\r\n <app-image-carousel [@toggleVisibilityByState]=\"show2D ? 'show' : 'hide'\" [images]=\"article?.images\" [showRefresh]=\"configurable && threeD\"></app-image-carousel>\r\n <ng-container *ngIf=\"settingsLoaded && this.configurable\">\r\n <threed-configurator #configurator class=\"threed-configurator\"\r\n [class.configurator-full-screen]=\"fullScreen\"\r\n [@toggleVisibilityByState]=\"show3D ? 'show' : 'hide'\"\r\n [@toggleFullScreen]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n ></threed-configurator>\r\n </ng-container>\r\n <co-icon #fullscreenbutton class=\"fullscreen-button\" *ngIf=\"show3D\"\r\n [@toggleTopLeft]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n [iconData]=\"iconCache.getIcon(fullScreenIcon)\"\r\n (click)=\"showFullScreen()\"></co-icon>\r\n <co-icon class=\"threed-watermark\" *ngIf=\"show3D && fullScreen\"\r\n [iconData]=\"iconCache.getIcon(icon.Logo)\"></co-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-right\">\r\n <div class=\"product-page-block-description\">\r\n <app-product-description class=\"default-padding\" [article]=\"article\"></app-product-description>\r\n </div>\r\n <div class=\"product-page-block-additional\">\r\n <div class=\"product-page-block-additional-description\">\r\n <app-product-additional-description class=\"default-padding\" [article]=\"article\"></app-product-additional-description>\r\n </div>\r\n <div class=\"product-page-block-price\" [class.full]=\"configuring\">\r\n <app-product-price class=\"s-padding\" *ngIf=\"!configuring\"\r\n [pricing]=\"article?.pricing\"\r\n [configurable]=\"configurable\"\r\n ></app-product-price>\r\n <ng-container *ngIf=\"settingsLoaded\">\r\n <threed-selections #selections class=\"threed-selections\" [class.show-selections]=\"configuring\" [@toggleFullScreenRight]=\"fullScreen ? 'fullscreen' : 'halfscreen'\"\r\n [class.default-padding]=\"!fullScreen\"\r\n [class.show-full-screen]=\"fullScreen\"\r\n [class.mini-scrollbar]=\"fullScreen\"\r\n [sku]=\"sku\"\r\n [settings]=\"settings\"\r\n (onUserActionFromThreeD)=\"configuring = true\"\r\n (instanceSet)=\"setInstance($event)\"\r\n (onImageReceived)=\"appEventService.onImageReceived.next($event)\"\r\n (onRenderStarted)=\"appEventService.onRenderStarted.next()\"\r\n (onDraftRenderImageReceived)=\"appEventService.onDraftRenderImageReceived.next($event)\"\r\n (onArticleReceived)=\"appEventService.onArticleReceived.next($event.detail)\"\r\n (onSelectionsReceived)=\"appEventService.onSelectionsReceived.next($event.detail)\"\r\n (onArticleInfoReceived)=\"appEventService.onArticleInfoReceived.next($event.detail)\"\r\n (onAnswersAvailable)=\"appEventService.onAnswersAvailable.next($event.detail)\"\r\n ></threed-selections>\r\n </ng-container>\r\n </div>\r\n <div class=\"product-page-block-addtocart no-padding product-action-buttons\" *ngIf=\"!configuring\" [@toggleTopRight]=\"fullScreen ? 'fullscreen' : 'halfscreen'\">\r\n <app-product-addtocart\r\n [configurable]=\"configurable\"\r\n [createFrozenArticle]=\"createFrozenArticle\"\r\n [configuring]=\"configuring\"\r\n [showAddToCart]=\"showAddToCart\"\r\n [article]=\"article\"\r\n [externalSource]=\"externalSource\"\r\n [isReturn]=\"isReturn\"\r\n (startConfiguration)=\"handleStartConfiguration()\"\r\n (showRelatedPopup)=\"handlePopUpChange($event)\"\r\n ></app-product-addtocart>\r\n </div>\r\n <div class=\"addtocart-reserved product-action-buttons\" *ngIf=\"configuring\" [class.full-screen]=\"fullScreen\">\r\n <app-product-addtocart class=\"default-padding\"\r\n [configurable]=\"false\"\r\n [fullscreen]=\"fullScreen\"\r\n [showAddToCart]=\"showAddToCart\"\r\n [configuring]=\"configuring\"\r\n [article]=\"article\"\r\n [externalSource]=\"externalSource\"\r\n [isReturn]=\"isReturn\"\r\n (startConfiguration)=\"handleStartConfiguration()\"\r\n ></app-product-addtocart>\r\n </div>\r\n <div class=\"product-page-block-variants\">\r\n <app-product-related class=\"no-padding\" *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\" [refType]=\"64\" [label]=\"'VARIANTS' | localize\"></app-product-related>\r\n </div>\r\n <div class=\"product-page-block-stock\">\r\n <app-product-stock class=\"no-padding\" [goodId]=\"article?.goodId\" (openStockEvent)=\"openStock()\"></app-product-stock>\r\n </div>\r\n <div class=\"product-page-block-delivery\">\r\n <app-product-delivery class=\"no-padding\" [stockAndDelivery]=\"stockAndDelivery\"></app-product-delivery>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-content\">\r\n <div class=\"page-wrapper-left\" *ngIf=\"article\">\r\n <app-product-info-tabs class=\"no-padding\" [article]=\"article\"></app-product-info-tabs>\r\n </div>\r\n <div class=\"page-wrapper-right\">\r\n <div class=\"product-page-block-related s-padding\">\r\n <app-product-related\r\n *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"1\"\r\n [label]=\"'RELATED_PRODUCTS' | localize\">\r\n </app-product-related>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"page-wrapper-content no-top-margin\">\r\n <div class=\"page-wrapper-full\">\r\n <div class=\"product-page-block-alternatives s-padding\">\r\n <app-product-related\r\n *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"\r\n [externalSource]=\"externalSource\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"4\"\r\n [isSmallModus]=\"false\"\r\n [label]=\"'ALTERNATIVE_PRODUCTS' | localize\">\r\n </app-product-related>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"showRelatedProductsPopup\">\r\n <co-product-dialog\r\n [mainArticle]=\"article\"\r\n [articles]=\"article?.relatedArticles\"\r\n [refType]=\"1\"\r\n (closeRelatedPopup)=\"handlePopUpChange($event)\"\r\n >\r\n </co-product-dialog>\r\n\r\n<!-- <app-product-related class=\"no-padding\" *ngIf=\"article?.relatedArticles && article?.relatedArticles.length > 0\"-->\r\n<!-- [articles]=\"article?.relatedArticles\" [refType]=\"64\" [label]=\"'VARIANTS' | localize\"></app-product-related>-->\r\n </div>\r\n\r\n\r\n </div>\r\n</ng-container>\r\n",
1113
1137
  animations: [
1114
1138
  trigger('toggleFullScreen', [
1115
1139
  state('fullscreen', style({ 'position': 'fixed', 'top': '0', 'left': '0', 'width': '100%', 'height': '100%' })),
1116
1140
  state('halfscreen', style({ 'position': '*', 'top': '*', 'left': '*', 'width': '*', 'height': '*' })),
1117
- transition('halfscreen <=> fullscreen', animate('200ms ease-in-out')),
1141
+ transition('halfscreen <=> fullscreen', animate('200ms ease-in-out'))
1118
1142
  ]),
1119
1143
  trigger('toggleTopLeft', [
1120
1144
  state('fullscreen', style({ 'position': 'fixed', 'top': '0', 'left': '0' })),
1121
1145
  state('halfscreen', style({ 'position': 'absolute', 'top': '*', 'left': '*' })),
1122
- transition('halfscreen <=> fullscreen', animate('200ms ease-in-out')),
1146
+ transition('halfscreen <=> fullscreen', animate('200ms ease-in-out'))
1123
1147
  ]),
1124
1148
  trigger('toggleTopRight', [
1125
1149
  state('fullscreen', style({ 'position': 'fixed', 'top': '0', 'right': '0' })),
1126
1150
  state('halfscreen', style({ 'position': '*', 'top': '*', 'right': '*' })),
1127
- transition('halfscreen <=> fullscreen', animate('200ms ease-in-out')),
1151
+ transition('halfscreen <=> fullscreen', animate('200ms ease-in-out'))
1128
1152
  ]),
1129
1153
  trigger('toggleFullScreenRight', [
1130
1154
  state('fullscreen', style({ 'position': 'fixed', 'width': '400px', 'top': '0', 'right': '0' })),
1131
1155
  state('halfscreen', style({ 'position': '*', 'width': '*', 'top': '*', 'right': '*' })),
1132
- transition('halfscreen <=> fullscreen', animate('200ms ease-in-out')),
1156
+ transition('halfscreen <=> fullscreen', animate('200ms ease-in-out'))
1133
1157
  ]),
1134
1158
  trigger('toggleVisibilityByState', [
1135
1159
  state('hide', style({ 'opacity': '0', 'display': 'none' })),
1136
1160
  state('show', style({ 'display': 'block', 'opacity': '1' })),
1137
- transition('hide <=> show', animate('200ms 100ms ease-in-out')),
1161
+ transition('hide <=> show', animate('200ms 100ms ease-in-out'))
1138
1162
  ]),
1139
1163
  trigger('toggleVisibility', [
1140
1164
  state('void', style({ 'opacity': '0' })),
1141
1165
  state('*', style({ 'opacity': '1' })),
1142
- transition('void => *', animate('200ms ease-in-out')),
1166
+ transition('void => *', animate('200ms ease-in-out'))
1143
1167
  ])
1144
1168
  ],
1145
1169
  styles: [".page-wrapper{font-family:iOneMontserrat;font-size:12px;display:flex;flex-direction:column;max-width:1400px;padding:0 15px;margin:0 auto}.page-wrapper-content{display:flex;flex-direction:row;margin:40px 0}.page-wrapper-content:first-child{margin-top:0}.page-wrapper-content.no-top-margin{margin-top:0}.page-wrapper-left{display:flex;width:55%;flex-direction:column}.page-wrapper-right{display:flex;width:45%;flex-direction:column}.page-wrapper-full{display:flex;width:100%;flex-direction:column}.page-wrapper-66{display:flex;width:60%;flex-direction:column}.page-wrapper-33{display:flex;width:40%;flex-direction:column}.threed-selections{display:none}.threed-selections.show-selections{display:block}.threed-selections ::ng-deep .rp-lite-selector .rp-answers-slideout ::ng-deep co-slideout{width:480px;z-index:3}.threed-selections ::ng-deep .co-summary-line{cursor:pointer}.product-action-buttons{position:relative}.product-action-buttons.full-screen{z-index:10}.product-image-container{grid-column:1/7;grid-row:1/6;position:relative}.product-page-block-selector-type{width:auto;position:absolute;top:10px;right:10px;z-index:2}.product-page-block-image{box-sizing:border-box;width:100%;z-index:1;position:relative}.product-page-block-image .threed-configurator{border:1px solid #efefef}.product-page-block-image .threed-configurator .layer .viewer canvas{height:100%;width:100%}.product-page-block-image .threed-configurator ::ng-deep .rp-element-toolbar{top:30px}.product-page-block-image app-image-carousel.show-animated,.product-page-block-image threed-configurator.show-animated{opacity:1;z-index:0;transition:all .2s ease-in-out}.product-page-block-image .fullscreen-button{cursor:pointer;height:50px;width:50px;position:absolute;left:30px;z-index:100;top:30px}.product-page-block-image.full{grid-column:1/11;grid-row:2/span 10;z-index:3}.product-page-block-description{grid-column:7/12;grid-row:1/1}.product-page-block-additional{width:100%}.product-page-block-additional-description{width:100%}.product-page-block-price{grid-column:1/3;grid-row:2/2;align-self:center}.product-page-block-price.full{grid-column:1/5}.product-page-block-addtocart{grid-column:3/5;grid-row:2/2;align-self:center;padding-top:30px!important}.product-page-block-addtocart ::ng-deep co-number-picker ::ng-deep co-button{cursor:pointer}.product-page-block-addtocart ::ng-deep co-number-picker ::ng-deep co-button:hover div.rippler{background:#f6f5f4}.product-page-block-addtocart ::ng-deep co-number-picker ::ng-deep co-button ::ng-deep co-icon{position:relative;z-index:2}.product-page-block-addtocart ::ng-deep co-button.cart-button{cursor:pointer}.product-page-block-addtocart ::ng-deep co-button.cart-button:hover{background:#74B77F}.addtocart-reserved{grid-column:1/3;grid-row:3/3}.product-page-block-stock{grid-column:1/3;grid-row:4/4}.product-page-block-delivery{grid-column:3/5;grid-row:4/4}::ng-deep co-scroll-container{overflow:hidden;position:relative}::ng-deep co-scroll-container .content-wrapper{padding:0}::ng-deep co-scroll-container .scroll-layer{left:0;top:0}::ng-deep co-scroll-container .scroll-layer .scroller{width:34px;height:34px;border-radius:36px;background:#fff;cursor:pointer;box-shadow:0 0 5px #0003}::ng-deep co-scroll-container .scroll-layer .scroller:hover{background:#f6f5f4}::ng-deep co-scroll-container .scroll-layer .scroller.left-scroll{left:5px}::ng-deep co-scroll-container .scroll-layer .scroller.left-scroll:before{border-width:0 3px 3px 0;padding:4px;margin-left:13px;margin-top:11px}::ng-deep co-scroll-container .scroll-layer .scroller.right-scroll{right:5px}::ng-deep co-scroll-container .scroll-layer .scroller.right-scroll:after{border-width:0 3px 3px 0;padding:4px;margin-left:9px;margin-top:11px}.product-page-block-variants{margin:20px 0 0}.product-page-block-variants ::ng-deep app-product-related>div{display:flex;grid-gap:15px;gap:15px;align-items:center;border-top:1px solid #f6f5f4;padding:5px 0 7px 15px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep app-header h3{font-size:14px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container{width:320px;max-width:100%;padding:0 16px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container .scroller{width:26px;height:26px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container .scroller.left-scroll{left:5px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container .scroller.left-scroll:before{border-width:0 2px 2px 0;margin-left:9px;margin-top:9px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container .scroller.right-scroll{right:5px}.product-page-block-variants ::ng-deep app-product-related>div ::ng-deep co-scroll-container .scroller.right-scroll:after{border-width:0 2px 2px 0;margin-left:6px;margin-top:9px}.product-page-block-variants ::ng-deep co-tile.small{min-width:50px!important;max-width:50px!important;border:1px solid #f6f5f4;margin:0 10px 0 0;border-radius:4px}.product-page-block-variants ::ng-deep co-tile.small:hover{border-color:#22313c}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper{padding:0}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper .tile-top{display:none}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper .image{height:40px!important;padding:5px;margin-bottom:10px}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper .image .no-image-wrapper .no-image{width:40px;height:40px}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper .image .no-image-wrapper span{display:none!important}.product-page-block-variants ::ng-deep co-tile.small .tile-wrapper .tile-bottom{display:none}.product-page-block-variants ::ng-deep co-tile.small .tile-extra-bottom{display:none}.product-page-block-alternatives ::ng-deep .article-wrapper{margin:0 20px 0 0}.product-page-block-alternatives ::ng-deep .article-wrapper:last-child{margin:0}.product-page-block-alternatives ::ng-deep co-tile{cursor:pointer;transition:all .14s ease-out;border:1px solid transparent;border-bottom-color:#f6f5f4;padding:15px 10px 0;width:319px;max-width:none;min-width:0;box-sizing:border-box}.product-page-block-alternatives ::ng-deep co-tile:hover{box-shadow:none;border-color:#f6f5f4}.product-page-block-alternatives ::ng-deep co-tile:hover .tile-wrapper div.image co-image{transform:scale(1.05)}.product-page-block-alternatives ::ng-deep co-tile:hover .tile-wrapper .tile-bottom{margin:0}.product-page-block-alternatives ::ng-deep co-tile:hover .tile-extra-bottom .main .description{text-decoration:underline}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper{padding:0;position:relative;outline:none;overflow:hidden}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper .tile-top{position:absolute;left:0;top:0;width:100%}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper div.image{position:relative;padding:1px;display:flex;align-items:center;justify-content:center;overflow:hidden;max-width:250px;margin:0 auto 10px;height:auto}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper div.image:after{content:\"\";padding:100% 0 0;float:left;width:100%}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper div.image co-image{position:absolute;left:0;top:0;overflow:hidden;width:100%;height:100%;-o-object-fit:contain;object-fit:contain;z-index:-1;transition:all .2s ease}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper div.image .no-image-wrapper{position:absolute;display:flex;left:50%;top:50%;margin:-48px 0 0 -54px;flex-direction:column;align-items:center;opacity:.25}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper .tile-bottom{transition:all .2s ease;height:auto}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper .tile-bottom ::ng-deep co-button{margin:0 0 5px!important;width:36px;height:36px;border:1px solid #22313C;cursor:pointer;border-radius:4px;padding:0!important;font-size:0}.product-page-block-alternatives ::ng-deep co-tile .tile-wrapper .tile-bottom ::ng-deep co-button co-icon{width:32px;height:32px;margin:0 2px}.product-page-block-alternatives ::ng-deep co-tile .tile-extra-bottom{outline:none;padding:15px 0;background:transparent!important;min-height:60px}.product-page-block-alternatives ::ng-deep co-tile .tile-extra-bottom .main{padding:0 10px}.product-page-block-alternatives ::ng-deep co-tile .tile-extra-bottom .main .description{font-size:15px;font-weight:bold;margin:0 0 2px}.product-page-block-alternatives ::ng-deep co-tile .tile-extra-bottom .main .price{font-size:16px;margin:15px 0 0;font-weight:bold;color:#2b60a7}.product-page-block-additional-information{grid-column:1/6;grid-row:4/4}.product-page-block-properties{grid-column:7/10;grid-row:3/3}.product-page-block-related-articles{grid-column:2/6;grid-row:4/4}.product-page-block-alternative-articles{grid-column:6/10;grid-row:4/4}.product-page-block-documents{grid-column:2/6;grid-row:5/5}.product-page-block-symbols{grid-column:6/10;grid-row:5/5}@media screen and (max-width: 950px){.default-padding{padding-top:20px;padding-bottom:20px}.m-padding{padding-top:15px;padding-bottom:15px}.s-padding{padding-top:5px;padding-bottom:5px}.page-wrapper{max-width:650px}.page-wrapper .page-wrapper-content{flex-direction:column;margin:30px 0}.page-wrapper .page-wrapper-content .page-wrapper-left{width:100%}.page-wrapper .page-wrapper-content .page-wrapper-right{width:100%}.product-page-block-alternatives ::ng-deep co-tile{width:284px!important}}@media screen and (max-width: 650px){[class*=-padding]{padding-left:0!important;padding-right:0!important}.product-page-block-addtocart ::ng-deep co-number-picker co-button{height:38px!important}.product-page-block-addtocart ::ng-deep co-number-picker co-input-text{height:38px!important;width:36px!important}.product-page-block-addtocart ::ng-deep co-button.cart-button{height:40px;font-size:13px}}\n"]
@@ -1287,6 +1311,7 @@ class ImageCarouselComponent {
1287
1311
  this._appEventService = _appEventService;
1288
1312
  this._changeDetector = _changeDetector;
1289
1313
  this._domSanitizer = _domSanitizer;
1314
+ this.isPopupOpen = false;
1290
1315
  this.showRefresh = false;
1291
1316
  this.resizing = false;
1292
1317
  this.imageViewModels = [];
@@ -1316,6 +1341,12 @@ class ImageCarouselComponent {
1316
1341
  this._changeDetector.detectChanges();
1317
1342
  }));
1318
1343
  }
1344
+ // Close on ESC
1345
+ onEsc() {
1346
+ if (this.isPopupOpen) {
1347
+ this.closePopup();
1348
+ }
1349
+ }
1319
1350
  set images(value) {
1320
1351
  if (value && value.length > 0) {
1321
1352
  this._images = this._filterValidImages(value);
@@ -1362,15 +1393,16 @@ class ImageCarouselComponent {
1362
1393
  }
1363
1394
  handleShowImage(imageViewModel) {
1364
1395
  if (imageViewModel && imageViewModel.originalSource) {
1365
- let popupWindow = window.open('', 'Image zoom', 'width=600,height=400');
1366
- // Set the content of the popup window
1367
- popupWindow.document.write('<html><head><title>Image zoom</title></head><body>');
1368
- popupWindow.document.write(`<img src=${imageViewModel.originalSource} alt="Image" style="width:100%; height:auto;">`);
1369
- popupWindow.document.write('</body></html>');
1370
- // Close the document to render the popup window
1371
- popupWindow.document.close();
1396
+ this.selectedImage = imageViewModel;
1397
+ this.isPopupOpen = true;
1398
+ this._changeDetector.markForCheck();
1372
1399
  }
1373
1400
  }
1401
+ closePopup() {
1402
+ this.isPopupOpen = false;
1403
+ this.selectedImage = undefined;
1404
+ this._changeDetector.markForCheck();
1405
+ }
1374
1406
  _filterValidImages(value) {
1375
1407
  if (!value) {
1376
1408
  return [];
@@ -1413,38 +1445,54 @@ class ImageCarouselComponent {
1413
1445
  }
1414
1446
  _resizeAndSanitizeSource(source, imageViewModel) {
1415
1447
  const resizeCanvas = document.createElement('canvas');
1416
- const resizeCanvasContext = resizeCanvas.getContext('2d');
1417
- const resizeImage = document.createElement('img');
1418
- resizeImage.crossOrigin = 'anonymous';
1419
- resizeImage.onload = () => __awaiter(this, void 0, void 0, function* () {
1420
- resizeCanvasContext.imageSmoothingEnabled = true;
1421
- resizeCanvasContext.imageSmoothingQuality = 'high';
1422
- // Get the original image dimensions
1423
- const originalWidth = resizeImage.width;
1424
- const originalHeight = resizeImage.height;
1425
- // Calculate the aspect ratio
1426
- const aspectRatio = originalWidth / originalHeight;
1427
- // Calculate the new width and height while maintaining the aspect ratio
1428
- let newWidth = this._resizeCanvasHeight;
1429
- let newHeight = this._resizeCanvasHeight;
1430
- if (originalWidth > originalHeight) {
1431
- newHeight = this._resizeCanvasHeight / aspectRatio;
1448
+ const ctx = resizeCanvas.getContext('2d');
1449
+ const img = document.createElement('img');
1450
+ img.crossOrigin = 'anonymous';
1451
+ img.onload = () => {
1452
+ ctx.imageSmoothingEnabled = true;
1453
+ ctx.imageSmoothingQuality = 'high';
1454
+ const ow = img.width;
1455
+ const oh = img.height;
1456
+ const aspect = ow / oh;
1457
+ let newW = this._resizeCanvasHeight;
1458
+ let newH = this._resizeCanvasHeight;
1459
+ if (ow > oh) {
1460
+ newH = this._resizeCanvasHeight / aspect;
1432
1461
  }
1433
1462
  else {
1434
- newWidth = this._resizeCanvasHeight * aspectRatio;
1435
- }
1436
- // Set the canvas size to the new width and height
1437
- resizeCanvas.width = newWidth;
1438
- resizeCanvas.height = newHeight;
1439
- const imageWidth = this._resizeCanvasHeight * (resizeImage.height / resizeImage.width);
1440
- resizeCanvasContext.drawImage(resizeImage, 0, 0, newWidth, newHeight);
1441
- const resizedSource = resizeCanvas.toDataURL('image/jpeg');
1463
+ newW = this._resizeCanvasHeight * aspect;
1464
+ }
1465
+ resizeCanvas.width = Math.round(newW);
1466
+ resizeCanvas.height = Math.round(newH);
1467
+ // Ensure transparent background before drawing
1468
+ ctx.clearRect(0, 0, resizeCanvas.width, resizeCanvas.height);
1469
+ ctx.drawImage(img, 0, 0, resizeCanvas.width, resizeCanvas.height);
1470
+ const mime = this._detectPreferredMime(source);
1471
+ const resizedSource = mime === 'image/jpeg'
1472
+ ? resizeCanvas.toDataURL('image/jpeg', 0.92) // only if original was JPEG
1473
+ : resizeCanvas.toDataURL(mime); // PNG/WebP keep alpha
1442
1474
  imageViewModel.source = this._domSanitizer.bypassSecurityTrustUrl(resizedSource);
1443
1475
  imageViewModel.originalSource = source;
1444
1476
  this._changeDetector.detectChanges();
1445
- });
1446
- // @ts-ignore
1447
- resizeImage.src = source;
1477
+ };
1478
+ img.src = source;
1479
+ }
1480
+ _detectPreferredMime(source) {
1481
+ // Data URI check
1482
+ const m = source.match(/^data:(image\/[a-zA-Z+.-]+);base64,/);
1483
+ if (m) {
1484
+ const t = m[1].toLowerCase();
1485
+ if (t === 'image/png' || t === 'image/webp' || t === 'image/jpeg')
1486
+ return t;
1487
+ }
1488
+ const lower = source.toLowerCase();
1489
+ if (lower.endsWith('.png'))
1490
+ return 'image/png';
1491
+ if (lower.endsWith('.webp'))
1492
+ return 'image/webp';
1493
+ if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
1494
+ return 'image/jpeg';
1495
+ return 'image/png';
1448
1496
  }
1449
1497
  _scrollCarouselToIndex() {
1450
1498
  if (this.currentIndex > -1 && this.currentIndex <= this.images.length) {
@@ -1493,10 +1541,32 @@ ImageCarouselComponent.decorators = [
1493
1541
  </div>
1494
1542
  </co-scroll-container>
1495
1543
  </div>
1544
+ </div>
1545
+ <!-- Modal (real popup) -->
1546
+ <div
1547
+ class="image-modal"
1548
+ *ngIf="isPopupOpen"
1549
+ (click)="closePopup()"
1550
+ role="dialog"
1551
+ aria-modal="true"
1552
+ aria-label="Image preview"
1553
+ >
1554
+ <div class="image-modal__content" (click)="$event.stopPropagation()">
1555
+ <button
1556
+ class="image-modal__close"
1557
+ type="button"
1558
+ aria-label="Close"
1559
+ (click)="closePopup()"
1560
+ >
1561
+ ×
1562
+ </button>
1563
+
1564
+ <img [src]="selectedImage?.originalSource" alt="Image preview" />
1565
+ </div>
1496
1566
  </div>
1497
1567
  `,
1498
1568
  changeDetection: ChangeDetectionStrategy.OnPush,
1499
- styles: [":host{max-height:540px;height:100%;position:relative}:host:not(.resizing) .inner-carousel{scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory}#product_page_carousel{position:relative}#product_page_carousel .refresh-button{position:absolute;bottom:10px;right:10px;background:#fff}#product_page_carousel .refresh-button.loading{animation:spin 1s linear infinite}#product_page_carousel .refresh-button:hover{box-shadow:none;background:#74B77F;transition:all .2s ease-in-out}#product_page_carousel .refresh-button:hover ::ng-deep svg path{fill:#fff!important}#product_page_carousel #product_page_carousel_items{position:relative;margin-bottom:10px}#product_page_carousel #product_page_carousel_items ::ng-deep co-loader{position:absolute}#product_page_carousel .inner-carousel{display:flex;flex-direction:row;align-items:center;overflow:hidden;max-height:500px;border:1px solid #efefef}#product_page_carousel .carousel-item{max-height:500px;width:100%;display:flex;cursor:zoom-in;flex-shrink:0;flex-grow:0}#product_page_carousel .carousel-item img{width:100%;height:auto;-o-object-fit:contain;object-fit:contain}#product_page_carousel .carousel-scroller-layer{height:100%;width:100%;position:absolute;pointer-events:none;top:0;left:0}#product_page_carousel #product_page_carousel_thumbs{display:flex;justify-content:flex-start;height:80px;margin-left:auto;margin-right:auto}#product_page_carousel #product_page_carousel_thumbs ::ng-deep co-scroll-container{padding:0 22px}#product_page_carousel #product_page_carousel_thumbs ::ng-deep co-scroll-container .content-wrapper{padding:0}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb{opacity:1;cursor:pointer;transition:all .2s ease;padding:4px;border:1px solid #f6f5f4}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb.active,#product_page_carousel #product_page_carousel_thumbs .carousel-thumb:hover{border-color:#22313c}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb:not(:last-child){margin-right:10px}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb img{height:68px}@media screen and (max-width: 650px){#product_page_carousel_thumbs{height:57px!important}#product_page_carousel_thumbs .carousel-thumb img{height:50px!important}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"]
1569
+ styles: [":host{max-height:540px;height:100%;position:relative}:host:not(.resizing) .inner-carousel{scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory}#product_page_carousel{position:relative}#product_page_carousel .refresh-button{position:absolute;bottom:10px;right:10px;background:#fff}#product_page_carousel .refresh-button.loading{animation:spin 1s linear infinite}#product_page_carousel .refresh-button:hover{box-shadow:none;background:#74B77F;transition:all .2s ease-in-out}#product_page_carousel .refresh-button:hover ::ng-deep svg path{fill:#fff!important}#product_page_carousel #product_page_carousel_items{position:relative;margin-bottom:10px}#product_page_carousel #product_page_carousel_items ::ng-deep co-loader{position:absolute}#product_page_carousel .inner-carousel{display:flex;flex-direction:row;align-items:center;overflow:hidden;max-height:500px;border:1px solid #efefef}#product_page_carousel .carousel-item{max-height:500px;width:100%;display:flex;cursor:zoom-in;flex-shrink:0;flex-grow:0}#product_page_carousel .carousel-item img{width:100%;height:auto;-o-object-fit:contain;object-fit:contain}#product_page_carousel .carousel-scroller-layer{height:100%;width:100%;position:absolute;pointer-events:none;top:0;left:0}#product_page_carousel #product_page_carousel_thumbs{display:flex;justify-content:flex-start;height:80px;margin-left:auto;margin-right:auto}#product_page_carousel #product_page_carousel_thumbs ::ng-deep co-scroll-container{padding:0 22px}#product_page_carousel #product_page_carousel_thumbs ::ng-deep co-scroll-container .content-wrapper{padding:0}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb{opacity:1;cursor:pointer;transition:all .2s ease;padding:4px;border:1px solid #f6f5f4}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb.active,#product_page_carousel #product_page_carousel_thumbs .carousel-thumb:hover{border-color:#22313c}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb:not(:last-child){margin-right:10px}#product_page_carousel #product_page_carousel_thumbs .carousel-thumb img{height:68px}.image-modal{position:fixed;inset:0;background:rgba(0,0,0,.8);display:flex;align-items:center;justify-content:center;z-index:1000}.image-modal__content{position:relative;max-width:90vw;max-height:90vh}.image-modal__content img{max-width:90vw;max-height:90vh;-o-object-fit:contain;object-fit:contain;display:block}.image-modal__close{position:fixed;top:15px;right:30px;background:transparent;border:none;color:#fff;font-size:60px;line-height:1;cursor:pointer}@media screen and (max-width: 650px){#product_page_carousel_thumbs{height:57px!important}#product_page_carousel_thumbs .carousel-thumb img{height:50px!important}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"]
1500
1570
  },] }
1501
1571
  ];
1502
1572
  ImageCarouselComponent.ctorParameters = () => [
@@ -1507,6 +1577,7 @@ ImageCarouselComponent.ctorParameters = () => [
1507
1577
  ];
1508
1578
  ImageCarouselComponent.propDecorators = {
1509
1579
  carousel: [{ type: ViewChild, args: ['carousel', { read: ElementRef },] }],
1580
+ onEsc: [{ type: HostListener, args: ['document:keydown.escape',] }],
1510
1581
  showRefresh: [{ type: Input }],
1511
1582
  images: [{ type: Input }],
1512
1583
  handleWindowResize: [{ type: HostListener, args: ['window:resize',] }],
@@ -1755,11 +1826,12 @@ ProductPriceModule.decorators = [
1755
1826
  ];
1756
1827
 
1757
1828
  class ProductAddtocartComponent {
1758
- constructor(iconCache, _ioneControllerService, _appEventService, _settingsService) {
1829
+ constructor(iconCache, _ioneControllerService, _appEventService, _settingsService, _productConnectorAdapterService) {
1759
1830
  this.iconCache = iconCache;
1760
1831
  this._ioneControllerService = _ioneControllerService;
1761
1832
  this._appEventService = _appEventService;
1762
1833
  this._settingsService = _settingsService;
1834
+ this._productConnectorAdapterService = _productConnectorAdapterService;
1763
1835
  this.icon = IconEnum;
1764
1836
  this.createFrozenArticle = true;
1765
1837
  this.configurable = false;
@@ -1799,9 +1871,14 @@ class ProductAddtocartComponent {
1799
1871
  return __awaiter(this, void 0, void 0, function* () {
1800
1872
  if (this.createFrozenArticle) {
1801
1873
  if (this.article.goodType === 'B') {
1802
- const article = yield this._getJSONFromArticleObject({ article: this.article, quantity: quantity });
1803
- if (article) {
1804
- this._appEventService.onAddToCart.next({ article: article, quantity: quantity });
1874
+ if (this.article.isConfigurable) {
1875
+ const article = yield this._getJSONFromArticleObject({ article: this.article, quantity: quantity });
1876
+ if (article) {
1877
+ this._appEventService.onAddToCart.next({ article: article, quantity: quantity });
1878
+ }
1879
+ }
1880
+ else {
1881
+ yield this._handleGeneratedArticleDirectly(quantity);
1805
1882
  }
1806
1883
  }
1807
1884
  else {
@@ -1818,8 +1895,15 @@ class ProductAddtocartComponent {
1818
1895
  }
1819
1896
  }
1820
1897
  else {
1821
- const article = this._ioneControllerService.convertArticleFullObjectToArticleExtended(this.article);
1822
- this._appEventService.onAddToCart.next({ article: article, quantity: quantity });
1898
+ if (this.article.goodType === 'B') {
1899
+ if (!this.article.isConfigurable) {
1900
+ yield this._handleGeneratedArticleDirectly(quantity);
1901
+ }
1902
+ }
1903
+ else {
1904
+ const article = this._ioneControllerService.convertArticleFullObjectToArticleExtended(this.article);
1905
+ this._appEventService.onAddToCart.next({ article: article, quantity: quantity });
1906
+ }
1823
1907
  }
1824
1908
  });
1825
1909
  }
@@ -1828,6 +1912,21 @@ class ProductAddtocartComponent {
1828
1912
  this._appEventService.onAddToQuote.next(yield this._getJSONFromArticleObject({ article: this.article, quantity: quantity }));
1829
1913
  });
1830
1914
  }
1915
+ _handleGeneratedArticleDirectly(quantity) {
1916
+ return __awaiter(this, void 0, void 0, function* () {
1917
+ const generatedGoodId = yield this._getGeneratedArtDirectly(this.article.goodId);
1918
+ if (generatedGoodId) {
1919
+ const articleFull = yield this._productConnectorAdapterService.getArticleFullObject(generatedGoodId, true);
1920
+ const article = this._ioneControllerService.convertArticleFullObjectToArticleExtended(articleFull);
1921
+ this._appEventService.onAddToCart.next({ article: article, quantity: quantity });
1922
+ }
1923
+ });
1924
+ }
1925
+ _getGeneratedArtDirectly(goodId) {
1926
+ return __awaiter(this, void 0, void 0, function* () {
1927
+ return yield this._ioneControllerService.getGeneratedArtDirectly(goodId, true);
1928
+ });
1929
+ }
1831
1930
  _getJSONFromArticleObject(article) {
1832
1931
  return __awaiter(this, void 0, void 0, function* () {
1833
1932
  const configuratorStatistics = new ConfiguratorStatisticsEnvironment();
@@ -1882,7 +1981,8 @@ ProductAddtocartComponent.ctorParameters = () => [
1882
1981
  { type: IconCacheService },
1883
1982
  { type: ProductConnectorService },
1884
1983
  { type: ProductEventService },
1885
- { type: ProductSettingsService }
1984
+ { type: ProductSettingsService },
1985
+ { type: ProductConnectorAdapterService }
1886
1986
  ];
1887
1987
  ProductAddtocartComponent.propDecorators = {
1888
1988
  addToCartButton: [{ type: ViewChild, args: ['addtocartbutton', { read: ElementRef },] }],
@@ -2273,7 +2373,7 @@ class ProductInfoTabsComponent {
2273
2373
  this.updateHeight(tabIndex);
2274
2374
  }
2275
2375
  updateHeight(tabIndex) {
2276
- if (this.tabContent.nativeElement.children.length > 0) {
2376
+ if (this.tabContent && this.tabContent.nativeElement.children.length > 0) {
2277
2377
  if (this.tabContent.nativeElement.children[tabIndex] !== undefined) {
2278
2378
  this.activeTabHeight = this.tabContent.nativeElement.children[tabIndex].offsetHeight;
2279
2379
  }