Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
66e6f0c
change links in promoted_offers
Oct 29, 2019
45230ad
update formatCategoryLink
Oct 29, 2019
4e21f41
format category link in menu
Oct 29, 2019
6d164dc
update breadcrumbs component
Oct 29, 2019
d7c9c3a
update changelog
Oct 29, 2019
154ae90
update links in main-image and slider
Oct 30, 2019
8394964
remove product mutate when assign product
Oct 30, 2019
bb7feb2
update changelog
Oct 30, 2019
a996b04
Merge pull request #3766 from gibkigonzo/bugfix/display-reviews-for-c…
andrzejewsky Nov 5, 2019
4041554
Merge branch 'hotfix/v1.10.5' into bugfix/backport-invalid-category-l…
andrzejewsky Nov 5, 2019
ca1fab8
PAT-1721 Issue #3748 apply hot fix for Cannot assign to read only pro…
yuriboyko Nov 5, 2019
9236ddd
PAT-1721 Issue #3748 add changelogs
yuriboyko Nov 5, 2019
9dcd248
Merge pull request #3756 from gibkigonzo/bugfix/backport-invalid-cate…
andrzejewsky Nov 6, 2019
c870480
Merge branch 'hotfix/v1.10.5' into hotfix/issue-3748
pkarw Nov 6, 2019
dc3880c
Merge pull request #3783 from yuriboyko/hotfix/issue-3748
andrzejewsky Nov 6, 2019
92132f7
3785 sorting fixed
lysy-vlc Nov 6, 2019
2b22315
changelog updated
lysy-vlc Nov 6, 2019
ced5c86
3778 fixed null in search input - ternary operator
lysy-vlc Nov 6, 2019
27d1353
Merge branch 'hotfix/v1.10.5' into bug/3778
andrzejewsky Nov 7, 2019
53cc119
Merge pull request #3789 from AdKamil/bug/3778
andrzejewsky Nov 7, 2019
1a90846
Merge branch 'hotfix/v1.10.5' into bug/3785
andrzejewsky Nov 7, 2019
72b79f6
Merge pull request #3788 from AdKamil/bug/3785
andrzejewsky Nov 7, 2019
d9528a0
mount app in beforeResolve, after all components are resolved
Nov 19, 2019
d5f3943
if route is already resolved then we can mount app
Nov 19, 2019
a37c4c2
Merge branch 'hotfix/v1.10.5' of https://github.com/DivanteLtd/vue-st…
Nov 19, 2019
b8d9d38
update changelog
Nov 19, 2019
f410757
check if router history is pending
Nov 20, 2019
a20bc88
update code readability
Nov 20, 2019
ce137e4
backport fix for memory leak in category page
Nov 21, 2019
c5462b5
Merge pull request #3820 from gibkigonzo/bugfix/3669
pkarw Nov 21, 2019
fd3a278
dont use nonReactiveState on SSR
Nov 21, 2019
faf678b
Merge branch 'hotfix/v1.10.5' of https://github.com/DivanteLtd/vue-st…
Nov 21, 2019
d992225
change translation from jp-JP to ja-JP
Nov 21, 2019
60fadaa
update changelog
Nov 21, 2019
1cd48aa
Merge pull request #3830 from gibkigonzo/bugfix/backport-memory-leak-…
andrzejewsky Nov 21, 2019
56871db
Merge branch 'hotfix/v1.10.5' into bugfix/3824
andrzejewsky Nov 22, 2019
571be67
Merge pull request #3831 from gibkigonzo/bugfix/3824
andrzejewsky Nov 22, 2019
0238dbf
small fixes
andrzejewsky Nov 27, 2019
104b744
small fixes
andrzejewsky Nov 27, 2019
3def2c5
fix product image, update changelog
andrzejewsky Nov 27, 2019
54263c3
remove v-if
andrzejewsky Nov 28, 2019
59f1049
Merge pull request #3850 from andrzejewsky/quickFixes
andrzejewsky Nov 28, 2019
e1126df
Merge branch 'master' into hotfix/v1.10.5
andrzejewsky Nov 28, 2019
24571ba
Fix duplicate keys errors
andrzejewsky Nov 28, 2019
76542f0
fix searching
andrzejewsky Nov 28, 2019
fe1be66
Merge pull request #3858 from andrzejewsky/fixDuplicateKeys
patzick Nov 28, 2019
348acb0
bump versions
andrzejewsky Nov 28, 2019
6622bca
Merge pull request #3859 from andrzejewsky/bumpVersions
andrzejewsky Nov 28, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ core/resource/i18n/en-US.json
core/resource/i18n/es-ES.json
core/resource/i18n/fr-FR.json
core/resource/i18n/it-IT.json
core/resource/i18n/jp-JP.json
core/resource/i18n/ja-JP.json
core/resource/i18n/multistoreLanguages.json
core/resource/i18n/nl-NL.json
core/resource/i18n/pl-PL.json
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ 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.10.5] - 28.11.2019

### Fixed
- Disable product mutation when assigning product variant - @gibkigonzo (#3735)
- Fix issue with Cannot assign to read only property 'storeCode' - @yuriboyko (#3748)
- Render correct category links when multistore is active - @gibkigonzo (#3753)
- Disable product mutation when assigning product variant - @gibkigonzo (#3735)
- Fixed null value of search input - @AdKamil (#3778)
- Sorting fixed on category page - @AdKamil (#3785)
- Mount app in 'beforeResolve' if it's not dispatched in 'onReady' - @gibkigonzo (#3669)
- change translation from jp-JP to ja-JP - @gibkigonzo (#3824)
- Fix product images, my account link, warnings in console - @andrzejewsky (#3850)

## [1.10.4] - 18.10.2019

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
"order": "desc"
},
"sortByAttributes": {
"Latest": "updated_at",
"Latest": "updated_at:desc",
"Price: Low to high":"final_price",
"Price: High to low":"final_price:desc"
},
Expand Down Expand Up @@ -403,7 +403,7 @@
"i18n": {
"defaultCountry": "US",
"defaultLanguage": "EN",
"availableLocale": ["en-US","de-DE","fr-FR","es-ES","nl-NL", "jp-JP", "ru-RU", "it-IT", "pt-BR", "pl-PL", "cs-CZ"],
"availableLocale": ["en-US","de-DE","fr-FR","es-ES","nl-NL", "ja-JP", "ru-RU", "it-IT", "pt-BR", "pl-PL", "cs-CZ"],
"defaultLocale": "en-US",
"currencyCode": "USD",
"currencySign": "$",
Expand Down
15 changes: 10 additions & 5 deletions core/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vu
store.state.version = process.env.APPVERSION
store.state.config = config // @deprecated
store.state.__DEMO_MODE__ = (config.demomode === true)
if (ssrContext) Vue.prototype.$ssrRequestContext = ssrContext
if (ssrContext) {
// @deprecated - we shouldn't share server context between requests
Vue.prototype.$ssrRequestContext = {output: {cacheTags: ssrContext.output.cacheTags}}

Vue.prototype.$cacheTags = ssrContext.output.cacheTags
}
if (!store.state.config) store.state.config = globalConfig // @deprecated - we should avoid the `config`
const storeView = await prepareStoreView(storeCode) // prepare the default storeView
store.state.storeView = storeView
Expand All @@ -87,6 +92,10 @@ const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vu
Object.keys(coreMixins).forEach(key => {
Vue.mixin(coreMixins[key])
})

Object.keys(coreFilters).forEach(key => {
Vue.filter(key, coreFilters[key])
})
})

// @todo remove this part when we'll get rid of global multistore mixin
Expand All @@ -99,10 +108,6 @@ const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vu
})
}

Object.keys(coreFilters).forEach(key => {
Vue.filter(key, coreFilters[key])
})

let vueOptions = {
router,
store,
Expand Down
26 changes: 16 additions & 10 deletions core/client-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,23 @@ const invokeClientEntry = async () => {
})
}
router.onReady(async () => {
// check if app can be mounted
const canBeMounted = () => RouterManager.isRouteDispatched() && // route is dispatched
!(router as any).history.pending && // there is no pending in router history
!(app as any)._isMounted // it's not mounted before

if (canBeMounted()) {
app.$mount('#app')
}
router.beforeResolve((to, from, next) => {
if (!from.name) return next() // do not resolve asyncData on server render - already been done
if (Vue.prototype.$ssrRequestContext) Vue.prototype.$ssrRequestContext.output.cacheTags = new Set<string>()
if (!from.name) {
next()
if (canBeMounted()) {
app.$mount('#app')
}
return // do not resolve asyncData on server render - already been done
}
if (!Vue.prototype.$cacheTags) Vue.prototype.$cacheTags = new Set<string>()
const matched = router.getMatchedComponents(to)
if (to) { // this is from url
if (globalConfig.storeViews.multistore === true) {
Expand Down Expand Up @@ -99,14 +113,6 @@ const invokeClientEntry = async () => {
}
}))
})
// Mounting app
if (!RouterManager.isRouteDispatched()) {
RouterManager.addDispatchCallback(() => {
app.$mount('#app')
})
} else {
app.$mount('#app')
}
})
registerSyncTaskProcessor()
window.addEventListener('online', () => { onNetworkStatusChange(store) })
Expand Down
4 changes: 3 additions & 1 deletion core/filters/price.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export function price (value) {
}
let formattedVal = Math.abs(parseFloat(value)).toFixed(2)
const storeView = currentStoreView()

if (!storeView.i18n) {
return value;
}
const prependCurrency = (price) => {
return storeView.i18n.currencySign + price
}
Expand Down
6 changes: 5 additions & 1 deletion core/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ const loadDateLocales = async (lang: string = 'en'): Promise<void> => {
const separatorIndex = localeCode.indexOf('-')
if (separatorIndex) {
localeCode = separatorIndex ? localeCode.substr(0, separatorIndex) : localeCode
await import(/* webpackChunkName: "dayjs-locales" */ `dayjs/locale/${localeCode}`)
try {
await import(/* webpackChunkName: "dayjs-locales" */ `dayjs/locale/${localeCode}`)
} catch (err) {
Logger.debug('Unable to load translation from dayjs')()
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/i18n/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue-storefront/i18n",
"version": "1.10.4",
"version": "1.10.5",
"description": "Vue Storefront i18n",
"license": "MIT",
"main": "index.ts",
Expand Down
File renamed without changes.
6 changes: 5 additions & 1 deletion core/lib/multistore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ export async function prepareStoreView (storeCode: string): Promise<StoreView> {
}
const storeViewHasChanged = !rootStore.state.storeView || rootStore.state.storeView.storeCode !== storeCode
if (storeCode) { // current store code
if ((storeView = config.storeViews[storeCode])) {
const currentStoreView = config.storeViews[storeCode]
if (currentStoreView) {
storeView = Object.assign({}, currentStoreView);
storeView.storeCode = storeCode
rootStore.state.user.current_storecode = storeCode
} else {
console.warn(`Not found 'storeView' matching the given 'storeCode': ${storeCode}`)
}
} else {
storeView.storeCode = config.defaultStoreCode || ''
Expand Down
8 changes: 4 additions & 4 deletions core/lib/search/adapter/api/searchAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ export class SearchAdapter {
},
body: config.elasticsearch.queryMethod === 'POST' ? JSON.stringify(ElasticsearchQueryBody) : null
})
.then(resp => { return resp.json() })
.catch(error => {
throw new Error('FetchError in request to ES: ' + error.toString())
})
.then(resp => { return resp.json() })
.catch(error => {
throw new Error('FetchError in request to ES: ' + error.toString())
})
}

public handleResult (resp, type, start = 0, size = 50): SearchResponse {
Expand Down
2 changes: 1 addition & 1 deletion core/modules/catalog/components/Search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const Search = {
}
},
beforeDestroy () {
localStorage.setItem(`shop/user/searchQuery`, this.search);
localStorage.setItem(`shop/user/searchQuery`, this.search ? this.search : '');
},
methods: {
onEscapePress () {
Expand Down
4 changes: 2 additions & 2 deletions core/modules/catalog/store/category/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ const actions: ActionTree<CategoryState, RootState> = {
if (setCurrentCategory) {
commit(types.CATEGORY_UPD_CURRENT_CATEGORY, mainCategory)
}
if (populateRequestCacheTags && mainCategory && Vue.prototype.$ssrRequestContext) {
Vue.prototype.$ssrRequestContext.output.cacheTags.add(`C${mainCategory.id}`)
if (populateRequestCacheTags && mainCategory && Vue.prototype.$cacheTags) {
Vue.prototype.$cacheTags.add(`C${mainCategory.id}`)
}
if (setCurrentCategoryPath) {
let currentPath = []
Expand Down
8 changes: 4 additions & 4 deletions core/modules/catalog/store/product/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ const actions: ActionTree<ProductState, RootState> = {
return quickSearchByQuery({ query, start, size, entityType, sort, excludeFields, includeFields }).then((resp) => {
if (resp.items && resp.items.length) { // preconfigure products; eg: after filters
for (let product of resp.items) {
if (populateRequestCacheTags && Vue.prototype.$ssrRequestContext) {
Vue.prototype.$ssrRequestContext.output.cacheTags.add(`P${product.id}`)
if (populateRequestCacheTags && Vue.prototype.$cacheTags) {
Vue.prototype.$cacheTags.add(`P${product.id}`);
}
product.errors = {} // this is an object to store validation result for custom options and others
product.info = {}
Expand All @@ -307,7 +307,7 @@ const actions: ActionTree<ProductState, RootState> = {
}
if (configuration) {
let selectedVariant = configureProductAsync(context, { product: product, configuration: configuration, selectDefaultVariant: false })
Object.assign(product, omit(selectedVariant, ['visibility']))
product = Object.assign({}, product, omit(selectedVariant, ['visibility']))
}
if (product.url_path) {
rootStore.dispatch('url/registerMapping', {
Expand Down Expand Up @@ -430,7 +430,7 @@ const actions: ActionTree<ProductState, RootState> = {
// todo: probably a good idea is to change this [0] to specific id
const selectedVariant = configureProductAsync(context, { product: prod, configuration: { sku: options.childSku }, selectDefaultVariant: selectDefaultVariant, setProductErorrs: true })
if (selectedVariant && assignDefaultVariant) {
prod = Object.assign(prod, selectedVariant)
prod = Object.assign({}, prod, selectedVariant)
}
} else if (!skipCache || (prod.type_id === 'simple' || prod.type_id === 'downloadable')) {
if (setCurrentProduct) context.dispatch('setCurrent', prod)
Expand Down
16 changes: 15 additions & 1 deletion core/modules/catalog/store/product/getters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { PagedProductList } from './../../types/ProductState';
import { nonReactiveState } from './index';
import { GetterTree } from 'vuex'
import RootState from '@vue-storefront/core/types/RootState'
import ProductState from '../../types/ProductState'
import cloneDeep from 'lodash-es/cloneDeep'

function mapCategoryProducts (productsFromState, productsData) {
return productsFromState.map(prodState => {
if (typeof prodState === 'string') {
const product = productsData.find(prodData => prodData.sku === prodState)
return cloneDeep(product)
}
return prodState
})
}

const getters: GetterTree<ProductState, RootState> = {
productParent: (state) => state.parent,
Expand All @@ -9,7 +22,8 @@ const getters: GetterTree<ProductState, RootState> = {
productOriginal: (state) => state.original,
currentOptions: (state) => state.current_options,
breadcrumbs: (state) => state.breadcrumbs,
productGallery: (state) => state.productGallery
productGallery: (state) => state.productGallery,
list: (state) => mapCategoryProducts((state.list as PagedProductList).items, nonReactiveState.list)
}

export default getters
4 changes: 4 additions & 0 deletions core/modules/catalog/store/product/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ export const productModule: Module<ProductState, RootState> = {
actions,
mutations
}

export const nonReactiveState = {
list: []
}
16 changes: 12 additions & 4 deletions core/modules/catalog/store/product/mutations.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { isServer } from '@vue-storefront/core/helpers';
import { nonReactiveState } from './index';
import Vue from 'vue'
import { MutationTree } from 'vuex'
import * as types from './mutation-types'
import ProductState, { PagedProductList } from '../../types/ProductState'
import cloneDeep from 'lodash-es/cloneDeep'

const mutations: MutationTree<ProductState> = {
[types.CATALOG_SET_BREADCRUMBS] (state, payload) {
Expand Down Expand Up @@ -29,11 +32,16 @@ const mutations: MutationTree<ProductState> = {
},
[types.CATALOG_UPD_PRODUCTS] (state, { products, append }) {
if (append === false) {
state.list = products
nonReactiveState.list = cloneDeep(products.items)
state.list = isServer ? products : cloneDeep({...products, items: products.items.map(prod => prod.sku)})
} else {
(state.list as PagedProductList).start = products.start as number
(state.list as PagedProductList).perPage = products.perPage as number
(state.list as PagedProductList).items = (state.list as PagedProductList).items.concat(products.items)
const pagedProductList = state.list as PagedProductList
pagedProductList.start = products.start as number
pagedProductList.perPage = products.perPage as number
nonReactiveState.list = cloneDeep(nonReactiveState.list.concat(products.items))
pagedProductList.items = isServer
? pagedProductList.items.concat(products.items)
: cloneDeep(pagedProductList.items.concat(products.items.map(prod => prod.sku)))
}
},
[types.CATALOG_SET_PRODUCT_CURRENT] (state, product) {
Expand Down
13 changes: 11 additions & 2 deletions core/modules/url/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,17 @@ export function normalizeUrlPath (url: string): string {
return url
}

export function formatCategoryLink (category: { url_path: string, slug: string }): string {
return config.seo.useUrlDispatcher ? ('/' + category.url_path) : ('/c/' + category.slug)
export function formatCategoryLink (category: { url_path: string, slug: string }, storeCode: string = currentStoreView().storeCode): string {
storeCode ? storeCode += '/' : storeCode = '';

if (currentStoreView().appendStoreCode === false) {
storeCode = ''
}

if (category) {
return config.seo.useUrlDispatcher ? ('/' + storeCode + category.url_path) : ('/' + storeCode + 'c/' + category.slug)
}
return '/' + storeCode;
}

export function formatProductLink (
Expand Down
6 changes: 3 additions & 3 deletions core/pages/Category.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ export default {
computed: {
...mapGetters('category', ['getCurrentCategory', 'getCurrentCategoryProductQuery', 'getAllCategoryFilters', 'getCategoryBreadcrumbs', 'getCurrentCategoryPath']),
products () {
return this.$store.state.product.list.items
return this.$store.getters['product/list']
},
productsCounter () {
return this.$store.state.product.list.items ? this.$store.state.product.list.items.length : 0
return this.products ? this.products.length : 0
},
productsTotal () {
return this.$store.state.product.list.total
Expand All @@ -41,7 +41,7 @@ export default {
return this.getCurrentCategoryProductQuery
},
isCategoryEmpty () {
return (!(this.$store.state.product.list.items) || this.$store.state.product.list.items.length === 0)
return (!(this.products) || this.products.length === 0)
},
category () {
return this.getCurrentCategory
Expand Down
13 changes: 11 additions & 2 deletions core/scripts/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ if (isProd) {
})
}

function clearSSRContext (context) {
Object.keys(context.server).forEach(key => delete context.server[key])
delete context.output['cacheTags']
delete context['meta']
}

function invalidateCache (req, res) {
if (config.server.useOutputCache) {
if (req.query.tag && req.query.key) { // clear cache pages for specific query tag
Expand Down Expand Up @@ -171,7 +177,7 @@ app.get('*', (req, res, next) => {
append: (context) => { return '' },
appendHead: (context) => { return '' },
template: 'default',
cacheTags: null
cacheTags: new Set()
},
server: {
app: app,
Expand All @@ -189,7 +195,7 @@ app.get('*', (req, res, next) => {
res.setHeader('Content-Type', 'text/html')
}
let tagsArray = []
if (config.server.useOutputCacheTagging && context.output.cacheTags !== null) {
if (config.server.useOutputCacheTagging && context.output.cacheTags && context.output.cacheTags.size > 0) {
tagsArray = Array.from(context.output.cacheTags)
const cacheTags = tagsArray.join(' ')
res.setHeader('X-VS-Cache-Tags', cacheTags)
Expand Down Expand Up @@ -218,6 +224,9 @@ app.get('*', (req, res, next) => {
console.log(`whole request [${req.url}]: ${Date.now() - s}ms`)
next()
}).catch(errorHandler)
.finally(() => {
clearSSRContext(context)
})
}

const dynamicCacheHandler = () => {
Expand Down
1 change: 0 additions & 1 deletion core/server-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default async context => {
}
const { app, router, store } = await createApp(context, context.vs && context.vs.config ? context.vs.config : buildTimeConfig, storeCode)
return new Promise((resolve, reject) => {
context.output.cacheTags = new Set<string>()
const meta = (app as any).$meta()
router.push(context.url)
context.meta = meta
Expand Down
Loading