ng-miam 9.3.1 → 9.3.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.
@@ -725,6 +725,155 @@
725
725
  event.preventDefault();
726
726
  };
727
727
 
728
+ /**
729
+ * Journey detection utility
730
+ *
731
+ * Allows to determine the journey name based on elements present on the page.
732
+ * You can define custom mappings between CSS selectors, URL parameters, and URLs.
733
+ */
734
+ /**
735
+ * Default journey mappings
736
+ * You can extend or override these mappings as needed
737
+ */
738
+ var defaultJourneyMappings = {
739
+ 'meals-space-catalog-search': {
740
+ selector: ['.mealz-catalog__title', '.miam-recipe-catalog__content__title__search__text'],
741
+ urlParam: 'search'
742
+ },
743
+ 'meals-space-home': ['mealz-catalog-home', '.miam-catalog-header'],
744
+ 'meals-space-category-search': {
745
+ selector: ['mealz-catalog-category', '.miam-catalog-header__category-label'],
746
+ urlParam: 'search'
747
+ },
748
+ 'meals-space-category': ['mealz-catalog-category', '.miam-catalog-header__category-label'],
749
+ 'meals-space-all-recipes': ['mealz-catalog-all-recipes', '.miam-recipe-catalog__content__title__all-recipes__text'],
750
+ 'my-space-favorites': ['mealz-catalog-favorites', '#favorites-panel'],
751
+ 'my-space-history': 'mealz-catalog-history'
752
+ };
753
+ /**
754
+ * Checks if a URL parameter exists in the current URL
755
+ *
756
+ * @param paramName - The name of the URL parameter to check
757
+ * @param location - Optional location object (defaults to window.location)
758
+ * @returns True if the parameter exists (even if empty), false otherwise
759
+ */
760
+ var hasUrlParam = function (paramName, location) {
761
+ var loc = location !== null && location !== void 0 ? location : (typeof window !== 'undefined' ? window.location : null);
762
+ if (!loc) {
763
+ return false;
764
+ }
765
+ var urlParams = new URLSearchParams(loc.search);
766
+ return urlParams.has(paramName);
767
+ };
768
+ /**
769
+ * Checks if the current URL matches a pattern
770
+ *
771
+ * @param pattern - URL string or RegExp pattern to match
772
+ * @param location - Optional location object (defaults to window.location)
773
+ * @returns True if the URL matches the pattern, false otherwise
774
+ */
775
+ var matchesUrl = function (pattern, location) {
776
+ var loc = location !== null && location !== void 0 ? location : (typeof window !== 'undefined' ? window.location : null);
777
+ if (!loc) {
778
+ return false;
779
+ }
780
+ var fullUrl = loc.href;
781
+ var pathname = loc.pathname;
782
+ if (pattern instanceof RegExp) {
783
+ return pattern.test(fullUrl) || pattern.test(pathname);
784
+ }
785
+ // String pattern: check if it's a full URL or a path
786
+ if (pattern.startsWith('http://') || pattern.startsWith('https://')) {
787
+ return fullUrl.includes(pattern);
788
+ }
789
+ // Treat as pathname pattern
790
+ return pathname.includes(pattern);
791
+ };
792
+ /**
793
+ * Normalizes a journey configuration to a standard format
794
+ *
795
+ * @param config - The journey configuration (can be string, string[], or object)
796
+ * @returns Normalized configuration object
797
+ */
798
+ var normalizeJourneyConfig = function (config) {
799
+ if (typeof config === 'string') {
800
+ return { selector: config };
801
+ }
802
+ if (Array.isArray(config)) {
803
+ return { selector: config };
804
+ }
805
+ return config;
806
+ };
807
+ /**
808
+ * Detects the journey name based on elements present on the page
809
+ *
810
+ * @param mappings - Optional custom mappings. If not provided, uses default mappings
811
+ * @param document - Optional document object (defaults to window.document)
812
+ * @param location - Optional location object (defaults to window.location)
813
+ * @returns The detected journey name, or null if no match is found
814
+ */
815
+ var detectJourney = function (mappings, document, location) {
816
+ var e_1, _b;
817
+ var doc = document !== null && document !== void 0 ? document : (typeof window !== 'undefined' ? window.document : null);
818
+ if (!doc) {
819
+ return null;
820
+ }
821
+ var journeyMappings = mappings !== null && mappings !== void 0 ? mappings : defaultJourneyMappings;
822
+ try {
823
+ // Check each journey mapping
824
+ for (var _c = __values(Object.entries(journeyMappings)), _d = _c.next(); !_d.done; _d = _c.next()) {
825
+ var _e = __read(_d.value, 2), journeyName = _e[0], config = _e[1];
826
+ var normalizedConfig = normalizeJourneyConfig(config);
827
+ var selectorArray = Array.isArray(normalizedConfig.selector)
828
+ ? normalizedConfig.selector
829
+ : [normalizedConfig.selector];
830
+ // Check if at least one selector matches an element on the page
831
+ var hasSelectorMatch = selectorArray.some(function (selector) {
832
+ try {
833
+ return doc.querySelector(selector) !== null;
834
+ }
835
+ catch (_a) {
836
+ // Invalid selector, skip it
837
+ return false;
838
+ }
839
+ });
840
+ if (!hasSelectorMatch) {
841
+ continue;
842
+ }
843
+ // Check URL parameter if specified
844
+ if (normalizedConfig.urlParam) {
845
+ if (!hasUrlParam(normalizedConfig.urlParam, location)) {
846
+ continue;
847
+ }
848
+ }
849
+ // Check URL pattern if specified
850
+ if (normalizedConfig.url) {
851
+ if (!matchesUrl(normalizedConfig.url, location)) {
852
+ continue;
853
+ }
854
+ }
855
+ // All conditions met, return this journey
856
+ return journeyName;
857
+ }
858
+ }
859
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
860
+ finally {
861
+ try {
862
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
863
+ }
864
+ finally { if (e_1) throw e_1.error; }
865
+ }
866
+ return null;
867
+ };
868
+ /**
869
+ * Registers custom journey mappings
870
+ * Merges with default mappings (custom mappings take precedence)
871
+ *
872
+ * @param customMappings - Custom journey mappings to add or override
873
+ * @returns Combined mappings (default + custom)
874
+ */
875
+ var createJourneyMappings = function (customMappings) { return (Object.assign(Object.assign({}, defaultJourneyMappings), customMappings)); };
876
+
728
877
  var CapitalizeFirstLetterPipe = /** @class */ (function () {
729
878
  function CapitalizeFirstLetterPipe() {
730
879
  }
@@ -3503,7 +3652,7 @@
3503
3652
  EventJourney["EMPTY"] = "";
3504
3653
  })(EventJourney || (EventJourney = {}));
3505
3654
 
3506
- var VERSION = "9.3.1"; // TODO: replace by ##VERSION## and update it in the CI/CD
3655
+ var VERSION = "9.3.3"; // TODO: replace by ##VERSION## and update it in the CI/CD
3507
3656
 
3508
3657
  var ContextRegistryService = /** @class */ (function () {
3509
3658
  function ContextRegistryService() {
@@ -3606,52 +3755,69 @@
3606
3755
  if (environment$1.env === 'dev' && environment$1.analyticsEnabled === false) {
3607
3756
  return;
3608
3757
  }
3609
- if (!journey) {
3610
- journey = this.isMealzPage ? EventJourney.MEALZ : EventJourney.EMPTY;
3611
- }
3612
- // Currently no way to know if it is search or shelves
3613
- this.callMethodOrAddToQueue(function () { return mealzSharedAnalytics.sendEvent(name, url(path), journey, props); });
3758
+ // Use provided journey or determine from context
3759
+ var eventJourney = journey || (this.isMealzPage ? EventJourney.MEALZ : EventJourney.EMPTY);
3760
+ this.callMethodOrAddToQueue(function () { return mealzSharedAnalytics.sendEvent(name, url(path), eventJourney, props); });
3614
3761
  };
3615
3762
  /** ************************************************* SEND EVENT FOR BASKET ACTIONS ************************************************* **/
3616
- AnalyticsService.prototype.sendRemoveRecipesEvents = function (actions) {
3763
+ AnalyticsService.prototype.sendRemoveRecipesEvents = function (actions, journey) {
3617
3764
  var _this = this;
3765
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3618
3766
  actions.forEach(function (action) {
3619
- _this.sendEvent('recipe.remove', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId });
3767
+ _this.sendEvent('recipe.remove', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3620
3768
  });
3621
3769
  };
3622
- AnalyticsService.prototype.sendAddRecipesEvents = function (actions) {
3770
+ AnalyticsService.prototype.sendAddRecipesEvents = function (actions, journey) {
3623
3771
  var _this = this;
3772
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3624
3773
  actions.forEach(function (action) {
3625
- _this.sendEvent('recipe.add', '', { recipe_id: action.params.recipeId });
3774
+ _this.sendEvent('recipe.add', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3626
3775
  });
3627
3776
  };
3628
- AnalyticsService.prototype.sendUpdateGuestsEvents = function (actions) {
3777
+ AnalyticsService.prototype.sendUpdateGuestsEvents = function (actions, journey) {
3629
3778
  var _this = this;
3779
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3630
3780
  actions.forEach(function (action) {
3631
- _this.sendEvent('recipe.change-guests', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId });
3781
+ _this.sendEvent('recipe.change-guests', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3632
3782
  });
3633
3783
  };
3634
- AnalyticsService.prototype.sendEventsOfResetBasket = function (basket, eventTrace) {
3784
+ AnalyticsService.prototype.sendEventsOfResetBasket = function (basket, eventTrace, journey) {
3635
3785
  var _this = this;
3786
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3636
3787
  basket.recipeInfos.forEach(function (info) {
3637
- _this.sendEvent('recipe.remove', eventTrace.originPath, { recipe_id: info.id });
3788
+ _this.sendEvent('recipe.remove', eventTrace.originPath, { recipe_id: info.id }, detectedJourney);
3638
3789
  });
3639
3790
  };
3640
- AnalyticsService.prototype.sendAddProductsEvents = function (actions) {
3791
+ AnalyticsService.prototype.sendAddProductsEvents = function (actions, journey) {
3641
3792
  var _this = this;
3793
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3794
+ var isBulk = actions.length > 1;
3642
3795
  actions.forEach(function (action) {
3796
+ // Determine add_source: replacement if previousItem exists, otherwise unit or bulk based on actions count
3797
+ var addSource;
3798
+ if (action.params.previousItem) {
3799
+ addSource = 'replacement';
3800
+ }
3801
+ else if (isBulk) {
3802
+ addSource = 'bulk';
3803
+ }
3804
+ else {
3805
+ addSource = 'unit';
3806
+ }
3643
3807
  _this.sendEvent('entry.added', action.params.eventTrace.originPath, {
3644
3808
  entry_name: action.params.basketEntry.name,
3645
3809
  item_id: action.params.basketEntry.selectedItem.id,
3646
3810
  ext_item_id: action.params.basketEntry.selectedItem.attributes['ext-id'],
3647
3811
  item_ean: action.params.basketEntry.selectedItem.ean,
3648
3812
  product_quantity: action.params.basketEntry.quantity.toString(),
3649
- recipe_id: action.params.recipeId
3650
- });
3813
+ recipe_id: action.params.recipeId,
3814
+ add_source: addSource
3815
+ }, detectedJourney);
3651
3816
  });
3652
3817
  };
3653
- AnalyticsService.prototype.sendRemoveProductsEvents = function (actions) {
3818
+ AnalyticsService.prototype.sendRemoveProductsEvents = function (actions, journey) {
3654
3819
  var _this = this;
3820
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3655
3821
  actions.forEach(function (action) {
3656
3822
  _this.sendEvent('entry.deleted', action.params.eventTrace.originPath, {
3657
3823
  entry_name: action.params.basketEntry.name,
@@ -3660,11 +3826,12 @@
3660
3826
  item_ean: action.params.basketEntry.selectedItem.ean,
3661
3827
  product_quantity: action.params.basketEntry.quantity.toString(),
3662
3828
  recipe_id: action.params.recipeId
3663
- });
3829
+ }, detectedJourney);
3664
3830
  });
3665
3831
  };
3666
- AnalyticsService.prototype.sendProductsChangeQuantityEvents = function (actions) {
3832
+ AnalyticsService.prototype.sendProductsChangeQuantityEvents = function (actions, journey) {
3667
3833
  var _this = this;
3834
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3668
3835
  actions.forEach(function (action) {
3669
3836
  _this.sendEvent('entry.change-quantity', action.params.eventTrace.originPath, {
3670
3837
  entry_name: action.params.basketEntry.name,
@@ -3673,7 +3840,7 @@
3673
3840
  item_ean: action.params.basketEntry.selectedItem.ean,
3674
3841
  product_quantity: action.params.newQuantity.toString(),
3675
3842
  recipe_id: action.params.recipeId
3676
- });
3843
+ }, detectedJourney);
3677
3844
  });
3678
3845
  };
3679
3846
  AnalyticsService.prototype.callMethodOrAddToQueue = function (method) {
@@ -5280,12 +5447,26 @@
5280
5447
  return null;
5281
5448
  }));
5282
5449
  };
5283
- RecipesService.prototype.getPricing = function (recipeId, posId, serves) {
5450
+ RecipesService.prototype.getPricing = function (recipeId, posId, serves, isExtStoreId) {
5451
+ var _this = this;
5284
5452
  if (serves === void 0) { serves = null; }
5453
+ if (isExtStoreId === void 0) { isExtStoreId = false; }
5285
5454
  if (!recipeId) {
5286
5455
  return rxjs.of(null);
5287
5456
  }
5288
- var url = MIAM_API_HOST$2 + ("recipes/" + recipeId + "/pricing?point_of_sale_id=" + posId);
5457
+ if (isExtStoreId) {
5458
+ return this.suppliersService.supplier$.pipe(operators.skipWhile(function (supplier) { return !(supplier === null || supplier === void 0 ? void 0 : supplier.id); }), operators.take(1), operators.switchMap(function (supplier) {
5459
+ var pricingUrl = MIAM_API_HOST$2 + ("recipes/" + recipeId + "/pricing");
5460
+ pricingUrl += "?point-of-sale-ext-id=" + posId;
5461
+ pricingUrl += "&supplier-id=" + supplier.id;
5462
+ if (serves) {
5463
+ pricingUrl += "&serves=" + serves;
5464
+ }
5465
+ return _this.http.get(pricingUrl).pipe(operators.map(function (result) { return new RecipePricing(result); }));
5466
+ }));
5467
+ }
5468
+ var url = MIAM_API_HOST$2 + ("recipes/" + recipeId + "/pricing");
5469
+ url += "?point_of_sale_id=" + posId;
5289
5470
  if (serves) {
5290
5471
  url += "&serves=" + serves;
5291
5472
  }
@@ -5976,7 +6157,11 @@
5976
6157
  BasketsService.prototype.fetchCurrentBasket = function (posId) {
5977
6158
  var _this = this;
5978
6159
  var getUrl = "current?point_of_sale_id=" + posId + "&fields[baskets]=" + BASKET_SPARSE_FIELDS.baskets.join(',');
5979
- return this.get(getUrl).pipe(operators.switchMap(function (basket) { return _this.updateLocalBasket(basket); }), operators.tap(function () { return _this.posService.emitBasketLoadedForNewPos(); }));
6160
+ return this.get(getUrl).pipe(operators.switchMap(function (basket) { return _this.updateLocalBasket(basket); }), operators.tap(function () {
6161
+ if (_this.posService.emitBasketLoadedForNewPos) {
6162
+ _this.posService.emitBasketLoadedForNewPos();
6163
+ }
6164
+ }));
5980
6165
  };
5981
6166
  BasketsService.prototype.resetBasket = function (eventTrace) {
5982
6167
  var _this = this;
@@ -6195,11 +6380,11 @@
6195
6380
  }); });
6196
6381
  this.basketActionsQueue.next(toAdd);
6197
6382
  };
6198
- BasketsService.prototype.addItemToBasket = function (item, eventTrace) {
6383
+ BasketsService.prototype.addItemToBasket = function (item, eventTrace, previousItem) {
6199
6384
  var toAdd = this.basketActionsQueue.value;
6200
6385
  toAdd.push({
6201
6386
  type: BasketActionType.ADD_ITEM,
6202
- params: { item: item, eventTrace: eventTrace }
6387
+ params: { item: item, eventTrace: eventTrace, previousItem: previousItem }
6203
6388
  });
6204
6389
  this.basketActionsQueue.next(toAdd);
6205
6390
  };
@@ -6448,8 +6633,13 @@
6448
6633
  ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
6449
6634
  return _this.http.patch(patchUrl, {});
6450
6635
  });
6451
- _this.analyticsService.sendAddProductsEvents(ingredientsToAdd);
6452
6636
  return rxjs.forkJoin(requests);
6637
+ }), operators.tap(function () {
6638
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6639
+ var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
6640
+ ? 'item-replacement'
6641
+ : 'meals-space-recipe-details';
6642
+ _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
6453
6643
  }), operators.switchMap(function () { return _this.reloadBasket(); }), operators.switchMap(function () { return rxjs.of(null); }), // Just to keep the return type as Observable<void> to match with the other methods
6454
6644
  operators.catchError(function () { return rxjs.of(null); }));
6455
6645
  };
@@ -6468,8 +6658,13 @@
6468
6658
  ("&name=" + action.params.item.attributes.name);
6469
6659
  return _this.http.post(encodeURI(postUrl.trim()), {});
6470
6660
  });
6471
- _this.analyticsService.sendAddProductsEvents(itemsToAdd);
6472
6661
  return rxjs.forkJoin(requests);
6662
+ }), operators.tap(function () {
6663
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6664
+ var journey = itemsToAdd.some(function (action) { return action.params.previousItem; })
6665
+ ? 'item-replacement'
6666
+ : 'meals-space-recipe-details';
6667
+ _this.analyticsService.sendAddProductsEvents(itemsToAdd, journey);
6473
6668
  }), operators.switchMap(function () { return _this.reloadBasket(); }), operators.switchMap(function () { return rxjs.of(null); }), // Just to keep the return type as Observable<void> to match with the other methods
6474
6669
  operators.catchError(function () { return rxjs.of(null); }));
6475
6670
  };
@@ -8508,11 +8703,12 @@
8508
8703
  recipeLikeUpdated: function () { return _this.recipeLikesService.recipeLikeUpdated$; },
8509
8704
  guestsUpdated: function () { return _this.guestsChanged; },
8510
8705
  recipePriceUpdated: function () { return _this.recipePriceChanged; },
8511
- fetchPricing: function (recipeId, posId, serves) {
8706
+ fetchPricing: function (recipeId, posId, serves, isExtStoreId) {
8707
+ if (isExtStoreId === void 0) { isExtStoreId = false; }
8512
8708
  if (!recipeId || !posId || !serves) {
8513
8709
  return rxjs.of(null);
8514
8710
  }
8515
- return _this.recipesService.getPricing(recipeId, posId, serves).pipe(operators.skipWhile(function (result) { return result.price === 0; }));
8711
+ return _this.recipesService.getPricing(recipeId, posId, serves, isExtStoreId).pipe(operators.skipWhile(function (result) { return result.price === 0; }));
8516
8712
  }
8517
8713
  },
8518
8714
  supplier: {
@@ -11106,6 +11302,13 @@
11106
11302
  }
11107
11303
  }, eventTrace).subscribe(function (passed) {
11108
11304
  if (passed) {
11305
+ // Send analytics event for add all products button click
11306
+ _this.analyticsService.sendEvent('entry.add-all', eventTrace.originPath, {
11307
+ recipe_id: _this.recipe.id,
11308
+ entry_count: _this.remainingBasketEntries.length.toString(),
11309
+ total_products: _this.recipe.ingredients.length.toString(),
11310
+ total_price: _this.recipePrice.remaining.toFixed(2).toString()
11311
+ }, detectJourney());
11109
11312
  _this.allIngredientsToBasketLoading = true;
11110
11313
  var productsToAdd_1 = [];
11111
11314
  _this.remainingProducts().forEach(function (re) { return _this.basketSynchroService.entryWillBeAdded(re.entry.selectedItem.extId).pipe(operators.take(1)).subscribe(function (result) {
@@ -18498,13 +18701,13 @@
18498
18701
  ReplaceItemComponent.prototype.onSelectItem = function (item) {
18499
18702
  this.replaceItemLoading = item;
18500
18703
  this.cdr.detectChanges();
18704
+ this.previousItem = this.basketEntry.selectedItem;
18501
18705
  if (this.addProductMode) {
18502
18706
  return this.itemAddition(item);
18503
18707
  }
18504
18708
  if (this.ignoreSelected) {
18505
18709
  this.ignoredBasketsService.removeIngredientFromIgnored(this.ingredient.id);
18506
18710
  }
18507
- this.previousItem = this.basketEntry.selectedItem;
18508
18711
  if (this.basketEntry.status === 'active') {
18509
18712
  this.selectItem(item);
18510
18713
  }
@@ -18604,7 +18807,7 @@
18604
18807
  this.recipeDetailsService.updateIngredientFromBasketLoading = this.basketEntry.status !== 'initial';
18605
18808
  };
18606
18809
  ReplaceItemComponent.prototype.itemAddition = function (item) {
18607
- this.basketsService.addItemToBasket(item, this.eventTrace);
18810
+ this.basketsService.addItemToBasket(item, this.eventTrace, this.previousItem);
18608
18811
  this.emitWhenRequestsEnded(item.id);
18609
18812
  };
18610
18813
  ReplaceItemComponent.prototype.emitWhenRequestsEnded = function (itemId) {