ng-miam 9.2.9 → 9.2.10

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
  }
@@ -3590,7 +3739,7 @@
3590
3739
  }
3591
3740
  this.alreadyInitialized$.next(true);
3592
3741
  };
3593
- AnalyticsService.prototype.sendEvent = function (name, path, props) {
3742
+ AnalyticsService.prototype.sendEvent = function (name, path, props, journey) {
3594
3743
  if (this.contextRegistryService.disabledAnalytics && this.contextRegistryService.forbidProfiling) {
3595
3744
  return;
3596
3745
  }
@@ -3598,50 +3747,69 @@
3598
3747
  if (environment$1.env === 'dev' && environment$1.analyticsEnabled === false) {
3599
3748
  return;
3600
3749
  }
3601
- // Currently no way to know if it is search or shelves
3602
- var journey = this.isMealzPage ? EventJourney.MEALZ : EventJourney.EMPTY;
3603
- this.callMethodOrAddToQueue(function () { return mealzSharedAnalytics.sendEvent(name, url(path), journey, props); });
3750
+ // Use provided journey or determine from context
3751
+ var eventJourney = journey || (this.isMealzPage ? EventJourney.MEALZ : EventJourney.EMPTY);
3752
+ this.callMethodOrAddToQueue(function () { return mealzSharedAnalytics.sendEvent(name, url(path), eventJourney, props); });
3604
3753
  };
3605
3754
  /** ************************************************* SEND EVENT FOR BASKET ACTIONS ************************************************* **/
3606
- AnalyticsService.prototype.sendRemoveRecipesEvents = function (actions) {
3755
+ AnalyticsService.prototype.sendRemoveRecipesEvents = function (actions, journey) {
3607
3756
  var _this = this;
3757
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3608
3758
  actions.forEach(function (action) {
3609
- _this.sendEvent('recipe.remove', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId });
3759
+ _this.sendEvent('recipe.remove', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3610
3760
  });
3611
3761
  };
3612
- AnalyticsService.prototype.sendAddRecipesEvents = function (actions) {
3762
+ AnalyticsService.prototype.sendAddRecipesEvents = function (actions, journey) {
3613
3763
  var _this = this;
3764
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3614
3765
  actions.forEach(function (action) {
3615
- _this.sendEvent('recipe.add', '', { recipe_id: action.params.recipeId });
3766
+ _this.sendEvent('recipe.add', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3616
3767
  });
3617
3768
  };
3618
- AnalyticsService.prototype.sendUpdateGuestsEvents = function (actions) {
3769
+ AnalyticsService.prototype.sendUpdateGuestsEvents = function (actions, journey) {
3619
3770
  var _this = this;
3771
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3620
3772
  actions.forEach(function (action) {
3621
- _this.sendEvent('recipe.change-guests', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId });
3773
+ _this.sendEvent('recipe.change-guests', action.params.eventTrace.originPath, { recipe_id: action.params.recipeId }, detectedJourney);
3622
3774
  });
3623
3775
  };
3624
- AnalyticsService.prototype.sendEventsOfResetBasket = function (basket, eventTrace) {
3776
+ AnalyticsService.prototype.sendEventsOfResetBasket = function (basket, eventTrace, journey) {
3625
3777
  var _this = this;
3778
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3626
3779
  basket.recipeInfos.forEach(function (info) {
3627
- _this.sendEvent('recipe.remove', eventTrace.originPath, { recipe_id: info.id });
3780
+ _this.sendEvent('recipe.remove', eventTrace.originPath, { recipe_id: info.id }, detectedJourney);
3628
3781
  });
3629
3782
  };
3630
- AnalyticsService.prototype.sendAddProductsEvents = function (actions) {
3783
+ AnalyticsService.prototype.sendAddProductsEvents = function (actions, journey) {
3631
3784
  var _this = this;
3785
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3786
+ var isBulk = actions.length > 1;
3632
3787
  actions.forEach(function (action) {
3788
+ // Determine add_source: replacement if previousItem exists, otherwise unit or bulk based on actions count
3789
+ var addSource;
3790
+ if (action.params.previousItem) {
3791
+ addSource = 'replacement';
3792
+ }
3793
+ else if (isBulk) {
3794
+ addSource = 'bulk';
3795
+ }
3796
+ else {
3797
+ addSource = 'unit';
3798
+ }
3633
3799
  _this.sendEvent('entry.added', action.params.eventTrace.originPath, {
3634
3800
  entry_name: action.params.basketEntry.name,
3635
3801
  item_id: action.params.basketEntry.selectedItem.id,
3636
3802
  ext_item_id: action.params.basketEntry.selectedItem.attributes['ext-id'],
3637
3803
  item_ean: action.params.basketEntry.selectedItem.ean,
3638
3804
  product_quantity: action.params.basketEntry.quantity.toString(),
3639
- recipe_id: action.params.recipeId
3640
- });
3805
+ recipe_id: action.params.recipeId,
3806
+ add_source: addSource
3807
+ }, detectedJourney);
3641
3808
  });
3642
3809
  };
3643
- AnalyticsService.prototype.sendRemoveProductsEvents = function (actions) {
3810
+ AnalyticsService.prototype.sendRemoveProductsEvents = function (actions, journey) {
3644
3811
  var _this = this;
3812
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3645
3813
  actions.forEach(function (action) {
3646
3814
  _this.sendEvent('entry.deleted', action.params.eventTrace.originPath, {
3647
3815
  entry_name: action.params.basketEntry.name,
@@ -3650,11 +3818,12 @@
3650
3818
  item_ean: action.params.basketEntry.selectedItem.ean,
3651
3819
  product_quantity: action.params.basketEntry.quantity.toString(),
3652
3820
  recipe_id: action.params.recipeId
3653
- });
3821
+ }, detectedJourney);
3654
3822
  });
3655
3823
  };
3656
- AnalyticsService.prototype.sendProductsChangeQuantityEvents = function (actions) {
3824
+ AnalyticsService.prototype.sendProductsChangeQuantityEvents = function (actions, journey) {
3657
3825
  var _this = this;
3826
+ var detectedJourney = journey !== null && journey !== void 0 ? journey : detectJourney();
3658
3827
  actions.forEach(function (action) {
3659
3828
  _this.sendEvent('entry.change-quantity', action.params.eventTrace.originPath, {
3660
3829
  entry_name: action.params.basketEntry.name,
@@ -3663,7 +3832,7 @@
3663
3832
  item_ean: action.params.basketEntry.selectedItem.ean,
3664
3833
  product_quantity: action.params.newQuantity.toString(),
3665
3834
  recipe_id: action.params.recipeId
3666
- });
3835
+ }, detectedJourney);
3667
3836
  });
3668
3837
  };
3669
3838
  AnalyticsService.prototype.callMethodOrAddToQueue = function (method) {
@@ -5961,7 +6130,11 @@
5961
6130
  BasketsService.prototype.fetchCurrentBasket = function (posId) {
5962
6131
  var _this = this;
5963
6132
  var getUrl = "current?point_of_sale_id=" + posId + "&fields[baskets]=" + BASKET_SPARSE_FIELDS.baskets.join(',');
5964
- return this.get(getUrl).pipe(operators.switchMap(function (basket) { return _this.updateLocalBasket(basket); }), operators.tap(function () { return _this.posService.emitBasketLoadedForNewPos(); }));
6133
+ return this.get(getUrl).pipe(operators.switchMap(function (basket) { return _this.updateLocalBasket(basket); }), operators.tap(function () {
6134
+ if (_this.posService.emitBasketLoadedForNewPos) {
6135
+ _this.posService.emitBasketLoadedForNewPos();
6136
+ }
6137
+ }));
5965
6138
  };
5966
6139
  BasketsService.prototype.resetBasket = function (eventTrace) {
5967
6140
  var _this = this;
@@ -6180,11 +6353,11 @@
6180
6353
  }); });
6181
6354
  this.basketActionsQueue.next(toAdd);
6182
6355
  };
6183
- BasketsService.prototype.addItemToBasket = function (item, eventTrace) {
6356
+ BasketsService.prototype.addItemToBasket = function (item, eventTrace, previousItem) {
6184
6357
  var toAdd = this.basketActionsQueue.value;
6185
6358
  toAdd.push({
6186
6359
  type: BasketActionType.ADD_ITEM,
6187
- params: { item: item, eventTrace: eventTrace }
6360
+ params: { item: item, eventTrace: eventTrace, previousItem: previousItem }
6188
6361
  });
6189
6362
  this.basketActionsQueue.next(toAdd);
6190
6363
  };
@@ -6433,8 +6606,13 @@
6433
6606
  ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
6434
6607
  return _this.http.patch(patchUrl, {});
6435
6608
  });
6436
- _this.analyticsService.sendAddProductsEvents(ingredientsToAdd);
6437
6609
  return rxjs.forkJoin(requests);
6610
+ }), operators.tap(function () {
6611
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6612
+ var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
6613
+ ? 'item-replacement'
6614
+ : 'meals-space-recipe-details';
6615
+ _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
6438
6616
  }), 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
6439
6617
  operators.catchError(function () { return rxjs.of(null); }));
6440
6618
  };
@@ -6453,8 +6631,13 @@
6453
6631
  ("&name=" + action.params.item.attributes.name);
6454
6632
  return _this.http.post(encodeURI(postUrl.trim()), {});
6455
6633
  });
6456
- _this.analyticsService.sendAddProductsEvents(itemsToAdd);
6457
6634
  return rxjs.forkJoin(requests);
6635
+ }), operators.tap(function () {
6636
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6637
+ var journey = itemsToAdd.some(function (action) { return action.params.previousItem; })
6638
+ ? 'item-replacement'
6639
+ : 'meals-space-recipe-details';
6640
+ _this.analyticsService.sendAddProductsEvents(itemsToAdd, journey);
6458
6641
  }), 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
6459
6642
  operators.catchError(function () { return rxjs.of(null); }));
6460
6643
  };
@@ -10920,6 +11103,13 @@
10920
11103
  }
10921
11104
  }, eventTrace).subscribe(function (passed) {
10922
11105
  if (passed) {
11106
+ // Send analytics event for add all products button click
11107
+ _this.analyticsService.sendEvent('entry.add-all', eventTrace.originPath, {
11108
+ recipe_id: _this.recipe.id,
11109
+ entry_count: _this.remainingBasketEntries.length.toString(),
11110
+ total_products: _this.recipe.ingredients.length.toString(),
11111
+ total_price: _this.recipePrice.remaining.toFixed(2).toString()
11112
+ }, detectJourney());
10923
11113
  _this.allIngredientsToBasketLoading = true;
10924
11114
  var productsToAdd_1 = [];
10925
11115
  _this.remainingProducts().forEach(function (re) { return _this.basketSynchroService.entryWillBeAdded(re.entry.selectedItem.extId).pipe(operators.take(1)).subscribe(function (result) {
@@ -18312,13 +18502,13 @@
18312
18502
  ReplaceItemComponent.prototype.onSelectItem = function (item) {
18313
18503
  this.replaceItemLoading = item;
18314
18504
  this.cdr.detectChanges();
18505
+ this.previousItem = this.basketEntry.selectedItem;
18315
18506
  if (this.addProductMode) {
18316
18507
  return this.itemAddition(item);
18317
18508
  }
18318
18509
  if (this.ignoreSelected) {
18319
18510
  this.ignoredBasketsService.removeIngredientFromIgnored(this.ingredient.id);
18320
18511
  }
18321
- this.previousItem = this.basketEntry.selectedItem;
18322
18512
  if (this.basketEntry.status === 'active') {
18323
18513
  this.selectItem(item);
18324
18514
  }
@@ -18418,7 +18608,7 @@
18418
18608
  this.recipeDetailsService.updateIngredientFromBasketLoading = this.basketEntry.status !== 'initial';
18419
18609
  };
18420
18610
  ReplaceItemComponent.prototype.itemAddition = function (item) {
18421
- this.basketsService.addItemToBasket(item, this.eventTrace);
18611
+ this.basketsService.addItemToBasket(item, this.eventTrace, this.previousItem);
18422
18612
  this.emitWhenRequestsEnded(item.id);
18423
18613
  };
18424
18614
  ReplaceItemComponent.prototype.emitWhenRequestsEnded = function (itemId) {
@@ -26628,7 +26818,7 @@
26628
26818
  i0__namespace.ɵɵadvance(1);
26629
26819
  i0__namespace.ɵɵproperty("ngForOf", ctx.sponsorBlocks);
26630
26820
  }
26631
- }, directives: [i2__namespace.NgForOf, SponsorBlockContainerComponent, i2__namespace.NgStyle], styles: [".sponsor-storytelling{border-radius:8px;width:100%;height:-moz-fit-content;height:fit-content;display:grid;grid-template-columns:repeat(10,1fr);grid-template-rows:auto;gap:24px}"], encapsulation: 2, changeDetection: 0 });
26821
+ }, directives: [i2__namespace.NgForOf, SponsorBlockContainerComponent, i2__namespace.NgStyle], styles: [".sponsor-storytelling{border-radius:8px;width:100%;height:-moz-fit-content;height:fit-content;display:grid;grid-template-columns:repeat(10,1fr);grid-template-rows:auto;gap:0 24px}"], encapsulation: 2, changeDetection: 0 });
26632
26822
  (function () {
26633
26823
  (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(SponsorStorytellingComponent, [{
26634
26824
  type: i0.Component,