From 1484bf90871eedbce40c5c1f433788892ee18602 Mon Sep 17 00:00:00 2001 From: tkostuch Date: Fri, 29 May 2020 10:56:12 +0200 Subject: [PATCH 1/4] move deprecated code to files --- .../catalog-next/store/category/actions.ts | 47 +-- .../store/category/deprecatedActions.ts | 47 +++ .../catalog/helpers/deprecatedHelpers.ts | 145 +++++++ core/modules/catalog/helpers/index.ts | 147 +------- core/modules/catalog/store/product/actions.ts | 346 +---------------- .../store/product/deprecatedActions.ts | 355 ++++++++++++++++++ 6 files changed, 562 insertions(+), 525 deletions(-) create mode 100644 core/modules/catalog-next/store/category/deprecatedActions.ts create mode 100644 core/modules/catalog/helpers/deprecatedHelpers.ts create mode 100644 core/modules/catalog/store/product/deprecatedActions.ts diff --git a/core/modules/catalog-next/store/category/actions.ts b/core/modules/catalog-next/store/category/actions.ts index 8b7c38d4f3..05dcb3e431 100644 --- a/core/modules/catalog-next/store/category/actions.ts +++ b/core/modules/catalog-next/store/category/actions.ts @@ -4,19 +4,17 @@ import * as types from './mutation-types' import RootState from '@vue-storefront/core/types/RootState' import CategoryState from './CategoryState' import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import { buildFilterProductsQuery, isServer } from '@vue-storefront/core/helpers' +import { buildFilterProductsQuery } from '@vue-storefront/core/helpers' import { router } from '@vue-storefront/core/app' -import { currentStoreView, localizedDispatcherRoute, localizedDispatcherRouteName } from '@vue-storefront/core/lib/multistore' +import { localizedDispatcherRoute } from '@vue-storefront/core/lib/multistore' import FilterVariant from '../../types/FilterVariant' import { CategoryService } from '@vue-storefront/core/data-resolver' import { changeFilterQuery } from '../../helpers/filterHelpers' import { products, entities } from 'config' -import { configureProductAsync } from '@vue-storefront/core/modules/catalog/helpers' import { DataResolver } from 'core/data-resolver/types/DataResolver'; import { Category } from '../../types/Category'; import { _prepareCategoryPathIds } from '../../helpers/categoryHelpers'; import { prefetchStockItems } from '../../helpers/cacheProductsHelper'; -import { preConfigureProduct } from '@vue-storefront/core/modules/catalog/helpers/search' import chunk from 'lodash-es/chunk' import omit from 'lodash-es/omit' import cloneDeep from 'lodash-es/cloneDeep' @@ -121,43 +119,6 @@ const actions: ActionTree = { } } }, - /** - * Calculates products taxes - * Registers URLs - * Configures products - */ - async processCategoryProducts ({ dispatch, rootState }, { products = [], filters = {} } = {}) { - dispatch('registerCategoryProductsMapping', products) // we don't need to wait for this - const configuredProducts = await dispatch('configureProducts', { products, filters }) - return dispatch('tax/calculateTaxes', { products: configuredProducts }, { root: true }) - }, - /** - * Configure configurable products to have first available options selected - * so they can be added to cart/wishlist/compare without manual configuring - */ - async configureProducts ({ rootState }, { products = [], filters = {}, populateRequestCacheTags = config.server.useOutputCacheTagging } = {}) { - return products.map(product => { - product = Object.assign({}, preConfigureProduct({ product, populateRequestCacheTags })) - const configuredProductVariant = configureProductAsync({ rootState, state: { current_configuration: {} } }, { product, configuration: filters, selectDefaultVariant: false, fallbackToDefaultWhenNoAvailable: true, setProductErorrs: false }) - return Object.assign(product, omit(configuredProductVariant, ['visibility'])) - }) - }, - async registerCategoryProductsMapping ({ dispatch }, products = []) { - const { storeCode, appendStoreCode } = currentStoreView() - await Promise.all(products.map(product => { - const { url_path, sku, slug, type_id } = product - return dispatch('url/registerMapping', { - url: localizedDispatcherRoute(url_path, storeCode), - routeData: { - params: { - parentSku: product.parentSku || product.sku, - slug - }, - 'name': localizedDispatcherRouteName(type_id + '-product', storeCode, appendStoreCode) - } - }, { root: true }) - })) - }, async findCategories (context, categorySearchOptions: DataResolver.CategorySearchOptions): Promise { return CategoryService.getCategories(categorySearchOptions) }, @@ -299,7 +260,9 @@ const actions: ActionTree = { }, { root: true }) } } - } + }, + /** Below actions are not used from 1.12 and can be removed to reduce bundle */ + ...require('./deprecatedActions').default } export default actions diff --git a/core/modules/catalog-next/store/category/deprecatedActions.ts b/core/modules/catalog-next/store/category/deprecatedActions.ts new file mode 100644 index 0000000000..f6701570ed --- /dev/null +++ b/core/modules/catalog-next/store/category/deprecatedActions.ts @@ -0,0 +1,47 @@ +import { currentStoreView, localizedDispatcherRoute, localizedDispatcherRouteName } from '@vue-storefront/core/lib/multistore' +import { preConfigureProduct } from '@vue-storefront/core/modules/catalog/helpers/search' +import omit from 'lodash-es/omit' +import config from 'config' +const { configureProductAsync } = require('@vue-storefront/core/modules/catalog/helpers') + +const actions = { + /** + * Calculates products taxes + * Registers URLs + * Configures products + */ + async processCategoryProducts ({ dispatch, rootState }, { products = [], filters = {} } = {}) { + dispatch('registerCategoryProductsMapping', products) // we don't need to wait for this + const configuredProducts = await dispatch('configureProducts', { products, filters }) + return dispatch('tax/calculateTaxes', { products: configuredProducts }, { root: true }) + }, + /** + * Configure configurable products to have first available options selected + * so they can be added to cart/wishlist/compare without manual configuring + */ + async configureProducts ({ rootState }, { products = [], filters = {}, populateRequestCacheTags = config.server.useOutputCacheTagging } = {}) { + return products.map(product => { + product = Object.assign({}, preConfigureProduct({ product, populateRequestCacheTags })) + const configuredProductVariant = configureProductAsync({ rootState, state: { current_configuration: {} } }, { product, configuration: filters, selectDefaultVariant: false, fallbackToDefaultWhenNoAvailable: true, setProductErorrs: false }) + return Object.assign(product, omit(configuredProductVariant, ['visibility'])) + }) + }, + async registerCategoryProductsMapping ({ dispatch }, products = []) { + const { storeCode, appendStoreCode } = currentStoreView() + await Promise.all(products.map(product => { + const { url_path, sku, slug, type_id } = product + return dispatch('url/registerMapping', { + url: localizedDispatcherRoute(url_path, storeCode), + routeData: { + params: { + parentSku: product.parentSku || product.sku, + slug + }, + 'name': localizedDispatcherRouteName(type_id + '-product', storeCode, appendStoreCode) + } + }, { root: true }) + })) + } +} + +export default actions diff --git a/core/modules/catalog/helpers/deprecatedHelpers.ts b/core/modules/catalog/helpers/deprecatedHelpers.ts new file mode 100644 index 0000000000..2917769e9e --- /dev/null +++ b/core/modules/catalog/helpers/deprecatedHelpers.ts @@ -0,0 +1,145 @@ +import Vue from 'vue' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' +import omit from 'lodash-es/omit' +import i18n from '@vue-storefront/i18n' +import { Logger } from '@vue-storefront/core/lib/logger' +import { optionLabel } from './optionLabel' +import { setProductConfigurableOptions } from './productOptions' +import config from 'config' +import { findConfigurableVariant } from './variant' +import { hasImage } from './' + +export function populateProductConfigurationAsync (context, { product, selectedVariant }) { + Logger.warn('deprecated, will be not used from 1.12')() + if (product.configurable_options) { + for (let option of product.configurable_options) { + let attribute_code + let attribute_label + if (option.attribute_code) { + attribute_code = option.attribute_code + attribute_label = option.label ? option.label : (option.frontend_label ? option.frontend_label : option.default_frontend_label) + } else { + if (option.attribute_id) { + let attr = context.rootState.attribute.list_by_id[option.attribute_id] + if (!attr) { + Logger.error('Wrong attribute given in configurable_options - can not find by attribute_id', option)() + continue + } else { + attribute_code = attr.attribute_code + attribute_label = attr.frontend_label ? attr.frontend_label : attr.default_frontend_label + } + } else { + Logger.error('Wrong attribute given in configurable_options - no attribute_code / attribute_id', option)() + } + } + let selectedOption = null + if (selectedVariant.custom_attributes) { + selectedOption = selectedVariant.custom_attributes.find((a) => { // this is without the "label" + return (a.attribute_code === attribute_code) + }) + } else { + selectedOption = { + attribute_code: attribute_code, + value: selectedVariant[attribute_code] + } + } + if (option.values && option.values.length) { + const selectedOptionMeta = option.values.find(ov => { return ov.value_index === selectedOption.value }) + if (selectedOptionMeta) { + selectedOption.label = selectedOptionMeta.label ? selectedOptionMeta.label : selectedOptionMeta.default_label + selectedOption.value_data = selectedOptionMeta.value_data + } + } + + const confVal = { + attribute_code: attribute_code, + id: selectedOption.value, + label: selectedOption.label ? selectedOption.label : /* if not set - find by attribute */optionLabel(context.rootState.attribute, { attributeKey: selectedOption.attribute_code, searchBy: 'code', optionId: selectedOption.value }) + } + Vue.set(context.state.current_configuration, attribute_code, confVal) + } + setProductConfigurableOptions({ + product, + configuration: context.state.current_configuration, + setConfigurableProductOptions: config.cart.setConfigurableProductOptions + }) // set the custom options + } + return selectedVariant +} + +export function configureProductAsync (context, { product, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = true, setProductErorrs = false }) { + Logger.warn('deprecated, will be not used from 1.12')() + // use current product if product wasn't passed + if (product === null) product = context.getters.getCurrentProduct + const hasConfigurableChildren = (product.configurable_children && product.configurable_children.length > 0) + + if (hasConfigurableChildren) { + // handle custom_attributes for easier comparing in the future + product.configurable_children.forEach((child) => { + let customAttributesAsObject = {} + if (child.custom_attributes) { + child.custom_attributes.forEach((attr) => { + customAttributesAsObject[attr.attribute_code] = attr.value + }) + // add values from custom_attributes in a different form + Object.assign(child, customAttributesAsObject) + } + }) + // find selected variant + let desiredProductFound = false + let selectedVariant = findConfigurableVariant({ product, configuration, availabilityCheck: true }) + if (!selectedVariant) { + if (fallbackToDefaultWhenNoAvailable) { + selectedVariant = findConfigurableVariant({ product, selectDefaultChildren: true, availabilityCheck: true }) // return first available child + desiredProductFound = false + } else { + desiredProductFound = false + } + } else { + desiredProductFound = true + } + + if (selectedVariant) { + if (!desiredProductFound && selectDefaultVariant /** don't change the state when no selectDefaultVariant is set */) { // update the configuration + populateProductConfigurationAsync(context, { product: product, selectedVariant: selectedVariant }) + configuration = context.state.current_configuration + } + if (setProductErorrs) { + product.errors = {} // clear the product errors + } + product.is_configured = true + + if (config.cart.setConfigurableProductOptions && !selectDefaultVariant && !(Object.keys(configuration).length === 1 && configuration.sku)) { + // the condition above: if selectDefaultVariant - then "setCurrent" is seeting the configurable options; if configuration = { sku: '' } -> this is a special case when not configuring the product but just searching by sku + setProductConfigurableOptions({ + product, + configuration, + setConfigurableProductOptions: config.cart.setConfigurableProductOptions + }) // set the custom options + }/* else { + Logger.debug('Skipping configurable options setup', configuration)() + } */ + const fieldsToOmit = ['name'] + if (!hasImage(selectedVariant)) fieldsToOmit.push('image') + selectedVariant = omit(selectedVariant, fieldsToOmit) // We need to send the parent SKU to the Magento cart sync but use the child SKU internally in this case + // use chosen variant for the current product + if (selectDefaultVariant) { + context.dispatch('setCurrent', selectedVariant) + } + EventBus.$emit('product-after-configure', { product: product, configuration: configuration, selectedVariant: selectedVariant }) + } + if (!selectedVariant && setProductErorrs) { // can not find variant anyway, even the default one + product.errors.variants = i18n.t('No available product variants') + if (selectDefaultVariant) { + context.dispatch('setCurrent', product) // without the configuration + } + } + return selectedVariant + } else { + if (fallbackToDefaultWhenNoAvailable) { + return product + } else { + return null + } + } +} diff --git a/core/modules/catalog/helpers/index.ts b/core/modules/catalog/helpers/index.ts index 4d07df405b..4510c56e73 100644 --- a/core/modules/catalog/helpers/index.ts +++ b/core/modules/catalog/helpers/index.ts @@ -1,11 +1,7 @@ import Vue from 'vue' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import omit from 'lodash-es/omit' // TODO: Remove this dependency import { optionLabel } from './optionLabel' -import i18n from '@vue-storefront/i18n' import { getThumbnailPath } from '@vue-storefront/core/helpers' -import { Logger } from '@vue-storefront/core/lib/logger' import config from 'config' import registerProductsMapping from './registerProductsMapping' import getProductGallery from './getProductGallery' @@ -14,6 +10,14 @@ import { filterOutUnavailableVariants } from './stock' import { doPlatformPricesSync } from './price' import { setProductConfigurableOptions } from './productOptions' +/** Below helpers are not used from 1.12 and can be removed to reduce bundle */ +import { populateProductConfigurationAsync, configureProductAsync } from './deprecatedHelpers' +export { + populateProductConfigurationAsync, + configureProductAsync +} +/***/ + export { registerProductsMapping, getProductGallery, @@ -64,141 +68,6 @@ export function setBundleProductOptionsAsync (context, { product, bundleOptions return productOption } -export function populateProductConfigurationAsync (context, { product, selectedVariant }) { - Logger.warn('deprecated, will be not used from 1.12')() - if (product.configurable_options) { - for (let option of product.configurable_options) { - let attribute_code - let attribute_label - if (option.attribute_code) { - attribute_code = option.attribute_code - attribute_label = option.label ? option.label : (option.frontend_label ? option.frontend_label : option.default_frontend_label) - } else { - if (option.attribute_id) { - let attr = context.rootState.attribute.list_by_id[option.attribute_id] - if (!attr) { - Logger.error('Wrong attribute given in configurable_options - can not find by attribute_id', option)() - continue - } else { - attribute_code = attr.attribute_code - attribute_label = attr.frontend_label ? attr.frontend_label : attr.default_frontend_label - } - } else { - Logger.error('Wrong attribute given in configurable_options - no attribute_code / attribute_id', option)() - } - } - let selectedOption = null - if (selectedVariant.custom_attributes) { - selectedOption = selectedVariant.custom_attributes.find((a) => { // this is without the "label" - return (a.attribute_code === attribute_code) - }) - } else { - selectedOption = { - attribute_code: attribute_code, - value: selectedVariant[attribute_code] - } - } - if (option.values && option.values.length) { - const selectedOptionMeta = option.values.find(ov => { return ov.value_index === selectedOption.value }) - if (selectedOptionMeta) { - selectedOption.label = selectedOptionMeta.label ? selectedOptionMeta.label : selectedOptionMeta.default_label - selectedOption.value_data = selectedOptionMeta.value_data - } - } - - const confVal = { - attribute_code: attribute_code, - id: selectedOption.value, - label: selectedOption.label ? selectedOption.label : /* if not set - find by attribute */optionLabel(context.rootState.attribute, { attributeKey: selectedOption.attribute_code, searchBy: 'code', optionId: selectedOption.value }) - } - Vue.set(context.state.current_configuration, attribute_code, confVal) - } - setProductConfigurableOptions({ - product, - configuration: context.state.current_configuration, - setConfigurableProductOptions: config.cart.setConfigurableProductOptions - }) // set the custom options - } - return selectedVariant -} - -export function configureProductAsync (context, { product, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = true, setProductErorrs = false }) { - Logger.warn('deprecated, will be not used from 1.12')() - // use current product if product wasn't passed - if (product === null) product = context.getters.getCurrentProduct - const hasConfigurableChildren = (product.configurable_children && product.configurable_children.length > 0) - - if (hasConfigurableChildren) { - // handle custom_attributes for easier comparing in the future - product.configurable_children.forEach((child) => { - let customAttributesAsObject = {} - if (child.custom_attributes) { - child.custom_attributes.forEach((attr) => { - customAttributesAsObject[attr.attribute_code] = attr.value - }) - // add values from custom_attributes in a different form - Object.assign(child, customAttributesAsObject) - } - }) - // find selected variant - let desiredProductFound = false - let selectedVariant = findConfigurableVariant({ product, configuration, availabilityCheck: true }) - if (!selectedVariant) { - if (fallbackToDefaultWhenNoAvailable) { - selectedVariant = findConfigurableVariant({ product, selectDefaultChildren: true, availabilityCheck: true }) // return first available child - desiredProductFound = false - } else { - desiredProductFound = false - } - } else { - desiredProductFound = true - } - - if (selectedVariant) { - if (!desiredProductFound && selectDefaultVariant /** don't change the state when no selectDefaultVariant is set */) { // update the configuration - populateProductConfigurationAsync(context, { product: product, selectedVariant: selectedVariant }) - configuration = context.state.current_configuration - } - if (setProductErorrs) { - product.errors = {} // clear the product errors - } - product.is_configured = true - - if (config.cart.setConfigurableProductOptions && !selectDefaultVariant && !(Object.keys(configuration).length === 1 && configuration.sku)) { - // the condition above: if selectDefaultVariant - then "setCurrent" is seeting the configurable options; if configuration = { sku: '' } -> this is a special case when not configuring the product but just searching by sku - setProductConfigurableOptions({ - product, - configuration, - setConfigurableProductOptions: config.cart.setConfigurableProductOptions - }) // set the custom options - }/* else { - Logger.debug('Skipping configurable options setup', configuration)() - } */ - const fieldsToOmit = ['name'] - if (!hasImage(selectedVariant)) fieldsToOmit.push('image') - selectedVariant = omit(selectedVariant, fieldsToOmit) // We need to send the parent SKU to the Magento cart sync but use the child SKU internally in this case - // use chosen variant for the current product - if (selectDefaultVariant) { - context.dispatch('setCurrent', selectedVariant) - } - EventBus.$emit('product-after-configure', { product: product, configuration: configuration, selectedVariant: selectedVariant }) - } - if (!selectedVariant && setProductErorrs) { // can not find variant anyway, even the default one - product.errors.variants = i18n.t('No available product variants') - if (selectDefaultVariant) { - context.dispatch('setCurrent', product) // without the configuration - } - } - return selectedVariant - } else { - if (fallbackToDefaultWhenNoAvailable) { - return product - } else { - return null - } - } -} - /** * Get media Gallery images from product */ diff --git a/core/modules/catalog/store/product/actions.ts b/core/modules/catalog/store/product/actions.ts index e9d7ca1d7c..82c1471c72 100644 --- a/core/modules/catalog/store/product/actions.ts +++ b/core/modules/catalog/store/product/actions.ts @@ -1,24 +1,18 @@ import { ActionTree } from 'vuex' import * as types from './mutation-types' -import { formatBreadCrumbRoutes, isServer } from '@vue-storefront/core/helpers' -import { preConfigureProduct, storeProductToCache, isGroupedOrBundle } from '@vue-storefront/core/modules/catalog/helpers/search' +import { isServer } from '@vue-storefront/core/helpers' import { SearchQuery } from 'storefront-query-builder' -import { optionLabel } from '../../helpers/optionLabel' -import trim from 'lodash-es/trim' import cloneDeep from 'lodash-es/cloneDeep' import rootStore from '@vue-storefront/core/store' import RootState from '@vue-storefront/core/types/RootState' import ProductState from '../../types/ProductState' import { Logger } from '@vue-storefront/core/lib/logger'; -import toString from 'lodash-es/toString' import config from 'config' import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' import { ProductService } from '@vue-storefront/core/data-resolver/ProductService' import { registerProductsMapping, doPlatformPricesSync, - filterOutUnavailableVariants, - populateProductConfigurationAsync, setCustomProductOptionsAsync, setBundleProductOptionsAsync, getProductGallery, @@ -27,8 +21,6 @@ import { import { getProductConfigurationOptions } from '@vue-storefront/core/modules/catalog/helpers/productOptions' import { checkParentRedirection } from '@vue-storefront/core/modules/catalog/events' -const PRODUCT_REENTER_TIMEOUT = 20000 - const actions: ActionTree = { doPlatformPricesSync (context, { products }) { return doPlatformPricesSync(products) @@ -323,341 +315,7 @@ const actions: ActionTree = { return { ...selectedVariant, options, product_option } }, /** Below actions are not used from 1.12 and can be removed to reduce bundle */ - /** - * Reset current configuration and selected variatnts - */ - reset (context) { - Logger.warn('`product/reset` deprecated, will be not used from 1.12')() - const originalProduct = Object.assign({}, context.getters.getOriginalProduct) - context.commit(types.PRODUCT_RESET_CURRENT, originalProduct) - }, - /** - * Setup product breadcrumbs path - */ - async setupBreadcrumbs (context, { product }) { - Logger.warn('`product/setupBreadcrumbs` deprecated, will be not used from 1.12')() - let breadcrumbsName = null - let setBreadcrumbRoutesFromPath = (path) => { - if (path.findIndex(itm => { - return itm.slug === context.rootGetters['category/getCurrentCategory'].slug - }) < 0) { - path.push({ - url_path: context.rootGetters['category/getCurrentCategory'].url_path, - slug: context.rootGetters['category/getCurrentCategory'].slug, - name: context.rootGetters['category/getCurrentCategory'].name - }) // current category at the end - } - // deprecated, TODO: base on breadcrumbs module - breadcrumbsName = product.name - const breadcrumbs = { - routes: formatBreadCrumbRoutes(path), - current: breadcrumbsName, - name: breadcrumbsName - } - context.commit(types.CATALOG_SET_BREADCRUMBS, breadcrumbs) - } - - if (product.category && product.category.length > 0) { - const categoryIds = product.category.reverse().map(cat => cat.category_id) - await context.dispatch('category/list', { key: 'id', value: categoryIds }, { root: true }).then(async (categories) => { - const catList = [] - - for (let catId of categoryIds) { - let category = categories.items.find((itm) => { return toString(itm['id']) === toString(catId) }) - if (category) { - catList.push(category) - } - } - - const rootCat = catList.shift() - let catForBreadcrumbs = rootCat - - for (let cat of catList) { - const catPath = cat.path - if (catPath && catPath.includes(rootCat.path) && (catPath.split('/').length > catForBreadcrumbs.path.split('/').length)) { - catForBreadcrumbs = cat - } - } - if (typeof catForBreadcrumbs !== 'undefined') { - await context.dispatch('category/single', { key: 'id', value: catForBreadcrumbs.id }, { root: true }).then(() => { // this sets up category path and current category - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) - }).catch(err => { - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) - Logger.error(err)() - }) - } else { - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) - } - }) - } - }, - /** - * Download Magento2 / other platform prices to put them over ElasticSearch prices - */ - async syncPlatformPricesOver ({ rootGetters }, { skus }) { - Logger.warn('`product/syncPlatformPricesOver`deprecated, will be not used from 1.12')() - const result = await ProductService.getProductRenderList({ - skus, - isUserGroupedTaxActive: rootGetters['tax/getIsUserGroupedTaxActive'], - userGroupId: rootGetters['tax/getUserTaxGroupId'], - token: rootGetters['user/getToken'] - }) - return result - }, - /** - * Setup associated products - */ - setupAssociated (context, { product, skipCache = true }) { - Logger.warn('`product/setupAssociated` deprecated, will be not used from 1.12')() - let subloaders = [] - if (product.type_id === 'grouped') { - product.price = 0 - product.price_incl_tax = 0 - Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() - if (product.product_links && product.product_links.length > 0) { - for (let pl of product.product_links) { - if (pl.link_type === 'associated' && pl.linked_product_type === 'simple') { // prefetch links - Logger.debug('Prefetching grouped product link for ' + pl.sku + ' = ' + pl.linked_product_sku)() - subloaders.push(context.dispatch('single', { - options: { sku: pl.linked_product_sku }, - setCurrentProduct: false, - selectDefaultVariant: false, - skipCache: skipCache - }).catch(err => { Logger.error(err) }).then((asocProd) => { - if (asocProd) { - pl.product = asocProd - pl.product.qty = 1 - product.price += pl.product.price - product.price_incl_tax += pl.product.price_incl_tax - product.tax += pl.product.tax - } else { - Logger.error('Product link not found', pl.linked_product_sku)() - } - })) - } - } - } else { - Logger.error('Product with type grouped has no product_links set!', product)() - } - } - if (product.type_id === 'bundle') { - product.price = 0 - product.price_incl_tax = 0 - Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() - if (product.bundle_options && product.bundle_options.length > 0) { - for (let bo of product.bundle_options) { - let defaultOption = bo.product_links.find((p) => { return p.is_default }) - if (!defaultOption) defaultOption = bo.product_links[0] - for (let pl of bo.product_links) { - Logger.debug('Prefetching bundle product link for ' + bo.sku + ' = ' + pl.sku)() - subloaders.push(context.dispatch('single', { - options: { sku: pl.sku }, - setCurrentProduct: false, - selectDefaultVariant: false, - skipCache: skipCache - }).catch(err => { Logger.error(err) }).then((asocProd) => { - if (asocProd) { - pl.product = asocProd - pl.product.qty = pl.qty - - if (pl.id === defaultOption.id) { - product.price += pl.product.price * pl.product.qty - product.price_incl_tax += pl.product.price_incl_tax * pl.product.qty - product.tax += pl.product.tax * pl.product.qty - } - } else { - Logger.error('Product link not found', pl.sku)() - } - })) - } - } - } - } - return Promise.all(subloaders) - }, - /** - * Load required configurable attributes - * @param context - * @param product - */ - loadConfigurableAttributes (context, { product }) { - Logger.warn('`product/loadConfigurableAttributes` deprecated, will be not used from 1.12')() - let attributeKey = 'attribute_id' - const configurableAttrKeys = product.configurable_options.map(opt => { - if (opt.attribute_id) { - attributeKey = 'attribute_id' - return opt.attribute_id - } else { - attributeKey = 'attribute_code' - return opt.attribute_code - } - }) - return context.dispatch('attribute/list', { - filterValues: configurableAttrKeys, - filterField: attributeKey - }, { root: true }) - }, - /** - * Setup product current variants - */ - async setupVariants (context, { product }) { - Logger.warn('`product/setupVariants` deprecated, will be not used from 1.12')() - if (product.type_id !== 'configurable' || !product.hasOwnProperty('configurable_options')) { - return - } - if (config.entities.attribute.loadByAttributeMetadata) { - await context.dispatch('attribute/loadProductAttributes', { products: [product] }, { root: true }) - } - let productOptions = {} - for (let option of product.configurable_options) { - for (let ov of option.values) { - let lb = ov.label ? ov.label : optionLabel(context.rootState.attribute, { attributeKey: option.attribute_id, searchBy: 'id', optionId: ov.value_index }) - if (trim(lb) !== '') { - let optionKey = option.attribute_code ? option.attribute_code : option.label.toLowerCase() - if (!productOptions[optionKey]) { - productOptions[optionKey] = [] - } - - productOptions[optionKey].push({ - label: lb, - id: ov.value_index, - attribute_code: option.attribute_code - }) - } - } - } - context.commit(types.PRODUCT_SET_CURRENT_OPTIONS, productOptions) - let selectedVariant = context.getters.getCurrentProduct - populateProductConfigurationAsync(context, { selectedVariant: selectedVariant, product: product }) - }, - filterUnavailableVariants (context, { product }) { - Logger.warn('`product/filterUnavailableVariants` deprecated, will be not used from 1.12')() - return filterOutUnavailableVariants(context, product) - }, - preConfigureAssociated (context, { searchResult, prefetchGroupProducts }) { - Logger.warn('`product/preConfigureAssociated` deprecated, will be not used from 1.12')() - registerProductsMapping(context, searchResult.items) - for (let product of searchResult.items) { - if (isGroupedOrBundle(product) && prefetchGroupProducts && !isServer) { - context.dispatch('setupAssociated', { product }) - } - } - }, - async preConfigureProduct (context, { product, populateRequestCacheTags, configuration }) { - Logger.warn('`product/preConfigureProduct` deprecated, will be not used from 1.12')() - let _product = preConfigureProduct({ product, populateRequestCacheTags }) - - if (configuration) { - const selectedVariant = await context.dispatch('getProductVariant', { product: _product, configuration }) - _product = Object.assign({}, _product, selectedVariant) - } - - return _product - }, - async configureLoadedProducts (context, { products, isCacheable, cacheByKey, populateRequestCacheTags, configuration }) { - Logger.warn('`product/configureLoadedProducts` deprecated, will be not used from 1.12')() - const configuredProducts = await context.dispatch( - 'category-next/configureProducts', - { - products: products.items, - filters: configuration || {}, - populateRequestCacheTags - }, - { root: true } - ) - - await context.dispatch('tax/calculateTaxes', { products: configuredProducts }, { root: true }) - - for (let product of configuredProducts) { // we store each product separately in cache to have offline access to products/single method - if (isCacheable) { // store cache only for full loads - storeProductToCache(product, cacheByKey) - } - } - - return products - }, - /** - * Update associated products for bundle product - * @param context - * @param product - */ - configureBundleAsync (context, product) { - Logger.warn('`product/configureBundleAsync` deprecated, will be not used from 1.12')() - return context.dispatch( - 'setupAssociated', { - product: product, - skipCache: true - }) - .then(() => { context.dispatch('setCurrent', product) }) - .then(() => { EventBus.$emit('product-after-setup-associated') }) - }, - - /** - * Update associated products for group product - * @param context - * @param product - */ - configureGroupedAsync (context, product) { - Logger.warn('`product/configureGroupedAsync` deprecated, will be not used from 1.12')() - return context.dispatch( - 'setupAssociated', { - product: product, - skipCache: true - }) - .then(() => { context.dispatch('setCurrent', product) }) - }, - /** - * Configure product with given configuration and set it as current - * @param {Object} context - * @param {Object} product - * @param {Array} configuration - */ - async configure (context, { product = null, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = false }) { - Logger.warn('`product/configure` deprecated, will be not used from 1.12, use "product/getProductVariant"')() - const result = await context.dispatch('getProductVariant', { product, configuration }) - return result - }, - - setCurrentOption (context, productOption) { - Logger.warn('`product/setCurrentOption` deprecated, will be not used from 1.12')() - if (productOption && typeof productOption === 'object') { // TODO: this causes some kind of recurrency error - context.commit(types.PRODUCT_SET_CURRENT, Object.assign({}, context.getters.getCurrentProduct, { product_option: productOption })) - } - }, - - setCurrentErrors (context, errors) { - Logger.warn('`product/setCurrentErrors` deprecated, will be not used from 1.12')() - if (errors && typeof errors === 'object') { - context.commit(types.PRODUCT_SET_CURRENT, Object.assign({}, context.getters.getCurrentProduct, { errors: errors })) - } - }, - /** - * Set given product as original - * @param {Object} context - * @param {Object} originalProduct - */ - setOriginal (context, originalProduct) { - Logger.warn('`product/setOriginal` deprecated, will be not used from 1.12')() - if (originalProduct && typeof originalProduct === 'object') context.commit(types.PRODUCT_SET_ORIGINAL, Object.assign({}, originalProduct)) - else Logger.debug('Unable to setup original product.', 'product')() - }, - - /** - * Load product attributes - */ - async loadProductAttributes ({ dispatch }, { product }) { - Logger.warn('`product/loadProductAttributes` deprecated, will be not used from 1.12')() - const productFields = Object.keys(product).filter(fieldName => { - return !config.entities.product.standardSystemFields.includes(fieldName) // don't load metadata info for standard fields - }) - const { product: { useDynamicAttributeLoader }, optimize, attribute } = config.entities - return dispatch('attribute/list', { // load attributes to be shown on the product details - the request is now async - filterValues: useDynamicAttributeLoader ? productFields : null, - only_visible: !!useDynamicAttributeLoader, - only_user_defined: true, - includeFields: optimize ? attribute.includeFields : null - }, { root: true }) - } + ...require('./deprecatedActions').default } export default actions diff --git a/core/modules/catalog/store/product/deprecatedActions.ts b/core/modules/catalog/store/product/deprecatedActions.ts new file mode 100644 index 0000000000..ef89406088 --- /dev/null +++ b/core/modules/catalog/store/product/deprecatedActions.ts @@ -0,0 +1,355 @@ +import { optionLabel } from '../../helpers/optionLabel' +import trim from 'lodash-es/trim' +import { formatBreadCrumbRoutes, isServer } from '@vue-storefront/core/helpers' +import { preConfigureProduct, storeProductToCache, isGroupedOrBundle } from '@vue-storefront/core/modules/catalog/helpers/search' +import toString from 'lodash-es/toString' +import { + registerProductsMapping, + filterOutUnavailableVariants +} from '@vue-storefront/core/modules/catalog/helpers' +import { Logger } from '@vue-storefront/core/lib/logger'; +import * as types from './mutation-types' +import { ProductService } from '@vue-storefront/core/data-resolver/ProductService' +import config from 'config' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' +const { populateProductConfigurationAsync } = require('@vue-storefront/core/modules/catalog/helpers') + +const actions = { + /** + * Reset current configuration and selected variatnts + */ + reset (context) { + Logger.warn('`product/reset` deprecated, will be not used from 1.12')() + const originalProduct = Object.assign({}, context.getters.getOriginalProduct) + context.commit(types.PRODUCT_RESET_CURRENT, originalProduct) + }, + /** + * Setup product breadcrumbs path + */ + async setupBreadcrumbs (context, { product }) { + Logger.warn('`product/setupBreadcrumbs` deprecated, will be not used from 1.12')() + let breadcrumbsName = null + let setBreadcrumbRoutesFromPath = (path) => { + if (path.findIndex(itm => { + return itm.slug === context.rootGetters['category/getCurrentCategory'].slug + }) < 0) { + path.push({ + url_path: context.rootGetters['category/getCurrentCategory'].url_path, + slug: context.rootGetters['category/getCurrentCategory'].slug, + name: context.rootGetters['category/getCurrentCategory'].name + }) // current category at the end + } + // deprecated, TODO: base on breadcrumbs module + breadcrumbsName = product.name + const breadcrumbs = { + routes: formatBreadCrumbRoutes(path), + current: breadcrumbsName, + name: breadcrumbsName + } + context.commit(types.CATALOG_SET_BREADCRUMBS, breadcrumbs) + } + + if (product.category && product.category.length > 0) { + const categoryIds = product.category.reverse().map(cat => cat.category_id) + await context.dispatch('category/list', { key: 'id', value: categoryIds }, { root: true }).then(async (categories) => { + const catList = [] + + for (let catId of categoryIds) { + let category = categories.items.find((itm) => { return toString(itm['id']) === toString(catId) }) + if (category) { + catList.push(category) + } + } + + const rootCat = catList.shift() + let catForBreadcrumbs = rootCat + + for (let cat of catList) { + const catPath = cat.path + if (catPath && catPath.includes(rootCat.path) && (catPath.split('/').length > catForBreadcrumbs.path.split('/').length)) { + catForBreadcrumbs = cat + } + } + if (typeof catForBreadcrumbs !== 'undefined') { + await context.dispatch('category/single', { key: 'id', value: catForBreadcrumbs.id }, { root: true }).then(() => { // this sets up category path and current category + setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) + }).catch(err => { + setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) + Logger.error(err)() + }) + } else { + setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) + } + }) + } + }, + /** + * Download Magento2 / other platform prices to put them over ElasticSearch prices + */ + async syncPlatformPricesOver ({ rootGetters }, { skus }) { + Logger.warn('`product/syncPlatformPricesOver`deprecated, will be not used from 1.12')() + const result = await ProductService.getProductRenderList({ + skus, + isUserGroupedTaxActive: rootGetters['tax/getIsUserGroupedTaxActive'], + userGroupId: rootGetters['tax/getUserTaxGroupId'], + token: rootGetters['user/getToken'] + }) + return result + }, + /** + * Setup associated products + */ + setupAssociated (context, { product, skipCache = true }) { + Logger.warn('`product/setupAssociated` deprecated, will be not used from 1.12')() + let subloaders = [] + if (product.type_id === 'grouped') { + product.price = 0 + product.price_incl_tax = 0 + Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() + if (product.product_links && product.product_links.length > 0) { + for (let pl of product.product_links) { + if (pl.link_type === 'associated' && pl.linked_product_type === 'simple') { // prefetch links + Logger.debug('Prefetching grouped product link for ' + pl.sku + ' = ' + pl.linked_product_sku)() + subloaders.push(context.dispatch('single', { + options: { sku: pl.linked_product_sku }, + setCurrentProduct: false, + selectDefaultVariant: false, + skipCache: skipCache + }).catch(err => { Logger.error(err) }).then((asocProd) => { + if (asocProd) { + pl.product = asocProd + pl.product.qty = 1 + product.price += pl.product.price + product.price_incl_tax += pl.product.price_incl_tax + product.tax += pl.product.tax + } else { + Logger.error('Product link not found', pl.linked_product_sku)() + } + })) + } + } + } else { + Logger.error('Product with type grouped has no product_links set!', product)() + } + } + if (product.type_id === 'bundle') { + product.price = 0 + product.price_incl_tax = 0 + Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() + if (product.bundle_options && product.bundle_options.length > 0) { + for (let bo of product.bundle_options) { + let defaultOption = bo.product_links.find((p) => { return p.is_default }) + if (!defaultOption) defaultOption = bo.product_links[0] + for (let pl of bo.product_links) { + Logger.debug('Prefetching bundle product link for ' + bo.sku + ' = ' + pl.sku)() + subloaders.push(context.dispatch('single', { + options: { sku: pl.sku }, + setCurrentProduct: false, + selectDefaultVariant: false, + skipCache: skipCache + }).catch(err => { Logger.error(err) }).then((asocProd) => { + if (asocProd) { + pl.product = asocProd + pl.product.qty = pl.qty + + if (pl.id === defaultOption.id) { + product.price += pl.product.price * pl.product.qty + product.price_incl_tax += pl.product.price_incl_tax * pl.product.qty + product.tax += pl.product.tax * pl.product.qty + } + } else { + Logger.error('Product link not found', pl.sku)() + } + })) + } + } + } + } + return Promise.all(subloaders) + }, + /** + * Load required configurable attributes + * @param context + * @param product + */ + loadConfigurableAttributes (context, { product }) { + Logger.warn('`product/loadConfigurableAttributes` deprecated, will be not used from 1.12')() + let attributeKey = 'attribute_id' + const configurableAttrKeys = product.configurable_options.map(opt => { + if (opt.attribute_id) { + attributeKey = 'attribute_id' + return opt.attribute_id + } else { + attributeKey = 'attribute_code' + return opt.attribute_code + } + }) + return context.dispatch('attribute/list', { + filterValues: configurableAttrKeys, + filterField: attributeKey + }, { root: true }) + }, + /** + * Setup product current variants + */ + async setupVariants (context, { product }) { + Logger.warn('`product/setupVariants` deprecated, will be not used from 1.12')() + if (product.type_id !== 'configurable' || !product.hasOwnProperty('configurable_options')) { + return + } + if (config.entities.attribute.loadByAttributeMetadata) { + await context.dispatch('attribute/loadProductAttributes', { products: [product] }, { root: true }) + } + let productOptions = {} + for (let option of product.configurable_options) { + for (let ov of option.values) { + let lb = ov.label ? ov.label : optionLabel(context.rootState.attribute, { attributeKey: option.attribute_id, searchBy: 'id', optionId: ov.value_index }) + if (trim(lb) !== '') { + let optionKey = option.attribute_code ? option.attribute_code : option.label.toLowerCase() + if (!productOptions[optionKey]) { + productOptions[optionKey] = [] + } + + productOptions[optionKey].push({ + label: lb, + id: ov.value_index, + attribute_code: option.attribute_code + }) + } + } + } + context.commit(types.PRODUCT_SET_CURRENT_OPTIONS, productOptions) + let selectedVariant = context.getters.getCurrentProduct + populateProductConfigurationAsync(context, { selectedVariant: selectedVariant, product: product }) + }, + filterUnavailableVariants (context, { product }) { + Logger.warn('`product/filterUnavailableVariants` deprecated, will be not used from 1.12')() + return filterOutUnavailableVariants(context, product) + }, + preConfigureAssociated (context, { searchResult, prefetchGroupProducts }) { + Logger.warn('`product/preConfigureAssociated` deprecated, will be not used from 1.12')() + registerProductsMapping(context, searchResult.items) + for (let product of searchResult.items) { + if (isGroupedOrBundle(product) && prefetchGroupProducts && !isServer) { + context.dispatch('setupAssociated', { product }) + } + } + }, + async preConfigureProduct (context, { product, populateRequestCacheTags, configuration }) { + Logger.warn('`product/preConfigureProduct` deprecated, will be not used from 1.12')() + let _product = preConfigureProduct({ product, populateRequestCacheTags }) + + if (configuration) { + const selectedVariant = await context.dispatch('getProductVariant', { product: _product, configuration }) + _product = Object.assign({}, _product, selectedVariant) + } + + return _product + }, + async configureLoadedProducts (context, { products, isCacheable, cacheByKey, populateRequestCacheTags, configuration }) { + Logger.warn('`product/configureLoadedProducts` deprecated, will be not used from 1.12')() + const configuredProducts = await context.dispatch( + 'category-next/configureProducts', + { + products: products.items, + filters: configuration || {}, + populateRequestCacheTags + }, + { root: true } + ) + + await context.dispatch('tax/calculateTaxes', { products: configuredProducts }, { root: true }) + + for (let product of configuredProducts) { // we store each product separately in cache to have offline access to products/single method + if (isCacheable) { // store cache only for full loads + storeProductToCache(product, cacheByKey) + } + } + + return products + }, + /** + * Update associated products for bundle product + * @param context + * @param product + */ + configureBundleAsync (context, product) { + Logger.warn('`product/configureBundleAsync` deprecated, will be not used from 1.12')() + return context.dispatch( + 'setupAssociated', { + product: product, + skipCache: true + }) + .then(() => { context.dispatch('setCurrent', product) }) + .then(() => { EventBus.$emit('product-after-setup-associated') }) + }, + + /** + * Update associated products for group product + * @param context + * @param product + */ + configureGroupedAsync (context, product) { + Logger.warn('`product/configureGroupedAsync` deprecated, will be not used from 1.12')() + return context.dispatch( + 'setupAssociated', { + product: product, + skipCache: true + }) + .then(() => { context.dispatch('setCurrent', product) }) + }, + /** + * Configure product with given configuration and set it as current + * @param {Object} context + * @param {Object} product + * @param {Array} configuration + */ + async configure (context, { product = null, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = false }) { + Logger.warn('`product/configure` deprecated, will be not used from 1.12, use "product/getProductVariant"')() + const result = await context.dispatch('getProductVariant', { product, configuration }) + return result + }, + + setCurrentOption (context, productOption) { + Logger.warn('`product/setCurrentOption` deprecated, will be not used from 1.12')() + if (productOption && typeof productOption === 'object') { // TODO: this causes some kind of recurrency error + context.commit(types.PRODUCT_SET_CURRENT, Object.assign({}, context.getters.getCurrentProduct, { product_option: productOption })) + } + }, + + setCurrentErrors (context, errors) { + Logger.warn('`product/setCurrentErrors` deprecated, will be not used from 1.12')() + if (errors && typeof errors === 'object') { + context.commit(types.PRODUCT_SET_CURRENT, Object.assign({}, context.getters.getCurrentProduct, { errors: errors })) + } + }, + /** + * Set given product as original + * @param {Object} context + * @param {Object} originalProduct + */ + setOriginal (context, originalProduct) { + Logger.warn('`product/setOriginal` deprecated, will be not used from 1.12')() + if (originalProduct && typeof originalProduct === 'object') context.commit(types.PRODUCT_SET_ORIGINAL, Object.assign({}, originalProduct)) + else Logger.debug('Unable to setup original product.', 'product')() + }, + + /** + * Load product attributes + */ + async loadProductAttributes ({ dispatch }, { product }) { + Logger.warn('`product/loadProductAttributes` deprecated, will be not used from 1.12')() + const productFields = Object.keys(product).filter(fieldName => { + return !config.entities.product.standardSystemFields.includes(fieldName) // don't load metadata info for standard fields + }) + const { product: { useDynamicAttributeLoader }, optimize, attribute } = config.entities + return dispatch('attribute/list', { // load attributes to be shown on the product details - the request is now async + filterValues: useDynamicAttributeLoader ? productFields : null, + only_visible: !!useDynamicAttributeLoader, + only_user_defined: true, + includeFields: optimize ? attribute.includeFields : null + }, { root: true }) + } +} + +export default actions From 44a42f964027f5eb9c1339190abaab4c200e5bb1 Mon Sep 17 00:00:00 2001 From: tkostuch Date: Fri, 29 May 2020 11:21:58 +0200 Subject: [PATCH 2/4] update ugrade notes --- docs/guide/upgrade-notes/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/guide/upgrade-notes/README.md b/docs/guide/upgrade-notes/README.md index 87bbaf6687..6d2643af93 100644 --- a/docs/guide/upgrade-notes/README.md +++ b/docs/guide/upgrade-notes/README.md @@ -64,6 +64,10 @@ product/loadProductBreadcrumbs product/getProductVariant All of those actions and helpers that are deprecated, can be removed so you will have smaller bundle. +Comment those lines: +- core/modules/catalog/store/product/actions.ts:318 +- core/modules/catalog/helpers/index.ts:14-18 +- core/modules/catalog-next/store/category/actions.ts:265 ## 1.10 -> 1.11 From e5030f82403b040e4a26d1fa723d0c3ecaeab7f9 Mon Sep 17 00:00:00 2001 From: tkostuch Date: Fri, 29 May 2020 11:26:15 +0200 Subject: [PATCH 3/4] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca6c650fa5..ac006d01e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - removed possible memory leak in ssr - @resubaka (#4247) - Bugfix for reactivity of `current_configuration` in `populateProductConfigurationAsync` - @cewald (#4258) - Bugfix for build exception in Node v13.13+ - @cewald (#4249) +- change value to number in price filter - @gibkigonzo (#4478) ### Changed / Improved @@ -79,6 +80,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Homepage, new products query, uses now `new` attribute - @mdanilwoicz - Refactor product module, more info in upgrade notes- @gibkigonzo (#3952, #4459) - Move default theme to separate repository https://github.com/DivanteLtd/vsf-default - @gibkigonzo (#4255) +- add two numbers after dot to price by default, calculate default price for bundle or grouped main product, update typing, add fallback to attribute options - @gibkigonzo (#4476) +- udpate yarn and filter shipping methods for instant checkout - @gibkigonzo (#4480) ## [1.11.4] - 2020.05.26 From 1cedd4e45bc19ccdb9e2e6fd6eaea95ddbd8bc9b Mon Sep 17 00:00:00 2001 From: tkostuch Date: Fri, 29 May 2020 11:59:58 +0200 Subject: [PATCH 4/4] bump version --- CHANGELOG.md | 2 +- core/i18n/package.json | 2 +- core/package.json | 2 +- docs/package.json | 2 +- package.json | 2 +- packages/cli/boilerplates/module/package.json | 4 ++-- test/unit/package.json | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac006d01e5..2ba7da8f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.12.0-rc1] - UNRELEASED +## [1.12.0] - 2020.06.01 ### Added diff --git a/core/i18n/package.json b/core/i18n/package.json index 2f260f8c43..290d0f99c5 100644 --- a/core/i18n/package.json +++ b/core/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/i18n", - "version": "1.11.4", + "version": "1.12.0", "description": "Vue Storefront i18n", "license": "MIT", "main": "index.ts", diff --git a/core/package.json b/core/package.json index 5f5cf8f6d2..35ec249b40 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/core", - "version": "1.11.4", + "version": "1.12.0", "description": "Vue Storefront Core", "license": "MIT", "main": "app.js", diff --git a/docs/package.json b/docs/package.json index f1a99307ae..6f2c15ddb9 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,7 +1,7 @@ { "name": "@vue-storefront/docs", "private": true, - "version": "1.11.4", + "version": "1.12.0", "scripts": { "docs:dev": "vuepress dev", "docs:build": "vuepress build", diff --git a/package.json b/package.json index bfdce76825..2c7cb7bd74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-storefront", - "version": "1.11.4", + "version": "1.12.0", "description": "A Vue.js, PWA eCommerce frontend", "private": true, "engines": { diff --git a/packages/cli/boilerplates/module/package.json b/packages/cli/boilerplates/module/package.json index 7f17459757..bcaa84869f 100644 --- a/packages/cli/boilerplates/module/package.json +++ b/packages/cli/boilerplates/module/package.json @@ -12,13 +12,13 @@ "license": "MIT", "dependencies": {}, "devDependencies": { - "@vue-storefront/core": "^1.11.1", + "@vue-storefront/core": "^1.12.0", "ts-loader": "^6.0.4", "typescript": "^3.5.2", "webpack": "^4.35.2", "webpack-cli": "^3.3.11" }, "peerDependencies": { - "@vue-storefront/core": "^1.11.1" + "@vue-storefront/core": "^1.12.0" } } diff --git a/test/unit/package.json b/test/unit/package.json index 32a0c11c33..39acef06c2 100644 --- a/test/unit/package.json +++ b/test/unit/package.json @@ -1,5 +1,5 @@ { "name": "@vue-storefront/unit-tests", "private": true, - "version": "1.11.4" + "version": "1.12.0" }