@worksafevictoria/wcl7.5 1.1.0-beta.2 → 1.1.0

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.
@@ -1,59 +1,47 @@
1
1
  <template>
2
- <div :class="searchClass">
3
- <template v-if="searchType === 'google'">
4
- <div class="wcl-google">
5
- <div class="gcse-search"></div>
6
- </div>
7
- </template>
8
- <template v-else>
9
- <b-input-group>
10
- <label class="visually-hidden" for="site-search"
11
- >Search by keyword (Typed keyword automatically filters below
12
- results)</label
13
- >
14
- <b-form-input
15
- id="site-search"
16
- v-model="searchQuery"
17
- name="search"
18
- aria-label="searchbar"
19
- debounce="600"
20
- autocomplete="off"
21
- trim
22
- @update="searchType !== 'googlerest' ? onChange : () => {}"
23
- @keyup.enter="onChange"
24
- ></b-form-input>
25
- <b-input-group-append>
26
- <b-button size="sm" class="search-button" @click="onSearch"
27
- ><span class="not-extra-small-screen">Search</span>
28
- <img alt="search icon" :src="searchIcon"
29
- /></b-button>
30
- </b-input-group-append>
31
- </b-input-group>
32
- <search-listing
33
- v-if="loadSearchList && (searchResults || isLoading)"
34
- :class="{
35
- [`wcl-search__typeahead`]: isTypeahead,
36
- [`wcl-search__modal`]: isTypeahead
37
- }"
38
- :is-loading="isLoading"
39
- :is-typeahead="isTypeahead"
40
- :num-found="searchResults && searchResults.numFound"
41
- :suggestion="searchResults && searchResults.suggestion"
42
- :query="searchResults && searchResults.query"
43
- :results="searchResults ? searchResults.results : []"
44
- :offset="searchResults && searchResults.offset"
45
- :page-limit="pageLimit"
46
- :content-parser="contentParser"
47
- :is-card-title-selectable="searchType === 'googlerest' ? true : false"
48
- @selected="$emit('selected')"
49
- @pageChanged="pageChanged"
50
- />
51
- </template>
2
+ <div class="wcl-search">
3
+ <b-input-group>
4
+ <label class="visually-hidden" for="site-search"
5
+ >Search by keyword (Typed keyword automatically filters below
6
+ results)</label
7
+ >
8
+ <b-form-input
9
+ id="site-search"
10
+ v-model="searchQuery"
11
+ aria-label="searchbar"
12
+ debounce="600"
13
+ autocomplete="off"
14
+ trim
15
+ @update="onChange"
16
+ ></b-form-input>
17
+ <b-input-group-append>
18
+ <b-button size="sm" @click="onSearch"
19
+ ><span class="not-extra-small-screen">Search</span>
20
+ <img alt="search icon" :src="searchIcon"
21
+ /></b-button>
22
+ </b-input-group-append>
23
+ </b-input-group>
24
+ <search-listing
25
+ v-if="searchResults || isLoading"
26
+ :class="{
27
+ [`wcl-search__typeahead`]: isTypeahead,
28
+ [`wcl-search__modal`]: isTypeahead
29
+ }"
30
+ :is-loading="isLoading"
31
+ :is-typeahead="isTypeahead"
32
+ :num-found="searchResults && searchResults.numFound"
33
+ :query="searchResults && searchResults.query"
34
+ :results="searchResults ? searchResults.results : []"
35
+ :offset="searchResults && searchResults.offset"
36
+ :page-limit="pageLimit"
37
+ :content-parser="contentParser"
38
+ @selected="$emit('selected')"
39
+ @pageChanged="pageChanged"
40
+ />
52
41
  </div>
53
42
  </template>
54
43
 
55
44
  <script>
56
- import axios from 'axios'
57
45
  import searchIcon from '../../../assets/icons/search.svg?url'
58
46
  import SearchListing from './SearchListing/index.vue'
59
47
  import { BButton, BInputGroup, BFormInput, BInputGroupAppend } from 'bootstrap-vue-next'
@@ -76,14 +64,6 @@ export default {
76
64
  initialSearchQuery: {
77
65
  type: String,
78
66
  default: ''
79
- },
80
- googleSearchFlag: {
81
- type: String,
82
- default: 'solar'
83
- },
84
- visibleSearchList: {
85
- type: Boolean,
86
- default: true
87
67
  }
88
68
  },
89
69
  data() {
@@ -92,177 +72,28 @@ export default {
92
72
  searchQuery: '',
93
73
  searchResults: null,
94
74
  isLoading: false,
95
- field_language: '8671',
96
- searchType: this.googleSearchFlag,
97
- googleSearchScript: false,
98
- loadSearchList: this.visibleSearchList
99
- }
100
- },
101
- computed: {
102
- searchClass() {
103
- return {
104
- 'wcl-search': true,
105
- 'wcl-search__google': this.searchType !== 'solar'
106
- }
75
+ field_language: '8671'
107
76
  }
108
77
  },
109
78
  mounted() {
110
- if (this.searchType === 'google') {
111
- this.setupGoogleStyle()
112
- } else {
113
- if (this.initialSearchQuery) {
114
- this.searchQuery = this.initialSearchQuery
115
- this.onSearch()
116
- }
117
- if (this.isTypeahead && window) {
118
- window.document.addEventListener('click', this.closeSearchResults)
119
- }
79
+ if (this.initialSearchQuery) {
80
+ this.searchQuery = this.initialSearchQuery
81
+ this.onSearch()
82
+ }
83
+ if (this.isTypeahead && window) {
84
+ window.document.addEventListener('click', this.closeSearchResults)
120
85
  }
121
86
  },
122
87
  beforeDestroy() {
123
- if (this.isTypeahead && window && document) {
88
+ if (this.isTypeahead && window) {
124
89
  window.document.removeEventListener('click', this.closeSearchResults)
125
90
  }
126
91
  },
127
92
  methods: {
128
- async fetchSearchResults(apiKey, searchEngineId, query, start) {
129
- try {
130
- const response = await (this?.$axios || axios).get(
131
- `https://www.googleapis.com/customsearch/v1`,
132
- {
133
- params: {
134
- key: apiKey,
135
- cx: searchEngineId,
136
- q: query,
137
- start: start
138
- }
139
- }
140
- )
141
- return response
142
- } catch (error) {
143
- console.error('Error fetching search results:', error)
144
- return []
145
- }
146
- },
147
- async onGoogleSearch(pageNr = 1, searchQuery) {
148
- this.$emit('loading', true)
149
- this.isLoading = true
150
-
151
- const apiKey = 'AIzaSyD76GAmQQ6DuxKWf-aLXPZ9pwdz4nOvs2c'
152
- const searchEngineId = '53b1506aa03c64160'
153
-
154
- const start = (pageNr - 1) * this.pageLimit
155
- let response = await this.fetchSearchResults(
156
- apiKey,
157
- searchEngineId,
158
- searchQuery,
159
- start
160
- )
161
- let items = []
162
- let suggest = response?.data?.spelling?.correctedQuery || ''
163
- if (response?.data?.spelling?.correctedQuery) {
164
- response = await this.fetchSearchResults(
165
- apiKey,
166
- searchEngineId,
167
- response?.data?.spelling?.correctedQuery,
168
- start
169
- )
170
- items = response?.data?.items
171
- } else if (response?.data?.items) {
172
- items = response?.data?.items
173
- }
174
- if (items.length > 0) {
175
- const totalResults = response?.data?.searchInformation?.totalResults
176
- // Loop through each item in the items array
177
- const modifiedResults = items.map((item) => {
178
- // Update the title using the handleSearchResultLinkTitle function
179
- const modifiedTitle = this.handleSearchResultLinkTitle(item.title)
180
-
181
- // Return the modified item with the updated title
182
- return {
183
- ...item,
184
- title: modifiedTitle
185
- }
186
- })
187
-
188
- this.searchResults = {
189
- offset: Number(pageNr === 1 ? pageNr - 1 : pageNr),
190
- numFound: Number(totalResults),
191
- query: this.searchQuery,
192
- results: modifiedResults,
193
- suggestion: suggest
194
- }
195
- } else {
196
- this.searchResults = {
197
- offset: 0,
198
- numFound: 0,
199
- query: this.searchQuery ?? '',
200
- results: [],
201
- suggestion: suggest
202
- }
203
- }
204
- this.$emit('loading', false)
205
- this.isLoading = false
206
- this.$emit('results', this.searchResults)
207
-
208
- // wait for the page title to be updated and then fire the search event
209
- setTimeout(() => {
210
- const attrs = {
211
- pageTitle: document.title,
212
- pageURL: this.$route?.fullPath,
213
- location:
214
- this.$route?.path === '/'
215
- ? 'Homepage'
216
- : this.$route?.path === '/search'
217
- ? 'Search Page'
218
- : this.$route?.path,
219
- label: this.searchQuery,
220
- results: this.searchResults.numFound
221
- }
222
- if (this.$gtm) {
223
- this.$gtm.push({ event: 'custom.search.site.submit', ...attrs })
224
- }
225
- }, 300)
226
- },
227
- pageChanged(newPageNumber) {
228
- if (this.searchType === 'solar') {
229
- // Reset search results before fetching new results
230
- this.resetSearchResults()
231
- this.performSearch(newPageNumber, this.searchQuery, this.pageLimit)
232
- } else {
233
- // Fetch new search results with the updated page number
234
- this.onGoogleSearch(newPageNumber, this.searchQuery)
235
- }
236
- },
237
- onSearch(e) {
238
- const { path } = this.$route || {}
239
-
240
- // Home page
241
- if (
242
- (e?.type === 'click' || e?.key === 'Enter') &&
243
- this.searchQuery &&
244
- this.searchQuery.length > 2 &&
245
- path === '/'
246
- ) {
247
- // Search page
248
- const searchQuery = encodeURIComponent(this.searchQuery)
249
- const origin = window.location.origin
250
- const hash = window.location.hash
251
- const pathname = 'search'
252
- const URL = `${origin}/${pathname}${hash}?q=${searchQuery}`
253
-
254
- // Uncomment below commented code when goes live
255
- window.location.assign(URL)
256
- } else {
257
- this.resetSearchResults()
258
- this.$emit('query', this.searchQuery)
259
-
260
- if (this.searchType === 'solar') {
261
- this.performSearch(1, this.searchQuery, this.pageLimit)
262
- } else {
263
- this.onGoogleSearch(1, this.searchQuery)
264
- }
265
- }
93
+ onSearch() {
94
+ this.resetSearchResults()
95
+ this.$emit('query', this.searchQuery)
96
+ this.performSearch(1, this.searchQuery, this.pageLimit)
266
97
  },
267
98
  resetSearchResults() {
268
99
  this.searchResults = null
@@ -278,11 +109,15 @@ export default {
278
109
  this.$emit('query', null)
279
110
  }
280
111
  },
281
- onChange(e) {
112
+ onChange() {
282
113
  if (this.searchQuery && this.searchQuery.length > 2) {
283
- this.onSearch(e)
114
+ this.onSearch()
284
115
  }
285
116
  },
117
+ pageChanged(newPageNumber) {
118
+ this.resetSearchResults()
119
+ this.performSearch(newPageNumber, this.searchQuery, this.pageLimit)
120
+ },
286
121
  performSearch(pageNr = 1, searchQuery, pageLimit) {
287
122
  if (searchQuery) {
288
123
  this.$emit('loading', true)
@@ -298,16 +133,14 @@ export default {
298
133
  offset: Number(res.offset),
299
134
  numFound: Number(res.numFound),
300
135
  query: searchQuery,
301
- results: res.results,
302
- suggestion: null
136
+ results: res.results
303
137
  }
304
138
  } else {
305
139
  this.searchResults = {
306
140
  offset: 0,
307
141
  numFound: 0,
308
142
  query: this.searchQuery ?? '',
309
- results: [],
310
- suggestion: null
143
+ results: []
311
144
  }
312
145
  }
313
146
  this.$emit('loading', false)
@@ -333,59 +166,6 @@ export default {
333
166
  }, 300)
334
167
  })
335
168
  }
336
- },
337
-
338
- // Method to customize google search style
339
- setupGoogleStyle() {
340
- if (this.googleSearchScript === false) {
341
- const script = document.createElement('script')
342
- script.async = true
343
- script.src = process.env.GOOGLE__URL
344
- document.head.appendChild(script)
345
- this.googleSearchScript = true
346
-
347
- // Create a new style element
348
- const style = document.createElement('style')
349
- style.id = 'searchStyle' // Assign an ID to the style element
350
- // The CSS we are going to inject
351
- const cssVar = 'table.gssb_c {display: none !important;}'
352
- // Inject the style element into the head
353
- document.head.appendChild(style)
354
- // Set the text content of the style element to the CSS text
355
- style.textContent = cssVar
356
- }
357
- },
358
-
359
- // function to handle search result link titles
360
- handleSearchResultLinkTitle(title) {
361
- // Split the title by the '|' character
362
- const titleParts = title.split('|')
363
-
364
- // Remove any leading or trailing whitespace from each part
365
- const cleanedTitleParts = titleParts.map((part) => part.trim())
366
-
367
- // Join the cleaned title parts back together without the text after the '|' character
368
- const modifiedTitle = cleanedTitleParts[0] // Take only the first part before '|'
369
-
370
- return modifiedTitle
371
- },
372
-
373
- handleKeyUp(event) {
374
- if (event.key === 'Enter' || event.type === 'click') {
375
- let keyword = event.key
376
- ? event.target.value
377
- : document.querySelector('input[name="search"]').value
378
-
379
- // Check if the URL does not contain "/search"
380
- if (keyword && !window.location.href.includes('/search')) {
381
- let origin = window.location.origin
382
- let hash = window.location.hash
383
- let pathname = 'search'
384
- let URL = origin + '/' + pathname + hash
385
- }
386
-
387
- this.setupPaginationEvent()
388
- }
389
169
  }
390
170
  }
391
171
  }
@@ -454,289 +234,5 @@ export default {
454
234
  display: none;
455
235
  }
456
236
  }
457
- // Google Search styling
458
- &.wcl-search__google {
459
- :deep(form.gsc-search-box) {
460
- position: relative;
461
- display: -ms-flexbox;
462
- display: flex;
463
- -ms-flex-wrap: wrap;
464
- flex-wrap: wrap;
465
- -ms-flex-align: stretch;
466
- align-items: stretch;
467
- width: 100%;
468
- }
469
-
470
- :deep(.gsib_a) {
471
- padding: 0 !important;
472
- height: 56px;
473
- }
474
-
475
- :deep(.gsib_b) {
476
- position: absolute;
477
- right: 5px;
478
- top: 15px;
479
- }
480
-
481
- :deep(.gcsc-more-maybe-branding-root) {
482
- display: none;
483
- }
484
-
485
- :deep(table.gsc-input) {
486
- position: relative;
487
- }
488
-
489
- :deep(td.gsc-input) {
490
- border: none;
491
- padding: 0;
492
- width: 100%;
493
- }
494
-
495
- :deep(.gsc-input-box) {
496
- border: none;
497
- }
498
-
499
- :deep(input.gsc-input) {
500
- border-radius: 8px 0px 0px 8px;
501
- border: 1px solid $gray !important;
502
- border-right: 0 !important;
503
- background: none !important;
504
- color: #495057;
505
- height: 56px !important;
506
- position: relative;
507
- -ms-flex: 1 1 auto;
508
- flex: 1 1 auto;
509
- padding: 0.375rem 0.75rem !important;
510
-
511
- @media screen and (max-width: 320px) {
512
- width: 220px;
513
- }
514
-
515
- &:focus {
516
- box-shadow: none;
517
- }
518
- }
519
-
520
- :deep(.gsc-search-button) {
521
- display: -ms-flexbox;
522
- display: flex;
523
- margin-left: 0px;
524
- height: 56px;
525
- margin-top: 0px;
526
- }
527
-
528
- :deep(button.gsc-search-button) {
529
- background: $orange;
530
- border: none;
531
- border-radius: 0px 8px 8px 0px;
532
- color: $black;
533
- display: flex;
534
- align-items: center;
535
- height: 56px !important;
536
- font-size: 16px;
537
- font-weight: 700;
538
- padding-right: 32px;
539
- padding-left: 32px;
540
-
541
- &:before {
542
- content: 'Search';
543
- }
544
-
545
- @media screen and (max-width: 767px) {
546
- margin-top: 6px;
547
- }
548
-
549
- @media screen and (max-width: 320px) {
550
- padding-right: 16px;
551
- padding-left: 16px;
552
- }
553
-
554
- svg {
555
- fill: black;
556
- height: 18px;
557
- width: 18px;
558
- margin-left: 10px;
559
- }
560
-
561
- :focus {
562
- box-shadow: 0px;
563
- }
564
- }
565
-
566
- :deep(.gsst_a .gscb_a) {
567
- color: #191919;
568
- }
569
-
570
- :deep(.gsc-result-info) {
571
- color: #191919;
572
- font-size: 16px;
573
- font-weight: 400;
574
- }
575
-
576
- :deep(.gsc-above-wrapper-area) {
577
- padding: 20px 0;
578
- border-bottom: none;
579
- }
580
-
581
- /* search list start */
582
- :deep(.gsc-url-top) {
583
- display: none;
584
- }
585
-
586
- :deep(.gsc-table-result) {
587
- line-height: 1.6;
588
- padding: 0 5px;
589
- font-size: 16px;
590
- font-weight: 400;
591
- width: 80%;
592
-
593
- b {
594
- color: #191919;
595
- font-size: 16px;
596
- font-weight: normal;
597
- }
598
- }
599
-
600
- :deep(.gsc-resultsRoot.gsc-tabData) {
601
- width: 100%;
602
- margin-left: auto;
603
- margin-right: auto;
604
- padding-left: 15px;
605
- padding-right: 15px;
606
-
607
- &:hover {
608
- border: none;
609
- }
610
- }
611
-
612
- :deep(.gs-bidi-start-align.gs-snippet) {
613
- color: #191919 !important;
614
- line-height: 24px;
615
- }
616
-
617
- :deep(.gsc-thumbnail-inside) {
618
- position: relative;
619
- padding: 0;
620
-
621
- &::after {
622
- content: ' ';
623
- position: absolute;
624
- height: 16px;
625
- width: 11px;
626
- top: 5px;
627
- right: 16px;
628
- background-repeat: no-repeat;
629
- background-image: url(./../../../assets/icons/chev-right.svg);
630
- background-size: 100%;
631
- }
632
-
633
- div.gs-title {
634
- width: 90%;
635
- margin-bottom: 12px;
636
- overflow: visible;
637
- }
638
-
639
- a.gs-title {
640
- color: #191919 !important;
641
- font-weight: 700;
642
- line-height: 24px;
643
- font-size: 20px;
644
- border: 3px solid transparent;
645
- padding-left: 5px;
646
- padding-right: 5px;
647
- text-decoration: underline;
648
-
649
- &:hover {
650
- border: 3px solid #da47ff;
651
- color: #006bff !important;
652
-
653
- b {
654
- color: #006bff !important;
655
- }
656
- }
657
-
658
- b {
659
- color: #191919 !important;
660
- font-size: 20px;
661
- }
662
- }
663
- }
664
-
665
- :deep(.gsc-orderby-label) {
666
- font-size: 16px;
667
- font-weight: 700;
668
- color: #191919;
669
- }
670
-
671
- :deep(.gsc-selected-option-container) {
672
- background-color: white;
673
- border-radius: 10px;
674
- margin-top: 0px;
675
- padding-top: 6px;
676
- margin-right: 0;
677
- margin-left: 4px;
678
- padding-left: 20px;
679
- padding-bottom: 6px;
680
- height: 40px;
681
-
682
- .gsc-selected-option {
683
- font-size: 16px;
684
- font-weight: 400;
685
- line-height: 24px;
686
- margin-right: 20px;
687
- }
688
- }
689
-
690
- :deep(.gsc-control-cse .gsc-option-selector) {
691
- margin-top: 0;
692
- margin-right: 10px;
693
- }
694
-
695
- :deep(.gsc-expansionArea > .gsc-webResult.gsc-result) {
696
- border: 0;
697
- flex: 0 0 100%;
698
- max-width: 100%;
699
- padding: 0;
700
-
701
- &:first-child {
702
- border-top: 1px solid #bababa;
703
- }
704
-
705
- > div {
706
- border-bottom: 1px solid #bababa;
707
- padding: 32px 0;
708
- }
709
- }
710
-
711
- :deep(.gsc-results .gsc-cursor-box .gsc-cursor-current-page) {
712
- background-color: lightgrey;
713
- }
714
-
715
- :deep(.gsc-results .gsc-cursor-box .gsc-cursor-page) {
716
- border: 1px solid grey;
717
- color: #333333;
718
- padding: 10px 12px;
719
- border-radius: 5px;
720
- font-size: 16px;
721
- font-weight: 400;
722
- }
723
-
724
- :deep(.gsc-results .gsc-cursor-box) {
725
- margin-top: 50px;
726
- }
727
-
728
- /* search list end */
729
- @include mq('xs') {
730
- .not-extra-small-screen {
731
- display: none;
732
- }
733
- }
734
- }
735
- }
736
-
737
- @media screen and (max-width: 767px) {
738
- :deep(.gssb_c) {
739
- width: 85% !important;
740
- }
741
237
  }
742
238
  </style>