@ecomplus/widget-search-engine 0.3.7 → 1.0.0-beta.100

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +862 -7
  2. package/README.md +2 -1
  3. package/cms.config.js +39 -0
  4. package/dist/public/widget-search-engine.1.min.js +2 -0
  5. package/dist/public/widget-search-engine.1.min.js.map +1 -0
  6. package/dist/public/widget-search-engine.2.min.js +2 -0
  7. package/dist/public/widget-search-engine.2.min.js.map +1 -0
  8. package/dist/public/widget-search-engine.3.min.js +5 -0
  9. package/dist/public/widget-search-engine.3.min.js.map +1 -0
  10. package/dist/public/widget-search-engine.4.min.js +5 -0
  11. package/dist/public/widget-search-engine.4.min.js.map +1 -0
  12. package/dist/public/widget-search-engine.5.min.js +2 -0
  13. package/dist/public/widget-search-engine.5.min.js.map +1 -0
  14. package/dist/public/widget-search-engine.var.min.js +1 -1
  15. package/dist/public/widget-search-engine.var.min.js.map +1 -1
  16. package/dist/widget-search-engine.1.min.js +2 -0
  17. package/dist/widget-search-engine.1.min.js.map +1 -0
  18. package/dist/widget-search-engine.2.min.js +2 -0
  19. package/dist/widget-search-engine.2.min.js.map +1 -0
  20. package/dist/widget-search-engine.3.min.js +5 -0
  21. package/dist/widget-search-engine.3.min.js.map +1 -0
  22. package/dist/widget-search-engine.4.min.js +5 -0
  23. package/dist/widget-search-engine.4.min.js.map +1 -0
  24. package/dist/widget-search-engine.5.min.js +2 -0
  25. package/dist/widget-search-engine.5.min.js.map +1 -0
  26. package/dist/widget-search-engine.min.js +1 -1
  27. package/dist/widget-search-engine.min.js.map +1 -1
  28. package/package.json +7 -6
  29. package/src/index.js +180 -30
  30. package/webpack.config.js +1 -0
  31. package/__tests__/index.js +0 -6
  32. package/src/components/EcSearchEngine.vue +0 -3
  33. package/src/components/html/EcSearchEngine.html +0 -272
  34. package/src/components/js/EcSearchEngine.js +0 -290
  35. package/src/components/scss/EcSearchEngine.scss +0 -132
  36. package/src/lib/dictionary.js +0 -77
@@ -1,290 +0,0 @@
1
- import { $ecomConfig } from '@ecomplus/utils'
2
- import EcomSearch from '@ecomplus/search-engine'
3
- import dictionary from './../../lib/dictionary'
4
- import EcProductCard from '@ecomplus/widget-product-card/src/components/EcProductCard.vue'
5
-
6
- export default {
7
- name: 'EcSearchEngine',
8
-
9
- components: {
10
- EcProductCard
11
- },
12
-
13
- props: {
14
- lang: {
15
- type: String,
16
- default: $ecomConfig.get('lang')
17
- },
18
- storeId: {
19
- type: Number,
20
- default: $ecomConfig.get('store_id')
21
- },
22
- term: {
23
- type: String
24
- },
25
- page: {
26
- type: Number
27
- },
28
- pageSize: {
29
- type: Number
30
- },
31
- brands: {
32
- type: Array
33
- },
34
- categories: {
35
- type: Array
36
- },
37
- autoFixScore: {
38
- type: [Number, Boolean],
39
- default: 0.6
40
- },
41
- showFilters: {
42
- type: Boolean,
43
- default: false
44
- },
45
- navbarId: String,
46
- prerenderedHTML: String
47
- },
48
-
49
- data () {
50
- return {
51
- ecomSearch: new EcomSearch(this.storeId),
52
- currentPage: 0,
53
- resultItems: [],
54
- fixedTerm: '',
55
- totalSearchResults: 0,
56
- searching: false,
57
- loadingMore: false,
58
- searched: false,
59
- emptyResult: false,
60
- networkError: false,
61
- filters: [],
62
- lastSelectedFilter: null,
63
- selectedOptions: {},
64
- sortOptions: [null, 'sales', 'lowest_price', 'highest_price'],
65
- selectedSortOption: null
66
- }
67
- },
68
-
69
- computed: {
70
- hasSelectedOptions () {
71
- for (const filter in this.selectedOptions) {
72
- if (this.selectedOptions[filter] && this.selectedOptions[filter].length) {
73
- return true
74
- }
75
- }
76
- return false
77
- },
78
-
79
- countedItems () {
80
- return (this.pageSize || 24) * (this.currentPage - 1) + this.resultItems.length
81
- }
82
- },
83
-
84
- methods: {
85
- dictionary,
86
-
87
- fixTerm () {
88
- if (this.term) {
89
- let fixedTerm = this.term
90
- let autoFix = true
91
- this.ecomSearch.getTermSuggestions().forEach(({ options, text }) => {
92
- if (options.length) {
93
- const opt = options[0]
94
- if (opt.score < this.autoFixScore) {
95
- autoFix = false
96
- }
97
- fixedTerm = fixedTerm.replace(text, opt.text)
98
- }
99
- })
100
- if (autoFix && fixedTerm !== this.term) {
101
- this.fixedTerm = fixedTerm
102
- this.ecomSearch.setSearchTerm(fixedTerm).history.shift()
103
- this.fetchItems()
104
- return true
105
- }
106
- }
107
- return false
108
- },
109
-
110
- updateFilters () {
111
- const keepFilter = this.filters.find(({ filter }) => filter === this.lastSelectedFilter)
112
- this.filters = keepFilter ? [keepFilter] : []
113
- const addFilter = (filter, options, isSpec) => {
114
- if (this.lastSelectedFilter !== filter) {
115
- this.filters.push({
116
- filter,
117
- filterObj: {
118
- show: this.filters.length < 5,
119
- options
120
- },
121
- isSpec
122
- })
123
- const { selectedOptions } = this
124
- const optionsList = selectedOptions[filter]
125
- ? selectedOptions[filter].filter(option => options.find(({ key }) => key === option))
126
- : []
127
- this.$set(this.selectedOptions, filter, optionsList)
128
- }
129
- }
130
- ;['Brands', 'Categories'].forEach(filter => {
131
- addFilter(filter, this.ecomSearch[`get${filter}`]())
132
- })
133
- this.ecomSearch.getSpecs().forEach(({ key, options }, index) => {
134
- addFilter(key, options, true)
135
- })
136
- },
137
-
138
- fetchItems (page, isRetry) {
139
- const { ecomSearch } = this
140
- this.searching = true
141
- this.loadingMore = page > 1 || this.page > 1
142
- ecomSearch.setPageNumber(page).fetch()
143
- .then(() => {
144
- this.totalSearchResults = ecomSearch.getTotalCount()
145
- if (this.totalSearchResults || this.fixedTerm || !this.fixTerm()) {
146
- if (page) {
147
- this.currentPage = page
148
- this.resultItems = this.resultItems.concat(ecomSearch.getItems())
149
- } else {
150
- this.currentPage = 1
151
- this.resultItems = ecomSearch.getItems()
152
- }
153
- if (!this.searched) {
154
- if (!this.resultItems.length) {
155
- ecomSearch.reset()
156
- this.emptyResult = true
157
- return this.fetchItems()
158
- }
159
- setTimeout(() => {
160
- this.searched = true
161
- }, 10)
162
- }
163
- this.updateFilters()
164
- this.networkError = false
165
- }
166
- })
167
- .catch(err => {
168
- console.error(err)
169
- if (!isRetry && (!err.response || err.response.status !== 400)) {
170
- this.fetchItems(page, true)
171
- } else {
172
- this.networkError = true
173
- }
174
- })
175
- .finally(() => {
176
- this.searching = this.loadingMore = false
177
- })
178
- },
179
-
180
- toggleFilters (toShow = false) {
181
- this.$emit('update:showFilters', toShow)
182
- },
183
-
184
- filterLabel (filter) {
185
- const label = this.dictionary(filter.toLowerCase())
186
- if (!label && window._data && Array.isArray(window._data.grids)) {
187
- const grid = window._data.grids.find(grid => grid.grid_id === filter)
188
- if (grid) {
189
- return grid.title || grid.grid_id
190
- }
191
- }
192
- return label || filter
193
- },
194
-
195
- updateSearchFilter (filter) {
196
- const { ecomSearch } = this
197
- let setOptions = this.selectedOptions[filter]
198
- if (!setOptions.length) {
199
- setOptions = null
200
- }
201
- switch (filter) {
202
- case 'Brands':
203
- ecomSearch.setBrandNames(setOptions)
204
- break
205
- case 'Categories':
206
- ecomSearch.setCategoryNames(setOptions)
207
- break
208
- default:
209
- ecomSearch.setSpec(filter, setOptions)
210
- }
211
- },
212
-
213
- setFilterOption (filter, option, isSet) {
214
- const { selectedOptions } = this
215
- const optionsList = selectedOptions[filter]
216
- if (isSet) {
217
- this.lastSelectedFilter = filter
218
- optionsList.push(option)
219
- } else {
220
- const optionIndex = optionsList.indexOf(option)
221
- if (optionIndex > -1) {
222
- optionsList.splice(optionIndex, 1)
223
- }
224
- if (!optionsList.length && this.lastSelectedFilter === filter) {
225
- this.lastSelectedFilter = null
226
- }
227
- }
228
- this.updateSearchFilter(filter)
229
- this.fetchItems()
230
- },
231
-
232
- clearFilters () {
233
- const { selectedOptions } = this
234
- for (const filter in selectedOptions) {
235
- if (selectedOptions[filter]) {
236
- selectedOptions[filter] = []
237
- this.updateSearchFilter(filter)
238
- }
239
- }
240
- this.fetchItems()
241
- },
242
-
243
- setSortOrder (sort) {
244
- this.selectedSortOption = sort
245
- this.ecomSearch.setSortOrder(sort)
246
- this.fetchItems()
247
- }
248
- },
249
-
250
- created () {
251
- const {
252
- ecomSearch,
253
- term,
254
- page,
255
- pageSize,
256
- brands,
257
- categories
258
- } = this
259
- if (term) {
260
- ecomSearch.setSearchTerm(term)
261
- }
262
- if (Array.isArray(brands) && brands.length) {
263
- ecomSearch.setBrandNames(brands)
264
- }
265
- if (Array.isArray(categories) && categories.length) {
266
- ecomSearch.setCategoryNames(categories)
267
- }
268
- ecomSearch.setPageSize(pageSize || 24)
269
- this.fetchItems(page || 1)
270
- },
271
-
272
- mounted () {
273
- if (this.navbarId) {
274
- const $nav = this.$refs.nav
275
- document.getElementById(this.navbarId).appendChild($nav)
276
- }
277
- let onScrollTimer
278
- window.addEventListener('scroll', () => {
279
- clearTimeout(onScrollTimer)
280
- if (!this.searching && this.totalSearchResults > this.countedItems) {
281
- onScrollTimer = setTimeout(() => {
282
- const { offsetTop, offsetHeight } = this.$el
283
- if (window.pageYOffset + window.screen.height >= offsetTop + offsetHeight) {
284
- this.fetchItems(this.currentPage + 1)
285
- }
286
- }, 100)
287
- }
288
- })
289
- }
290
- }
@@ -1,132 +0,0 @@
1
- .ec-search-engine {
2
- &__nav {
3
- background: rgba(128, 128, 128, .1);
4
- color: var(--gray);
5
- }
6
-
7
- &__count {
8
- padding-left: .5rem;
9
- position: relative;
10
- line-height: 2.5;
11
- }
12
-
13
- &__spinner {
14
- position: absolute;
15
- top: .4rem;
16
- right: -3rem;
17
- color: var(--secondary);
18
- margin-left: 1.5rem;
19
- width: 1.75rem;
20
- height: 1.75rem;
21
- }
22
-
23
- &__toggle {
24
- color: inherit;
25
- display: inline-block;
26
- text-decoration: none;
27
- transition: opacity .15s, color .2s;
28
- padding: 0 .5rem;
29
- opacity: .75;
30
- line-height: 2.5;
31
- border: none;
32
-
33
- i,
34
- svg {
35
- font-size: .825rem;
36
- color: var(--gray-dark);
37
- margin-right: .15rem;
38
- }
39
-
40
- &:hover,
41
- &:focus {
42
- opacity: 1;
43
- text-decoration: none;
44
- color: inherit;
45
- box-shadow: none;
46
- }
47
-
48
- &[aria-expanded="true"] {
49
- color: var(--gray-dark);
50
- opacity: 1;
51
- }
52
- }
53
-
54
- &__results {
55
- transition: opacity .25s;
56
- }
57
-
58
- &__info {
59
- margin-bottom: 1.5rem;
60
- padding-top: 1rem;
61
- }
62
-
63
- &__terms {
64
- display: flex;
65
- justify-content: space-between;
66
- align-items: center;
67
-
68
- small {
69
- font-size: .95rem;
70
- color: var(--gray);
71
- }
72
- }
73
-
74
- &__retail {
75
- padding-top: .5rem;
76
- }
77
-
78
- &__item {
79
- margin-bottom: 1rem;
80
- }
81
-
82
- &__sidebar {
83
- position: fixed;
84
- width: 280px;
85
- max-width: 100%;
86
- height: 100%;
87
- top: 0;
88
- right: 0;
89
- z-index: 1100;
90
- border-radius: 0;
91
-
92
- .card {
93
- &-body {
94
- overflow-y: auto;
95
- }
96
- }
97
- }
98
-
99
- &__filter {
100
- &:not(:first-child) {
101
- margin-top: 1rem;
102
- }
103
-
104
- &:last-child {
105
- margin-bottom: 1.5rem;
106
- }
107
-
108
- &__btn {
109
- padding-left: 0;
110
- color: var(--secondary);
111
- font-size: 1.2rem;
112
- font-weight: 300;
113
-
114
- i,
115
- svg {
116
- margin-right: .25rem;
117
- color: var(--gray);
118
- opacity: .6;
119
- }
120
-
121
- &:focus {
122
- box-shadow: none;
123
- }
124
- }
125
- }
126
-
127
- &__option {
128
- small {
129
- color: var(--gray);
130
- }
131
- }
132
- }
@@ -1,77 +0,0 @@
1
- const dictionary = {
2
- items: {
3
- en_us: 'items',
4
- pt_br: 'itens'
5
- },
6
- filter: {
7
- en_us: 'filter',
8
- pt_br: 'filtrar'
9
- },
10
- results: {
11
- en_us: 'results',
12
- pt_br: 'resultados'
13
- },
14
- sort: {
15
- en_us: 'sort',
16
- pt_br: 'ordenar'
17
- },
18
- searching_for: {
19
- en_us: 'Searching for',
20
- pt_br: 'Buscando por'
21
- },
22
- no_results_for: {
23
- en_us: 'No results for',
24
- pt_br: 'Nenhum resultado para'
25
- },
26
- brands: {
27
- en_us: 'Brands',
28
- pt_br: 'Marcas'
29
- },
30
- categories: {
31
- en_us: 'Categories',
32
- pt_br: 'Categorias'
33
- },
34
- refine_search: {
35
- en_us: 'Refine search',
36
- pt_br: 'Refinar busca'
37
- },
38
- close_filters: {
39
- en_us: 'Close filters',
40
- pt_br: 'Fechar filtros'
41
- },
42
- clear_filters: {
43
- en_us: 'Clear filters',
44
- pt_br: 'Limpar filtros'
45
- },
46
- relevance: {
47
- en_us: 'Most relevant',
48
- pt_br: 'Mais relevantes'
49
- },
50
- sales: {
51
- en_us: 'Best sellers',
52
- pt_br: 'Mais vendidos'
53
- },
54
- lowest_price: {
55
- en_us: 'Lowest price',
56
- pt_br: 'Menor preço'
57
- },
58
- highest_price: {
59
- en_us: 'Highest price',
60
- pt_br: 'Maior preço'
61
- },
62
- popular_products: {
63
- en_us: 'Popular products',
64
- pt_br: 'Produtos populares'
65
- },
66
- search_again: {
67
- en_us: 'Search again',
68
- pt_br: 'Buscar novamente'
69
- }
70
- }
71
-
72
- export default function (word, lang) {
73
- if (!lang) {
74
- lang = (this && this.lang) || 'en_us'
75
- }
76
- return (dictionary[word] && dictionary[word][lang]) || ''
77
- }