@lancom/shared 0.0.90 → 0.0.91
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/assets/js/utils/filters.js +4 -4
- package/components/editor/editor_layers/editor_layers_toolbar/editor-layers-toolbar.vue +4 -0
- package/components/products/product_list/product-list.vue +23 -2
- package/components/products/product_list_product_placeholder/product-list-product-placeholder.scss +52 -0
- package/components/products/product_list_product_placeholder/product-list-product-placeholder.vue +26 -0
- package/components/products/products_aside/products-aside.scss +32 -0
- package/components/products/products_aside/products-aside.vue +27 -27
- package/components/products/products_catalog/products-catalog.vue +8 -3
- package/components/products/products_colors/products-colors.vue +1 -1
- package/components/quotes/quote_request/quote-request.vue +3 -1
- package/mixins/product-preview.js +2 -5
- package/package.json +1 -1
- package/plugins/global-components.js +0 -2
- package/plugins/vue-recaptcha.js +12 -7
- package/store/products.js +7 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
2
|
import DateOnly from 'dateonly';
|
|
3
3
|
|
|
4
4
|
import currencies from '../constants/currencies';
|
|
@@ -68,11 +68,11 @@ export const highlight = (string = '', query) => {
|
|
|
68
68
|
return string.toString().replace(q, matchedTxt => (`<span class="highlight">${matchedTxt}</span>`));
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
export const date = d =>
|
|
71
|
+
export const date = d => dayjs(d).format('ddd, MMM D, YYYY h:mm A');
|
|
72
72
|
|
|
73
|
-
export const shortDate = d =>
|
|
73
|
+
export const shortDate = d => dayjs(d).format('DD/MM/YYYY');
|
|
74
74
|
|
|
75
|
-
export const sydneyTime = d =>
|
|
75
|
+
export const sydneyTime = d => dayjs(d).utc().utcOffset(10).format('MMM D, YYYY h:mm A');
|
|
76
76
|
|
|
77
77
|
export const priceInRange = (prices, amount) => (prices.find(({ min, max }) => min <= amount && (!max || max >= amount)) || { price: 0 }).price;
|
|
78
78
|
|
|
@@ -79,12 +79,16 @@
|
|
|
79
79
|
|
|
80
80
|
<script>
|
|
81
81
|
import { createNamespacedHelpers, mapGetters } from 'vuex';
|
|
82
|
+
import FileUploader from '@lancom/shared/components/common/file_uploader';
|
|
82
83
|
import modals from '@lancom/shared/mixins/modals';
|
|
83
84
|
|
|
84
85
|
const { mapActions, mapMutations } = createNamespacedHelpers('product');
|
|
85
86
|
|
|
86
87
|
export default {
|
|
87
88
|
name: 'EditorLayersToolbar',
|
|
89
|
+
components: {
|
|
90
|
+
FileUploader
|
|
91
|
+
},
|
|
88
92
|
mixins: [
|
|
89
93
|
modals
|
|
90
94
|
],
|
|
@@ -14,7 +14,22 @@
|
|
|
14
14
|
}"
|
|
15
15
|
@mouseenter="setActiveProduct(index)"
|
|
16
16
|
@mouseleave="setActiveProduct(null)">
|
|
17
|
-
<slot
|
|
17
|
+
<slot
|
|
18
|
+
v-if="placeholder"
|
|
19
|
+
name="placeholder"
|
|
20
|
+
v-bind="{ product, full: activeProduct === index, toEditor }">
|
|
21
|
+
<product-list-product-placeholder
|
|
22
|
+
:product="product"
|
|
23
|
+
:to-editor="toEditor"
|
|
24
|
+
class="ProductList__item"
|
|
25
|
+
:class="{
|
|
26
|
+
'ProductList__item--active': activeProduct === index
|
|
27
|
+
}" />
|
|
28
|
+
</slot>
|
|
29
|
+
<slot
|
|
30
|
+
v-else
|
|
31
|
+
name="product"
|
|
32
|
+
v-bind="{ product, full: activeProduct === index, toEditor }">
|
|
18
33
|
<product-list-product
|
|
19
34
|
:product="product"
|
|
20
35
|
:to-editor="toEditor"
|
|
@@ -36,11 +51,13 @@
|
|
|
36
51
|
|
|
37
52
|
<script>
|
|
38
53
|
import ProductListProduct from '../product_list_product/product-list-product';
|
|
54
|
+
import ProductListProductPlaceholder from '../product_list_product_placeholder/product-list-product-placeholder';
|
|
39
55
|
|
|
40
56
|
export default {
|
|
41
57
|
name: 'LancomProductList',
|
|
42
58
|
components: {
|
|
43
|
-
ProductListProduct
|
|
59
|
+
ProductListProduct,
|
|
60
|
+
ProductListProductPlaceholder
|
|
44
61
|
},
|
|
45
62
|
props: {
|
|
46
63
|
products: {
|
|
@@ -50,6 +67,10 @@ export default {
|
|
|
50
67
|
toEditor: {
|
|
51
68
|
type: Boolean,
|
|
52
69
|
default: true
|
|
70
|
+
},
|
|
71
|
+
placeholder: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
default: true
|
|
53
74
|
}
|
|
54
75
|
},
|
|
55
76
|
data() {
|
package/components/products/product_list_product_placeholder/product-list-product-placeholder.scss
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
@import "@/assets/scss/variables";
|
|
2
|
+
|
|
3
|
+
.ProductListProductPlaceholder {
|
|
4
|
+
&__wrapper {
|
|
5
|
+
padding: 30px;
|
|
6
|
+
}
|
|
7
|
+
&__link {
|
|
8
|
+
position: absolute;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
right: 0;
|
|
12
|
+
bottom: 0;
|
|
13
|
+
padding: 30px;
|
|
14
|
+
text-indent: -99999px;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
}
|
|
20
|
+
&__image {
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 250px;
|
|
23
|
+
animation-name: backgroundColorPalette;
|
|
24
|
+
animation-duration: 1s;
|
|
25
|
+
animation-iteration-count: infinite;
|
|
26
|
+
animation-direction: alternate;
|
|
27
|
+
}
|
|
28
|
+
&__info {
|
|
29
|
+
margin-top: 20px;
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 30px;
|
|
32
|
+
animation-name: backgroundColorPalette;
|
|
33
|
+
animation-duration: 1.5s;
|
|
34
|
+
animation-iteration-count: infinite;
|
|
35
|
+
animation-direction: alternate;
|
|
36
|
+
&--medium {
|
|
37
|
+
width: 80%;
|
|
38
|
+
}
|
|
39
|
+
&--small {
|
|
40
|
+
width: 60%;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@keyframes backgroundColorPalette {
|
|
46
|
+
0% {
|
|
47
|
+
background: #efefef;
|
|
48
|
+
}
|
|
49
|
+
100% {
|
|
50
|
+
background: #d9d9d9;
|
|
51
|
+
}
|
|
52
|
+
}
|
package/components/products/product_list_product_placeholder/product-list-product-placeholder.vue
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ProductListProductPlaceholder__wrapper">
|
|
3
|
+
<nuxt-link
|
|
4
|
+
:to="productLink"
|
|
5
|
+
class="ProductListProductPlaceholder__link">
|
|
6
|
+
<span class="ProductListProductPlaceholder__image"></span>
|
|
7
|
+
<span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--large"></span>
|
|
8
|
+
<span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--medium"></span>
|
|
9
|
+
<span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--small"></span>
|
|
10
|
+
{{ product.name }}
|
|
11
|
+
</nuxt-link>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
import productPreview from '@lancom/shared/mixins/product-preview';
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
name: 'ProductListProductPlaceholder',
|
|
20
|
+
mixins: [productPreview]
|
|
21
|
+
};
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<style lang="scss" scoped>
|
|
25
|
+
@import 'product-list-product-placeholder';
|
|
26
|
+
</style>
|
|
@@ -11,4 +11,36 @@
|
|
|
11
11
|
display: none;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
&__placeholder {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
margin-right: 20px;
|
|
18
|
+
}
|
|
19
|
+
&__info {
|
|
20
|
+
margin-top: 20px;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 20px;
|
|
23
|
+
animation-name: backgroundColorPalette;
|
|
24
|
+
animation-duration: 1.5s;
|
|
25
|
+
animation-iteration-count: infinite;
|
|
26
|
+
animation-direction: alternate;
|
|
27
|
+
&--medium {
|
|
28
|
+
width: 85%;
|
|
29
|
+
}
|
|
30
|
+
&--small {
|
|
31
|
+
width: 70%;
|
|
32
|
+
}
|
|
33
|
+
&--small2 {
|
|
34
|
+
width: 55%;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@keyframes backgroundColorPalette {
|
|
40
|
+
0% {
|
|
41
|
+
background: #efefef;
|
|
42
|
+
}
|
|
43
|
+
100% {
|
|
44
|
+
background: #d9d9d9;
|
|
45
|
+
}
|
|
14
46
|
}
|
|
@@ -2,38 +2,35 @@
|
|
|
2
2
|
<div
|
|
3
3
|
:data-aos="aosFadeRight"
|
|
4
4
|
class="ProductsAside__wrapper">
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@change="goToTextSearch" />
|
|
13
|
-
</div> -->
|
|
14
|
-
<!-- <div class="ProductsAside__item">
|
|
15
|
-
<products-types
|
|
16
|
-
:has-selected-icon="hasSelectedIcon"
|
|
17
|
-
:has-thumbs="hasThumbs" />
|
|
18
|
-
</div> -->
|
|
19
|
-
<div class="ProductsAside__item">
|
|
20
|
-
<products-brands
|
|
21
|
-
:has-selected-icon="hasSelectedIcon" />
|
|
5
|
+
<div
|
|
6
|
+
v-if="placeholder"
|
|
7
|
+
class="ProductsAside__placeholder">
|
|
8
|
+
<span class="ProductsAside__info ProductsAside__info--large"></span>
|
|
9
|
+
<span class="ProductsAside__info ProductsAside__info--medium"></span>
|
|
10
|
+
<span class="ProductsAside__info ProductsAside__info--small"></span>
|
|
11
|
+
<span class="ProductsAside__info ProductsAside__info--small2"></span>
|
|
22
12
|
</div>
|
|
23
|
-
<div
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
<div v-else>
|
|
14
|
+
<div class="ProductsAside__item">
|
|
15
|
+
<products-brands
|
|
16
|
+
:has-selected-icon="hasSelectedIcon" />
|
|
17
|
+
</div>
|
|
18
|
+
<div class="ProductsAside__item">
|
|
19
|
+
<products-colors />
|
|
20
|
+
</div>
|
|
21
|
+
<div class="ProductsAside__item">
|
|
22
|
+
<products-attributes
|
|
23
|
+
:has-selected-icon="hasSelectedIcon" />
|
|
24
|
+
<products-tags
|
|
25
|
+
:has-selected-icon="hasSelectedIcon" />
|
|
26
|
+
</div>
|
|
31
27
|
</div>
|
|
32
28
|
</div>
|
|
33
29
|
</template>
|
|
34
30
|
|
|
35
31
|
<script>
|
|
36
|
-
import ProductsTypes from '@lancom/shared/components/products/products_types/products-types';
|
|
32
|
+
// import ProductsTypes from '@lancom/shared/components/products/products_types/products-types';
|
|
33
|
+
import { mapGetters } from 'vuex';
|
|
37
34
|
import ProductsBrands from '@lancom/shared/components/products/products_brands/products-brands';
|
|
38
35
|
import ProductsTags from '@lancom/shared/components/products/products_tags/products-tags';
|
|
39
36
|
import ProductsAttributes from '@lancom/shared/components/products/products_attributes/products-attributes';
|
|
@@ -43,7 +40,7 @@ import { generateProductsLink } from '@lancom/shared/assets/js/utils/product';
|
|
|
43
40
|
export default {
|
|
44
41
|
name: 'ProductsAside',
|
|
45
42
|
components: {
|
|
46
|
-
ProductsTypes,
|
|
43
|
+
// ProductsTypes,
|
|
47
44
|
ProductsBrands,
|
|
48
45
|
ProductsTags,
|
|
49
46
|
ProductsAttributes,
|
|
@@ -64,6 +61,9 @@ export default {
|
|
|
64
61
|
search: this.$route.query.text || ''
|
|
65
62
|
};
|
|
66
63
|
},
|
|
64
|
+
computed: {
|
|
65
|
+
...mapGetters('products', ['placeholder'])
|
|
66
|
+
},
|
|
67
67
|
methods: {
|
|
68
68
|
goToTextSearch() {
|
|
69
69
|
this.goToPageWithFilters({ text: this.search });
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
<div v-if="products">
|
|
4
4
|
<slot
|
|
5
5
|
name="list"
|
|
6
|
-
v-bind="{ products, toEditor }">
|
|
7
|
-
<product-list
|
|
6
|
+
v-bind="{ products, toEditor, placeholder }">
|
|
7
|
+
<product-list
|
|
8
|
+
:products="products"
|
|
9
|
+
:to-editor="toEditor"
|
|
10
|
+
:placeholder="placeholder" />
|
|
8
11
|
</slot>
|
|
9
12
|
<pagination
|
|
10
13
|
v-model="currentPage"
|
|
@@ -38,7 +41,8 @@ export default {
|
|
|
38
41
|
'products',
|
|
39
42
|
'page',
|
|
40
43
|
'count',
|
|
41
|
-
'perPage'
|
|
44
|
+
'perPage',
|
|
45
|
+
'placeholder'
|
|
42
46
|
]),
|
|
43
47
|
currentPage: {
|
|
44
48
|
get() {
|
|
@@ -47,6 +51,7 @@ export default {
|
|
|
47
51
|
set(page) {
|
|
48
52
|
const link = generateProductsLink(this.$route, { page });
|
|
49
53
|
this.$router.push(link);
|
|
54
|
+
window.scrollTo(0, 0);
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -297,11 +297,13 @@
|
|
|
297
297
|
import api from '@lancom/shared/assets/js/api';
|
|
298
298
|
import { mapGetters } from 'vuex';
|
|
299
299
|
import CheckedIcon from '@lancom/shared/components/common/checked-icon';
|
|
300
|
+
import FileUploader from '@lancom/shared/components/common/file_uploader';
|
|
300
301
|
|
|
301
302
|
export default {
|
|
302
303
|
name: 'QuoteRequest',
|
|
303
304
|
components: {
|
|
304
|
-
CheckedIcon
|
|
305
|
+
CheckedIcon,
|
|
306
|
+
FileUploader
|
|
305
307
|
},
|
|
306
308
|
data() {
|
|
307
309
|
return {
|
|
@@ -54,9 +54,6 @@ const productPreview = {
|
|
|
54
54
|
productLink() {
|
|
55
55
|
return generateProductLink(this.product, this.currentColor, this.toEditor);
|
|
56
56
|
},
|
|
57
|
-
productСoverBig() {
|
|
58
|
-
return getProductLargeCover(this.product, 'front', this.currentColor);
|
|
59
|
-
},
|
|
60
57
|
productСover() {
|
|
61
58
|
return getProductMediumCover(this.product, 'front', this.currentColor);
|
|
62
59
|
},
|
|
@@ -84,11 +81,11 @@ const productPreview = {
|
|
|
84
81
|
if (process.client) {
|
|
85
82
|
setTimeout(() => {
|
|
86
83
|
this.loadHolder.canLoadImages = true;
|
|
87
|
-
},
|
|
84
|
+
}, 0);
|
|
88
85
|
setTimeout(() => {
|
|
89
86
|
this.loadHolder.canLoadBackImages = true;
|
|
90
87
|
this.loadHolder.canLoadColorImages = true;
|
|
91
|
-
},
|
|
88
|
+
}, 3000);
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import Vue from 'vue';
|
|
2
2
|
import Btn from '@lancom/shared/components/common/btn';
|
|
3
3
|
import Spinner from '@lancom/shared/components/common/spinner';
|
|
4
|
-
import FileUploader from '@lancom/shared/components/common/file_uploader';
|
|
5
4
|
import Checkbox from '@lancom/shared/components/common/checkbox';
|
|
6
5
|
import Breakpoint from '@lancom/shared/components/common/breakpoint';
|
|
7
6
|
|
|
8
7
|
Vue.component('btn', Btn);
|
|
9
8
|
Vue.component('spinner', Spinner);
|
|
10
|
-
Vue.component('file-uploader', FileUploader);
|
|
11
9
|
Vue.component('Checkbox', Checkbox);
|
|
12
10
|
Vue.component('breakpoint', Breakpoint);
|
package/plugins/vue-recaptcha.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import Vue from 'vue';
|
|
2
|
-
import { VueReCaptcha } from 'vue-recaptcha-v3';
|
|
3
2
|
|
|
4
3
|
export default () => {
|
|
5
|
-
Vue.use(VueReCaptcha, {
|
|
6
|
-
siteKey: process.env.RECAPTCHA_KEY,
|
|
7
|
-
loaderOptions: {
|
|
8
|
-
useRecaptchaNet: true
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
4
|
Vue.mixin({
|
|
12
5
|
methods: {
|
|
13
6
|
async getRecaptcha(name) {
|
|
7
|
+
if (!this.$recaptcha) {
|
|
8
|
+
await this.loadReCaptcha();
|
|
9
|
+
}
|
|
14
10
|
return process.env.IS_LOCAL === 'true' || await this.$recaptcha(name);
|
|
11
|
+
},
|
|
12
|
+
async loadReCaptcha() {
|
|
13
|
+
const { VueReCaptcha } = await import('vue-recaptcha-v3');
|
|
14
|
+
Vue.use(VueReCaptcha, {
|
|
15
|
+
siteKey: process.env.RECAPTCHA_KEY,
|
|
16
|
+
loaderOptions: {
|
|
17
|
+
useRecaptchaNet: true
|
|
18
|
+
}
|
|
19
|
+
});
|
|
15
20
|
}
|
|
16
21
|
}
|
|
17
22
|
});
|
package/store/products.js
CHANGED
|
@@ -10,7 +10,8 @@ export const state = () => ({
|
|
|
10
10
|
brands: [],
|
|
11
11
|
tags: [],
|
|
12
12
|
attributes: [],
|
|
13
|
-
loadError: null
|
|
13
|
+
loadError: null,
|
|
14
|
+
placeholder: false
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
export const getters = {
|
|
@@ -23,7 +24,8 @@ export const getters = {
|
|
|
23
24
|
page: ({ page }) => page,
|
|
24
25
|
count: ({ count }) => count,
|
|
25
26
|
perPage: ({ perPage }) => perPage,
|
|
26
|
-
loadError: ({ loadError }) => loadError
|
|
27
|
+
loadError: ({ loadError }) => loadError,
|
|
28
|
+
placeholder: ({ placeholder }) => placeholder
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
export const actions = {
|
|
@@ -55,6 +57,9 @@ export const actions = {
|
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
export const mutations = {
|
|
60
|
+
setPlaceholder(state, placeholder) {
|
|
61
|
+
state.placeholder = placeholder;
|
|
62
|
+
},
|
|
58
63
|
setProducts(state, products) {
|
|
59
64
|
state.products = products;
|
|
60
65
|
},
|