Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
da309f9
Added quantity of products to input
Michal-Dziedzinski Jul 1, 2019
ce9f955
Added max range of product which depends on quantity of product
Michal-Dziedzinski Jul 1, 2019
4bfa064
Added disable atribute to input component
Michal-Dziedzinski Jul 1, 2019
23dab04
Added button disable if quantity is equal 0 and changed InputNumber s…
Michal-Dziedzinski Jul 2, 2019
d6f1a45
Added changes to actions filem proposed at CR
Michal-Dziedzinski Jul 5, 2019
ad8c519
Merged with develop
Michal-Dziedzinski Jul 15, 2019
98c86bb
Added await to check action
Michal-Dziedzinski Jul 15, 2019
ff7ec1a
Merge branch 'develop' into feature/2733
pkarw Jul 16, 2019
928e000
Add pleceholder when getting quantity, change place of calling getQua…
Michal-Dziedzinski Jul 16, 2019
13df17c
Merge branch 'feature/2733' of https://github.com/DivanteLtd/vue-stor…
Michal-Dziedzinski Jul 16, 2019
c05c851
Fix disabled button
Michal-Dziedzinski Jul 17, 2019
792074b
Added info to changelog and merged changes
Michal-Dziedzinski Jul 17, 2019
5d4a07e
Merged with feture/#2773
Michal-Dziedzinski Jul 18, 2019
2881635
Merged with develop
Michal-Dziedzinski Jul 18, 2019
a523cca
Remove console.log()
Michal-Dziedzinski Jul 18, 2019
f9727f3
Add mutations to stock
Michal-Dziedzinski Jul 18, 2019
841d333
Fix some names, import mutations to indes.ts, fix SET_STOCK_CACHE_PRO…
Michal-Dziedzinski Jul 18, 2019
a599674
Merge branch 'develop' into feature/2733
pkarw Jul 23, 2019
5f0637a
Update core/modules/catalog/store/stock/mutations.ts
Michal-Dziedzinski Jul 23, 2019
b938eb7
Merge branch 'develop' into feature/2733
Michal-Dziedzinski Jul 23, 2019
2fd3f7c
Update core/modules/catalog/store/stock/mutations.ts
Michal-Dziedzinski Jul 23, 2019
a081cea
Add loader and add computed property as input name
Michal-Dziedzinski Jul 23, 2019
d2fd540
Merge branch 'develop' into feature/2733
Michal-Dziedzinski Jul 24, 2019
52049e2
Merge branch 'develop' into feature/2733
pkarw Jul 25, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add icons on the product tiles that allow to add to the wish list and to the list to compare products from the list of products - @Michal-Dziedzinski (#2773)
- Get also none product image thumbnails via API - @cewald, @resubaka (#3207)
- Added a config option `optimizeShoppingCartOmitFields` - @EmilsM (#3222)
- Added information on the number of available products - @Michal-Dziedzinski (#2733)
- Added possibility to change color or size of the product that is already in the cart - @andrzejewsky (#2346)
- Added price formatting based on locales in multistore - @andrzejewsky (#3060)
- Added support for tax calculation where the values from customer_tax_class_ids is used - @resubaka (#3245)
Expand Down
129 changes: 110 additions & 19 deletions core/modules/catalog/store/stock/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ActionTree } from 'vuex'
import i18n from '@vue-storefront/i18n'
// requires cart module
import * as types from '@vue-storefront/core/modules/cart/store/mutation-types'
import * as stockMutationTypes from '@vue-storefront/core/modules/catalog/store/stock/mutation-types'
import RootState from '@vue-storefront/core/types/RootState'
import StockState from '../../types/StockState'
import { TaskQueue } from '@vue-storefront/core/lib/sync'
Expand All @@ -16,7 +17,12 @@ const actions: ActionTree<StockState, RootState> = {
*/
async queueCheck (context, { product, qty = 1 }) {
if (config.stock.synchronize) {
const task: any = await TaskQueue.queue({ url: processURLAddress(`${config.stock.endpoint}/check?sku=${encodeURIComponent(product.sku)}`),
const task: any = await TaskQueue.queue({
url: processURLAddress(
`${config.stock.endpoint}/check?sku=${encodeURIComponent(
product.sku
)}`
),
payload: {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
Expand All @@ -26,36 +32,76 @@ const actions: ActionTree<StockState, RootState> = {
product_sku: product.sku,
callback_event: 'store:stock/stockAfterCheck'
})
return { qty: product.stock ? product.stock.qty : 0, status: product.stock ? (product.stock.is_in_stock ? 'ok' : 'out_of_stock') : 'ok', onlineCheckTaskId: task.task_id } // if online we can return ok because it will be verified anyway
return {
qty: product.stock ? product.stock.qty : 0,
status: product.stock
? product.stock.is_in_stock
? 'ok'
: 'out_of_stock'
: 'ok',
onlineCheckTaskId: task.task_id
} // if online we can return ok because it will be verified anyway
} else {
return { qty: product.stock ? product.stock.qty : 0, status: product.stock ? (product.stock.is_in_stock ? 'ok' : 'out_of_stock') : 'volatile' } // if not online, cannot check the source of true here
return {
qty: product.stock ? product.stock.qty : 0,
status: product.stock
? product.stock.is_in_stock
? 'ok'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we use consts defined at the top of the file for these statuses?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that this will not improve readability in this case. Unless I do not see something;)

: 'out_of_stock'
: 'volatile'
} // if not online, cannot check the source of true here
}
},
/**
* Reset current configuration and selected variatnts
*/
async check (context, { product, qty = 1 }) {
if (config.stock.synchronize) {
const task: any = TaskQueue.execute({ url: processURLAddress(`${config.stock.endpoint}/check?sku=${encodeURIComponent(product.sku)}`),
const task: any = await TaskQueue.execute({
url: processURLAddress(
`${config.stock.endpoint}/check?sku=${encodeURIComponent(
product.sku
)}`
),
payload: {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
},
product_sku: product.sku
})
return { qty: task.result ? task.result.qty : 0, status: task.result ? (task.result.is_in_stock ? 'ok' : 'out_of_stock') : 'ok', onlineCheckTaskId: task.task_id } // if online we can return ok because it will be verified anyway
return {
qty: task.result ? task.result.qty : 0,
status: task.result
? task.result.is_in_stock
? 'ok'
: 'out_of_stock'
: 'ok',
onlineCheckTaskId: task.task_id
} // if online we can return ok because it will be verified anyway
} else {
return { qty: product.stock ? product.stock.qty : 0, status: product.stock ? (product.stock.is_in_stock ? 'ok' : 'out_of_stock') : 'volatile' } // if not online, cannot check the source of true here
return {
qty: product.stock ? product.stock.qty : 0,
status: product.stock
? product.stock.is_in_stock
? 'ok'
: 'out_of_stock'
: 'volatile'
} // if not online, cannot check the source of true here
}
},
/**
* Reset current configuration and selected variatnts
*/
list (context, { skus }) {
list ({ commit }, { skus }) {
if (config.stock.synchronize) {
try {
const task: any = TaskQueue.execute({ url: processURLAddress(`${config.stock.endpoint}/list?skus=${encodeURIComponent(skus.join(','))}`),
const task: any = TaskQueue.execute({
url: processURLAddress(
`${config.stock.endpoint}/list?skus=${encodeURIComponent(
skus.join(',')
)}`
),
payload: {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
Expand All @@ -65,7 +111,15 @@ const actions: ActionTree<StockState, RootState> = {
})
if (task.resultCode === 200) {
for (const si of task.result) {
context.state.cache[si.product_id] = { is_in_stock: si.is_in_stock, qty: si.qty, product_id: si.product_id } // TODO: should be moved to mutation
const productInfo = {
is_in_stock: si.is_in_stock,
qty: si.qty,
product_id: si.product_id
}
commit(stockMutationTypes.SET_STOCK_CACHE_PRODUCT, {
productId: si.product_id,
productInfo
})
}
}
return task // if online we can return ok because it will be verified anyway
Expand All @@ -77,27 +131,64 @@ const actions: ActionTree<StockState, RootState> = {
return null // if not online, cannot check the source of true here
}
},
clearCache (context) {
context.state.cache = {}
clearCache ({ commit }) {
commit(stockMutationTypes.SET_STOCK_CACHE, {})
},
async stockAfterCheck (context, event) {
async stockAfterCheck ({ dispatch, commit }, event) {
setTimeout(async () => {
// TODO: Move to cart module
const cartItem: any = await context.dispatch('cart/getItem', event.product_sku, { root: true })
const cartItem: any = await dispatch('cart/getItem', event.product_sku, {
root: true
})
if (cartItem && event.result.code !== 'ENOTFOUND') {
if (!event.result.is_in_stock) {
if (!config.stock.allowOutOfStockInCart && !config.cart.synchronize) { // if config.cart.synchronize is true then - the items are being removed by the result of cart/update action executed from cart/sync
Logger.log('Removing product from cart' + event.product_sku, 'stock')()
context.commit('cart/' + types.CART_DEL_ITEM, { product: { sku: event.product_sku } }, {root: true})
if (!config.stock.allowOutOfStockInCart && !config.cart.synchronize) {
// if config.cart.synchronize is true then - the items are being removed by the result of cart/update action executed from cart/sync
Logger.log(
'Removing product from cart' + event.product_sku,
'stock'
)()
commit(
'cart/' + types.CART_DEL_ITEM,
{ product: { sku: event.product_sku } },
{ root: true }
)
} else {
context.dispatch('cart/updateItem', { product: { errors: { stock: i18n.t('Out of the stock!') }, sku: event.product_sku, is_in_stock: false } }, { root: true })
dispatch(
'cart/updateItem',
{
product: {
errors: { stock: i18n.t('Out of the stock!') },
sku: event.product_sku,
is_in_stock: false
}
},
{ root: true }
)
}
} else {
context.dispatch('cart/updateItem', { product: { info: { stock: i18n.t('In stock!') }, sku: event.product_sku, is_in_stock: true } }, { root: true })
dispatch(
'cart/updateItem',
{
product: {
info: { stock: i18n.t('In stock!') },
sku: event.product_sku,
is_in_stock: true
}
},
{ root: true }
)
}
EventBus.$emit('cart-after-itemchanged', { item: cartItem })
}
Logger.debug('Stock quantity checked for ' + event.result.product_id + ', response time: ' + (event.transmited_at - event.created_at) + ' ms', 'stock')()
Logger.debug(
'Stock quantity checked for ' +
event.result.product_id +
', response time: ' +
(event.transmited_at - event.created_at) +
' ms',
'stock'
)()
Logger.debug(event, 'stock')()
}, 500)
}
Expand Down
2 changes: 2 additions & 0 deletions core/modules/catalog/store/stock/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Module } from 'vuex'
import actions from './actions'
import mutations from './mutations'
import RootState from '@vue-storefront/core/types/RootState'
import StockState from '../../types/StockState'

export const stockModule: Module<StockState, RootState> = {
namespaced: true,
actions,
mutations,
state: {
cache: {}
}
Expand Down
3 changes: 3 additions & 0 deletions core/modules/catalog/store/stock/mutation-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const SN_CATALOG = 'catalog'
export const SET_STOCK_CACHE = `${SN_CATALOG}/SET_STOCK_CACHE`
export const SET_STOCK_CACHE_PRODUCT = `${SN_CATALOG}/SET_STOCK_CACHE_PRODUCT`
16 changes: 16 additions & 0 deletions core/modules/catalog/store/stock/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { MutationTree } from 'vuex'
import StockState from '../../types/StockState'
import * as types from './mutation-types'

const mutations: MutationTree<StockState> = {
[types.SET_STOCK_CACHE] (state, cache) {
state.cache = cache
},
[types.SET_STOCK_CACHE_PRODUCT] (state, { productId, productInfo }) {
state.cache = Object.assign({}, state.cache, {
[productId]: productInfo
})
}
}

export default mutations
18 changes: 18 additions & 0 deletions src/themes/default/components/core/Spinner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template functional>
<div class="spinner">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="22px" height="22px" viewBox="0 0 128 128" xml:space="preserve"><rect x="0" y="0" width="100%" height="100%" fill="transparent" /><g transform="rotate(135 64 64)"><circle cx="16" cy="64" r="16" fill="#000000" fill-opacity="1" /><circle cx="16" cy="64" r="16" fill="#555555" fill-opacity="0.67" transform="rotate(45,64,64)" /><circle cx="16" cy="64" r="16" fill="#949494" fill-opacity="0.42" transform="rotate(90,64,64)" /><circle cx="16" cy="64" r="16" fill="#cccccc" fill-opacity="0.2" transform="rotate(135,64,64)" /><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(180,64,64)" /><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(225,64,64)" /><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(270,64,64)" /><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(315,64,64)" /><animateTransform attributeName="transform" type="rotate" values="0 64 64;315 64 64;270 64 64;225 64 64;180 64 64;135 64 64;90 64 64;45 64 64" calcMode="discrete" dur="720ms" repeatCount="indefinite" /></g></svg>
</div>
</template>

<script>
export default {
name: 'Spinner',
functional: true
}
</script>

<style lang="scss" scoped>
.spinner {
padding: 0 15px;
}
</style>
55 changes: 30 additions & 25 deletions src/themes/default/components/core/blocks/Form/BaseInputNumber.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
:id="getInputId"
type="number"
:min="min"
:max="max"
:disabled="disabled"
class="m0 no-outline base-input-number__input brdr-cl-primary bg-cl-transparent h4"
:focus="autofocus"
:value="value"
Expand All @@ -23,8 +25,7 @@ export default {
ValidationMessages
},
data () {
return {
}
return {}
},
props: {
value: {
Expand All @@ -40,6 +41,14 @@ export default {
type: Number,
default: 0
},
max: {
type: Number,
default: 0
},
disabled: {
type: Boolean,
default: false
},
autofocus: {
type: Boolean,
required: false,
Expand All @@ -59,32 +68,28 @@ export default {
</script>

<style lang="scss" scoped>
@import '~theme/css/variables/colors';
@import '~theme/css/helpers/functions/color';

.base-input-number {
width: 100%;
@import '~theme/css/variables/colors';
@import '~theme/css/helpers/functions/color';

&__input {
border-style: solid;
border-width: 0 0 1px 0;
width: 50px;
height: 1.4rem;
line-height: 1.7rem;
@media (min-width: 768px) {
height: 1.7rem;
}
.base-input-number {
&__input {
border-style: solid;
border-width: 0 0 1px 0;
width: 50px;
height: 1.4rem;
line-height: 1.7rem;
@media (min-width: 768px) {
height: 1.7rem;
}
}

&__label {
font-size: 0.8rem;
line-height: 1.2rem;
max-width: 100px;
@media (min-width: 768px) {
font-size: 1rem;
line-height: 1.4rem;
}
&__label {
font-size: 0.8rem;
line-height: 1.2rem;
@media (min-width: 768px) {
font-size: 1rem;
line-height: 1.4rem;
}
}

}
</style>
Loading