@zenky/storefront-vue 0.9.34 → 0.9.38

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/dist/cjs/index.js CHANGED
@@ -579,7 +579,7 @@ const useCategoriesStore = pinia.defineStore({
579
579
  }
580
580
  this.loading = true;
581
581
  try {
582
- this.tree = await api.getCategoriesTree({ visibility: 'visible', with: 'media' });
582
+ this.tree = await api.getCategoriesTree({ visibility: api.Visibility.Visible, with: 'media' });
583
583
  this.loaded = true;
584
584
  }
585
585
  catch (e) {
@@ -754,7 +754,7 @@ const useCollectionsStore = pinia.defineStore({
754
754
  this.loading = true;
755
755
  try {
756
756
  this.collections = (await api.getProductsCollections({
757
- visibility: 'visible',
757
+ visibility: api.Visibility.Visible,
758
758
  order_by: 'name',
759
759
  with: 'media',
760
760
  count: 100,
@@ -1630,10 +1630,13 @@ var ProductsFiltersType;
1630
1630
  ProductsFiltersType["FeaturesGroups"] = "featuresGroups";
1631
1631
  })(ProductsFiltersType || (ProductsFiltersType = {}));
1632
1632
 
1633
- function getSourceParams(source) {
1633
+ function getSourceParams(source, promotion) {
1634
1634
  if (source === null || !source.id || !source.type) {
1635
1635
  return {};
1636
1636
  }
1637
+ else if (promotion !== null) {
1638
+ return {};
1639
+ }
1637
1640
  switch (source.type) {
1638
1641
  case ProductsSourceType.Category:
1639
1642
  return { category_id: source.id };
@@ -1720,9 +1723,15 @@ function getLoaderParams(page, loader) {
1720
1723
  if (loader.search) {
1721
1724
  params.search = loader.search;
1722
1725
  }
1723
- if (typeof loader.promotionReward === 'string' && loader.promotionReward) {
1724
- params.promotion_reward = loader.promotionReward;
1726
+ if (typeof loader.promotion === 'undefined' || loader.promotion === null) {
1727
+ return params;
1728
+ }
1729
+ params.promotion_reward = 'all';
1730
+ if (!loader.promotion.context_type || !loader.promotion.context_id) {
1731
+ return params;
1725
1732
  }
1733
+ params.context_type = loader.promotion.context_type;
1734
+ params.context_id = loader.promotion.context_id;
1726
1735
  return params;
1727
1736
  }
1728
1737
  function getProductsPaginationRequest(page, loader) {
@@ -1730,7 +1739,7 @@ function getProductsPaginationRequest(page, loader) {
1730
1739
  return null;
1731
1740
  }
1732
1741
  return {
1733
- ...getSourceParams(loader.source),
1742
+ ...getSourceParams(loader.source, loader.promotion),
1734
1743
  ...getSortingParams(loader.sorting),
1735
1744
  ...getFiltersParams(loader.filters),
1736
1745
  ...getPricesFiltersParams(loader.pricesFilters),
@@ -1771,7 +1780,7 @@ function useProductsList(config, errorHandler) {
1771
1780
  count: config.value.count,
1772
1781
  },
1773
1782
  with: config.value.with || '',
1774
- promotionReward: config.value.promotionReward || null,
1783
+ promotion: config.value.promotion || null,
1775
1784
  }));
1776
1785
  const load = async (page, reset = false, callback) => {
1777
1786
  const request = getProductsPaginationRequest(page, loader.value);
@@ -1832,9 +1841,26 @@ function getFiltersFromUrl(param) {
1832
1841
  });
1833
1842
  return filters;
1834
1843
  }
1844
+ function getProductsListQueryParamsWithPromotion(params, promotion) {
1845
+ if (!promotion) {
1846
+ return params;
1847
+ }
1848
+ const clone = {
1849
+ ...params,
1850
+ promotion_id: promotion.id,
1851
+ reward_id: promotion.reward_id,
1852
+ };
1853
+ if (promotion.context_type) {
1854
+ clone.context_type = promotion.context_type;
1855
+ }
1856
+ if (promotion.context_id) {
1857
+ clone.context_id = promotion.context_id;
1858
+ }
1859
+ return clone;
1860
+ }
1835
1861
  function getProductsListQueryParams(config, request) {
1836
1862
  if (request === null) {
1837
- return {};
1863
+ return getProductsListQueryParamsWithPromotion({}, config.promotion);
1838
1864
  }
1839
1865
  const query = {};
1840
1866
  if (request.order_by && request.order_by !== config.sorting) {
@@ -1852,7 +1878,25 @@ function getProductsListQueryParams(config, request) {
1852
1878
  if (request.search) {
1853
1879
  query.search = request.search;
1854
1880
  }
1855
- return query;
1881
+ return getProductsListQueryParamsWithPromotion(query, config.promotion);
1882
+ }
1883
+ function getQueryParam(query, param) {
1884
+ return typeof query[param] !== 'undefined' && query[param] ? query[param] : null;
1885
+ }
1886
+ function getPromotionFromQuery(query) {
1887
+ const promotionId = getQueryParam(query, 'promotion_id');
1888
+ const rewardId = getQueryParam(query, 'reward_id');
1889
+ if (!promotionId || !rewardId) {
1890
+ return null;
1891
+ }
1892
+ const contextType = getQueryParam(query, 'context_type');
1893
+ const contextId = getQueryParam(query, 'context_id');
1894
+ return {
1895
+ id: promotionId,
1896
+ reward_id: rewardId,
1897
+ context_type: contextType,
1898
+ context_id: contextId,
1899
+ };
1856
1900
  }
1857
1901
  function getProductsListParamsFromQuery(query) {
1858
1902
  if (!query) {
@@ -1861,9 +1905,10 @@ function getProductsListParamsFromQuery(query) {
1861
1905
  return {
1862
1906
  sorting: typeof query.order_by !== 'undefined' ? query.order_by : null,
1863
1907
  f: typeof query.f === 'string' ? getFiltersFromUrl(query.f) : null,
1864
- min_price: typeof query.min_price !== 'undefined' && query.min_price ? query.min_price : null,
1865
- max_price: typeof query.max_price !== 'undefined' && query.max_price ? query.max_price : null,
1866
- search: typeof query.search !== 'undefined' && query.search ? query.search : null,
1908
+ min_price: getQueryParam(query, 'min_price'),
1909
+ max_price: getQueryParam(query, 'max_price'),
1910
+ search: getQueryParam(query, 'search'),
1911
+ promotion: getPromotionFromQuery(query),
1867
1912
  };
1868
1913
  }
1869
1914
 
@@ -1912,6 +1957,123 @@ function getProductsSource(source) {
1912
1957
  }
1913
1958
  }
1914
1959
 
1960
+ const usePromotionsStore = pinia.defineStore({
1961
+ id: 'zenky:storefront:promotions',
1962
+ state: () => ({
1963
+ checking: false,
1964
+ failed: false,
1965
+ selector: {
1966
+ available: false,
1967
+ closed: false,
1968
+ offer: null,
1969
+ promotion_id: '',
1970
+ reward_id: '',
1971
+ max_quantity: 0,
1972
+ context: null,
1973
+ },
1974
+ }),
1975
+ getters: {
1976
+ hasSelector() {
1977
+ if (this.checking) {
1978
+ return false;
1979
+ }
1980
+ else if (!this.selector.available) {
1981
+ return false;
1982
+ }
1983
+ else if (!this.selector.promotion_id || !this.selector.reward_id) {
1984
+ return false;
1985
+ }
1986
+ return true;
1987
+ },
1988
+ hasSelectorContext() {
1989
+ if (this.selector.context === null) {
1990
+ return false;
1991
+ }
1992
+ return !!this.selector.context.id && !!this.selector.context.type;
1993
+ },
1994
+ },
1995
+ actions: {
1996
+ setCheckerState(value, timedOut = false) {
1997
+ this.checking = value;
1998
+ this.failed = timedOut;
1999
+ },
2000
+ disableRewardsSelector() {
2001
+ this.selector.available = false;
2002
+ this.selector.offer = null;
2003
+ this.selector.promotion_id = '';
2004
+ this.selector.reward_id = '';
2005
+ this.selector.max_quantity = 0;
2006
+ this.selector.context = null;
2007
+ },
2008
+ enableRewardsSelector(selector) {
2009
+ this.selector.available = true;
2010
+ this.selector.offer = selector.offer;
2011
+ this.selector.promotion_id = selector.promotion_id;
2012
+ this.selector.reward_id = selector.reward_id;
2013
+ this.selector.max_quantity = selector.limit;
2014
+ this.selector.context = selector.context;
2015
+ },
2016
+ closeRewardsSelector() {
2017
+ this.selector.closed = true;
2018
+ },
2019
+ openRewardsSelector() {
2020
+ this.selector.closed = false;
2021
+ },
2022
+ initialize() {
2023
+ events.usePromotionsCheckerStarted().subscribe('storefront.promotions.initialize', () => this.setCheckerState(true));
2024
+ events.usePromotionsCheckerCompleted().subscribe('storefront.promotions.initialize', (params) => this.setCheckerState(false, params && params.timeout === true));
2025
+ events.useDisplayOrderPromotionRewardSelection().subscribe('storefront.promotions.initialize', ({ data }) => this.enableRewardsSelector(data));
2026
+ events.useOrderPromotionsNotFound().subscribe('storefront.promotions.initialize', () => this.disableRewardsSelector());
2027
+ },
2028
+ },
2029
+ });
2030
+
2031
+ function initializePromotions(order, timeout = 10000) {
2032
+ const promotionsStore = usePromotionsStore();
2033
+ promotionsStore.initialize();
2034
+ const promotionsAreChecking = vue.computed(() => promotionsStore.checking);
2035
+ let manualTimeout = undefined;
2036
+ const checker = async () => {
2037
+ if (promotionsAreChecking.value) {
2038
+ return;
2039
+ }
2040
+ if (manualTimeout) {
2041
+ clearTimeout(manualTimeout);
2042
+ }
2043
+ events.usePromotionsCheckerStarted().publish();
2044
+ await api.checkCompletedPromotions({ id: order.id, token: order.token });
2045
+ manualTimeout = setTimeout(() => {
2046
+ if (promotionsAreChecking.value) {
2047
+ events.usePromotionsCheckerCompleted().publish({ timeout: true });
2048
+ }
2049
+ }, timeout);
2050
+ };
2051
+ events.useProductQuantityIncreased().subscribe('promotions.init', checker);
2052
+ events.useProductQuantityDecreased().subscribe('promotions.init', checker);
2053
+ api.checkCompletedPromotions({ id: order.id, token: order.token }).then(() => {
2054
+ console.log('[storefront/promotions] Promotions checker has been initialized.');
2055
+ });
2056
+ }
2057
+ function useRewardsSelector() {
2058
+ const promotionsStore = usePromotionsStore();
2059
+ const selector = vue.computed(() => promotionsStore.selector);
2060
+ const checking = vue.computed(() => promotionsStore.checking);
2061
+ const failed = vue.computed(() => promotionsStore.failed);
2062
+ const available = vue.computed(() => selector.value.available);
2063
+ const collapsed = vue.computed(() => selector.value.closed);
2064
+ const close = () => promotionsStore.closeRewardsSelector();
2065
+ const open = () => promotionsStore.openRewardsSelector();
2066
+ return {
2067
+ checking,
2068
+ failed,
2069
+ available,
2070
+ collapsed,
2071
+ selector,
2072
+ open,
2073
+ close,
2074
+ };
2075
+ }
2076
+
1915
2077
  exports.ZenkyWebsocketEvent = void 0;
1916
2078
  (function (ZenkyWebsocketEvent) {
1917
2079
  ZenkyWebsocketEvent["OrderPriceRecalculated"] = "orders.price.recalculated";
@@ -1994,6 +2156,7 @@ exports.getStockAddress = getStockAddress;
1994
2156
  exports.getStockSchedule = getStockSchedule;
1995
2157
  exports.getStorage = getStorage;
1996
2158
  exports.getWebsocketsConnection = getWebsocketsConnection;
2159
+ exports.initializePromotions = initializePromotions;
1997
2160
  exports.subscribeToOrderEvents = subscribeToOrderEvents;
1998
2161
  exports.useAddressFormValue = useAddressFormValue;
1999
2162
  exports.useArticleCategoriesList = useArticleCategoriesList;
@@ -2037,8 +2200,10 @@ exports.usePhoneConfirmation = usePhoneConfirmation;
2037
2200
  exports.useProductsList = useProductsList;
2038
2201
  exports.useProductsPricesRange = useProductsPricesRange;
2039
2202
  exports.useProductsPricesRangeFilters = useProductsPricesRangeFilters;
2203
+ exports.usePromotionsStore = usePromotionsStore;
2040
2204
  exports.useRegistration = useRegistration;
2041
2205
  exports.useReversedTree = useReversedTree;
2206
+ exports.useRewardsSelector = useRewardsSelector;
2042
2207
  exports.useSplittedCategoriesTree = useSplittedCategoriesTree;
2043
2208
  exports.useStateDataLoader = useStateDataLoader;
2044
2209
  exports.useStoreStore = useStoreStore;
package/dist/esm/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { ref, computed, watch, unref, inject } from 'vue';
2
2
  import { debounce, isBoolean } from 'lodash-es';
3
- import { getStore, getAddressSuggestions, getCategoriesTree, getProductsCollections, getApiErrorMessage, getCategoryFeatures, getCategoryFeaturesGroups, getArticles, getArticleCategories, getArticle, getAuthenticationStatus, setAxiosToken, getCustomerProfile, login, requestPasswordResetCode, resetPassword, register, resendConfirmationCode, confirm, getApiErrorCode, getCustomerAddresses, deleteAddress, updateAddress, getCustomerOrders, getOrder, getCustomerPaymentMethods, deleteCustomerPaymentMethod, ImageType, getOffers, getOffer, getProductsPricesRange, getProducts } from '@zenky/api';
3
+ import { getStore, getAddressSuggestions, getCategoriesTree, Visibility, getProductsCollections, getApiErrorMessage, getCategoryFeatures, getCategoryFeaturesGroups, getArticles, getArticleCategories, getArticle, getAuthenticationStatus, setAxiosToken, getCustomerProfile, login, requestPasswordResetCode, resetPassword, register, resendConfirmationCode, confirm, getApiErrorCode, getCustomerAddresses, deleteAddress, updateAddress, getCustomerOrders, getOrder, getCustomerPaymentMethods, deleteCustomerPaymentMethod, ImageType, getOffers, getOffer, getProductsPricesRange, getProducts, checkCompletedPromotions } from '@zenky/api';
4
4
  import { defineStore } from 'pinia';
5
5
  import { useNotification } from '@zenky/ui';
6
- import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, useOrderPriceRecalculated, useOrderShouldBeReloaded, useOrderPromotionRewardsShouldBeReloaded, useDisplayOrderPromotionRewardSelection, usePromotionsCheckerCompleted, useOrderPromotionsNotFound, useOrderSubmitted } from '@zenky/events';
6
+ import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, usePromotionsCheckerStarted, usePromotionsCheckerCompleted, useDisplayOrderPromotionRewardSelection, useOrderPromotionsNotFound, useProductQuantityIncreased, useProductQuantityDecreased, useOrderPriceRecalculated, useOrderShouldBeReloaded, useOrderPromotionRewardsShouldBeReloaded, useOrderSubmitted } from '@zenky/events';
7
7
  import Pusher from 'pusher-js';
8
8
 
9
9
  function useDataDestroyer(destroyer, errorHandler) {
@@ -571,7 +571,7 @@ const useCategoriesStore = defineStore({
571
571
  }
572
572
  this.loading = true;
573
573
  try {
574
- this.tree = await getCategoriesTree({ visibility: 'visible', with: 'media' });
574
+ this.tree = await getCategoriesTree({ visibility: Visibility.Visible, with: 'media' });
575
575
  this.loaded = true;
576
576
  }
577
577
  catch (e) {
@@ -746,7 +746,7 @@ const useCollectionsStore = defineStore({
746
746
  this.loading = true;
747
747
  try {
748
748
  this.collections = (await getProductsCollections({
749
- visibility: 'visible',
749
+ visibility: Visibility.Visible,
750
750
  order_by: 'name',
751
751
  with: 'media',
752
752
  count: 100,
@@ -1622,10 +1622,13 @@ var ProductsFiltersType;
1622
1622
  ProductsFiltersType["FeaturesGroups"] = "featuresGroups";
1623
1623
  })(ProductsFiltersType || (ProductsFiltersType = {}));
1624
1624
 
1625
- function getSourceParams(source) {
1625
+ function getSourceParams(source, promotion) {
1626
1626
  if (source === null || !source.id || !source.type) {
1627
1627
  return {};
1628
1628
  }
1629
+ else if (promotion !== null) {
1630
+ return {};
1631
+ }
1629
1632
  switch (source.type) {
1630
1633
  case ProductsSourceType.Category:
1631
1634
  return { category_id: source.id };
@@ -1712,9 +1715,15 @@ function getLoaderParams(page, loader) {
1712
1715
  if (loader.search) {
1713
1716
  params.search = loader.search;
1714
1717
  }
1715
- if (typeof loader.promotionReward === 'string' && loader.promotionReward) {
1716
- params.promotion_reward = loader.promotionReward;
1718
+ if (typeof loader.promotion === 'undefined' || loader.promotion === null) {
1719
+ return params;
1720
+ }
1721
+ params.promotion_reward = 'all';
1722
+ if (!loader.promotion.context_type || !loader.promotion.context_id) {
1723
+ return params;
1717
1724
  }
1725
+ params.context_type = loader.promotion.context_type;
1726
+ params.context_id = loader.promotion.context_id;
1718
1727
  return params;
1719
1728
  }
1720
1729
  function getProductsPaginationRequest(page, loader) {
@@ -1722,7 +1731,7 @@ function getProductsPaginationRequest(page, loader) {
1722
1731
  return null;
1723
1732
  }
1724
1733
  return {
1725
- ...getSourceParams(loader.source),
1734
+ ...getSourceParams(loader.source, loader.promotion),
1726
1735
  ...getSortingParams(loader.sorting),
1727
1736
  ...getFiltersParams(loader.filters),
1728
1737
  ...getPricesFiltersParams(loader.pricesFilters),
@@ -1763,7 +1772,7 @@ function useProductsList(config, errorHandler) {
1763
1772
  count: config.value.count,
1764
1773
  },
1765
1774
  with: config.value.with || '',
1766
- promotionReward: config.value.promotionReward || null,
1775
+ promotion: config.value.promotion || null,
1767
1776
  }));
1768
1777
  const load = async (page, reset = false, callback) => {
1769
1778
  const request = getProductsPaginationRequest(page, loader.value);
@@ -1824,9 +1833,26 @@ function getFiltersFromUrl(param) {
1824
1833
  });
1825
1834
  return filters;
1826
1835
  }
1836
+ function getProductsListQueryParamsWithPromotion(params, promotion) {
1837
+ if (!promotion) {
1838
+ return params;
1839
+ }
1840
+ const clone = {
1841
+ ...params,
1842
+ promotion_id: promotion.id,
1843
+ reward_id: promotion.reward_id,
1844
+ };
1845
+ if (promotion.context_type) {
1846
+ clone.context_type = promotion.context_type;
1847
+ }
1848
+ if (promotion.context_id) {
1849
+ clone.context_id = promotion.context_id;
1850
+ }
1851
+ return clone;
1852
+ }
1827
1853
  function getProductsListQueryParams(config, request) {
1828
1854
  if (request === null) {
1829
- return {};
1855
+ return getProductsListQueryParamsWithPromotion({}, config.promotion);
1830
1856
  }
1831
1857
  const query = {};
1832
1858
  if (request.order_by && request.order_by !== config.sorting) {
@@ -1844,7 +1870,25 @@ function getProductsListQueryParams(config, request) {
1844
1870
  if (request.search) {
1845
1871
  query.search = request.search;
1846
1872
  }
1847
- return query;
1873
+ return getProductsListQueryParamsWithPromotion(query, config.promotion);
1874
+ }
1875
+ function getQueryParam(query, param) {
1876
+ return typeof query[param] !== 'undefined' && query[param] ? query[param] : null;
1877
+ }
1878
+ function getPromotionFromQuery(query) {
1879
+ const promotionId = getQueryParam(query, 'promotion_id');
1880
+ const rewardId = getQueryParam(query, 'reward_id');
1881
+ if (!promotionId || !rewardId) {
1882
+ return null;
1883
+ }
1884
+ const contextType = getQueryParam(query, 'context_type');
1885
+ const contextId = getQueryParam(query, 'context_id');
1886
+ return {
1887
+ id: promotionId,
1888
+ reward_id: rewardId,
1889
+ context_type: contextType,
1890
+ context_id: contextId,
1891
+ };
1848
1892
  }
1849
1893
  function getProductsListParamsFromQuery(query) {
1850
1894
  if (!query) {
@@ -1853,9 +1897,10 @@ function getProductsListParamsFromQuery(query) {
1853
1897
  return {
1854
1898
  sorting: typeof query.order_by !== 'undefined' ? query.order_by : null,
1855
1899
  f: typeof query.f === 'string' ? getFiltersFromUrl(query.f) : null,
1856
- min_price: typeof query.min_price !== 'undefined' && query.min_price ? query.min_price : null,
1857
- max_price: typeof query.max_price !== 'undefined' && query.max_price ? query.max_price : null,
1858
- search: typeof query.search !== 'undefined' && query.search ? query.search : null,
1900
+ min_price: getQueryParam(query, 'min_price'),
1901
+ max_price: getQueryParam(query, 'max_price'),
1902
+ search: getQueryParam(query, 'search'),
1903
+ promotion: getPromotionFromQuery(query),
1859
1904
  };
1860
1905
  }
1861
1906
 
@@ -1904,6 +1949,123 @@ function getProductsSource(source) {
1904
1949
  }
1905
1950
  }
1906
1951
 
1952
+ const usePromotionsStore = defineStore({
1953
+ id: 'zenky:storefront:promotions',
1954
+ state: () => ({
1955
+ checking: false,
1956
+ failed: false,
1957
+ selector: {
1958
+ available: false,
1959
+ closed: false,
1960
+ offer: null,
1961
+ promotion_id: '',
1962
+ reward_id: '',
1963
+ max_quantity: 0,
1964
+ context: null,
1965
+ },
1966
+ }),
1967
+ getters: {
1968
+ hasSelector() {
1969
+ if (this.checking) {
1970
+ return false;
1971
+ }
1972
+ else if (!this.selector.available) {
1973
+ return false;
1974
+ }
1975
+ else if (!this.selector.promotion_id || !this.selector.reward_id) {
1976
+ return false;
1977
+ }
1978
+ return true;
1979
+ },
1980
+ hasSelectorContext() {
1981
+ if (this.selector.context === null) {
1982
+ return false;
1983
+ }
1984
+ return !!this.selector.context.id && !!this.selector.context.type;
1985
+ },
1986
+ },
1987
+ actions: {
1988
+ setCheckerState(value, timedOut = false) {
1989
+ this.checking = value;
1990
+ this.failed = timedOut;
1991
+ },
1992
+ disableRewardsSelector() {
1993
+ this.selector.available = false;
1994
+ this.selector.offer = null;
1995
+ this.selector.promotion_id = '';
1996
+ this.selector.reward_id = '';
1997
+ this.selector.max_quantity = 0;
1998
+ this.selector.context = null;
1999
+ },
2000
+ enableRewardsSelector(selector) {
2001
+ this.selector.available = true;
2002
+ this.selector.offer = selector.offer;
2003
+ this.selector.promotion_id = selector.promotion_id;
2004
+ this.selector.reward_id = selector.reward_id;
2005
+ this.selector.max_quantity = selector.limit;
2006
+ this.selector.context = selector.context;
2007
+ },
2008
+ closeRewardsSelector() {
2009
+ this.selector.closed = true;
2010
+ },
2011
+ openRewardsSelector() {
2012
+ this.selector.closed = false;
2013
+ },
2014
+ initialize() {
2015
+ usePromotionsCheckerStarted().subscribe('storefront.promotions.initialize', () => this.setCheckerState(true));
2016
+ usePromotionsCheckerCompleted().subscribe('storefront.promotions.initialize', (params) => this.setCheckerState(false, params && params.timeout === true));
2017
+ useDisplayOrderPromotionRewardSelection().subscribe('storefront.promotions.initialize', ({ data }) => this.enableRewardsSelector(data));
2018
+ useOrderPromotionsNotFound().subscribe('storefront.promotions.initialize', () => this.disableRewardsSelector());
2019
+ },
2020
+ },
2021
+ });
2022
+
2023
+ function initializePromotions(order, timeout = 10000) {
2024
+ const promotionsStore = usePromotionsStore();
2025
+ promotionsStore.initialize();
2026
+ const promotionsAreChecking = computed(() => promotionsStore.checking);
2027
+ let manualTimeout = undefined;
2028
+ const checker = async () => {
2029
+ if (promotionsAreChecking.value) {
2030
+ return;
2031
+ }
2032
+ if (manualTimeout) {
2033
+ clearTimeout(manualTimeout);
2034
+ }
2035
+ usePromotionsCheckerStarted().publish();
2036
+ await checkCompletedPromotions({ id: order.id, token: order.token });
2037
+ manualTimeout = setTimeout(() => {
2038
+ if (promotionsAreChecking.value) {
2039
+ usePromotionsCheckerCompleted().publish({ timeout: true });
2040
+ }
2041
+ }, timeout);
2042
+ };
2043
+ useProductQuantityIncreased().subscribe('promotions.init', checker);
2044
+ useProductQuantityDecreased().subscribe('promotions.init', checker);
2045
+ checkCompletedPromotions({ id: order.id, token: order.token }).then(() => {
2046
+ console.log('[storefront/promotions] Promotions checker has been initialized.');
2047
+ });
2048
+ }
2049
+ function useRewardsSelector() {
2050
+ const promotionsStore = usePromotionsStore();
2051
+ const selector = computed(() => promotionsStore.selector);
2052
+ const checking = computed(() => promotionsStore.checking);
2053
+ const failed = computed(() => promotionsStore.failed);
2054
+ const available = computed(() => selector.value.available);
2055
+ const collapsed = computed(() => selector.value.closed);
2056
+ const close = () => promotionsStore.closeRewardsSelector();
2057
+ const open = () => promotionsStore.openRewardsSelector();
2058
+ return {
2059
+ checking,
2060
+ failed,
2061
+ available,
2062
+ collapsed,
2063
+ selector,
2064
+ open,
2065
+ close,
2066
+ };
2067
+ }
2068
+
1907
2069
  var ZenkyWebsocketEvent;
1908
2070
  (function (ZenkyWebsocketEvent) {
1909
2071
  ZenkyWebsocketEvent["OrderPriceRecalculated"] = "orders.price.recalculated";
@@ -1969,4 +2131,4 @@ function subscribeToOrderEvents(order) {
1969
2131
  });
1970
2132
  }
1971
2133
 
1972
- export { AuthenticationEvent, AuthenticationResultType, AuthenticationStage, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getWebsocketsConnection, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useOfferItem, useOffersList, useOrderItem, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, useRegistration, useReversedTree, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity };
2134
+ export { AuthenticationEvent, AuthenticationResultType, AuthenticationStage, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getWebsocketsConnection, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useOfferItem, useOffersList, useOrderItem, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity };
package/dist/zenky.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Ref, ComputedRef } from 'vue';
2
2
  import * as _zenky_api from '@zenky/api';
3
- import { PaginationRequest, Pagination, PaginatedResponse, ResourceRequest, Address, City, NestedCategory, ProductsCollection, Feature, FeaturesGroupContainer, Article, ArticleCategory, Customer, AuthenticationPhone, Order, OrderCredentials, CustomerPaymentMethod, Medium, Image, Offer, Product, ProductsPricesRange, ProductsPaginationRequest, Schedule, Stock, Store, StoreSettings } from '@zenky/api';
3
+ import { PaginationRequest, Pagination, PaginatedResponse, ResourceRequest, Address, City, NestedCategory, ProductsCollection, Feature, FeaturesGroupContainer, Article, ArticlesPaginationRequest, ArticleCategory, ArticleCategoriesPaginationRequest, Customer, AuthenticationPhone, Order, OrderCredentials, CustomerPaymentMethod, Medium, Image, Offer, OffersPaginationRequest, Product, ProductsPricesRange, ProductsPaginationRequest, Schedule, Stock, Store, StoreSettings } from '@zenky/api';
4
4
  import * as pinia from 'pinia';
5
5
  import Pusher from 'pusher-js';
6
6
 
@@ -210,8 +210,8 @@ declare const useCollectionsStore: pinia.StoreDefinition<"zenky:storefront:colle
210
210
  declare function useCategoryFeaturesList(categoryId: string | null, errorHandler?: OptionalApiErrorHandler): ListLoader<Feature>;
211
211
  declare function useCategoryFeaturesGroupsList(categoryId: string | null, errorHandler?: OptionalApiErrorHandler): ListLoader<FeaturesGroupContainer>;
212
212
 
213
- declare function useArticlesList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<Article>;
214
- declare function useArticleCategoriesList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<ArticleCategory>;
213
+ declare function useArticlesList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<Article, ArticlesPaginationRequest>;
214
+ declare function useArticleCategoriesList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<ArticleCategory, ArticleCategoriesPaginationRequest>;
215
215
  declare function useArticleItem(errorHandler?: OptionalApiErrorHandler): ItemLoader<Article>;
216
216
 
217
217
  declare enum AuthenticationStage {
@@ -1060,7 +1060,7 @@ declare const useCustomerStore: pinia.StoreDefinition<"zenky:storefront:customer
1060
1060
 
1061
1061
  declare function getFirstMedium(media: Medium | Medium[], sizes?: string[], preferWebp?: boolean): Image | null;
1062
1062
 
1063
- declare function useOffersList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<Offer>;
1063
+ declare function useOffersList(errorHandler?: OptionalApiErrorHandler): PaginatedLoader<Offer, OffersPaginationRequest>;
1064
1064
  declare function useOfferItem(errorHandler?: OptionalApiErrorHandler): ItemLoader<Offer>;
1065
1065
 
1066
1066
  declare enum ProductsSourceType {
@@ -1102,7 +1102,7 @@ interface ProductsLoader {
1102
1102
  count: number;
1103
1103
  };
1104
1104
  with?: string;
1105
- promotionReward?: string | null;
1105
+ promotion?: ProductsPromotion | null;
1106
1106
  }
1107
1107
  declare type ProductsRequestCallback = (request: ProductsPaginationRequest | null) => void;
1108
1108
  interface ProductsListProvider {
@@ -1123,6 +1123,12 @@ declare enum ProductsFiltersType {
1123
1123
  Features = "features",
1124
1124
  FeaturesGroups = "featuresGroups"
1125
1125
  }
1126
+ interface ProductsPromotion {
1127
+ id: string;
1128
+ reward_id: string;
1129
+ context_type: string | null;
1130
+ context_id: string | null;
1131
+ }
1126
1132
  interface ProductsListConfig {
1127
1133
  source: ProductsSource | null;
1128
1134
  search?: string | null;
@@ -1132,7 +1138,7 @@ interface ProductsListConfig {
1132
1138
  count: number;
1133
1139
  filtersType: ProductsFiltersType | null;
1134
1140
  with?: string;
1135
- promotionReward?: string;
1141
+ promotion?: ProductsPromotion | null;
1136
1142
  }
1137
1143
 
1138
1144
  declare function useFeaturesFilters(categoryId: string | null, values: ProductsFilters | null): {
@@ -1161,6 +1167,64 @@ declare function getProductsSource(source: ProductsSource | null): ProductsSourc
1161
1167
 
1162
1168
  declare function getProductsPaginationRequest(page: number, loader: ProductsLoader): ProductsPaginationRequest | null;
1163
1169
 
1170
+ interface PromotionsSelectorContext {
1171
+ id: string;
1172
+ type: string;
1173
+ }
1174
+ interface PromotionsSelectorOffer {
1175
+ id: string;
1176
+ short_id: string;
1177
+ slug: string;
1178
+ }
1179
+ interface PromotionsSelector {
1180
+ available: boolean;
1181
+ closed: boolean;
1182
+ offer: PromotionsSelectorOffer | null;
1183
+ promotion_id: string;
1184
+ reward_id: string;
1185
+ max_quantity: number;
1186
+ context: PromotionsSelectorContext | null;
1187
+ }
1188
+ interface PromotionsCheckerSelector {
1189
+ offer: PromotionsSelectorOffer | null;
1190
+ promotion_id: string;
1191
+ reward_id: string;
1192
+ limit: number;
1193
+ context: PromotionsSelectorContext | null;
1194
+ }
1195
+ interface PromotionsStoreState {
1196
+ checking: boolean;
1197
+ failed: boolean;
1198
+ selector: PromotionsSelector;
1199
+ }
1200
+ interface PromotionsCheckerCompletedPayload {
1201
+ timeout?: boolean;
1202
+ }
1203
+ interface PromotionsRewardsSelectorProvider {
1204
+ checking: ComputedRef<boolean>;
1205
+ failed: ComputedRef<boolean>;
1206
+ available: ComputedRef<boolean>;
1207
+ collapsed: ComputedRef<boolean>;
1208
+ selector: ComputedRef<PromotionsSelector>;
1209
+ open: () => void;
1210
+ close: () => void;
1211
+ }
1212
+
1213
+ declare const usePromotionsStore: pinia.StoreDefinition<"zenky:storefront:promotions", PromotionsStoreState, {
1214
+ hasSelector(): boolean;
1215
+ hasSelectorContext(): boolean;
1216
+ }, {
1217
+ setCheckerState(value: boolean, timedOut?: boolean): void;
1218
+ disableRewardsSelector(): void;
1219
+ enableRewardsSelector(selector: PromotionsCheckerSelector): void;
1220
+ closeRewardsSelector(): void;
1221
+ openRewardsSelector(): void;
1222
+ initialize(): void;
1223
+ }>;
1224
+
1225
+ declare function initializePromotions(order: Order, timeout?: number): void;
1226
+ declare function useRewardsSelector(): PromotionsRewardsSelectorProvider;
1227
+
1164
1228
  declare function getStockSchedule(schedule: Schedule): string;
1165
1229
  declare function getStockAddress(stock: Stock): string | null;
1166
1230
 
@@ -1196,4 +1260,4 @@ declare function createWebsocketsConnection(store: Store): Pusher;
1196
1260
  declare function getWebsocketsConnection(): Pusher;
1197
1261
  declare function subscribeToOrderEvents(order: Order): void;
1198
1262
 
1199
- export { AddressForm, AddressFormValue, AddressFormValueProvider, ApiErrorHandler, AuthenticationEvent, AuthenticationForm, AuthenticationFormProvider, AuthenticationResult, AuthenticationResultType, AuthenticationStage, AuthenticationStatusCheckerProvider, CategoriesProvider, CategoriesState, CategoriesTreeProvider, CategoryProvider, CollectionsState, ConfirmableDataDestroyer, ConfirmationProvider, CustomerStore, DadataProvider, DataDestroyer, DataDestroyerHandler, DataLoader, DataProvider, EditAddressFormProvider, EmitAuthenticationEvent, FlatCategoriesTreeProvider, FlattenNestedCategory, ItemLoader, ItemProvider, ListLoader, ListProvider, LoaderState, LoginProvider, LogoutProvider, OptionalApiErrorHandler, PaginatedItemsProvider, PaginatedLoader, PaginatedLoaderState, PasswordResetProvider, ProductsCollectionProvider, ProductsCollectionsProvider, RegistrationProvider, ReversedTreeProvider, SplittedCategoriesTreeProvider, StateDataLoader, StateDataLoaderState, StoreState, ZenkyInjection, ZenkyStorage, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getWebsocketsConnection, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useOfferItem, useOffersList, useOrderItem, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, useRegistration, useReversedTree, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity };
1263
+ export { AddressForm, AddressFormValue, AddressFormValueProvider, ApiErrorHandler, AuthenticationEvent, AuthenticationForm, AuthenticationFormProvider, AuthenticationResult, AuthenticationResultType, AuthenticationStage, AuthenticationStatusCheckerProvider, CategoriesProvider, CategoriesState, CategoriesTreeProvider, CategoryProvider, CollectionsState, ConfirmableDataDestroyer, ConfirmationProvider, CustomerStore, DadataProvider, DataDestroyer, DataDestroyerHandler, DataLoader, DataProvider, EditAddressFormProvider, EmitAuthenticationEvent, FlatCategoriesTreeProvider, FlattenNestedCategory, ItemLoader, ItemProvider, ListLoader, ListProvider, LoaderState, LoginProvider, LogoutProvider, OptionalApiErrorHandler, PaginatedItemsProvider, PaginatedLoader, PaginatedLoaderState, PasswordResetProvider, ProductsCollectionProvider, ProductsCollectionsProvider, PromotionsCheckerCompletedPayload, PromotionsCheckerSelector, PromotionsRewardsSelectorProvider, PromotionsSelector, PromotionsSelectorContext, PromotionsSelectorOffer, PromotionsStoreState, RegistrationProvider, ReversedTreeProvider, SplittedCategoriesTreeProvider, StateDataLoader, StateDataLoaderState, StoreState, ZenkyInjection, ZenkyStorage, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getWebsocketsConnection, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useOfferItem, useOffersList, useOrderItem, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenky/storefront-vue",
3
- "version": "0.9.34",
3
+ "version": "0.9.38",
4
4
  "description": "Zenky Storefront library for Vue 3.",
5
5
  "author": "Timur Zurbaev <hello@zurbaev.ru>",
6
6
  "license": "MIT",
@@ -19,7 +19,7 @@
19
19
  "Zenky"
20
20
  ],
21
21
  "peerDependencies": {
22
- "@zenky/api": "^0.9.41",
22
+ "@zenky/api": "^0.9.45",
23
23
  "@zenky/events": "^1.0.2",
24
24
  "@zenky/ui": "^0.9.63",
25
25
  "lodash-es": "^4.17.21",