@abi-software/map-side-bar 2.5.3-beta.18 → 2.5.3-beta.19

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,146 +1,33 @@
1
1
  <template>
2
- <div class="history-container" v-if="searchHistory.length">
3
- <div class="saved-search-history" v-if="savedSearchHistory.length">
4
- <template v-for="(item, i) in savedSearchHistory" :key="item.id">
5
- <el-tag
6
- class="search-tag"
7
- v-if="i < 2"
8
- v-bind:key="i"
9
- @click="search(item)"
10
- size="large"
11
- >
12
- <template v-if="item.longLabel">
13
- <el-popover
14
- width="auto"
15
- trigger="hover"
16
- :teleported="false"
17
- :show-after="200"
18
- :persistent="false"
19
- popper-class="popover-dropdown"
20
- >
21
- <template #reference>
22
- {{ item.label }}
23
- </template>
24
- {{ item.longLabel }}
25
- </el-popover>
26
- </template>
27
- <template v-else>
28
- {{ item.label }}
29
- </template>
30
- </el-tag>
31
- </template>
32
- </div>
33
- <div v-else>
34
- <span class="empty-saved-search">No Saved Searches</span>
35
- </div>
36
- <el-dropdown
37
- trigger="click"
38
- :hide-on-click="false"
2
+ <div class="history-container">
3
+ <!-- <span v-if="reversedSearchHistory.length > 0" class="title"> Search History </span> -->
4
+ <template v-for="(item, i) in reversedSearchHistory">
5
+ <el-tag
6
+ class="search-tag"
7
+ v-if="i < 3"
8
+ v-bind:key="i"
9
+ @click="search(item)"
10
+ size="large"
11
+ >
12
+ {{ item.search }}
13
+ </el-tag>
14
+ </template>
15
+ <el-select
16
+ v-if="reversedSearchHistory.length > 0"
17
+ :model-value="selectValue"
18
+ class="m-2 search-select"
19
+ placeholder="Full search History"
20
+ popper-class="sidebar-search-select-popper"
21
+ @change="selectChange"
39
22
  :teleported="false"
40
- class="search-history-dropdown"
41
- popper-class="search-history-dropdown__popper"
42
23
  >
43
- <span class="el-dropdown-select">
44
- Search history
45
- <el-icon class="el-icon--right">
46
- <el-icon-arrow-down />
47
- </el-icon>
48
- </span>
49
- <template #dropdown>
50
- <el-dropdown-menu>
51
- <el-dropdown-item v-for="item in searchHistory" :key="item.id">
52
- <div>
53
- <template v-if="item.longLabel">
54
- <el-popover
55
- width="auto"
56
- trigger="hover"
57
- :teleported="false"
58
- :show-after="200"
59
- :persistent="false"
60
- popper-class="popover-dropdown"
61
- >
62
- <template #reference>
63
- <span class="dropdown-clickable-item" @click="search(item)">
64
- {{ item.label }}
65
- </span>
66
- </template>
67
- {{ item.longLabel }}
68
- </el-popover>
69
- </template>
70
- <template v-else>
71
- <span class="dropdown-clickable-item" @click="search(item)">
72
- {{ item.label }}
73
- </span>
74
- </template>
75
- </div>
76
- <div>
77
- <el-popover
78
- width="auto"
79
- trigger="hover"
80
- :teleported="false"
81
- :show-after="200"
82
- :persistent="false"
83
- popper-class="popover-dropdown"
84
- >
85
- <template #reference>
86
- <el-button circle text size="small"
87
- @click="toggleSavedSearch(item)"
88
- :disabled="savedSearchHistory.length > 1 && !item.saved"
89
- >
90
- <el-icon color="#8300BF">
91
- <template v-if="item.saved">
92
- <svg
93
- viewBox="0 0 24 24"
94
- >
95
- <path d="m12 21.35-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54z"></path>
96
- </svg>
97
- </template>
98
- <template v-else>
99
- <svg
100
- viewBox="0 0 24 24"
101
- >
102
- <path d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3m-4.4 15.55-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05"></path>
103
- </svg>
104
- </template>
105
- </el-icon>
106
- </el-button>
107
- </template>
108
- <span v-if="savedSearchHistory.length > 1 && !item.saved">
109
- Limit 2: Please remove a saved search before adding another.
110
- </span>
111
- <span v-else-if="item.saved">
112
- Remove from saved searches.
113
- </span>
114
- <span v-else>
115
- Add up to two saved searches.
116
- </span>
117
- </el-popover>
118
- <el-popover
119
- width="auto"
120
- trigger="hover"
121
- :teleported="false"
122
- :show-after="200"
123
- :persistent="false"
124
- popper-class="popover-dropdown"
125
- >
126
- <template #reference>
127
- <el-button circle text size="small"
128
- @click="removeFromSavedSearch(item)"
129
- >
130
- <el-icon color="#8300BF">
131
- <el-icon-delete />
132
- </el-icon>
133
- </el-button>
134
- </template>
135
- <span>
136
- Remove from search history.
137
- </span>
138
- </el-popover>
139
- </div>
140
- </el-dropdown-item>
141
- </el-dropdown-menu>
142
- </template>
143
- </el-dropdown>
24
+ <el-option
25
+ v-for="(item, i) in cascaderOptions"
26
+ :key="i"
27
+ :label="item.label"
28
+ :value="item.value"
29
+ />
30
+ </el-select>
144
31
  </div>
145
32
  </template>
146
33
 
@@ -148,27 +35,16 @@
148
35
  /* eslint-disable no-alert, no-console */
149
36
  import {
150
37
  ElTag as Tag,
151
- ElSelect as Select,
152
- ElDropdown,
153
- ElIcon,
38
+ ElSelect as Select
154
39
  } from 'element-plus'
155
40
 
156
41
  import EventBus from './EventBus.js'
157
42
 
158
- const MAX_SEARCH_HISTORY = 12;
159
-
160
- function generateUUID() {
161
- const arr = new Uint8Array(16);
162
- window.crypto.getRandomValues(arr);
163
-
164
- arr[6] = (arr[6] & 0x0f) | 0x40;
165
- arr[8] = (arr[8] & 0x3f) | 0x80;
166
-
167
- const hex = Array.from(arr)
168
- .map(byte => byte.toString(16).padStart(2, '0'))
169
- .join('');
170
-
171
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
43
+ // remove duplicates by stringifying the objects
44
+ const removeDuplicates = function (arrayOfAnything) {
45
+ return [...new Set(arrayOfAnything.map((e) => JSON.stringify(e)))].map((e) =>
46
+ JSON.parse(e)
47
+ )
172
48
  }
173
49
 
174
50
  export default {
@@ -180,16 +56,26 @@ export default {
180
56
  data() {
181
57
  return {
182
58
  searchHistory: [],
183
- savedSearchHistory: [],
59
+ selectValue: 'Full search history',
184
60
  }
185
61
  },
186
- mounted: function () {
187
- this.getSearchHistory()
188
- EventBus.on('search-changed', (data) => {
189
- this.setSearchHistory(data)
190
- });
191
- this.updateSearchHistory();
192
- this.savedSearchHistory = this.searchHistory.filter((item) => item.saved);
62
+ computed: {
63
+ reversedSearchHistory: function () {
64
+ return removeDuplicates(
65
+ this.searchHistory
66
+ .slice()
67
+ .reverse()
68
+ .filter((item) => item.search !== '')
69
+ )
70
+ },
71
+ cascaderOptions: function () {
72
+ return this.reversedSearchHistory.map((item) => {
73
+ return {
74
+ value: item.search,
75
+ label: item.search,
76
+ }
77
+ })
78
+ },
193
79
  },
194
80
  methods: {
195
81
  getSearchHistory() {
@@ -205,260 +91,58 @@ export default {
205
91
  localStorage.removeItem('sparc.science-sidebar-search-history')
206
92
  this.searchHistory = []
207
93
  },
208
- sortFilters(a, b) {
209
- return a.facetPropPath.localeCompare(b.facetPropPath);
210
- },
211
- // Sort by saved and updated
212
- sortSearchHistory(a, b) {
213
- if (a.saved !== b.saved) {
214
- return b.saved - a.saved;
215
- }
216
- if (a.updated !== b.updated) {
217
- return b.updated - a.updated;
218
- }
219
- return 0;
220
- },
221
- formatFilters(filterItem) {
222
- // because filters do not work correctly with facet2
223
- if (filterItem.facet2) {
224
- filterItem.facet = filterItem.facet2;
225
- delete filterItem.facet2;
226
- }
227
- return filterItem;
228
- },
229
- addSearchToHistory(filters = [], search = '') {
94
+ addSearchToHistory(filters, search) {
95
+ filters = [] // disable filters for now
230
96
  search = search.trim() // remove whitespace
231
-
232
- const isExistingItem = this.searchHistory.some((item) => {
233
- let historyFilters = item.filters;
234
- let newFilters = filters;
235
-
236
- // make all filters same format
237
- historyFilters.forEach((filter) => this.formatFilters(filter));
238
- newFilters.forEach((filter) => this.formatFilters(filter));
239
-
240
- // sort filters (to check duplicates in string format)
241
- historyFilters = historyFilters.sort(this.sortFilters);
242
- newFilters = newFilters.sort(this.sortFilters);
243
-
244
- const historyFiltersString = JSON.stringify(historyFilters);
245
- const newFiltersString = JSON.stringify(newFilters);
246
-
247
- return (
248
- item.search === search &&
249
- historyFiltersString === newFiltersString
250
- );
251
- });
252
-
253
- if (!isExistingItem) {
254
- const {label, longLabel} = this.searchHistoryItemLabel(search, filters);
255
- const newItem = {
256
- filters: filters,
257
- search: search,
258
- saved: false,
259
- label: label,
260
- longLabel: longLabel,
261
- id: generateUUID(),
262
- updated: (new Date()).getTime(),
263
- };
264
-
265
- this.searchHistory.push(newItem);
266
-
267
- this.searchHistory = this.searchHistory.sort(this.sortSearchHistory);
268
-
269
- // trim search history to 12 items
270
- this.trimSearchHistory();
271
-
272
- // Save new data
97
+ let searchHistory = JSON.parse(
98
+ localStorage.getItem('sparc.science-sidebar-search-history')
99
+ )
100
+ if (searchHistory) {
101
+ searchHistory.push({ filters: filters, search: search })
102
+ this.searchHistory = removeDuplicates(searchHistory)
273
103
  localStorage.setItem(
274
104
  'sparc.science-sidebar-search-history',
275
- JSON.stringify(this.searchHistory)
276
- );
277
- }
278
- },
279
- /**
280
- * Remove the duplicate items in search history.
281
- */
282
- removeDuplicateSearchHistory: function () {
283
- const keys = [];
284
- const duplicateItemIDs = [];
285
-
286
- this.searchHistory.forEach((item) => {
287
- const key = `${item.search}-${JSON.stringify(item.filters)}`;
288
- const existingItem = keys.find(k => k.key === key);
289
- // duplicate item
290
- if (existingItem) {
291
- // if current item is saved item
292
- // add the other item into duplicates
293
- if (item.saved) {
294
- duplicateItemIDs.push(existingItem.id);
295
- } else {
296
- duplicateItemIDs.push(item.id);
297
- }
298
- } else {
299
- keys.push({
300
- id: item.id,
301
- key: key
302
- });
303
- }
304
- });
305
-
306
- if (duplicateItemIDs.length) {
307
- this.searchHistory = this.searchHistory.filter((item) => !duplicateItemIDs.includes(item.id));
308
- }
309
- },
310
- /**
311
- * Function to trim search history to maximum items,
312
- */
313
- trimSearchHistory: function () {
314
- // since saved has max 2
315
- // remove extra from unsaved
316
- if (this.searchHistory.length > MAX_SEARCH_HISTORY) {
317
- const savedItems = this.searchHistory.filter((item) => item.saved);
318
- const unsavedItems = this.searchHistory.filter((item) => !item.saved);
319
- const extra = MAX_SEARCH_HISTORY - this.searchHistory.length;
320
-
321
- this.searchHistory = [
322
- ...savedItems,
323
- ...unsavedItems.slice(0, extra),
324
- ];
105
+ JSON.stringify(searchHistory)
106
+ )
107
+ } else {
108
+ localStorage.setItem(
109
+ 'sparc.science-sidebar-search-history',
110
+ JSON.stringify([{ filters: filters, search: search }])
111
+ )
325
112
  }
326
113
  },
327
- updateSearchHistory: function () {
328
- // Update for missing attributes
329
- this.searchHistory.forEach((item) => {
330
- if (!item.id) {
331
- item['id'] = generateUUID();
332
- }
333
-
334
- if (!item.label) {
335
- const {label, longLabel} = this.searchHistoryItemLabel(item.search, item.filters);
336
- item['label'] = label;
337
- item['longLabel'] = longLabel;
338
- }
339
-
340
- // make all filters same format
341
- item.filters.forEach((filter) =>
342
- this.formatFilters(filter)
343
- );
344
-
345
- // sort filters (to check duplicates in string format)
346
- item.filters = item.filters.sort(this.sortFilters);
347
-
348
- if (!item.saved) {
349
- item['saved'] = false;
350
- }
351
-
352
- if (!item.updated) {
353
- item['updated'] = (new Date()).getTime();
354
- }
355
- });
356
-
357
- this.searchHistory = this.searchHistory.sort(this.sortSearchHistory);
358
-
359
- // check and remove duplicates
360
- this.removeDuplicateSearchHistory();
361
-
362
- // trim search history to 12 items
363
- this.trimSearchHistory();
364
-
365
- // Save updated data
366
- localStorage.setItem(
367
- 'sparc.science-sidebar-search-history',
368
- JSON.stringify(this.searchHistory)
369
- )
370
- },
371
114
  search: function (item) {
372
115
  this.$emit('search', item)
373
116
  },
374
- searchHistoryItemLabel: function (search, filters) {
375
- let label = search ? `"${search.trim()}"` : '';
376
- let longLabel = '';
377
- let filterItems = [];
378
- let filterLabels = [];
379
-
380
- if (filters) {
381
- filterItems = filters.filter((filterItem) => filterItem.facet !== 'Show all');
382
- filterLabels = filterItems.map((item) => item.facet2 || item.facet);
383
- }
384
-
385
- if (label && filterItems.length) {
386
- longLabel += label;
387
- longLabel += `, ${filterLabels.join(', ')}`;
388
- label += ` (+${filterItems.length})`;
389
- }
390
-
391
- if (!label && filterItems.length) {
392
- label = filterItems[0].facet;
393
-
394
- if (filterItems.length > 1) {
395
- longLabel += `${filterLabels.join(', ')}`;
396
- label += ` (+${filterItems.length - 1})`;
397
- }
398
- }
399
-
400
- if (!label) {
401
- label = 'Unknown search';
402
- } else if (label.length > 15 && !longLabel) {
403
- longLabel = label;
404
- }
405
-
406
- return {label, longLabel};
407
- },
408
- toggleSavedSearch: function (item) {
409
- this.searchHistory.forEach((_item) => {
410
- if (_item.id === item.id) {
411
- _item.saved = !_item.saved;
412
- }
413
- });
414
- this.savedSearchHistory = this.searchHistory.filter((item) => item.saved);
415
- this.updateSearchHistory();
416
- },
417
- removeFromSavedSearch: function (item) {
418
- const itemIndex = this.searchHistory.findIndex((_item) => _item.id === item.id);
419
- this.searchHistory.splice(itemIndex, 1);
420
- this.savedSearchHistory = this.searchHistory.filter((item) => item.saved);
421
- this.updateSearchHistory();
117
+ selectChange: function (value) {
118
+ this.selectValue = value
119
+ this.search({ search: value })
422
120
  },
423
121
  },
122
+ mounted: function () {
123
+ this.getSearchHistory()
124
+ EventBus.on('search-changed', (data) => {
125
+ this.setSearchHistory(data)
126
+ })
127
+ },
424
128
  }
425
129
  </script>
426
130
 
427
131
  <style lang="scss" scoped>
428
132
  .history-container {
429
- display: flex;
430
- align-items: center;
431
- justify-content: space-between;
432
- padding-bottom: 6px;
433
- z-index: 2;
434
- }
435
-
436
- .empty-saved-search {
437
- font-style: italic;
438
- font-size: 14px;
439
- font-weight: 400;
440
- color: var(--el-text-color-secondary);
441
- }
442
-
443
- .saved-search-history {
444
- display: flex;
445
- align-items: center;
446
- gap: 6px;
133
+ padding-bottom: 3px;
447
134
  }
448
135
 
449
136
  .search-tag.el-tag {
450
- margin: 0;
451
- cursor: pointer !important;
137
+ margin: 0 5px 5px 0;
138
+ cursor: pointer;
139
+ max-width: 100px;
140
+ overflow: hidden;
141
+ text-overflow: ellipsis;
142
+ float: left;
452
143
  background: #f9f2fc!important;
453
144
  border-color: $app-primary-color!important;
454
145
  color:$app-primary-color!important;
455
-
456
- :deep(.el-tag__content) {
457
- max-width: 15ch;
458
- overflow: hidden;
459
- text-overflow: ellipsis;
460
- line-height: 24px;
461
- }
462
146
  }
463
147
 
464
148
  .title {
@@ -470,156 +154,22 @@ export default {
470
154
  align-items: center;
471
155
  }
472
156
 
473
- .el-dropdown {
157
+ .search-select {
158
+ float: right;
474
159
  width: 180px;
475
- position: relative;
476
- box-sizing: border-box;
477
- cursor: pointer;
478
- text-align: left;
479
- font-size: 14px;
480
- padding: 4px 12px;
481
- min-height: 32px;
482
- line-height: 24px;
483
- border-radius: var(--el-border-radius-base);
484
- background-color: var(--el-fill-color-blank);
485
- transition: var(--el-transition-duration);
486
- transform: translateZ(0);
487
- box-shadow: 0 0 0 1px var(--el-border-color) inset;
488
- }
489
-
490
- .el-dropdown-select {
491
- width: 100%;
492
- display: flex;
493
- align-items: center;
494
- justify-content: space-between;
495
- gap: 1rem;
496
-
497
- .el-icon {
498
- transform: rotate(0deg);
499
- transition: transform 0.25s linear;
500
- }
501
-
502
- &[aria-expanded="true"] {
503
- .el-icon {
504
- transform: rotate(180deg);
505
- }
506
- }
507
- }
508
-
509
- :deep(.el-dropdown-menu__item) {
510
- justify-content: space-between;
511
- gap: 0.5rem;
512
- cursor: default;
513
- position: relative;
514
-
515
- > div:first-child {
516
- max-width: 148px;
517
- text-overflow: ellipsis;
518
- overflow: hidden;
519
- }
520
-
521
- .dropdown-clickable-item {
522
- cursor: pointer;
523
-
524
- &:hover {
525
- color: $app-primary-color;
526
- }
527
- }
528
-
529
- + .el-dropdown-menu__item {
530
- &::before {
531
- content: "";
532
- display: block;
533
- width: calc(100% - 32px);
534
- border-top: 1px solid var(--el-border-color);
535
- position: absolute;
536
- top: 0;
537
- }
538
- }
539
-
540
- &:hover,
541
- &:focus,
542
- &:active {
543
- color: inherit !important;
544
- background-color: var(--el-fill-color-light) !important;
545
- }
546
-
547
- i {
548
- margin: 0;
549
- }
550
- }
551
-
552
- :deep(.search-history-dropdown__popper) {
553
- position: fixed !important;
554
160
  }
555
161
  </style>
556
162
 
557
163
  <style lang="scss">
558
- .el-popper.el-dropdown__popper {
164
+ .sidebar-search-select-popper {
559
165
  font-family: Asap;
560
166
  font-size: 14px;
561
- font-weight: 400;
167
+ font-weight: 500;
562
168
  font-stretch: normal;
563
169
  font-style: normal;
564
170
  line-height: normal;
565
171
  letter-spacing: normal;
566
172
  color: #292b66;
567
- min-width: 180px;
568
- width: fit-content;
569
-
570
- .el-button {
571
- background-color: transparent !important;
572
- transition: all .25s ease;
573
-
574
- > span {
575
- pointer-events: none;
576
- }
577
-
578
- &:hover,
579
- &:focus {
580
- background-color: transparent !important;
581
- box-shadow: none !important;
582
- border: 0 none !important;
583
- }
584
-
585
- &:not([disabled]) {
586
- &:hover,
587
- &:focus {
588
- background-color: #f3e6f9 !important;
589
- }
590
- }
591
-
592
- + .el-button {
593
- margin: 0;
594
- }
595
- }
596
-
597
- // element plus's dropdown max-height has problem
598
- .el-dropdown__list {
599
- max-height: 350px;
600
- overflow-y: auto;
601
- scrollbar-width: thin;
602
- }
603
- }
604
-
605
- .el-popover.el-popper.popover-dropdown {
606
- padding: 4px 10px;
607
- width: max-content;
608
- max-width: 240px;
609
- font-family: Asap;
610
- font-size: 12px;
611
- white-space: normal;
612
- word-break: break-word;
613
- text-align: left;
614
- color: inherit;
615
- position: fixed !important;
616
- background: #f3ecf6 !important;
617
- border: 1px solid $app-primary-color;
618
-
619
- & .el-popper__arrow::before {
620
- border: 1px solid;
621
- border-color: $app-primary-color;
622
- background: #f3ecf6;
623
- }
173
+ max-width: 200px;
624
174
  }
625
175
  </style>