ng-miam 10.6.0 → 10.7.0

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.
Files changed (31) hide show
  1. package/bundles/ng-miam.umd.js +102 -36
  2. package/bundles/ng-miam.umd.js.map +1 -1
  3. package/bundles/ng-miam.umd.min.js +1 -1
  4. package/bundles/ng-miam.umd.min.js.map +1 -1
  5. package/esm2015/lib/_models/basket-actions/basket-action.js +3 -2
  6. package/esm2015/lib/_services/basket-utils.service.js +17 -3
  7. package/esm2015/lib/_services/baskets.service.js +71 -28
  8. package/esm2015/lib/_services/context.service.js +2 -1
  9. package/esm2015/lib/_services/point-of-sales.service.js +4 -7
  10. package/esm2015/lib/_services/recipes.service.js +5 -2
  11. package/esm2015/lib/_types/basket-stats.js +1 -1
  12. package/esm2015/lib/_types/builded/mealz-interface.js +1 -1
  13. package/esm2015/lib/environments/environment.js +2 -2
  14. package/esm2015/lib/environments/environment.prod.js +2 -2
  15. package/esm2015/lib/environments/version.js +2 -2
  16. package/fesm2015/ng-miam.js +97 -38
  17. package/fesm2015/ng-miam.js.map +1 -1
  18. package/lib/_models/basket-actions/basket-action.d.ts.map +1 -1
  19. package/lib/_services/basket-utils.service.d.ts +2 -0
  20. package/lib/_services/basket-utils.service.d.ts.map +1 -1
  21. package/lib/_services/baskets.service.d.ts +8 -0
  22. package/lib/_services/baskets.service.d.ts.map +1 -1
  23. package/lib/_services/context.service.d.ts.map +1 -1
  24. package/lib/_services/point-of-sales.service.d.ts.map +1 -1
  25. package/lib/_services/recipes.service.d.ts.map +1 -1
  26. package/lib/_types/basket-stats.d.ts +1 -0
  27. package/lib/_types/basket-stats.d.ts.map +1 -1
  28. package/lib/_types/builded/mealz-interface.d.ts +4 -0
  29. package/lib/_types/builded/mealz-interface.d.ts.map +1 -1
  30. package/lib/environments/version.d.ts +1 -1
  31. package/package.json +1 -1
@@ -1577,7 +1577,8 @@
1577
1577
  if (found) {
1578
1578
  // Clone to avoid changing the original object reference
1579
1579
  var updatedBasketEntry = deepCloneWithClass(_this.basketEntry);
1580
- updatedBasketEntry.quantity = found.quantity + _this.basketEntry.quantityToAdd;
1580
+ var baseQuantity = found.status === 'active' ? found.quantity : 0;
1581
+ updatedBasketEntry.quantity = baseQuantity + _this.basketEntry.quantityToAdd;
1581
1582
  _this.quantity = updatedBasketEntry.quantity;
1582
1583
  return updatedBasketEntry;
1583
1584
  }
@@ -1640,7 +1641,7 @@
1640
1641
  env: 'prod',
1641
1642
  miamAPI: 'https://api.miam.tech',
1642
1643
  miamWeb: 'https://miam.tech',
1643
- mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.10/dist',
1644
+ mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.11/dist',
1644
1645
  mealzSsrApi: 'https://ssr-api.mealz.ai',
1645
1646
  lang: 'fr',
1646
1647
  analyticsEnabled: true // Only used in DEV mode
@@ -3395,12 +3396,9 @@
3395
3396
  };
3396
3397
  PointOfSalesService.prototype.loadPos = function (posId) {
3397
3398
  var _this = this;
3398
- this.posIsLoading$.next(true);
3399
3399
  if (!this.pos$.value || this.pos$.value.id !== posId) {
3400
- this.get(posId, { include: ['supplier'] }).pipe(operators.skipWhile(function (pos) { return pos.is_loading; }), operators.tap(function (pos) {
3401
- _this.pos$.next(pos);
3402
- _this.posIsLoading$.next(false);
3403
- })).subscribe();
3400
+ this.posIsLoading$.next(true);
3401
+ this.get(posId, { include: ['supplier'] }).pipe(operators.skipWhile(function (pos) { return pos.is_loading; }), operators.tap(function (pos) { return _this.pos$.next(pos); }), operators.finalize(function () { return _this.posIsLoading$.next(false); })).subscribe();
3404
3402
  }
3405
3403
  return this.pos$;
3406
3404
  };
@@ -3648,7 +3646,7 @@
3648
3646
  EventJourney["EMPTY"] = "";
3649
3647
  })(EventJourney || (EventJourney = {}));
3650
3648
 
3651
- var VERSION = "10.6.0"; // TODO: replace by ##VERSION## and update it in the CI/CD
3649
+ var VERSION = "10.7.0"; // TODO: replace by ##VERSION## and update it in the CI/CD
3652
3650
 
3653
3651
  var ContextRegistryService = /** @class */ (function () {
3654
3652
  function ContextRegistryService() {
@@ -5773,7 +5771,10 @@
5773
5771
  RecipesService.prototype.getSuggestedRecipes = function () {
5774
5772
  var _this = this;
5775
5773
  var pref = this.buildfilterUrlFromPreferences();
5776
- var url = pref ? MIAM_API_HOST$2 + "recipes/suggest?" + pref.slice(1) : MIAM_API_HOST$2 + "recipes/suggest";
5774
+ var params = new URLSearchParams(pref ? pref.slice(1) : '');
5775
+ params.append('include', 'sponsors');
5776
+ params.append('fields[sponsors]', 'logo-url');
5777
+ var url = MIAM_API_HOST$2 + "recipes/suggest?" + params.toString();
5777
5778
  return this.http.get(url, {
5778
5779
  headers: {
5779
5780
  'Cache-Control': 'no-cache, no-store, must-revalidate',
@@ -6208,6 +6209,7 @@
6208
6209
  _this.basketPreviewIsCalculating$ = new rxjs.BehaviorSubject(true);
6209
6210
  _this.basketInitCalled = false;
6210
6211
  _this.recipesAdded = new i0.EventEmitter();
6212
+ _this.recipesAddFailed = new i0.EventEmitter();
6211
6213
  _this.confirming = new rxjs.BehaviorSubject(false);
6212
6214
  _this.currentlyAddingRecipes = [];
6213
6215
  _this.basketActionsQueue = new rxjs.BehaviorSubject([]);
@@ -6392,8 +6394,30 @@
6392
6394
  return this.basket$.pipe(operators.skipWhile(function (b) { return !b; }), operators.map(function (basket) { return basket.hasRecipe(recipeId); }));
6393
6395
  };
6394
6396
  BasketsService.prototype.guestsForRecipe = function (recipeId) {
6397
+ return this.resolveGuestsForRecipe(recipeId);
6398
+ };
6399
+ BasketsService.prototype.resolveGuestsForRecipe = function (recipeId) {
6395
6400
  var _a;
6396
- return (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
6401
+ var guestsFromBasket = (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
6402
+ if (Number.isFinite(guestsFromBasket)) {
6403
+ return guestsFromBasket;
6404
+ }
6405
+ var pendingRecipeAction = __spread(this.actionsBeingProcessed.value, this.basketActionsQueue.value).find(function (action) { return (action.type === BasketActionType.ADD_RECIPE || action.type === BasketActionType.ADD_RECIPE_LIGHT) &&
6406
+ action.params.recipeId === recipeId &&
6407
+ Number.isFinite(action.params.guests); });
6408
+ return pendingRecipeAction === null || pendingRecipeAction === void 0 ? void 0 : pendingRecipeAction.params.guests;
6409
+ };
6410
+ /**
6411
+ * Waits until the given recipe is in the basket before resolving.
6412
+ * Emits `true` when the recipe is confirmed in the basket, `false` when its addition failed,
6413
+ * so callers can avoid firing dependent requests (e.g. add-ingredient) against a recipe that was never created.
6414
+ */
6415
+ BasketsService.prototype.waitUntilRecipeInBasket = function (recipeId) {
6416
+ var _a;
6417
+ if (!recipeId || ((_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.hasRecipe(recipeId))) {
6418
+ return rxjs.of(true);
6419
+ }
6420
+ return rxjs.merge(this.basket$.pipe(operators.skipWhile(function (basket) { return !(basket === null || basket === void 0 ? void 0 : basket.hasRecipe(recipeId)); }), operators.take(1), operators.map(function () { return true; })), this.recipesAdded.pipe(operators.skipWhile(function (recipeIds) { return !recipeIds.includes(recipeId); }), operators.take(1), operators.map(function () { return true; })), this.recipesAddFailed.pipe(operators.skipWhile(function (recipeIds) { return !recipeIds.includes(recipeId); }), operators.take(1), operators.map(function () { return false; }))).pipe(operators.take(1));
6397
6421
  };
6398
6422
  BasketsService.prototype.showRecipeAddedToaster = function () {
6399
6423
  var _this = this;
@@ -6774,8 +6798,11 @@
6774
6798
  /** *************************************************** PROCESS THE ACTIONS QUEUE *************************************************** **/
6775
6799
  BasketsService.prototype.emptyActionsQueue = function () {
6776
6800
  var _this = this;
6777
- if (this.basketActionsQueue.value.length > 0) {
6801
+ if (this.basketActionsQueue.value.length > 0 && this.actionsBeingProcessed.value.length === 0) {
6778
6802
  var actionsToProcess_1 = this.nextActionsBatch();
6803
+ if (actionsToProcess_1.length === 0) {
6804
+ return;
6805
+ }
6779
6806
  this.actionsBeingProcessed.next(__spread(actionsToProcess_1));
6780
6807
  if (actionsToProcess_1.length > 0) {
6781
6808
  this.processActionsBatch(actionsToProcess_1).subscribe(function () {
@@ -6791,14 +6818,16 @@
6791
6818
  * @returns the next batch of actions to process
6792
6819
  */
6793
6820
  BasketsService.prototype.nextActionsBatch = function () {
6821
+ var _this = this;
6822
+ var pendingActions = this.basketActionsQueue.value.filter(function (action) { return !_this.actionsBeingProcessed.value.includes(action); });
6794
6823
  var batch = [];
6795
- var i = 0;
6796
- var currentAction = this.basketActionsQueue.value[i];
6824
+ var index = 0;
6825
+ var currentAction = pendingActions[index];
6797
6826
  var shouldForceStop = false;
6798
- while (this.basketActionsQueue.value[i] && this.basketActionsQueue.value[i].type === currentAction.type && !shouldForceStop) {
6799
- currentAction = this.basketActionsQueue.value[i];
6827
+ while (pendingActions[index] && pendingActions[index].type === currentAction.type && !shouldForceStop) {
6828
+ currentAction = pendingActions[index];
6800
6829
  shouldForceStop = this.addActionToBatchOrStopProcessingBatch(batch, currentAction);
6801
- i++;
6830
+ index++;
6802
6831
  }
6803
6832
  return batch;
6804
6833
  };
@@ -6923,6 +6952,10 @@
6923
6952
  return _this.http.post(postUrl, body).pipe(operators.switchMap(function (b) { var _a; return ((_a = b.data) === null || _a === void 0 ? void 0 : _a.id) ? _this.fillBasket(b) : rxjs.of(null); }), operators.tap(function () {
6924
6953
  _this.recipesAdded.emit(recipeIds.map(function (r) { return r.recipe_id; }));
6925
6954
  _this.currentlyAddingRecipes = _this.currentlyAddingRecipes.filter(function (id) { return !(_this.basket$.value.recipeInfos.find(function (i) { return i.id === id; })); });
6955
+ }), operators.catchError(function () {
6956
+ _this.currentlyAddingRecipes = _this.currentlyAddingRecipes.filter(function (recipeId) { return !recipeIds.some(function (candidate) { return candidate.recipe_id === recipeId; }); });
6957
+ _this.recipesAddFailed.emit(recipeIds.map(function (r) { return r.recipe_id; }));
6958
+ return rxjs.of(null);
6926
6959
  }));
6927
6960
  }), operators.catchError(function () { return rxjs.of(null); }));
6928
6961
  };
@@ -6982,23 +7015,32 @@
6982
7015
  */
6983
7016
  BasketsService.prototype.addItemsForIngredients = function (ingredientsToAdd) {
6984
7017
  var _this = this;
6985
- return this.waitForBasket.pipe(operators.switchMap(function (basket) {
6986
- var requests = ingredientsToAdd.map(function (action) {
6987
- var modifiedGuests = _this.guestsForRecipe(action.params.recipeId);
6988
- var patchUrl = environment$1.miamAPI + "/api/v1/baskets/" + basket.id + "/basket-entries/" + action.params.basketEntry.id + "/add-ingredient" +
6989
- ("?ingredient_id=" + action.params.ingredientId + "&selected_item_id=" + action.params.basketEntry.selectedItem.id) +
6990
- ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
6991
- return _this.http.patch(patchUrl, {});
6992
- });
6993
- return rxjs.forkJoin(requests);
6994
- }), operators.tap(function () {
6995
- // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6996
- var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
6997
- ? 'item-replacement'
6998
- : 'meals-space-recipe-details';
6999
- _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
7000
- }), 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
7001
- operators.catchError(function () { return rxjs.of(null); }));
7018
+ var _a;
7019
+ var recipeId = (_a = ingredientsToAdd[0]) === null || _a === void 0 ? void 0 : _a.params.recipeId;
7020
+ return this.waitUntilRecipeInBasket(recipeId).pipe(operators.switchMap(function (recipeIsInBasket) {
7021
+ // The parent recipe add failed: skip add-ingredient to avoid a request against a recipe that was never created
7022
+ // (which would leave the retailer basket updated while Mealz stays out of sync).
7023
+ if (!recipeIsInBasket) {
7024
+ return rxjs.of(null);
7025
+ }
7026
+ return _this.waitForBasket.pipe(operators.switchMap(function (basket) {
7027
+ var requests = ingredientsToAdd.map(function (action) {
7028
+ var modifiedGuests = _this.resolveGuestsForRecipe(action.params.recipeId);
7029
+ var patchUrl = environment$1.miamAPI + "/api/v1/baskets/" + basket.id + "/basket-entries/" + action.params.basketEntry.id + "/add-ingredient" +
7030
+ ("?ingredient_id=" + action.params.ingredientId + "&selected_item_id=" + action.params.basketEntry.selectedItem.id) +
7031
+ ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
7032
+ return _this.http.patch(patchUrl, {});
7033
+ });
7034
+ return rxjs.forkJoin(requests);
7035
+ }), operators.tap(function () {
7036
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
7037
+ var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
7038
+ ? 'item-replacement'
7039
+ : 'meals-space-recipe-details';
7040
+ _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
7041
+ }), 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
7042
+ );
7043
+ }), operators.catchError(function () { return rxjs.of(null); }));
7002
7044
  };
7003
7045
  /**
7004
7046
  * Add items to the basket HTTP request.
@@ -7126,7 +7168,7 @@
7126
7168
  var lines = _this.recipesAndLineEntriesToBasketPreviewLine(recipes, lineEntries);
7127
7169
  _this._basketPreview$.next(lines);
7128
7170
  _this.basketPreviewIsCalculating$.next(false);
7129
- _this.basketStats$.next(_this.buildStats(lines));
7171
+ _this.basketStats$.next(_this.buildStats(lines, entries));
7130
7172
  }));
7131
7173
  }));
7132
7174
  };
@@ -7144,7 +7186,8 @@
7144
7186
  return _this._entries$.value;
7145
7187
  }));
7146
7188
  };
7147
- BasketsService.prototype.buildStats = function (lines) {
7189
+ BasketsService.prototype.buildStats = function (lines, entries) {
7190
+ if (entries === void 0) { entries = []; }
7148
7191
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
7149
7192
  var entriesFound = lodashEs.unionBy.apply(void 0, __spread(lines.map(function (line) { return line.entries.found; }), ['id']));
7150
7193
  var totalPrice = entriesFound.reduce(function (total, entry) {
@@ -7152,8 +7195,11 @@
7152
7195
  total += (entry.attributes.quantity || 0) * parseFloat(basketEntriesItem['unit-price']);
7153
7196
  return total;
7154
7197
  }, 0);
7198
+ // productsCount cannot be derived from `lines` alone: preview lines are recipe-only,
7199
+ // while standalone products (empty recipe-ids) live only in the full entries list.
7155
7200
  return {
7156
7201
  recipesCount: lines.length,
7202
+ productsCount: entries.filter(function (entry) { return entry.status === 'active' && entry.attributes['selected-item-id'] != null; }).length,
7157
7203
  entriesCount: entriesFound.length,
7158
7204
  totalPrice: totalPrice
7159
7205
  };
@@ -8616,17 +8662,27 @@
8616
8662
 
8617
8663
  var BasketUtilsService = /** @class */ (function () {
8618
8664
  function BasketUtilsService(basketsService, recipesService, priceService, basketSynchroService, analyticsService, loadLitDrawerService) {
8665
+ var _this = this;
8619
8666
  this.basketsService = basketsService;
8620
8667
  this.recipesService = recipesService;
8621
8668
  this.priceService = priceService;
8622
8669
  this.basketSynchroService = basketSynchroService;
8623
8670
  this.analyticsService = analyticsService;
8624
8671
  this.loadLitDrawerService = loadLitDrawerService;
8672
+ this.removeRecipeJobs$ = new rxjs.Subject();
8625
8673
  this.recipesWithEntries = [];
8626
8674
  this.basketPreviewState$ = new rxjs.BehaviorSubject({
8627
8675
  isOpen: false,
8628
8676
  activeTabIndex: 0 // Default to the first tab (recipes)
8629
8677
  });
8678
+ this.removeRecipeJobs$.pipe(operators.concatMap(function (_a) {
8679
+ var recipeId = _a.recipeId, analyticsPath = _a.analyticsPath, result$ = _a.result$;
8680
+ return _this.removeRecipeInternal(recipeId, analyticsPath).pipe(operators.tap({
8681
+ next: function (value) { return result$.next(value); },
8682
+ error: function (error) { return result$.error(error); },
8683
+ complete: function () { return result$.complete(); }
8684
+ }), operators.catchError(function () { return rxjs.EMPTY; }));
8685
+ })).subscribe();
8630
8686
  }
8631
8687
  /**
8632
8688
  * Builds a preview of recipes in the basket, including their total price and total number of products per recipe.
@@ -8652,6 +8708,15 @@
8652
8708
  });
8653
8709
  };
8654
8710
  BasketUtilsService.prototype.removeRecipe = function (recipeId, analyticsPath) {
8711
+ var _this = this;
8712
+ return new rxjs.Observable(function (subscriber) {
8713
+ var result$ = new rxjs.Subject();
8714
+ var resultSubscription = result$.subscribe(subscriber);
8715
+ _this.removeRecipeJobs$.next({ recipeId: recipeId, analyticsPath: analyticsPath, result$: result$ });
8716
+ return function () { return resultSubscription.unsubscribe(); };
8717
+ });
8718
+ };
8719
+ BasketUtilsService.prototype.removeRecipeInternal = function (recipeId, analyticsPath) {
8655
8720
  var _this = this;
8656
8721
  return this.fetchDataToRemoveRecipe(recipeId).pipe(operators.switchMap(function (_a) {
8657
8722
  var recipe = _a.recipe, basketEntries = _a.basketEntries;
@@ -11397,6 +11462,7 @@
11397
11462
  _this.resetBasket();
11398
11463
  },
11399
11464
  recipeCount: function () { return _this.basketsService.waitForBasket.pipe(operators.switchMap(function () { return _this.basketsService.basketStats$; }), operators.skipWhile(function (bs) { return !bs; }), operators.map(function (bs) { return bs.recipesCount; }), operators.distinctUntilChanged()); },
11465
+ productCount: function () { return _this.basketsService.waitForBasket.pipe(operators.switchMap(function () { return _this.basketsService.basketStats$; }), operators.skipWhile(function (bs) { return !bs; }), operators.map(function (bs) { return bs.productsCount; }), operators.distinctUntilChanged()); },
11400
11466
  openPreview: function (analyticsPath, selectedTab) {
11401
11467
  if (analyticsPath === void 0) { analyticsPath = ''; }
11402
11468
  if (selectedTab === void 0) { selectedTab = 0; }
@@ -13391,7 +13457,7 @@
13391
13457
  env: 'prod',
13392
13458
  miamAPI: 'https://api.miam.tech',
13393
13459
  miamWeb: 'https://miam.tech',
13394
- mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.10/dist',
13460
+ mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.11/dist',
13395
13461
  mealzSsrApi: 'https://ssr-api.mealz.ai',
13396
13462
  lang: 'fr',
13397
13463
  analyticsEnabled: true // Only used in DEV mode