@colijnit/product 260.1.1 → 260.1.3

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.
@@ -2,17 +2,21 @@ import { ChangeDetectorRef, ElementRef, OnDestroy } from '@angular/core';
2
2
  import { CoDocument } from '@colijnit/mainapi/build/model/co-document.bo';
3
3
  import { ProductConnectorService } from '../../service/product-connector.service';
4
4
  import { ProductEventService } from '../../service/product-event.service';
5
+ import { IconEnum } from '../../enum/icon.enum';
5
6
  import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
7
+ import { IconCacheService } from '../../service/icon-cache.service';
6
8
  export declare class ImageViewModel {
7
9
  image: CoDocument | string;
8
10
  source: SafeUrl;
9
11
  originalSource: string;
10
12
  }
11
13
  export declare class ImageCarouselComponent implements OnDestroy {
14
+ iconCacheService: IconCacheService;
12
15
  private _ione;
13
16
  private _appEventService;
14
17
  private _changeDetector;
15
18
  private _domSanitizer;
19
+ readonly icons: typeof IconEnum;
16
20
  carousel: ElementRef;
17
21
  isPopupOpen: boolean;
18
22
  selectedImage?: ImageViewModel;
@@ -34,7 +38,7 @@ export declare class ImageCarouselComponent implements OnDestroy {
34
38
  private _images;
35
39
  private _subs;
36
40
  private _resizeCanvasHeight;
37
- constructor(_ione: ProductConnectorService, _appEventService: ProductEventService, _changeDetector: ChangeDetectorRef, _domSanitizer: DomSanitizer);
41
+ constructor(iconCacheService: IconCacheService, _ione: ProductConnectorService, _appEventService: ProductEventService, _changeDetector: ChangeDetectorRef, _domSanitizer: DomSanitizer);
38
42
  ngOnDestroy(): void;
39
43
  handleThumbClick(index: number): void;
40
44
  onForceRenderImage(): void;
@@ -43,6 +47,6 @@ export declare class ImageCarouselComponent implements OnDestroy {
43
47
  private _filterValidImages;
44
48
  private _loadAndRescaleImages;
45
49
  private _resizeAndSanitizeSource;
46
- private _detectPreferredMime;
50
+ private _handleMimeTypes;
47
51
  private _scrollCarouselToIndex;
48
52
  }
@@ -1,11 +1,16 @@
1
1
  import { ArticleListObject } from '@colijnit/articleapi/build/model/article-list-object';
2
2
  import { ProductConnectorService } from '../../service/product-connector.service';
3
3
  import { ProductEventService } from '../../service/product-event.service';
4
- import { ProductConnectorAdapterService } from "../../service/product-connector-adapter.service";
5
- import { ProductSettingsService } from "../../service/product-settings.service";
4
+ import { ProductConnectorAdapterService } from '../../service/product-connector-adapter.service';
5
+ import { ProductSettingsService } from '../../service/product-settings.service';
6
6
  import { ExternalSource } from '@colijnit/articleapi/build/model/external-source.bo';
7
+ export declare class ArticleViewModel {
8
+ article: ArticleListObject;
9
+ imageData: string;
10
+ constructor(article: ArticleListObject, imageData?: string);
11
+ }
7
12
  export declare class ProductRelatedComponent {
8
- _iOne: ProductConnectorService;
13
+ private _iOne;
9
14
  private _appEventService;
10
15
  private _productConnectorAdapterService;
11
16
  private _settingsService;
@@ -16,7 +21,7 @@ export declare class ProductRelatedComponent {
16
21
  createFrozenArticle: boolean;
17
22
  set articles(value: ArticleListObject[]);
18
23
  get articles(): ArticleListObject[];
19
- imageDataMap: Map<number, string>;
24
+ articleViewModels: ArticleViewModel[];
20
25
  private _articles;
21
26
  constructor(_iOne: ProductConnectorService, _appEventService: ProductEventService, _productConnectorAdapterService: ProductConnectorAdapterService, _settingsService: ProductSettingsService);
22
27
  handleContentClick(article: ArticleListObject): void;
@@ -25,4 +30,5 @@ export declare class ProductRelatedComponent {
25
30
  handleThreeDButtonClick(article: ArticleListObject): void;
26
31
  private _getJSONFromArticleObject;
27
32
  private _loadImages;
33
+ private _handleImageData;
28
34
  }
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('@colijnit/ioneconnector/build/model/options'), require('@colijnit/articleapi/build/model/article-full-object'), require('@colijnit/articleapi/build/model/super-article'), require('@colijnit/articleapi/build/articles'), require('@colijnit/articleapi/build/model/delivery-prognosis'), require('@colijnit/articleapi/build/model/document-content'), require('@colijnit/ioneconnector/build/service/business-object-factory'), require('@colijnit/transactionapi/build/transaction'), require('@colijnit/mainapi'), require('@colijnit/transactionapi/build/model/transaction-info-response.bo'), require('@colijnit/articleapi/build/model/article-list-object-extended.bo'), require('@colijnit/mainapi/build/model/image-content.bo'), require('@angular/common/http'), require('@colijnit/ioneconnector/build/utils/string-utils'), require('@angular/common'), require('@angular/animations'), require('@angular/platform-browser'), require('@colijnit/corecomponents'), require('@colijnit/mainapi/build/model/co-document.bo'), require('@colijnit/articleapi/build/model/configurator-statistics-environment'), require('@colijnit/corecomponents_v12')) :
3
- typeof define === 'function' && define.amd ? define('@colijnit/product', ['exports', '@angular/core', 'rxjs', '@colijnit/ioneconnector/build/model/options', '@colijnit/articleapi/build/model/article-full-object', '@colijnit/articleapi/build/model/super-article', '@colijnit/articleapi/build/articles', '@colijnit/articleapi/build/model/delivery-prognosis', '@colijnit/articleapi/build/model/document-content', '@colijnit/ioneconnector/build/service/business-object-factory', '@colijnit/transactionapi/build/transaction', '@colijnit/mainapi', '@colijnit/transactionapi/build/model/transaction-info-response.bo', '@colijnit/articleapi/build/model/article-list-object-extended.bo', '@colijnit/mainapi/build/model/image-content.bo', '@angular/common/http', '@colijnit/ioneconnector/build/utils/string-utils', '@angular/common', '@angular/animations', '@angular/platform-browser', '@colijnit/corecomponents', '@colijnit/mainapi/build/model/co-document.bo', '@colijnit/articleapi/build/model/configurator-statistics-environment', '@colijnit/corecomponents_v12'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.colijnit = global.colijnit || {}, global.colijnit.product = {}), global.ng.core, global.rxjs, global.options, global.articleFullObject, global.superArticle, global.articles, global.deliveryPrognosis, global.documentContent, global.businessObjectFactory, global.transaction, global.mainapi, global.transactionInfoResponse_bo, global.articleListObjectExtended_bo, global.imageContent_bo, global.ng.common.http, global.stringUtils, global.ng.common, global.ng.animations, global.ng.platformBrowser, global.corecomponents, global.coDocument_bo, global.configuratorStatisticsEnvironment, global.corecomponents_v12));
5
- })(this, (function (exports, i0, rxjs, options, articleFullObject, superArticle, articles, deliveryPrognosis, documentContent, businessObjectFactory, transaction, mainapi, transactionInfoResponse_bo, articleListObjectExtended_bo, imageContent_bo, i1, stringUtils, common, animations, i1$1, corecomponents, coDocument_bo, configuratorStatisticsEnvironment, corecomponents_v12) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('@colijnit/ioneconnector/build/model/options'), require('@colijnit/articleapi/build/model/article-full-object'), require('@colijnit/articleapi/build/model/super-article'), require('@colijnit/articleapi/build/articles'), require('@colijnit/articleapi/build/model/delivery-prognosis'), require('@colijnit/articleapi/build/model/document-content'), require('@colijnit/ioneconnector/build/service/business-object-factory'), require('@colijnit/transactionapi/build/transaction'), require('@colijnit/mainapi'), require('@colijnit/transactionapi/build/model/transaction-info-response.bo'), require('@colijnit/articleapi/build/model/article-list-object-extended.bo'), require('@colijnit/mainapi/build/model/image-content.bo'), require('@angular/common/http'), require('@colijnit/ioneconnector/build/utils/string-utils'), require('@angular/common'), require('@angular/animations'), require('@angular/platform-browser'), require('@colijnit/corecomponents'), require('@colijnit/mainapi/build/model/co-document.bo'), require('@angular/cdk/overlay'), require('@colijnit/corecomponents_v12'), require('@colijnit/articleapi/build/model/configurator-statistics-environment')) :
3
+ typeof define === 'function' && define.amd ? define('@colijnit/product', ['exports', '@angular/core', 'rxjs', '@colijnit/ioneconnector/build/model/options', '@colijnit/articleapi/build/model/article-full-object', '@colijnit/articleapi/build/model/super-article', '@colijnit/articleapi/build/articles', '@colijnit/articleapi/build/model/delivery-prognosis', '@colijnit/articleapi/build/model/document-content', '@colijnit/ioneconnector/build/service/business-object-factory', '@colijnit/transactionapi/build/transaction', '@colijnit/mainapi', '@colijnit/transactionapi/build/model/transaction-info-response.bo', '@colijnit/articleapi/build/model/article-list-object-extended.bo', '@colijnit/mainapi/build/model/image-content.bo', '@angular/common/http', '@colijnit/ioneconnector/build/utils/string-utils', '@angular/common', '@angular/animations', '@angular/platform-browser', '@colijnit/corecomponents', '@colijnit/mainapi/build/model/co-document.bo', '@angular/cdk/overlay', '@colijnit/corecomponents_v12', '@colijnit/articleapi/build/model/configurator-statistics-environment'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.colijnit = global.colijnit || {}, global.colijnit.product = {}), global.ng.core, global.rxjs, global.options, global.articleFullObject, global.superArticle, global.articles, global.deliveryPrognosis, global.documentContent, global.businessObjectFactory, global.transaction, global.mainapi, global.transactionInfoResponse_bo, global.articleListObjectExtended_bo, global.imageContent_bo, global.ng.common.http, global.stringUtils, global.ng.common, global.ng.animations, global.ng.platformBrowser, global.corecomponents, global.coDocument_bo, global.ng.cdk.overlay, global.corecomponents_v12, global.configuratorStatisticsEnvironment));
5
+ })(this, (function (exports, i0, rxjs, options, articleFullObject, superArticle, articles, deliveryPrognosis, documentContent, businessObjectFactory, transaction, mainapi, transactionInfoResponse_bo, articleListObjectExtended_bo, imageContent_bo, i1, stringUtils, common, animations, i1$1, corecomponents, coDocument_bo, overlay, corecomponents_v12, configuratorStatisticsEnvironment) { 'use strict';
6
6
 
7
7
  function _interopNamespace(e) {
8
8
  if (e && e.__esModule) return e;
@@ -31,8 +31,8 @@
31
31
  function Version() {
32
32
  this.name = "@colijnit/product";
33
33
  this.description = "Product detail page project for iOne";
34
- this.symVer = "260.1.1";
35
- this.publishDate = "15-12-2025 17:02:25";
34
+ this.symVer = "260.1.3";
35
+ this.publishDate = "24-3-2026 16:21:40";
36
36
  }
37
37
  return Version;
38
38
  }());
@@ -2078,12 +2078,14 @@
2078
2078
  return ImageViewModel;
2079
2079
  }());
2080
2080
  var ImageCarouselComponent = /** @class */ (function () {
2081
- function ImageCarouselComponent(_ione, _appEventService, _changeDetector, _domSanitizer) {
2081
+ function ImageCarouselComponent(iconCacheService, _ione, _appEventService, _changeDetector, _domSanitizer) {
2082
2082
  var _this = this;
2083
+ this.iconCacheService = iconCacheService;
2083
2084
  this._ione = _ione;
2084
2085
  this._appEventService = _appEventService;
2085
2086
  this._changeDetector = _changeDetector;
2086
2087
  this._domSanitizer = _domSanitizer;
2088
+ this.icons = IconEnum;
2087
2089
  this.isPopupOpen = false;
2088
2090
  this.showRefresh = false;
2089
2091
  this.resizing = false;
@@ -2232,51 +2234,63 @@
2232
2234
  var ctx = resizeCanvas.getContext('2d');
2233
2235
  var img = document.createElement('img');
2234
2236
  img.crossOrigin = 'anonymous';
2237
+ var handleFallback = function () {
2238
+ // When a CDN does not accept our tainted canvas, we fallback to the original source.
2239
+ imageViewModel.source = _this._domSanitizer.bypassSecurityTrustUrl(source);
2240
+ imageViewModel.originalSource = source;
2241
+ _this._changeDetector.detectChanges();
2242
+ };
2243
+ img.onerror = function () {
2244
+ handleFallback();
2245
+ };
2235
2246
  img.onload = function () {
2236
- ctx.imageSmoothingEnabled = true;
2237
- ctx.imageSmoothingQuality = 'high';
2238
- var ow = img.width;
2239
- var oh = img.height;
2240
- var aspect = ow / oh;
2241
- var newW = _this._resizeCanvasHeight;
2242
- var newH = _this._resizeCanvasHeight;
2243
- if (ow > oh) {
2244
- newH = _this._resizeCanvasHeight / aspect;
2247
+ try {
2248
+ ctx.imageSmoothingEnabled = true;
2249
+ ctx.imageSmoothingQuality = 'high';
2250
+ var aspect = img.width / img.height;
2251
+ var newW = _this._resizeCanvasHeight;
2252
+ var newH = _this._resizeCanvasHeight;
2253
+ if (img.width > img.height) {
2254
+ newH = _this._resizeCanvasHeight / aspect;
2255
+ }
2256
+ else {
2257
+ newW = _this._resizeCanvasHeight * aspect;
2258
+ }
2259
+ resizeCanvas.width = Math.round(newW);
2260
+ resizeCanvas.height = Math.round(newH);
2261
+ ctx.clearRect(0, 0, resizeCanvas.width, resizeCanvas.height);
2262
+ ctx.drawImage(img, 0, 0, resizeCanvas.width, resizeCanvas.height);
2263
+ var mime = _this._handleMimeTypes(source);
2264
+ var resizedSource = resizeCanvas.toDataURL(mime);
2265
+ imageViewModel.source = _this._domSanitizer.bypassSecurityTrustUrl(resizedSource);
2266
+ imageViewModel.originalSource = source;
2267
+ _this._changeDetector.detectChanges();
2245
2268
  }
2246
- else {
2247
- newW = _this._resizeCanvasHeight * aspect;
2269
+ catch (error) {
2270
+ handleFallback();
2248
2271
  }
2249
- resizeCanvas.width = Math.round(newW);
2250
- resizeCanvas.height = Math.round(newH);
2251
- // Ensure transparent background before drawing
2252
- ctx.clearRect(0, 0, resizeCanvas.width, resizeCanvas.height);
2253
- ctx.drawImage(img, 0, 0, resizeCanvas.width, resizeCanvas.height);
2254
- var mime = _this._detectPreferredMime(source);
2255
- var resizedSource = mime === 'image/jpeg'
2256
- ? resizeCanvas.toDataURL('image/jpeg', 0.92) // only if original was JPEG
2257
- : resizeCanvas.toDataURL(mime); // PNG/WebP keep alpha
2258
- imageViewModel.source = _this._domSanitizer.bypassSecurityTrustUrl(resizedSource);
2259
- imageViewModel.originalSource = source;
2260
- _this._changeDetector.detectChanges();
2261
2272
  };
2262
2273
  img.src = source;
2263
2274
  };
2264
- ImageCarouselComponent.prototype._detectPreferredMime = function (source) {
2265
- // Data URI check
2266
- var m = source.match(/^data:(image\/[a-zA-Z+.-]+);base64,/);
2267
- if (m) {
2268
- var t = m[1].toLowerCase();
2269
- if (t === 'image/png' || t === 'image/webp' || t === 'image/jpeg')
2270
- return t;
2275
+ ImageCarouselComponent.prototype._handleMimeTypes = function (imageSource) {
2276
+ // When we got base64 data
2277
+ if (imageSource.startsWith('data:')) {
2278
+ var match = imageSource.match(/^data:(image\/(png|webp|jpeg|jpg))/i);
2279
+ return match ? match[1].toLowerCase() : 'image/png';
2280
+ }
2281
+ // when we got an URL.
2282
+ var extension = imageSource.substring(imageSource.lastIndexOf('.') + 1).toLowerCase();
2283
+ switch (extension) {
2284
+ case 'png':
2285
+ return 'image/png';
2286
+ case 'webp':
2287
+ return 'image/webp';
2288
+ case 'jpg':
2289
+ case 'jpeg':
2290
+ return 'image/jpeg';
2291
+ default:
2292
+ return 'image/png';
2271
2293
  }
2272
- var lower = source.toLowerCase();
2273
- if (lower.endsWith('.png'))
2274
- return 'image/png';
2275
- if (lower.endsWith('.webp'))
2276
- return 'image/webp';
2277
- if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
2278
- return 'image/jpeg';
2279
- return 'image/png';
2280
2294
  };
2281
2295
  ImageCarouselComponent.prototype._scrollCarouselToIndex = function () {
2282
2296
  if (this.currentIndex > -1 && this.currentIndex <= this.images.length) {
@@ -2295,12 +2309,13 @@
2295
2309
  ImageCarouselComponent.decorators = [
2296
2310
  { type: i0.Component, args: [{
2297
2311
  selector: 'app-image-carousel',
2298
- template: "\n <div id=\"product_page_carousel\">\n <div id=\"product_page_carousel_items\">\n <co-loader [isShown]=\"true\" *ngIf=\"showLoader\"></co-loader>\n <div #carousel class=\"inner-carousel\">\n <!-- This has been taken out of the for loop to prevent flashing images when updating. -->\n <div *ngIf=\"imageViewModels[0]\" class=\"carousel-item\" [id]=\"'slide-0'\" [class.active]=\"isCurrentIndex(0)\" (click)=\"handleShowImage(imageViewModels[0])\">\n <img [src]=\"imageViewModels[0].source\">\n </div>\n <div *ngFor=\"let imageViewModel of imageViewModels.slice(1); let index = index\" class=\"carousel-item\"\n [id]=\"'slide-' + (index + 1)\" [class.active]=\"isCurrentIndex((index + 1))\" (click)=\"handleShowImage(imageViewModel)\">\n <img [src]=\"imageViewModel.source\">\n </div>\n <div class=\"carousel-scroller-layer\" *ngIf=\"imageViewModels && imageViewModels.length > 1\">\n <div class=\"carousel-item-scroller prev\" (click)=\"gotoPrevSlide()\" *ngIf=\"currentIndex > 0\"></div>\n <div class=\"carousel-item-scroller next\" (click)=\"gotoNextSlide()\" *ngIf=\"currentIndex < images.length - 1\"></div>\n </div>\n </div>\n <!--\n <co-icon class=\"selector-type-icon refresh-button\" [iconData]=\"iconCache.getIcon(icons.Refresh)\" (click)=\"onForceRenderImage()\" [class.loading]=\"showLoader\" *ngIf=\"showRefresh\"></co-icon>\n -->\n </div>\n\n <div id=\"product_page_carousel_thumbs\">\n <co-scroll-container class=\"scroll-container\" *ngIf=\"imageViewModels && imageViewModels.length > 1\">\n <div *ngFor=\"let imageViewModel of imageViewModels; let index = index\" class=\"carousel-thumb\"\n [class.active]=\"index === currentIndex\">\n <img [src]=\"imageViewModel.source\" (click)=\"handleThumbClick(index)\"/>\n </div>\n </co-scroll-container>\n </div>\n </div>\n <!-- Modal (real popup) -->\n <div\n class=\"image-modal\"\n *ngIf=\"isPopupOpen\"\n (click)=\"closePopup()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Image preview\"\n >\n <div class=\"image-modal__content\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"image-modal__close\"\n type=\"button\"\n aria-label=\"Close\"\n (click)=\"closePopup()\"\n >\n \u00D7\n </button>\n\n <img [src]=\"selectedImage?.originalSource\" alt=\"Image preview\" />\n </div>\n </div>\n ",
2312
+ template: "\n <div id=\"product_page_carousel\">\n <div id=\"product_page_carousel_items\">\n <co-loader [isShown]=\"true\" *ngIf=\"showLoader\"></co-loader>\n <div #carousel class=\"inner-carousel\">\n <!-- This has been taken out of the for loop to prevent flashing images when updating. -->\n <div *ngIf=\"imageViewModels[0]\" class=\"carousel-item\" [id]=\"'slide-0'\" [class.active]=\"isCurrentIndex(0)\"\n (click)=\"handleShowImage(imageViewModels[0])\">\n <img [src]=\"imageViewModels[0].source\">\n </div>\n <div *ngFor=\"let imageViewModel of imageViewModels.slice(1); let index = index\" class=\"carousel-item\"\n [id]=\"'slide-' + (index + 1)\" [class.active]=\"isCurrentIndex((index + 1))\" (click)=\"handleShowImage(imageViewModel)\">\n <img [src]=\"imageViewModel.source\">\n </div>\n <div class=\"carousel-scroller-layer\" *ngIf=\"imageViewModels && imageViewModels.length > 1\">\n <div class=\"carousel-item-scroller prev\" (click)=\"gotoPrevSlide()\" *ngIf=\"currentIndex > 0\"></div>\n <div class=\"carousel-item-scroller next\" (click)=\"gotoNextSlide()\" *ngIf=\"currentIndex < images.length - 1\"></div>\n </div>\n </div>\n <!--\n <co-icon class=\"selector-type-icon refresh-button\" [iconData]=\"iconCache.getIcon(icons.Refresh)\" (click)=\"onForceRenderImage()\" [class.loading]=\"showLoader\" *ngIf=\"showRefresh\"></co-icon>\n -->\n </div>\n\n <div id=\"product_page_carousel_thumbs\">\n <co-scroll-container class=\"scroll-container\" *ngIf=\"imageViewModels && imageViewModels.length > 1\">\n <div *ngFor=\"let imageViewModel of imageViewModels; let index = index\" class=\"carousel-thumb\"\n [class.active]=\"index === currentIndex\">\n <img [src]=\"imageViewModel.source\" (click)=\"handleThumbClick(index)\"/>\n </div>\n </co-scroll-container>\n </div>\n </div>\n\n <div cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\"></div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isPopupOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"closePopup()\">\n <div class=\"image-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Image preview\">\n <div class=\"image-modal__content\">\n <button class=\"image-modal__close\" type=\"button\" aria-label=\"Close\" (click)=\"closePopup()\">\n <co-icon [iconData]=\"iconCacheService.getIcon(icons.CrossSkinny)\"></co-icon>\n </button>\n <img [src]=\"selectedImage?.originalSource\" alt=\"Image preview\"/>\n </div>\n </div>\n </ng-template>\n\n ",
2299
2313
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
2300
2314
  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"]
2301
2315
  },] }
2302
2316
  ];
2303
2317
  ImageCarouselComponent.ctorParameters = function () { return [
2318
+ { type: IconCacheService },
2304
2319
  { type: ProductConnectorService },
2305
2320
  { type: ProductEventService },
2306
2321
  { type: i0.ChangeDetectorRef },
@@ -2328,7 +2343,9 @@
2328
2343
  common.CommonModule,
2329
2344
  corecomponents.LoaderModule,
2330
2345
  // IconModule,
2331
- corecomponents.ScrollContainerModule
2346
+ corecomponents.ScrollContainerModule,
2347
+ overlay.OverlayModule,
2348
+ corecomponents_v12.IconModule
2332
2349
  ],
2333
2350
  declarations: [
2334
2351
  ImageCarouselComponent
@@ -2785,6 +2802,15 @@
2785
2802
  },] }
2786
2803
  ];
2787
2804
 
2805
+ var ArticleViewModel = /** @class */ (function () {
2806
+ function ArticleViewModel(article, imageData) {
2807
+ this.article = article;
2808
+ if (imageData) {
2809
+ this.imageData = imageData;
2810
+ }
2811
+ }
2812
+ return ArticleViewModel;
2813
+ }());
2788
2814
  var ProductRelatedComponent = /** @class */ (function () {
2789
2815
  function ProductRelatedComponent(_iOne, _appEventService, _productConnectorAdapterService, _settingsService) {
2790
2816
  this._iOne = _iOne;
@@ -2793,7 +2819,7 @@
2793
2819
  this._settingsService = _settingsService;
2794
2820
  this.isSmallModus = true;
2795
2821
  this.createFrozenArticle = true;
2796
- this.imageDataMap = new Map();
2822
+ this.articleViewModels = [];
2797
2823
  this._articles = [];
2798
2824
  }
2799
2825
  Object.defineProperty(ProductRelatedComponent.prototype, "articles", {
@@ -2815,6 +2841,8 @@
2815
2841
  else {
2816
2842
  this._articles = value;
2817
2843
  }
2844
+ this.articleViewModels.length = 0;
2845
+ this._articles.forEach(function (a) { return _this.articleViewModels.push(new ArticleViewModel(a)); });
2818
2846
  this._loadImages();
2819
2847
  }
2820
2848
  },
@@ -2875,48 +2903,28 @@
2875
2903
  };
2876
2904
  ProductRelatedComponent.prototype._loadImages = function () {
2877
2905
  return __awaiter(this, void 0, void 0, function () {
2878
- var _a, _b, a, imageContent, e_1_1;
2879
- var e_1, _c;
2880
- return __generator(this, function (_d) {
2881
- switch (_d.label) {
2882
- case 0:
2883
- _d.trys.push([0, 5, 6, 7]);
2884
- _a = __values(this._articles), _b = _a.next();
2885
- _d.label = 1;
2886
- case 1:
2887
- if (!!_b.done) return [3 /*break*/, 4];
2888
- a = _b.value;
2889
- if (!a.image) return [3 /*break*/, 3];
2890
- return [4 /*yield*/, this._iOne.getImageForCoDocument(a.image, false)];
2891
- case 2:
2892
- imageContent = _d.sent();
2893
- this.imageDataMap.set(a.goodId, imageContent.image);
2894
- _d.label = 3;
2895
- case 3:
2896
- _b = _a.next();
2897
- return [3 /*break*/, 1];
2898
- case 4: return [3 /*break*/, 7];
2899
- case 5:
2900
- e_1_1 = _d.sent();
2901
- e_1 = { error: e_1_1 };
2902
- return [3 /*break*/, 7];
2903
- case 6:
2904
- try {
2905
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
2906
- }
2907
- finally { if (e_1) throw e_1.error; }
2908
- return [7 /*endfinally*/];
2909
- case 7: return [2 /*return*/];
2910
- }
2906
+ var _this = this;
2907
+ return __generator(this, function (_a) {
2908
+ this.articleViewModels.forEach(function (avm) {
2909
+ if (avm.article.image) {
2910
+ _this._iOne.getImageForCoDocument(avm.article.image, false).then(function (imageContent) { return _this._handleImageData(avm, imageContent); });
2911
+ }
2912
+ });
2913
+ return [2 /*return*/];
2911
2914
  });
2912
2915
  });
2913
2916
  };
2917
+ ProductRelatedComponent.prototype._handleImageData = function (avm, imageContent) {
2918
+ if (imageContent && imageContent.image) {
2919
+ avm.imageData = imageContent.image;
2920
+ }
2921
+ };
2914
2922
  return ProductRelatedComponent;
2915
2923
  }());
2916
2924
  ProductRelatedComponent.decorators = [
2917
2925
  { type: i0.Component, args: [{
2918
2926
  selector: 'app-product-related',
2919
- template: "\n <div *ngIf=\"articles && articles.length > 0\">\n <app-header [label]=\"label\" [amount]=\"articles?.length\" *ngIf=\"label\"></app-header>\n <co-scroll-container>\n <div class=\"article-wrapper\" *ngFor=\"let article of articles\">\n <co-article-tile \n [imageData]=\"imageDataMap.get(article.goodId)\"\n [description]=\"article.description\"\n [price]=\"article.price\"\n [level]=\"article.stockStatus\"\n [hasCartButton]=\"true\"\n [isSmallModus]=\"isSmallModus\"\n [hasConfigureButton]=\"article.goodType === 'B'\"\n (contentClick)=\"handleContentClick(article)\"\n (cartButtonClick)=\"handleAddToCartClick(article)\"\n (configureButtonClick)=\"handleContentClick(article)\"\n (threeDButtonClick)=\"handleThreeDButtonClick(article)\"\n ></co-article-tile>\n </div>\n </co-scroll-container>\n </div>\n ",
2927
+ template: "\n <div *ngIf=\"articles && articles.length > 0\">\n <app-header [label]=\"label\" [amount]=\"articles?.length\" *ngIf=\"label\"></app-header>\n <co-scroll-container>\n <div class=\"article-wrapper\" *ngFor=\"let articleViewModel of articleViewModels\">\n <co-article-tile \n [imageData]=\"articleViewModel.imageData\"\n [description]=\"articleViewModel.article.description\"\n [price]=\"articleViewModel.article.price\"\n [level]=\"articleViewModel.article.stockStatus\"\n [hasCartButton]=\"true\"\n [isSmallModus]=\"isSmallModus\"\n [hasConfigureButton]=\"articleViewModel.article.goodType === 'B'\"\n (contentClick)=\"handleContentClick(articleViewModel.article)\"\n (cartButtonClick)=\"handleAddToCartClick(articleViewModel.article)\"\n (configureButtonClick)=\"handleContentClick(articleViewModel.article)\"\n (threeDButtonClick)=\"handleThreeDButtonClick(articleViewModel.article)\"\n ></co-article-tile>\n </div>\n </co-scroll-container>\n </div>\n ",
2920
2928
  styles: [":host{display:block}.article-wrapper{display:flex;flex-direction:row;flex:1;min-width:25%}.article-wrapper ::ng-deep co-tile{transition:all .14s ease-out;border:1px solid transparent;padding:10px 20px;display:flex;flex-direction:column;color:#171721;justify-content:space-between}.article-wrapper ::ng-deep co-tile .price{display:block}.article-wrapper ::ng-deep co-tile .description{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;height:30px}.article-wrapper ::ng-deep co-tile .tile-bottom{display:flex;flex-direction:column;grid-gap:5px;gap:5px}.article-wrapper ::ng-deep co-tile:hover{border:1px solid #DCE4EA}.article-wrapper ::ng-deep co-tile .tile-extra-bottom co-button co-icon{width:24px;height:24px}.article-wrapper ::ng-deep co-tile .tile-extra-bottom co-button co-icon svg [fill]{fill:#fff}.article-wrapper ::ng-deep co-tile.small{max-width:189px;width:100%;height:100%;cursor:pointer}.article-wrapper ::ng-deep co-tile.small:hover .tile-bottom .left-buttons{margin:0!important}.article-wrapper ::ng-deep co-tile.small .tile-wrapper{outline:none!important;padding-bottom:0;overflow:hidden;grid-gap:10px;gap:10px;display:flex;flex-direction:column}.article-wrapper ::ng-deep co-tile.small .tile-wrapper div.image{height:100px}.article-wrapper ::ng-deep co-tile.small .tile-wrapper .tile-extra-bottom ::ng-deep co-button.card-button.mini{pointer-events:all;padding:0!important;font-size:0;width:42px;height:42px;text-align:center;margin:0;border-radius:100%;background:#3E7EFF;cursor:pointer;place-content:center;color:#fff}.article-wrapper ::ng-deep co-tile.small .tile-wrapper .tile-extra-bottom ::ng-deep co-button.card-button.mini ::ng-deep co-icon{width:30px;height:30px}.article-wrapper ::ng-deep co-tile.small .tile-extra-bottom{outline:none!important;background:transparent!important}.article-wrapper ::ng-deep co-tile.small .tile-extra-bottom .price{color:#74b77f;margin:5px 0 0;font-weight:400;font-size:12px}\n"]
2921
2929
  },] }
2922
2930
  ];