@ecomplus/storefront-components 1.0.0-beta.19 → 1.0.0-beta.190
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/CHANGELOG.md +1329 -135
- package/all.js +3 -1
- package/dist/1.storefront-components.min.js +2 -0
- package/dist/1.storefront-components.min.js.map +1 -0
- package/dist/2.storefront-components.min.js +5 -0
- package/dist/2.storefront-components.min.js.map +1 -0
- package/dist/3.storefront-components.min.js +5 -0
- package/dist/3.storefront-components.min.js.map +1 -0
- package/dist/storefront-components.min.js +33 -12
- package/dist/storefront-components.min.js.map +1 -1
- package/package.json +17 -12
- package/src/APagination.vue +2 -0
- package/src/AShare.vue +2 -0
- package/src/AccountAddresses.vue +3 -0
- package/src/AccountForm.vue +3 -0
- package/src/AccountPoints.vue +3 -0
- package/src/BuyTogether.vue +3 -0
- package/src/EarnPointsProgress.vue +3 -0
- package/src/ItemCustomizations.vue +2 -0
- package/src/KitProductVariations.vue +3 -0
- package/src/PointsApplier.vue +2 -0
- package/src/ProductQuickview.vue +3 -0
- package/src/QuantitySelector.vue +3 -0
- package/src/RecommendedItems.vue +3 -0
- package/src/ShippingLine.vue +1 -0
- package/src/TheCart.vue +3 -0
- package/src/html/APagination.html +90 -0
- package/src/html/APrices.html +24 -4
- package/src/html/AShare.html +31 -0
- package/src/html/AccountAddresses.html +90 -0
- package/src/html/AccountForm.html +269 -0
- package/src/html/AccountPoints.html +39 -0
- package/src/html/AddressForm.html +9 -7
- package/src/html/BuyTogether.html +60 -0
- package/src/html/CartItem.html +86 -38
- package/src/html/CartQuickview.html +28 -5
- package/src/html/DiscountApplier.html +3 -3
- package/src/html/EarnPointsProgress.html +28 -0
- package/src/html/InputDate.html +1 -1
- package/src/html/InputDocNumber.html +1 -0
- package/src/html/InputPhone.html +1 -1
- package/src/html/InstantSearch.html +3 -3
- package/src/html/ItemCustomizations.html +14 -0
- package/src/html/KitProductVariations.html +92 -0
- package/src/html/LoginBlock.html +34 -32
- package/src/html/LoginModal.html +9 -4
- package/src/html/PaymentOption.html +7 -5
- package/src/html/PointsApplier.html +26 -0
- package/src/html/ProductCard.html +68 -8
- package/src/html/ProductGallery.html +21 -3
- package/src/html/ProductQuickview.html +64 -0
- package/src/html/ProductVariations.html +30 -3
- package/src/html/QuantitySelector.html +85 -0
- package/src/html/RecommendedItems.html +48 -0
- package/src/html/SearchEngine.html +101 -24
- package/src/html/ShippingCalculator.html +84 -3
- package/src/html/ShippingLine.html +5 -2
- package/src/html/TheAccount.html +43 -9
- package/src/html/TheCart.html +156 -0
- package/src/html/TheProduct.html +416 -138
- package/src/js/APagination.js +74 -0
- package/src/js/APicture.js +27 -7
- package/src/js/APrices.js +80 -41
- package/src/js/AShare.js +83 -0
- package/src/js/AccountAddresses.js +201 -0
- package/src/js/AccountForm.js +312 -0
- package/src/js/AccountPoints.js +63 -0
- package/src/js/AddressForm.js +80 -35
- package/src/js/BuyTogether.js +246 -0
- package/src/js/CartItem.js +67 -14
- package/src/js/CartQuickview.js +20 -1
- package/src/js/DiscountApplier.js +181 -50
- package/src/js/EarnPointsProgress.js +77 -0
- package/src/js/InputDate.js +8 -8
- package/src/js/InputDocNumber.js +20 -0
- package/src/js/ItemCustomizations.js +10 -0
- package/src/js/KitProductVariations.js +218 -0
- package/src/js/LoginBlock.js +47 -6
- package/src/js/LoginModal.js +18 -10
- package/src/js/PaymentOption.js +28 -1
- package/src/js/PointsApplier.js +110 -0
- package/src/js/ProductCard.js +115 -11
- package/src/js/ProductGallery.js +32 -12
- package/src/js/ProductQuickview.js +72 -0
- package/src/js/ProductVariations.js +76 -19
- package/src/js/QuantitySelector.js +175 -0
- package/src/js/RecommendedItems.js +178 -0
- package/src/js/SearchEngine.js +185 -55
- package/src/js/ShippingCalculator.js +176 -35
- package/src/js/ShippingLine.js +44 -5
- package/src/js/TheAccount.js +97 -6
- package/src/js/TheCart.js +146 -0
- package/src/js/TheProduct.js +387 -43
- package/src/js/helpers/add-idle-callback.js +7 -0
- package/src/js/helpers/check-form-validity.js +3 -0
- package/src/js/helpers/favorite-products.js +24 -0
- package/src/js/helpers/scroll-to-element.js +10 -0
- package/src/js/helpers/sort-apps.js +14 -0
- package/src/js/helpers/wait-storefront-info.js +21 -0
- package/src/scss/APicture.scss +2 -0
- package/src/scss/APrices.scss +13 -1
- package/src/scss/AccountAddresses.scss +27 -0
- package/src/scss/AccountForm.scss +5 -0
- package/src/scss/AccountPoints.scss +17 -0
- package/src/scss/BuyTogether.scss +38 -0
- package/src/scss/CartItem.scss +17 -1
- package/src/scss/EarnPointsProgress.scss +6 -0
- package/src/scss/InstantSearch.scss +1 -0
- package/src/scss/KitProductVariations.scss +72 -0
- package/src/scss/LoginBlock.scss +5 -0
- package/src/scss/PaymentOption.scss +10 -1
- package/src/scss/ProductCard.scss +63 -25
- package/src/scss/ProductGallery.scss +4 -2
- package/src/scss/ProductQuickview.scss +36 -0
- package/src/scss/ProductVariations.scss +20 -4
- package/src/scss/QuantitySelector.scss +39 -0
- package/src/scss/RecommendedItems.scss +28 -0
- package/src/scss/SearchEngine.scss +9 -5
- package/src/scss/ShippingCalculator.scss +42 -1
- package/src/scss/ShippingLine.scss +24 -0
- package/src/scss/TheAccount.scss +4 -0
- package/src/scss/TheCart.scss +54 -0
- package/src/scss/TheProduct.scss +146 -1
- package/webpack.config.js +20 -6
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {
|
|
2
|
+
i19add,
|
|
3
|
+
i19seeMore,
|
|
4
|
+
i19weRecommendToYou
|
|
5
|
+
} from '@ecomplus/i18n'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
i18n,
|
|
9
|
+
recommendedIds as getRecommendedIds
|
|
10
|
+
} from '@ecomplus/utils'
|
|
11
|
+
|
|
12
|
+
import { graphs } from '@ecomplus/client'
|
|
13
|
+
import EcomSearch from '@ecomplus/search-engine'
|
|
14
|
+
import ecomCart from '@ecomplus/shopping-cart'
|
|
15
|
+
import { isMobile } from '@ecomplus/storefront-twbs'
|
|
16
|
+
import addIdleCallback from './helpers/add-idle-callback'
|
|
17
|
+
import ProductCard from '../ProductCard.vue'
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
name: 'RecommendedItems',
|
|
21
|
+
|
|
22
|
+
components: {
|
|
23
|
+
ProductCard
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
props: {
|
|
27
|
+
pageSize: {
|
|
28
|
+
type: Number,
|
|
29
|
+
default: !isMobile ? 4 : 2
|
|
30
|
+
},
|
|
31
|
+
sortOrder: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: 'sales'
|
|
34
|
+
},
|
|
35
|
+
canLoadMore: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: true
|
|
38
|
+
},
|
|
39
|
+
rowClassName: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: 'row no-gutters'
|
|
42
|
+
},
|
|
43
|
+
colClassName: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: 'col-6 col-md-4 col-lg-3'
|
|
46
|
+
},
|
|
47
|
+
productCardProps: {
|
|
48
|
+
type: Object,
|
|
49
|
+
default () {
|
|
50
|
+
return {
|
|
51
|
+
isSmall: true,
|
|
52
|
+
buyText: i18n(i19add),
|
|
53
|
+
installmentsOption: {},
|
|
54
|
+
discountOption: {}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
ecomCart: {
|
|
59
|
+
type: Object,
|
|
60
|
+
default () {
|
|
61
|
+
return ecomCart
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
productIds: {
|
|
65
|
+
type: Array,
|
|
66
|
+
default () {
|
|
67
|
+
return []
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
defaultMatchType: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: (typeof window === 'object' && window.ecomRecommendationsType) || 'recommended'
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
data () {
|
|
77
|
+
return {
|
|
78
|
+
ecomSearch: new EcomSearch()
|
|
79
|
+
.mergeFilter({
|
|
80
|
+
range: {
|
|
81
|
+
quantity: {
|
|
82
|
+
gt: 0
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
.mergeFilter({
|
|
87
|
+
term: {
|
|
88
|
+
available: true
|
|
89
|
+
}
|
|
90
|
+
}),
|
|
91
|
+
pageNumber: 1,
|
|
92
|
+
items: []
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
computed: {
|
|
97
|
+
i19seeMore: () => i18n(i19seeMore),
|
|
98
|
+
i19weRecommendToYou: () => i18n(i19weRecommendToYou)
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
methods: {
|
|
102
|
+
fetchItems () {
|
|
103
|
+
delete this.ecomSearch.dsl.aggs
|
|
104
|
+
this.ecomSearch.setPageNumber(this.pageNumber).fetch().then(() => {
|
|
105
|
+
this.items = this.items.concat(this.ecomSearch.getItems())
|
|
106
|
+
this.totalCount = this.ecomSearch.getTotalCount()
|
|
107
|
+
if (this.totalCount) {
|
|
108
|
+
this.$emit('recommend-items', {
|
|
109
|
+
items: this.items,
|
|
110
|
+
totalCount: this.totalCount
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}).finally(() => {
|
|
114
|
+
this.$emit('fetched')
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
created () {
|
|
120
|
+
const fetchRecommendations = (matchType = this.defaultMatchType) => {
|
|
121
|
+
const promises = []
|
|
122
|
+
const items = this.ecomCart.data.items.sort((a, b) => a.quantity > b.quantity ? -1 : 1)
|
|
123
|
+
for (let i = 0; i < items.length && i <= 4; i++) {
|
|
124
|
+
promises.push(graphs({ url: `/products/${items[i].product_id}/${matchType}.json` }))
|
|
125
|
+
}
|
|
126
|
+
Promise.allSettled(promises).then(results => {
|
|
127
|
+
const productIds = []
|
|
128
|
+
results.forEach(({ status, value }) => {
|
|
129
|
+
if (status === 'fulfilled') {
|
|
130
|
+
getRecommendedIds(value.data).forEach(productId => {
|
|
131
|
+
if (
|
|
132
|
+
!productIds.includes(productId) &&
|
|
133
|
+
!this.ecomCart.data.items.find(item => item.product_id === productId)
|
|
134
|
+
) {
|
|
135
|
+
productIds.push(productId)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
if (productIds.length) {
|
|
141
|
+
this.ecomSearch.setProductIds(productIds.slice(0, 24))
|
|
142
|
+
this.fetchItems()
|
|
143
|
+
} else if (matchType === 'recommended') {
|
|
144
|
+
fetchRecommendations('related')
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
if (this.productIds.length) {
|
|
149
|
+
this.ecomSearch.setProductIds(this.productIds)
|
|
150
|
+
this.totalCount = this.items.length
|
|
151
|
+
this.fetchItems()
|
|
152
|
+
} else {
|
|
153
|
+
addIdleCallback(() => {
|
|
154
|
+
fetchRecommendations()
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
watch: {
|
|
160
|
+
pageSize: {
|
|
161
|
+
handler (pageSize) {
|
|
162
|
+
this.ecomSearch.setPageSize(pageSize)
|
|
163
|
+
},
|
|
164
|
+
immediate: true
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
sortOrder: {
|
|
168
|
+
handler (sortOrder) {
|
|
169
|
+
this.ecomSearch.setSortOrder(sortOrder)
|
|
170
|
+
},
|
|
171
|
+
immediate: true
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
pageNumber () {
|
|
175
|
+
this.fetchItems()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/js/SearchEngine.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
i19all,
|
|
3
|
+
i19asOf,
|
|
2
4
|
i19brands,
|
|
3
5
|
i19categories,
|
|
4
6
|
i19clearFilters,
|
|
@@ -9,21 +11,31 @@ import {
|
|
|
9
11
|
i19highestPrice,
|
|
10
12
|
i19itemsFound,
|
|
11
13
|
i19lowestPrice,
|
|
14
|
+
i19name,
|
|
12
15
|
i19noResultsFor,
|
|
13
16
|
i19popularProducts,
|
|
17
|
+
i19price,
|
|
14
18
|
i19refineSearch,
|
|
19
|
+
i19releases,
|
|
15
20
|
i19relevance,
|
|
16
21
|
i19results,
|
|
17
22
|
i19sales,
|
|
18
23
|
i19searchAgain,
|
|
19
24
|
i19searchingFor,
|
|
20
25
|
i19searchOfflineErrorMsg,
|
|
21
|
-
i19sort
|
|
26
|
+
i19sort,
|
|
27
|
+
i19upTo
|
|
22
28
|
} from '@ecomplus/i18n'
|
|
23
29
|
|
|
24
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
i18n,
|
|
32
|
+
formatMoney
|
|
33
|
+
} from '@ecomplus/utils'
|
|
34
|
+
|
|
25
35
|
import lozad from 'lozad'
|
|
26
36
|
import EcomSearch from '@ecomplus/search-engine'
|
|
37
|
+
import { Portal } from '@linusborg/vue-simple-portal'
|
|
38
|
+
import scrollToElement from './helpers/scroll-to-element'
|
|
27
39
|
import ABackdrop from '../ABackdrop.vue'
|
|
28
40
|
import ProductCard from '../ProductCard.vue'
|
|
29
41
|
|
|
@@ -44,6 +56,7 @@ export default {
|
|
|
44
56
|
name: 'SearchEngine',
|
|
45
57
|
|
|
46
58
|
components: {
|
|
59
|
+
Portal,
|
|
47
60
|
ABackdrop,
|
|
48
61
|
ProductCard
|
|
49
62
|
},
|
|
@@ -63,6 +76,7 @@ export default {
|
|
|
63
76
|
isFixedBrands: Boolean,
|
|
64
77
|
isFixedCategories: Boolean,
|
|
65
78
|
defaultSort: String,
|
|
79
|
+
defaultFilters: Object,
|
|
66
80
|
autoFixScore: {
|
|
67
81
|
type: Number,
|
|
68
82
|
default: 0.6
|
|
@@ -79,10 +93,15 @@ export default {
|
|
|
79
93
|
type: Boolean,
|
|
80
94
|
default: true
|
|
81
95
|
},
|
|
96
|
+
loadMoreSelector: String,
|
|
82
97
|
canRetry: {
|
|
83
98
|
type: Boolean,
|
|
84
99
|
default: true
|
|
85
100
|
},
|
|
101
|
+
canShowItems: {
|
|
102
|
+
type: Boolean,
|
|
103
|
+
default: true
|
|
104
|
+
},
|
|
86
105
|
productCardProps: Object,
|
|
87
106
|
gridsData: {
|
|
88
107
|
type: Array,
|
|
@@ -103,6 +122,9 @@ export default {
|
|
|
103
122
|
noResultsTerm: '',
|
|
104
123
|
keepNoResultsTerm: false,
|
|
105
124
|
filters: [],
|
|
125
|
+
priceRange: {},
|
|
126
|
+
priceOptions: [],
|
|
127
|
+
hasSetPriceRange: false,
|
|
106
128
|
lastSelectedFilter: null,
|
|
107
129
|
selectedOptions: {},
|
|
108
130
|
selectedSortOption: null,
|
|
@@ -110,6 +132,7 @@ export default {
|
|
|
110
132
|
lastRequestId: null,
|
|
111
133
|
isScheduled: false,
|
|
112
134
|
isLoadingMore: false,
|
|
135
|
+
mustSkipLoadMore: false,
|
|
113
136
|
hasNetworkError: false,
|
|
114
137
|
popularItems: [],
|
|
115
138
|
hasSetPopularItems: false,
|
|
@@ -119,6 +142,7 @@ export default {
|
|
|
119
142
|
},
|
|
120
143
|
|
|
121
144
|
computed: {
|
|
145
|
+
i19all: () => i18n(i19all),
|
|
122
146
|
i19clearFilters: () => i18n(i19clearFilters),
|
|
123
147
|
i19closeFilters: () => i18n(i19closeFilters),
|
|
124
148
|
i19didYouMean: () => i18n(i19didYouMean),
|
|
@@ -127,8 +151,9 @@ export default {
|
|
|
127
151
|
i19itemsFound: () => i18n(i19itemsFound),
|
|
128
152
|
i19noResultsFor: () => i18n(i19noResultsFor),
|
|
129
153
|
i19popularProducts: () => i18n(i19popularProducts),
|
|
130
|
-
|
|
154
|
+
i19price: () => i18n(i19price),
|
|
131
155
|
i19refineSearch: () => i18n(i19refineSearch),
|
|
156
|
+
i19relevance: () => i18n(i19relevance),
|
|
132
157
|
i19results: () => i18n(i19results),
|
|
133
158
|
i19searchAgain: () => i18n(i19searchAgain),
|
|
134
159
|
i19searchingFor: () => i18n(i19searchingFor),
|
|
@@ -158,6 +183,12 @@ export default {
|
|
|
158
183
|
}, {
|
|
159
184
|
value: 'highest_price',
|
|
160
185
|
label: i18n(i19highestPrice)
|
|
186
|
+
}, {
|
|
187
|
+
value: 'news',
|
|
188
|
+
label: i18n(i19releases)
|
|
189
|
+
}, {
|
|
190
|
+
value: 'slug',
|
|
191
|
+
label: i18n(i19name)
|
|
161
192
|
}
|
|
162
193
|
],
|
|
163
194
|
|
|
@@ -172,7 +203,10 @@ export default {
|
|
|
172
203
|
|
|
173
204
|
isNavVisible () {
|
|
174
205
|
return this.hasSearched && this.isFilterable &&
|
|
175
|
-
(this.isSearching ||
|
|
206
|
+
(this.isSearching ||
|
|
207
|
+
this.totalSearchResults > 8 ||
|
|
208
|
+
this.hasSelectedOptions ||
|
|
209
|
+
this.hasSetPriceRange)
|
|
176
210
|
},
|
|
177
211
|
|
|
178
212
|
isResultsVisible () {
|
|
@@ -181,7 +215,8 @@ export default {
|
|
|
181
215
|
|
|
182
216
|
hasFilters () {
|
|
183
217
|
return this.hasSelectedOptions ||
|
|
184
|
-
this.filters.find(({ options }) => options.length)
|
|
218
|
+
this.filters.find(({ options }) => options.length) ||
|
|
219
|
+
this.hasSetPriceRange
|
|
185
220
|
},
|
|
186
221
|
|
|
187
222
|
suggestedItems () {
|
|
@@ -191,10 +226,18 @@ export default {
|
|
|
191
226
|
loadObserver () {
|
|
192
227
|
return this.canLoadMore && lozad('#search-engine-load-more', {
|
|
193
228
|
load: () => {
|
|
194
|
-
this.
|
|
195
|
-
|
|
229
|
+
if (!this.mustSkipLoadMore) {
|
|
230
|
+
this.mustSkipLoadMore = this.isLoadingMore = true
|
|
231
|
+
this.fetchItems()
|
|
232
|
+
}
|
|
196
233
|
}
|
|
197
234
|
})
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
pageAnchorIndex () {
|
|
238
|
+
const count = this.suggestedItems.length
|
|
239
|
+
const rest = count % this.pageSize
|
|
240
|
+
return (rest === 0 ? count - this.pageSize : count - rest) - 1
|
|
198
241
|
}
|
|
199
242
|
},
|
|
200
243
|
|
|
@@ -208,7 +251,7 @@ export default {
|
|
|
208
251
|
ecomSearch.setPageNumber(this.page + Math.ceil(this.resultItems.length / this.pageSize))
|
|
209
252
|
}
|
|
210
253
|
const fetching = ecomSearch.setPageSize(this.pageSize).fetch()
|
|
211
|
-
.then(
|
|
254
|
+
.then(result => {
|
|
212
255
|
if (this.lastRequestId === requestId) {
|
|
213
256
|
this.hasNetworkError = false
|
|
214
257
|
if (!isPopularItems) {
|
|
@@ -219,6 +262,7 @@ export default {
|
|
|
219
262
|
this.hasSetPopularItems = true
|
|
220
263
|
this.popularItems = ecomSearch.getItems()
|
|
221
264
|
}
|
|
265
|
+
return result
|
|
222
266
|
})
|
|
223
267
|
.catch(err => {
|
|
224
268
|
console.error(err)
|
|
@@ -232,9 +276,15 @@ export default {
|
|
|
232
276
|
})
|
|
233
277
|
.finally(() => {
|
|
234
278
|
this.countOpenRequests--
|
|
235
|
-
this.isLoadingMore
|
|
279
|
+
if (this.isLoadingMore) {
|
|
280
|
+
this.isLoadingMore = false
|
|
281
|
+
this.$nextTick(() => setTimeout(() => {
|
|
282
|
+
this.mustSkipLoadMore = false
|
|
283
|
+
this.loadObserver.observe()
|
|
284
|
+
}, 300))
|
|
285
|
+
}
|
|
236
286
|
})
|
|
237
|
-
this.$emit('fetch', { ecomSearch, fetching })
|
|
287
|
+
this.$emit('fetch', { ecomSearch, fetching, isPopularItems })
|
|
238
288
|
},
|
|
239
289
|
|
|
240
290
|
updateFilters () {
|
|
@@ -256,7 +306,8 @@ export default {
|
|
|
256
306
|
options,
|
|
257
307
|
isSpec
|
|
258
308
|
}
|
|
259
|
-
const optionsList = !this.selectedOptions[filter]
|
|
309
|
+
const optionsList = !this.selectedOptions[filter]
|
|
310
|
+
? []
|
|
260
311
|
: this.selectedOptions[filter]
|
|
261
312
|
.filter(option => options.find(({ key }) => key === option))
|
|
262
313
|
this.$set(this.selectedOptions, filter, optionsList)
|
|
@@ -265,46 +316,75 @@ export default {
|
|
|
265
316
|
}
|
|
266
317
|
addFilter('Brands', this.ecomSearch.getBrands())
|
|
267
318
|
addFilter('Categories', this.ecomSearch.getCategories())
|
|
268
|
-
this.ecomSearch.getSpecs().forEach(({ key, options }
|
|
319
|
+
this.ecomSearch.getSpecs().forEach(({ key, options }) => {
|
|
269
320
|
addFilter(key, options, true)
|
|
270
321
|
})
|
|
271
322
|
this.filters = this.filters.filter((_, i) => updatedFilters.includes(i))
|
|
272
323
|
this.searchFilterId = Date.now()
|
|
273
324
|
},
|
|
274
325
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
326
|
+
updatePriceOptions () {
|
|
327
|
+
this.priceRange = this.ecomSearch.getPriceRange()
|
|
328
|
+
if (Math.round(this.priceRange.min) < Math.round(this.priceRange.avg)) {
|
|
329
|
+
const price1 = Math.ceil(Math.max(this.priceRange.min * 1.5, this.priceRange.avg / 2))
|
|
330
|
+
const price2 = Math.ceil(Math.min(this.priceRange.max / 1.5, this.priceRange.avg * 2))
|
|
331
|
+
if (price1 !== price2) {
|
|
332
|
+
this.priceOptions = [Math.min(price1, price2), Math.max(price1, price2), null]
|
|
333
|
+
.map((max, i, prices) => {
|
|
334
|
+
const min = prices[i - 1]
|
|
335
|
+
return {
|
|
336
|
+
min,
|
|
337
|
+
max,
|
|
338
|
+
label: !min
|
|
339
|
+
? `${i18n(i19upTo)} ${formatMoney(max)}`
|
|
340
|
+
: i < 2
|
|
341
|
+
? `${formatMoney(min)} - ${formatMoney(max)}`
|
|
342
|
+
: `${i18n(i19asOf)} ${formatMoney(min)}`
|
|
343
|
+
}
|
|
344
|
+
})
|
|
345
|
+
return
|
|
292
346
|
}
|
|
293
|
-
})
|
|
294
|
-
if (!this.keepNoResultsTerm) {
|
|
295
|
-
this.noResultsTerm = ''
|
|
296
|
-
} else {
|
|
297
|
-
this.keepNoResultsTerm = false
|
|
298
347
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
348
|
+
this.priceOptions = []
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
handleSuggestions () {
|
|
352
|
+
if (this.term) {
|
|
353
|
+
const { ecomSearch } = this
|
|
354
|
+
const term = this.term.toLowerCase()
|
|
355
|
+
let suggestTerm = term
|
|
356
|
+
let canAutoFix = false
|
|
357
|
+
this.suggestedTerm = ''
|
|
358
|
+
ecomSearch.getTermSuggestions().forEach(({ options, text }) => {
|
|
359
|
+
if (options.length) {
|
|
360
|
+
const opt = options[0]
|
|
361
|
+
const optTerm = opt.text.toLowerCase()
|
|
362
|
+
if (
|
|
363
|
+
!this.totalSearchResults &&
|
|
364
|
+
this.autoFixScore > 0 &&
|
|
365
|
+
opt.score >= this.autoFixScore &&
|
|
366
|
+
optTerm.indexOf(term) === -1
|
|
367
|
+
) {
|
|
368
|
+
canAutoFix = true
|
|
369
|
+
}
|
|
370
|
+
suggestTerm = suggestTerm.replace(new RegExp(text, 'i'), optTerm)
|
|
371
|
+
}
|
|
372
|
+
})
|
|
373
|
+
if (!this.keepNoResultsTerm) {
|
|
374
|
+
this.noResultsTerm = ''
|
|
304
375
|
} else {
|
|
305
|
-
this.
|
|
376
|
+
this.keepNoResultsTerm = false
|
|
377
|
+
}
|
|
378
|
+
if (suggestTerm !== term) {
|
|
379
|
+
if (canAutoFix) {
|
|
380
|
+
this.noResultsTerm = term
|
|
381
|
+
this.keepNoResultsTerm = true
|
|
382
|
+
this.$emit('update:term', suggestTerm)
|
|
383
|
+
} else {
|
|
384
|
+
this.suggestedTerm = suggestTerm
|
|
385
|
+
}
|
|
386
|
+
ecomSearch.history.shift()
|
|
306
387
|
}
|
|
307
|
-
ecomSearch.history.shift()
|
|
308
388
|
}
|
|
309
389
|
},
|
|
310
390
|
|
|
@@ -315,6 +395,17 @@ export default {
|
|
|
315
395
|
? this.resultItems.concat(ecomSearch.getItems())
|
|
316
396
|
: ecomSearch.getItems()
|
|
317
397
|
this.updateFilters()
|
|
398
|
+
if (!this.hasSearched && this.defaultFilters) {
|
|
399
|
+
for (const filter in this.defaultFilters) {
|
|
400
|
+
const options = this.defaultFilters[filter]
|
|
401
|
+
if (Array.isArray(options)) {
|
|
402
|
+
options.forEach(option => this.setFilterOption(filter, option, true))
|
|
403
|
+
} else if (typeof options === 'string') {
|
|
404
|
+
this.setFilterOption(filter, options, true)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
this.updatePriceOptions()
|
|
318
409
|
this.handleSuggestions()
|
|
319
410
|
if (!this.totalSearchResults && this.hasPopularItems && !this.hasSetPopularItems) {
|
|
320
411
|
this.fetchItems(false, true)
|
|
@@ -349,7 +440,8 @@ export default {
|
|
|
349
440
|
|
|
350
441
|
toggleFilters (isVisible) {
|
|
351
442
|
this.isAsideVisible = typeof isVisible === 'boolean'
|
|
352
|
-
? isVisible
|
|
443
|
+
? isVisible
|
|
444
|
+
: !this.isAsideVisible
|
|
353
445
|
},
|
|
354
446
|
|
|
355
447
|
getFilterLabel (filter) {
|
|
@@ -409,23 +501,53 @@ export default {
|
|
|
409
501
|
}
|
|
410
502
|
},
|
|
411
503
|
|
|
504
|
+
handlePriceInputs () {
|
|
505
|
+
const { inputMinPrice, inputMaxPrice } = this.$refs
|
|
506
|
+
const min = Number(inputMinPrice.value) || null
|
|
507
|
+
const max = Number(inputMaxPrice.value) || null
|
|
508
|
+
if ((min && !max) || min <= max) {
|
|
509
|
+
this.setPriceRange(min, max)
|
|
510
|
+
}
|
|
511
|
+
inputMinPrice.value = (min || '')
|
|
512
|
+
inputMaxPrice.value = (max || '')
|
|
513
|
+
},
|
|
514
|
+
|
|
515
|
+
setPriceRange (min, max) {
|
|
516
|
+
if (
|
|
517
|
+
(min && min !== this.priceRange.min) ||
|
|
518
|
+
(max && max !== this.priceRange.max)
|
|
519
|
+
) {
|
|
520
|
+
this.hasSetPriceRange = true
|
|
521
|
+
} else if (this.hasSetPriceRange) {
|
|
522
|
+
this.hasSetPriceRange = false
|
|
523
|
+
} else {
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
this.ecomSearch.setPriceRange(min, max)
|
|
527
|
+
this.scheduleFetch()
|
|
528
|
+
},
|
|
529
|
+
|
|
412
530
|
setFilterOption (filter, option, isSet) {
|
|
413
531
|
const { selectedOptions } = this
|
|
414
532
|
const optionsList = selectedOptions[filter]
|
|
415
|
-
if (
|
|
416
|
-
this.lastSelectedFilter = filter
|
|
417
|
-
optionsList.push(option)
|
|
418
|
-
} else {
|
|
533
|
+
if (optionsList) {
|
|
419
534
|
const optionIndex = optionsList.indexOf(option)
|
|
420
|
-
if (
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
535
|
+
if (isSet) {
|
|
536
|
+
if (optionIndex === -1) {
|
|
537
|
+
this.lastSelectedFilter = filter
|
|
538
|
+
optionsList.push(option)
|
|
539
|
+
}
|
|
540
|
+
} else {
|
|
541
|
+
if (optionIndex > -1) {
|
|
542
|
+
optionsList.splice(optionIndex, 1)
|
|
543
|
+
}
|
|
544
|
+
if (!optionsList.length && this.lastSelectedFilter === filter) {
|
|
545
|
+
this.lastSelectedFilter = null
|
|
546
|
+
}
|
|
425
547
|
}
|
|
548
|
+
this.updateSearchFilter(filter)
|
|
549
|
+
this.scheduleFetch()
|
|
426
550
|
}
|
|
427
|
-
this.updateSearchFilter(filter)
|
|
428
|
-
this.scheduleFetch()
|
|
429
551
|
},
|
|
430
552
|
|
|
431
553
|
clearFilters () {
|
|
@@ -442,7 +564,11 @@ export default {
|
|
|
442
564
|
setSortOrder (sort) {
|
|
443
565
|
this.selectedSortOption = sort
|
|
444
566
|
this.ecomSearch.setSortOrder(sort)
|
|
445
|
-
this.
|
|
567
|
+
if (this.page > 1) {
|
|
568
|
+
this.page = 1
|
|
569
|
+
} else {
|
|
570
|
+
this.scheduleFetch()
|
|
571
|
+
}
|
|
446
572
|
}
|
|
447
573
|
},
|
|
448
574
|
|
|
@@ -465,7 +591,11 @@ export default {
|
|
|
465
591
|
isSearching (isSearching) {
|
|
466
592
|
if (!isSearching && this.loadObserver) {
|
|
467
593
|
this.$nextTick(() => {
|
|
468
|
-
this.
|
|
594
|
+
if (!this.mustSkipLoadMore) {
|
|
595
|
+
this.loadObserver.observe()
|
|
596
|
+
} else {
|
|
597
|
+
setTimeout(() => scrollToElement(this.$refs.pageAnchor[0], 40), 100)
|
|
598
|
+
}
|
|
469
599
|
})
|
|
470
600
|
}
|
|
471
601
|
}
|