@nuskin/product-components 3.18.0-brw-988.1 → 3.18.0-td-341.1

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.
package/.releaserc CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "branches": [
3
- "master", {"name":"BRW-988", "channel":"prerelease", "prerelease":"brw-988"}
3
+ "master", {"name":"TD-341", "channel":"prerelease", "prerelease":"td-341"}
4
4
  ],
5
5
  "plugins": [
6
6
  "@semantic-release/release-notes-generator",
@@ -46,10 +46,12 @@
46
46
 
47
47
  <script>
48
48
  import { NsExpressiveLink, NsIcon, NsSpinner } from "@nuskin/design-components";
49
- import { StringService } from "@nuskin/ns-util";
49
+ import { StringService, csStringService } from "@nuskin/ns-util";
50
50
  import { fromJsonString } from "@nuskin/ns-common-lib";
51
+ import { getConfiguration } from "@nuskin/configuration-sdk";
51
52
 
52
53
  import NsProductCard from "./NsProductCard.vue";
54
+ import { isEnabled } from "@nuskin/ns-feature-flags";
53
55
 
54
56
  /**
55
57
  * NsProductList
@@ -190,9 +192,24 @@ export default {
190
192
  await this.$nextTick();
191
193
 
192
194
  try {
193
- const commonStrings = await StringService.getStrings(
194
- commonStringKeys
195
- );
195
+ const configs = await getConfiguration(["Mysite"]);
196
+ let useCSResources = false;
197
+ if (
198
+ configs &&
199
+ configs.Mysite &&
200
+ configs.Mysite.useCSResources &&
201
+ Array.isArray(configs.Mysite.useCSResources)
202
+ ) {
203
+ useCSResources = configs.Mysite.useCSResources.includes(
204
+ this.runConfig.country
205
+ );
206
+ }
207
+ let commonStrings = {};
208
+ if (useCSResources && isEnabled("td_341")) {
209
+ commonStrings = await csStringService.getStrings(commonStringKeys);
210
+ } else {
211
+ commonStrings = await StringService.getStrings(commonStringKeys);
212
+ }
196
213
  if (commonStrings && commonStrings.loadMore) {
197
214
  this.loadMoreText = commonStrings.loadMore;
198
215
  }
@@ -772,7 +772,13 @@ export default {
772
772
  : this.products[sku].availableQuantity || 0;
773
773
  const selectedQuantity = this.products[sku].availability
774
774
  .selectedQuantity;
775
-
775
+ if (
776
+ this.products[sku].invalid ||
777
+ this.products[sku].data.availableQuantity <= 0 ||
778
+ !this.products[sku].availability.addToCart
779
+ ) {
780
+ return undefined;
781
+ }
776
782
  if (!this.products[sku].invalid && availableQuantity >= 1) {
777
783
  selectedQuantityArr[
778
784
  this.products[sku].activeSku
@@ -790,18 +796,27 @@ export default {
790
796
  return;
791
797
  }
792
798
 
799
+ let options = {
800
+ add: {
801
+ item: {
802
+ qty: this.totalProductQuantity
803
+ }
804
+ }
805
+ };
806
+
793
807
  let checkoutProducts = [];
794
808
  const equinoxMarketsConfig = getCachedConfiguration("Equinox_Markets");
795
809
  const countryCode = equinoxMarketsConfig.country_code;
796
810
 
797
811
  if (equinoxMarketsConfig.active) {
812
+ window.sessionStorage.setItem("nstoast-allowed", "true");
798
813
  EquinoxCartService.addBundleToEquinoxCart(
799
814
  validSkus,
800
815
  this.products,
801
816
  selectedQuantityArr
802
817
  )
803
818
  .then(() => {
804
- events.publish(events.shop.ADD_TO_CART);
819
+ events.publish(events.shop.ADD_TO_CART, options);
805
820
  })
806
821
  .catch(err => {
807
822
  console.error(`Failed to add ${validSkus} with Error: ${err} `);
@@ -906,6 +921,7 @@ export default {
906
921
 
907
922
  if (
908
923
  availability &&
924
+ availability.addToCart &&
909
925
  Object.keys(this.products[sku].data).length >= 1 &&
910
926
  availableQuantity >= 1
911
927
  ) {
package/docs/CHANGELOG.md CHANGED
@@ -1 +1 @@
1
- # [3.18.0-brw-988.1](https://code.tls.nuskin.io/ns-am/ux/product-components/compare/v3.17.2...v3.18.0-brw-988.1) (2024-06-24)
1
+ # [3.18.0-td-341.1](https://code.tls.nuskin.io/ns-am/ux/product-components/compare/v3.17.15...v3.18.0-td-341.1) (2024-10-22)
@@ -6,6 +6,7 @@ import {
6
6
  import {
7
7
  events,
8
8
  StringService,
9
+ csStringService,
9
10
  util,
10
11
  SitesSessionStorageService,
11
12
  ShoppingContext,
@@ -24,6 +25,7 @@ import {
24
25
  Product as ShopProduct,
25
26
  EquinoxCartService
26
27
  } from "@nuskin/ns-shop";
28
+ import { isEnabled } from "@nuskin/ns-feature-flags";
27
29
  import QualificationService from "@nuskin/exclusive-offer-sdk";
28
30
  import webLoyalty from "@nuskin/ns-loyalty-web";
29
31
  import { getProp, getFullUrl } from "@nuskin/ns-common-lib";
@@ -246,7 +248,11 @@ const NsProductMixin = {
246
248
  return this.$NsProductUserService.isPreferredCustomer;
247
249
  },
248
250
  isWholesale() {
249
- return this.$NsProductUserService.isWholesale;
251
+ if (this.$NsProductUserService.isLoggedIn) {
252
+ return this.$NsProductUserService.isUserWholesale;
253
+ } else {
254
+ return this.$NsProductUserService.isWholesale;
255
+ }
250
256
  },
251
257
  loyaltyStatusAndLinks() {
252
258
  return this.marketConfig.loyalty || {};
@@ -468,8 +474,44 @@ const NsProductMixin = {
468
474
  this.loyaltyStatusAndLinks.productOptedInRedeemNotEarn =
469
475
  "Save with Nu Skin Rewards";
470
476
 
471
- StringService.getApplicationStrings("loyalty").then(content => {
472
- this.loyaltyStrings = content;
477
+ const commonStringKeys = [
478
+ { key: "productDisplayNotOptedinMessage", dflt: "" },
479
+ {
480
+ key: "productDisplayOptedinMessage",
481
+ dflt: "{earnPercentage} Nu Skin enJoy Rewards Available!"
482
+ },
483
+ { key: "productOptedInEarnNotRedeem", dflt: "" },
484
+ {
485
+ key: "productOptedInRedeemNotEarn",
486
+ dflt:
487
+ "This product does not earn rewards points but is available to be redeemed for rewards points."
488
+ }
489
+ ];
490
+
491
+ try {
492
+ const configs = await getConfiguration(["Mysite"]);
493
+ let useCSResources = false;
494
+ if (
495
+ configs &&
496
+ configs.Mysite &&
497
+ configs.Mysite.useCSResources &&
498
+ Array.isArray(configs.Mysite.useCSResources)
499
+ ) {
500
+ useCSResources = configs.Mysite.useCSResources.includes(
501
+ this.runConfig.country
502
+ );
503
+ }
504
+ let loyalityStringsContent = {};
505
+ if (useCSResources && isEnabled("td_341")) {
506
+ loyalityStringsContent = await csStringService.getStrings(
507
+ commonStringKeys
508
+ );
509
+ } else {
510
+ loyalityStringsContent = await StringService.getStrings(
511
+ commonStringKeys
512
+ );
513
+ }
514
+ this.loyaltyStrings = loyalityStringsContent;
473
515
  // Link message to show to non-opted in users
474
516
  if (this.loyaltyStrings.productDisplayNotOptedinMessage) {
475
517
  this.loyaltyStatusAndLinks.landingPageLinkMessage = this.loyaltyStrings.productDisplayNotOptedinMessage;
@@ -511,12 +553,14 @@ const NsProductMixin = {
511
553
  );
512
554
  this.userLoyalty = loyaltyData;
513
555
  }
514
- });
515
556
 
516
- this.loyaltyStatusAndLinks.landingPage = this.localeReplace(
517
- this.loyaltyStatusAndLinks.dashboardPage
518
- );
519
- this.loyaltyStatusAndLinks.siteUrl = this.siteUrl;
557
+ this.loyaltyStatusAndLinks.landingPage = this.localeReplace(
558
+ this.loyaltyStatusAndLinks.dashboardPage
559
+ );
560
+ this.loyaltyStatusAndLinks.siteUrl = this.siteUrl;
561
+ } catch (err) {
562
+ console.warn("Unable to retrieve loyalty strings translations.", err);
563
+ }
520
564
  }
521
565
  },
522
566
 
@@ -657,12 +701,11 @@ const NsProductMixin = {
657
701
  // WARNING: this.product is volatile here. re-check is using this.product.
658
702
  this.maxQuantity = Math.min(
659
703
  shopProduct.maxQuantity,
660
- shopProduct.availableQuantity,
661
704
  productQuantity
662
705
  );
663
706
  })
664
707
  .catch(error => {
665
- this.maxQuantity = 0;
708
+ this.maxQuantity = shopProduct.maxQuantity;
666
709
  console.error("Failed to retrieve add to cart quantity.", error);
667
710
  })
668
711
  .finally(() => {
@@ -703,6 +746,24 @@ const NsProductMixin = {
703
746
  )
704
747
  );
705
748
  this.statusMessageKey = "backOrderedWithDate";
749
+
750
+ let backOrderDate = new Date(this.product.backOrderDate);
751
+ let today = new Date();
752
+ if (backOrderDate < today) {
753
+ if (this.product.availableQuantity > 0) {
754
+ this.statusMessage = "";
755
+ this.statusMessageKey = "releasedForSale";
756
+ //BRW-4541 -- Only allow to purchase the atpQuantity if backorder date is in the past
757
+ this.maxQuantity = Math.min(
758
+ this.product.maxQuantity,
759
+ this.product.availableQuantity
760
+ );
761
+ } else {
762
+ this.statusMessage = this.localTranslations.outOfStock;
763
+ this.statusMessageKey = "outOfStock";
764
+ this.disable();
765
+ }
766
+ }
706
767
  }
707
768
  } else {
708
769
  this.disable();
@@ -815,22 +876,8 @@ const NsProductMixin = {
815
876
  * Set product pricing
816
877
  */
817
878
  setStandardPricing() {
818
- const equinoxMarketsConfig = getCachedConfiguration("Equinox_Markets");
819
- const isGraphQLActive = equinoxMarketsConfig.MySite_graphql_active;
820
-
821
879
  // set price and points
822
880
  this.originalPrice = this.product.getPricing(PriceType.WRTL);
823
-
824
- //graphQL adjustments
825
- if (isGraphQLActive) {
826
- this.originalPrice =
827
- this.product.childSkus &&
828
- this.product.childSkus.length &&
829
- this.getPriceType() === PriceType.WWHL
830
- ? this.product.getPricing(PriceType.WHL)
831
- : this.product.getPricing(PriceType.RTL);
832
- }
833
-
834
881
  this.priceType = this.getPriceType();
835
882
  this.price = this.product.getPricing(this.priceType);
836
883
  this.points = this.product.getPvFixed();
@@ -882,33 +929,20 @@ const NsProductMixin = {
882
929
  // set sales event pricing and points
883
930
  this.originalPriceType = this.product.priceType;
884
931
 
885
- this.originalPrice =
886
- isEquinoxEnabled && !isGraphQLActive
887
- ? this.product.getPricing(PriceType.WRTL)
888
- : this.product.getOriginalPrice();
889
-
890
- //workaround for graphQL active to show original price
891
932
  if (isGraphQLActive) {
892
- this.originalPrice =
893
- this.product.childSkus &&
894
- this.product.childSkus.length &&
895
- this.getPriceType() === PriceType.WWHL
896
- ? this.product.getPricing(PriceType.WHL)
897
- : this.product.getPricing(PriceType.RTL);
933
+ this.originalPrice = this.product.getPricing(this.originalPriceType);
934
+ this.product.priceType = `${this.eventName}-${this.originalPriceType}`;
935
+ } else {
936
+ this.product.getOriginalPrice();
898
937
  }
899
938
 
900
939
  this.priceType = this.product.priceType;
901
-
902
- this.price = this.product.getPrice();
940
+ this.price = this.product.getPricing(this.priceType);
903
941
 
904
942
  //If EQ market, always show the discounted price if product has promotion
905
943
  //Hence, we set the price to member(wholesale / PriceType.WADW) if the price type PriceType.WADR (retail)
906
944
  //this is inline with the change in business rules to always show the discounted prices
907
- if (
908
- isEquinoxEnabled &&
909
- !isGraphQLActive &&
910
- this.getAdrPriceType() == PriceType.WADR
911
- ) {
945
+ if (isGraphQLActive && this.getAdrPriceType() == PriceType.WADR) {
912
946
  this.adrPrice = this.product.getPricing(PriceType.WADW);
913
947
  }
914
948
 
@@ -917,13 +951,9 @@ const NsProductMixin = {
917
951
  //for product that has promotion
918
952
  //set the price to WWHL if this.getPriceType() === WRTL
919
953
  //promotion price is set in product.js setPriceAndPvFromType function
920
- if (
921
- isEquinoxEnabled &&
922
- !isGraphQLActive &&
923
- this.getPriceType() == PriceType.WRTL
924
- ) {
925
- this.price = this.product.getPricing(PriceType.WWHL);
926
- }
954
+ // if (isGraphQLActive && this.getPriceType() == PriceType.WRTL) {
955
+ // this.price = this.product.getPricing(PriceType.WWHL);
956
+ // }
927
957
 
928
958
  if (this.user && this.isDistributor) {
929
959
  this.points = this.product.getPvFixed();
@@ -1142,6 +1172,14 @@ const NsProductMixin = {
1142
1172
  productToAdd.equinoxProductId = productIdentifier;
1143
1173
  //productToAdd.properties = productData.products[0].properties
1144
1174
  }
1175
+ if (
1176
+ productToAdd.backOrderDate &&
1177
+ new Date(productToAdd.backOrderDate) > new Date()
1178
+ ) {
1179
+ productToAdd.inventory = "BACKORDER";
1180
+ productToAdd.properties.isBackOrdered = true;
1181
+ productToAdd.properties.inventoryStatus = "BACKORDER";
1182
+ }
1145
1183
  options.product = new ShopProduct(productToAdd);
1146
1184
  options.add = {
1147
1185
  item: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/product-components",
3
- "version": "3.18.0-brw-988.1",
3
+ "version": "3.18.0-td-341.1",
4
4
  "description": "Nu Skin Product Components",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,8 +29,8 @@
29
29
  "@nuskin/ns-core-styles": "2.11.2",
30
30
  "@nuskin/ns-icon": "^2.12.0",
31
31
  "@nuskin/ns-loyalty-web": "1.5.6",
32
- "@nuskin/ns-product-lib": "2.16.0",
33
- "@nuskin/ns-shop": "7.1.0-brw-988.1",
32
+ "@nuskin/ns-product-lib": "2.19.0",
33
+ "@nuskin/ns-shop": "7.0.10",
34
34
  "@nuskin/product-recommendation": "2.0.1",
35
35
  "axios": "1.6.7",
36
36
  "lodash": "4.17.21",
@@ -41,6 +41,8 @@ const buildPayload = product => {
41
41
  let personalOffer = sessionStorage.getItem("personalOffer");
42
42
  if (personalOffer !== null) {
43
43
  personalOffer = JSON.parse(personalOffer);
44
+ } else {
45
+ personalOffer = { products: [] };
44
46
  }
45
47
  const matchedProduct = personalOffer.products.filter(
46
48
  offerProduct => offerProduct.sku === product.sku
@@ -55,18 +57,45 @@ const buildPayload = product => {
55
57
  const skus = [];
56
58
  if (product && product.childSkus) {
57
59
  product.childSkus.forEach(childSku => {
58
- if (childSku.type === "MANDATORY") {
60
+ if (
61
+ childSku.type === "MANDATORY" &&
62
+ !skus.some(sku => sku.productId === childSku.productId)
63
+ ) {
59
64
  skus.push({
60
- skuId:
61
- selectedVariants !== null && selectedVariants[childSku.productId]
62
- ? selectedVariants[childSku.productId]
63
- : childSku.skuId,
65
+ skuId: childSku.skuId,
64
66
  productId: childSku.productId,
65
- quantity: childSku.skuQuantity,
66
- type: "bundle"
67
+ type: "bundle",
68
+ quantity: childSku.skuQuantity
67
69
  });
68
70
  }
69
71
  });
72
+
73
+ if (selectedVariants !== null) {
74
+ for (const productId in selectedVariants) {
75
+ let isOptionalProduct = true;
76
+ skus.forEach(finalSku => {
77
+ if (finalSku.productId === productId) {
78
+ isOptionalProduct = false;
79
+ finalSku.skuId = selectedVariants[productId];
80
+ }
81
+ });
82
+
83
+ if (isOptionalProduct) {
84
+ // this means this is optional product
85
+ const optionalProduct = product.childSkus.filter(
86
+ childSku => childSku.productId === productId
87
+ )[0];
88
+ if (optionalProduct) {
89
+ skus.push({
90
+ skuId: selectedVariants[productId],
91
+ productId: optionalProduct.productId,
92
+ type: "bundle",
93
+ quantity: optionalProduct.skuQuantity
94
+ });
95
+ }
96
+ }
97
+ }
98
+ }
70
99
  }
71
100
 
72
101
  payload.skus = skus;
@@ -3,8 +3,11 @@ import Vue from "vue";
3
3
  import {
4
4
  RunConfigService,
5
5
  ConfigService,
6
- StringService
6
+ StringService,
7
+ csStringService
7
8
  } from "@nuskin/ns-util";
9
+ import { getConfiguration } from "@nuskin/configuration-sdk";
10
+ import { isEnabled } from "@nuskin/ns-feature-flags";
8
11
 
9
12
  import { isNullOrEmpty } from "@nuskin/ns-common-lib";
10
13
 
@@ -177,10 +180,31 @@ if (!NsProductAppService) {
177
180
  ];
178
181
 
179
182
  try {
180
- const commonStrings = await StringService.getStrings(
181
- commonStringKeys,
182
- this.locale
183
- );
183
+ const configs = await getConfiguration(["Mysite"]);
184
+ let useCSResources = false;
185
+ if (
186
+ configs &&
187
+ configs.Mysite &&
188
+ configs.Mysite.useCSResources &&
189
+ Array.isArray(configs.Mysite.useCSResources)
190
+ ) {
191
+ useCSResources = configs.Mysite.useCSResources.includes(
192
+ this.runConfig.country
193
+ );
194
+ }
195
+
196
+ let commonStrings = {};
197
+ if (useCSResources && isEnabled("td_341")) {
198
+ commonStrings = await csStringService.getStrings(
199
+ commonStringKeys,
200
+ this.locale
201
+ );
202
+ } else {
203
+ commonStrings = await StringService.getStrings(
204
+ commonStringKeys,
205
+ this.locale
206
+ );
207
+ }
184
208
 
185
209
  this.appendTranslations(commonStrings);
186
210
  } catch (err) {
@@ -9,7 +9,10 @@ import { isNullOrEmpty } from "@nuskin/ns-common-lib";
9
9
  import { ProductDataService } from "@nuskin/ns-product";
10
10
  import { Product, PriceType } from "@nuskin/ns-product-lib";
11
11
  import { equinoxLocalStorage } from "@nuskin/ns-util";
12
- import { getConfiguration } from "@nuskin/configuration-sdk";
12
+ import {
13
+ getConfiguration,
14
+ getCachedConfiguration
15
+ } from "@nuskin/configuration-sdk";
13
16
 
14
17
  class ProductDataBatch {
15
18
  constructor(id, skus) {
@@ -269,9 +272,7 @@ if (!NsProductDataService) {
269
272
  return;
270
273
  }
271
274
 
272
- const equinoxMarketConfig = (
273
- await getConfiguration(["Equinox_Markets"])
274
- ).Equinox_Markets;
275
+ const equinoxMarketConfig = getCachedConfiguration("Equinox_Markets");
275
276
 
276
277
  // product data response has products
277
278
  if (productData.count && productData.products.length) {