@abi-software/map-side-bar 1.1.3 → 1.1.5

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,434 +1,443 @@
1
- <template>
2
- <div class="filters">
3
- <SvgSpriteColor />
4
- <transition name="el-zoom-in-top">
5
- <span v-show="showFilters" class="search-filters transition-box">
6
- <custom-cascader
7
- class="cascader"
8
- ref="cascader"
9
- v-model="cascadeSelected"
10
- placeholder
11
- :collapse-tags="true"
12
- :options="options"
13
- :props="props"
14
- @change="cascadeEvent($event)"
15
- @expand-change="cascadeExpandChange"
16
- :show-all-levels="false"
17
- :append-to-body="false"
18
- @tags-changed="tagsChangedCallback"
19
- ></custom-cascader>
20
- <div v-if="showFiltersText" class="filter-default-value">
21
- <svg-icon icon="noun-filter" class="filter-icon-inside" />Apply Filters
22
- </div>
23
- </span>
24
- </transition>
25
-
26
- <el-select
27
- class="number-shown-select"
28
- v-model="numberShown"
29
- placeholder="10"
30
- @change="numberShownChanged($event)"
31
- >
32
- <el-option v-for="item in numberDatasetsShown" :key="item" :label="item" :value="item"></el-option>
33
- </el-select>
34
- <span class="dataset-results-feedback">{{this.numberOfResultsText}}</span>
35
- </div>
36
- </template>
37
-
38
-
39
- <script>
40
- /* eslint-disable no-alert, no-console */
41
- import Vue from "vue";
42
- import { Option, Select } from "element-ui";
43
- import CustomCascader from "./Cascader";
44
- import lang from "element-ui/lib/locale/lang/en";
45
- import locale from "element-ui/lib/locale";
46
- import speciesMap from "./species-map";
47
- import { SvgIcon, SvgSpriteColor } from "@abi-software/svg-sprite";
48
-
49
- Vue.component("svg-icon", SvgIcon);
50
-
51
- locale.use(lang);
52
- Vue.use(Option);
53
- Vue.use(Select);
54
-
55
- const capitalise = function(txt) {
56
- return txt.charAt(0).toUpperCase() + txt.slice(1);
57
- };
58
-
59
- const convertReadableLabel = function(original) {
60
- const name = original.toLowerCase();
61
- if (speciesMap[name]){
62
- return capitalise(speciesMap[name]);
63
- } else {
64
- return capitalise(name);
65
- }
66
- }
67
-
68
- export default {
69
- name: "SearchFilters",
70
- components: {
71
- CustomCascader,
72
- SvgSpriteColor
73
- },
74
- props: {
75
- /**
76
- * Object containing information for
77
- * the required viewing.
78
- */
79
- entry: Object,
80
- apiLocation: {
81
- type: String,
82
- default: ""
83
- }
84
- },
85
- data: function() {
86
- return {
87
- cascaderIsReady: false,
88
- previousShowAllChecked: {
89
- species: false,
90
- gender: false,
91
- organ: false,
92
- datasets: false
93
- },
94
- showFilters: true,
95
- showFiltersText: true,
96
- cascadeSelected: [],
97
- numberShown: 10,
98
- filters: [],
99
- facets: ["Species", "Gender", "Organ", "Datasets"],
100
- numberDatasetsShown: ["10", "20", "50"],
101
- props: { multiple: true },
102
- options: [
103
- {
104
- value: "Species",
105
- label: "Species",
106
- children: [{}]
107
- }
108
- ]
109
- };
110
- },
111
- computed: {
112
- numberOfResultsText: function() {
113
- return `${this.entry.numberOfHits} results | Showing`;
114
- }
115
- },
116
- methods: {
117
- createCascaderItemValue: function(term, facet) {
118
- if (facet) return term + "/" + facet;
119
- else return term;
120
- },
121
- populateCascader: function() {
122
- return new Promise(resolve => {
123
- this.options = [];
124
- let promiseList = [];
125
- for (let i in this.facets) {
126
- this.options.push({
127
- value: this.createCascaderItemValue(
128
- this.facets[i].toLowerCase(),
129
- undefined
130
- ),
131
- label: convertReadableLabel(this.facets[i]),
132
- children: []
133
- });
134
- promiseList.push(
135
- this.getFacet(this.facets[i]).then(labels => {
136
- // Populate children of each facet with scicrunch's facets
137
- for (let j in labels) {
138
- this.options[i].children.push({
139
- value: this.createCascaderItemValue(
140
- this.facets[i].toLowerCase(),
141
- labels[j].toLowerCase()),
142
- label: convertReadableLabel(labels[j]) // Capitalisation is to match design specs
143
- });
144
- }
145
- })
146
- );
147
- }
148
- Promise.allSettled(promiseList).then(() => {
149
- resolve();
150
- });
151
- });
152
- },
153
- getFacet: function(facetLabel) {
154
- if (facetLabel === "Datasets") {
155
- // The datasets facet doesn't exist on SciCrunch yet, so manually set it
156
- // for now.
157
- return new Promise(resolve => {
158
- resolve([...new Set(["Show all", "Scaffolds", "Simulations"])]);
159
- });
160
- }
161
- return new Promise(resolve => {
162
- let facets = ["Show all"]; // Set 'Show all' as our first label
163
- let facet = facetLabel.toLowerCase();
164
- this.callSciCrunch(this.apiLocation, this.facetEndpoint, facet).then(
165
- facet_terms => {
166
- facet_terms.forEach(element => {
167
- facets.push(element["key"]); // add facets that scicrunch includes
168
- });
169
- resolve([...new Set(facets)]); // return no duplicates
170
- }
171
- );
172
- });
173
- },
174
- // switchTermToRequest is used to remove the count for sending a request to scicrunch
175
- switchTermToRequest: function(term) {
176
- return term.split(" ")[0].toLowerCase();
177
- },
178
- tagsChangedCallback: function(presentTags) {
179
- if (presentTags.length > 0) {
180
- this.showFiltersText = false;
181
- } else {
182
- this.showFiltersText = true;
183
- }
184
- },
185
- cascadeEvent: function(event) {
186
- let filters = [];
187
- if (event) {
188
- // Check for show all in selected cascade options
189
- event = this.showAllEventModifier(event);
190
- for (let i in event) {
191
- if (event[i] !== undefined) {
192
- let value = event[i][1];
193
- let data = value.split("/");
194
- let output = {};
195
- output.term = this.switchTermToRequest(data[0]);
196
- output.facet = data[1];
197
- filters.push(output);
198
- }
199
- }
200
- }
201
- this.$emit("filterResults", filters);
202
- this.setCascader(filters); //update our cascader v-model if we modified the event
203
- this.makeCascadeLabelsClickable();
204
- },
205
- showAllEventModifier: function(event) {
206
- // check if show all is in the cascader checked option list
207
- let hasShowAll = event
208
- .map(ev => (ev ? ev[1].toLowerCase().includes("show all") : false))
209
- .includes(true);
210
- // remove all selected options below the show all if checked
211
- if (hasShowAll) {
212
- let modifiedEvent = [];
213
- let facetMaps = {};
214
- //catagorised different facet items
215
- for (const i in event) {
216
- if (facetMaps[event[i][0]] === undefined) facetMaps[event[i][0]] = [];
217
- facetMaps[event[i][0]].push(event[i]);
218
- }
219
- // go through each facets
220
- for (const facet in facetMaps) {
221
- let showAll = undefined;
222
- // Find the show all item if any
223
- for (let i = facetMaps[facet].length - 1; i >= 0; i--) {
224
- if (facetMaps[facet][i][1].toLowerCase().includes("show all")) {
225
- //seperate the showAll item and the rest
226
- showAll = facetMaps[facet].splice(i, 1)[0];
227
- break;
228
- }
229
- }
230
- if (showAll) {
231
- if (this.previousShowAllChecked[facet]) {
232
- //Unset the show all if it was present previously
233
- //and there are other items
234
- if (facetMaps[facet].length > 0)
235
- modifiedEvent.push(...facetMaps[facet]);
236
- else modifiedEvent.push(showAll);
237
- } else {
238
- //showAll is turned on
239
- modifiedEvent.push(showAll);
240
- }
241
- } else {
242
- modifiedEvent.push(...facetMaps[facet]);
243
- }
244
- }
245
- //Make sure the expanded item are sorted first.
246
- return modifiedEvent.sort((a, b) => {
247
- if (this.__expandItem__) {
248
- if (a[0] == this.__expandItem__) {
249
- if (b[0] == this.__expandItem__) {
250
- return 0;
251
- } else {
252
- return -1;
253
- }
254
- } else if (b[0] == this.__expandItem__) {
255
- if (a[0] == this.__expandItem__) {
256
- return 0;
257
- } else {
258
- return 1;
259
- }
260
- } else {
261
- return 0;
262
- }
263
- } else
264
- return 0;
265
- });
266
- }
267
- return event;
268
- },
269
- cascadeExpandChange: function(event) {
270
- //work around as the expand item may change on modifying the cascade props
271
- this.__expandItem__ = event;
272
- this.makeCascadeLabelsClickable();
273
- },
274
- numberShownChanged: function(event) {
275
- this.$emit("numberPerPage", parseInt(event));
276
- },
277
- callSciCrunch: function(apiLocation, endpoint, term) {
278
- return new Promise(resolve => {
279
- fetch(apiLocation + endpoint + term)
280
- .then(response => response.json())
281
- .then(data => {
282
- resolve(data);
283
- });
284
- });
285
- },
286
- updatePreviousShowAllChecked: function(options) {
287
- //Reset the states
288
- for (const facet in this.previousShowAllChecked) {
289
- this.previousShowAllChecked[facet] = false;
290
- }
291
- options.forEach(element => {
292
- if (element[1].toLowerCase().includes("show all"))
293
- this.previousShowAllChecked[element[0]] = true;
294
- });
295
- },
296
- setCascader: function(filterFacets) {
297
- //Do not set the value unless it is ready
298
- if (this.cascaderIsReady) {
299
- this.cascadeSelected = [];
300
- filterFacets.forEach(e => {
301
- this.cascadeSelected.push([
302
- e.term.toLowerCase(),
303
- this.createCascaderItemValue(
304
- e.term.toLowerCase(),
305
- e.facet.toLowerCase()
306
- )
307
- ]);
308
- });
309
- this.updatePreviousShowAllChecked(this.cascadeSelected);
310
- }
311
- },
312
- makeCascadeLabelsClickable: function() {
313
- // Next tick allows the cascader menu to change
314
- this.$nextTick(() => {
315
- this.$refs.cascader.$el
316
- .querySelectorAll(".el-cascader-node__label")
317
- .forEach(el => {
318
- // step through each cascade label
319
- el.onclick = function() {
320
- const checkbox = this.previousElementSibling;
321
- if (checkbox) {
322
- if (!checkbox.parentElement.attributes["aria-owns"]) {
323
- // check if we are at the lowest level of cascader
324
- this.previousElementSibling.click(); // Click the checkbox
325
- }
326
- }
327
- };
328
- });
329
- });
330
- }
331
- },
332
- created: function() {
333
- //Create non-reactive local variables
334
- this.facetEndpoint = "get-facets/";
335
- },
336
- mounted: function() {
337
- this.populateCascader().then(() => {
338
- this.cascaderIsReady = true;
339
- this.setCascader(this.entry.filterFacets);
340
- this.makeCascadeLabelsClickable();
341
- });
342
- }
343
- };
344
- </script>
345
-
346
- <!-- Add "scoped" attribute to limit CSS to this component only -->
347
- <style scoped>
348
- .filter-default-value {
349
- pointer-events: none;
350
- position: absolute;
351
- top: 0;
352
- left: 0;
353
- padding-top: 10px;
354
- padding-left: 16px;
355
- }
356
-
357
- .filter-icon-inside {
358
- width: 12px !important;
359
- height: 12px !important;
360
- color: #292b66;
361
- transform: scale(2) !important;
362
- margin-bottom: 0px !important;
363
- }
364
-
365
- .cascader {
366
- font-family: Asap;
367
- font-size: 14px;
368
- font-weight: 500;
369
- font-stretch: normal;
370
- font-style: normal;
371
- line-height: normal;
372
- letter-spacing: normal;
373
- color: #292b66;
374
- text-align: center;
375
- padding-bottom: 6px;
376
- }
377
-
378
- .cascader >>> .el-scrollbar__wrap {
379
- overflow-x: hidden;
380
- margin-bottom: 2px !important;
381
- }
382
-
383
- .cascader >>> li[aria-owns*="cascader"] > .el-checkbox {
384
- display: none;
385
- }
386
-
387
- .dataset-results-feedback {
388
- float: right;
389
- text-align: right;
390
- color: rgb(48, 49, 51);
391
- font-family: Asap;
392
- font-size: 18px;
393
- font-weight: 500;
394
- padding-top: 8px;
395
- }
396
-
397
- .search-filters {
398
- position: relative;
399
- float: left;
400
- padding-right: 15px;
401
- padding-bottom: 12px;
402
- }
403
-
404
- .number-shown-select {
405
- float: right;
406
- }
407
-
408
- .number-shown-select >>> .el-input__inner {
409
- width: 68px;
410
- height: 40px;
411
- color: rgb(48, 49, 51);
412
- }
413
-
414
- .search-filters >>> .el-cascader-node.is-active {
415
- color: #8300bf;
416
- }
417
-
418
- .search-filters >>> .el-cascader-node.in-active-path {
419
- color: #8300bf;
420
- }
421
-
422
- .search-filters >>> .el-checkbox__input.is-checked > .el-checkbox__inner {
423
- background-color: #8300bf;
424
- border-color: #8300bf;
425
- }
426
-
427
- .cascader >>> .el-cascader-menu:nth-child(2) .el-cascader-node:first-child {
428
- border-bottom: 1px solid #e4e7ed;
429
- }
430
-
431
- .cascader >>> .el-cascader-node__label {
432
- text-align: left;
433
- }
434
- </style>
1
+ <template>
2
+ <div class="filters">
3
+ <SvgSpriteColor />
4
+ <transition name="el-zoom-in-top">
5
+ <span v-show="showFilters" class="search-filters transition-box">
6
+ <custom-cascader
7
+ class="cascader"
8
+ ref="cascader"
9
+ v-model="cascadeSelected"
10
+ placeholder
11
+ :collapse-tags="true"
12
+ :options="options"
13
+ :props="props"
14
+ @change="cascadeEvent($event)"
15
+ @expand-change="cascadeExpandChange"
16
+ :show-all-levels="false"
17
+ :append-to-body="false"
18
+ @tags-changed="tagsChangedCallback"
19
+ ></custom-cascader>
20
+ <div v-if="showFiltersText" class="filter-default-value">
21
+ <svg-icon icon="noun-filter" class="filter-icon-inside" />Apply
22
+ Filters
23
+ </div>
24
+ </span>
25
+ </transition>
26
+
27
+ <el-select
28
+ class="number-shown-select"
29
+ v-model="numberShown"
30
+ placeholder="10"
31
+ @change="numberShownChanged($event)"
32
+ >
33
+ <el-option
34
+ v-for="item in numberDatasetsShown"
35
+ :key="item"
36
+ :label="item"
37
+ :value="item"
38
+ ></el-option>
39
+ </el-select>
40
+ <span class="dataset-results-feedback">{{ this.numberOfResultsText }}</span>
41
+ </div>
42
+ </template>
43
+
44
+
45
+ <script>
46
+ /* eslint-disable no-alert, no-console */
47
+ import Vue from "vue";
48
+ import { Option, Select } from "element-ui";
49
+ import CustomCascader from "./Cascader";
50
+ import lang from "element-ui/lib/locale/lang/en";
51
+ import locale from "element-ui/lib/locale";
52
+ import speciesMap from "./species-map";
53
+ import { SvgIcon, SvgSpriteColor } from "@abi-software/svg-sprite";
54
+
55
+ import {AlgoliaClient} from "../algolia/algolia.js";
56
+ import { facetPropPathMapping } from "../algolia/utils.js";
57
+
58
+ Vue.component("svg-icon", SvgIcon);
59
+
60
+ locale.use(lang);
61
+ Vue.use(Option);
62
+ Vue.use(Select);
63
+
64
+ const capitalise = function (txt) {
65
+ return txt.charAt(0).toUpperCase() + txt.slice(1);
66
+ };
67
+
68
+ const convertReadableLabel = function (original) {
69
+ const name = original.toLowerCase();
70
+ if (speciesMap[name]) {
71
+ return capitalise(speciesMap[name]);
72
+ } else {
73
+ return capitalise(name);
74
+ }
75
+ };
76
+
77
+ export default {
78
+ name: "SearchFilters",
79
+ components: {
80
+ CustomCascader,
81
+ SvgSpriteColor,
82
+ },
83
+ props: {
84
+ /**
85
+ * Object containing information for
86
+ * the required viewing.
87
+ */
88
+ entry: Object,
89
+ envVars: {
90
+ type: Object,
91
+ default: ()=>{}
92
+ },
93
+ },
94
+ data: function () {
95
+ return {
96
+ cascaderIsReady: false,
97
+ previousShowAllChecked: {
98
+ species: false,
99
+ gender: false,
100
+ organ: false,
101
+ datasets: false,
102
+ },
103
+ showFilters: true,
104
+ showFiltersText: true,
105
+ cascadeSelected: [],
106
+ numberShown: 10,
107
+ filters: [],
108
+ facets: ["Species", "Gender", "Organ", "Datasets"],
109
+ numberDatasetsShown: ["10", "20", "50"],
110
+ props: { multiple: true },
111
+ options: [
112
+ {
113
+ value: "Species",
114
+ label: "Species",
115
+ children: [{}],
116
+ },
117
+ ],
118
+ };
119
+ },
120
+ computed: {
121
+ numberOfResultsText: function () {
122
+ return `${this.entry.numberOfHits} results | Showing`;
123
+ },
124
+ },
125
+ methods: {
126
+ createCascaderItemValue: function (term, facet) {
127
+ if (facet) return term + "/" + facet;
128
+ else return term;
129
+ },
130
+ populateCascader: function () {
131
+ return new Promise((resolve) => {
132
+ // Algolia facet serach
133
+ this.algoliaClient.getAlgoliaFacets(facetPropPathMapping)
134
+ .then((data) => {
135
+ this.facets = data;
136
+ this.options = data;
137
+
138
+ // create top level of options in cascader
139
+ this.options.forEach((facet, i) => {
140
+ this.options[i].label = convertReadableLabel(facet.label);
141
+ this.options[i].value = this.createCascaderItemValue(
142
+ facet.key,
143
+ undefined
144
+ );
145
+
146
+ // put "Show all" as first option
147
+ this.options[i].children.unshift({
148
+ value: this.createCascaderItemValue("Show all"),
149
+ label: "Show all",
150
+ });
151
+
152
+ // populate second level of options
153
+ this.options[i].children.forEach((facetItem, j) => {
154
+ this.options[i].children[j].label = convertReadableLabel(
155
+ facetItem.label
156
+ );
157
+ this.options[i].children[j].value =
158
+ this.createCascaderItemValue(facet.label, facetItem.label);
159
+ });
160
+ });
161
+ })
162
+ .finally(() => {
163
+ resolve();
164
+ });
165
+ });
166
+ },
167
+ tagsChangedCallback: function (presentTags) {
168
+ if (presentTags.length > 0) {
169
+ this.showFiltersText = false;
170
+ } else {
171
+ this.showFiltersText = true;
172
+ }
173
+ },
174
+ // cascadeEvent: initiate searches based off cascader changes
175
+ cascadeEvent: function (event) {
176
+ if (event) {
177
+ // Check for show all in selected cascade options
178
+ event = this.showAllEventModifier(event);
179
+
180
+ // Move results from arrays to object
181
+ let filters = event.filter( selection => selection !== undefined).map( fs => ({
182
+ facetPropPath: fs[0],
183
+ facet: fs[1].split("/")[1],
184
+ term: fs[1].split("/")[0],
185
+ }))
186
+
187
+ this.$emit('loading', true) // let sidebarcontent wait for the requests
188
+
189
+ this.$emit("filterResults", filters); // emit filters for apps above sidebar
190
+ this.setCascader(filters); //update our cascader v-model if we modified the event
191
+ this.makeCascadeLabelsClickable();
192
+ }
193
+ },
194
+ // showAllEventModifier: Modifies a cascade event to unlick all selections in category if "show all" is clicked. Also unchecks "Show all" if any secection is clicked
195
+ // *NOTE* Does NOT remove 'Show all' selections from showing in 'cascadeSelected'
196
+ showAllEventModifier: function (event) {
197
+ // check if show all is in the cascader checked option list
198
+ let hasShowAll = event
199
+ .map((ev) => (ev ? ev[1].toLowerCase().includes("show all") : false))
200
+ .includes(true);
201
+ // remove all selected options below the show all if checked
202
+ if (hasShowAll) {
203
+ let modifiedEvent = [];
204
+ let facetMaps = {};
205
+ //catagorised different facet items
206
+ for (const i in event) {
207
+ if (facetMaps[event[i][0]] === undefined) facetMaps[event[i][0]] = [];
208
+ facetMaps[event[i][0]].push(event[i]);
209
+ }
210
+ // go through each facets
211
+ for (const facet in facetMaps) {
212
+ let showAll = undefined;
213
+ // Find the show all item if any
214
+ for (let i = facetMaps[facet].length - 1; i >= 0; i--) {
215
+ if (facetMaps[facet][i][1].toLowerCase().includes("show all")) {
216
+ //seperate the showAll item and the rest
217
+ showAll = facetMaps[facet].splice(i, 1)[0];
218
+ break;
219
+ }
220
+ }
221
+ if (showAll) {
222
+ if (this.previousShowAllChecked[facet]) {
223
+ //Unset the show all if it was present previously
224
+ //and there are other items
225
+ if (facetMaps[facet].length > 0)
226
+ modifiedEvent.push(...facetMaps[facet]);
227
+ else modifiedEvent.push(showAll);
228
+ } else {
229
+ //showAll is turned on
230
+ modifiedEvent.push(showAll);
231
+ }
232
+ } else {
233
+ modifiedEvent.push(...facetMaps[facet]);
234
+ }
235
+ }
236
+ //Make sure the expanded item are sorted first.
237
+ return modifiedEvent.sort((a, b) => {
238
+ if (this.__expandItem__) {
239
+ if (a[0] == this.__expandItem__) {
240
+ if (b[0] == this.__expandItem__) {
241
+ return 0;
242
+ } else {
243
+ return -1;
244
+ }
245
+ } else if (b[0] == this.__expandItem__) {
246
+ if (a[0] == this.__expandItem__) {
247
+ return 0;
248
+ } else {
249
+ return 1;
250
+ }
251
+ } else {
252
+ return 0;
253
+ }
254
+ } else return 0;
255
+ });
256
+ }
257
+ return event;
258
+ },
259
+ cascadeExpandChange: function (event) {
260
+ //work around as the expand item may change on modifying the cascade props
261
+ this.__expandItem__ = event;
262
+ this.makeCascadeLabelsClickable();
263
+ },
264
+ numberShownChanged: function (event) {
265
+ this.$emit("numberPerPage", parseInt(event));
266
+ },
267
+ updatePreviousShowAllChecked: function (options) {
268
+ //Reset the states
269
+ for (const facet in this.previousShowAllChecked) {
270
+ this.previousShowAllChecked[facet] = false;
271
+ }
272
+ options.forEach((element) => {
273
+ if (element[1].toLowerCase().includes("show all"))
274
+ this.previousShowAllChecked[element[0]] = true;
275
+ });
276
+ },
277
+ // setCascader: Clears previous selections and takes in an array of facets to select: filterFacets
278
+ // facets are in the form:
279
+ // {
280
+ // facetPropPath: 'anatomy.organ.name',
281
+ // term: 'Sex',
282
+ // facet: 'Male'
283
+ // }
284
+ setCascader: function (filterFacets) {
285
+ //Do not set the value unless it is ready
286
+ if (this.cascaderIsReady && filterFacets && filterFacets.length != 0) {
287
+ this.cascadeSelected = filterFacets.map(e => {
288
+ return [
289
+ e.facetPropPath,
290
+ this.createCascaderItemValue(capitalise(e.term), e.facet),
291
+ ]
292
+ });
293
+ this.updatePreviousShowAllChecked(this.cascadeSelected);
294
+ }
295
+ },
296
+ addFilter: function (filter) {
297
+ //Do not set the value unless it is ready
298
+ if (this.cascaderIsReady && filter) {
299
+ this.cascadeSelected.filter(f=>f.term != filter.term)
300
+ this.cascadeSelected.push([filter.facetPropPath, this.createCascaderItemValue(filter.term, filter.facet)])
301
+ }
302
+ },
303
+ initiateSearch: function() {
304
+ this.cascadeEvent(this.cascadeSelected)
305
+ },
306
+ // checkShowAllBoxes: Checks each 'Show all' cascade option by using the setCascader function
307
+ checkShowAllBoxes: function(){
308
+ this.setCascader(
309
+ this.options.map(option => {
310
+ return {
311
+ facetPropPath: option.value,
312
+ term: option.label,
313
+ facet: 'Show all'
314
+ }
315
+ })
316
+ )
317
+ },
318
+ makeCascadeLabelsClickable: function () {
319
+ // Next tick allows the cascader menu to change
320
+ this.$nextTick(() => {
321
+ this.$refs.cascader.$el
322
+ .querySelectorAll(".el-cascader-node__label")
323
+ .forEach((el) => {
324
+ // step through each cascade label
325
+ el.onclick = function () {
326
+ const checkbox = this.previousElementSibling;
327
+ if (checkbox) {
328
+ if (!checkbox.parentElement.attributes["aria-owns"]) {
329
+ // check if we are at the lowest level of cascader
330
+ this.previousElementSibling.click(); // Click the checkbox
331
+ }
332
+ }
333
+ };
334
+ });
335
+ });
336
+ },
337
+ },
338
+ mounted: function () {
339
+ this.algoliaClient = new AlgoliaClient(this.envVars.ALGOLIA_ID, this.envVars.ALGOLIA_KEY, this.envVars.PENNSIEVE_API_LOCATION);
340
+ this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX);
341
+ this.populateCascader().then(() => {
342
+ this.cascaderIsReady = true;
343
+ this.checkShowAllBoxes()
344
+ this.setCascader(this.entry.filterFacets);
345
+ this.makeCascadeLabelsClickable();
346
+ });
347
+ },
348
+ };
349
+ </script>
350
+
351
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
352
+ <style scoped>
353
+ .filter-default-value {
354
+ pointer-events: none;
355
+ position: absolute;
356
+ top: 0;
357
+ left: 0;
358
+ padding-top: 10px;
359
+ padding-left: 16px;
360
+ }
361
+
362
+ .filter-icon-inside {
363
+ width: 12px !important;
364
+ height: 12px !important;
365
+ color: #292b66;
366
+ transform: scale(2) !important;
367
+ margin-bottom: 0px !important;
368
+ }
369
+
370
+ .cascader {
371
+ font-family: Asap;
372
+ font-size: 14px;
373
+ font-weight: 500;
374
+ font-stretch: normal;
375
+ font-style: normal;
376
+ line-height: normal;
377
+ letter-spacing: normal;
378
+ color: #292b66;
379
+ text-align: center;
380
+ padding-bottom: 6px;
381
+ }
382
+
383
+ .cascader >>> .el-cascder-panel {
384
+ max-height: 500px;
385
+ }
386
+
387
+ .cascader >>> .el-scrollbar__wrap {
388
+ overflow-x: hidden;
389
+ margin-bottom: 2px !important;
390
+ }
391
+
392
+ .cascader >>> li[aria-owns*="cascader"] > .el-checkbox {
393
+ display: none;
394
+ }
395
+
396
+ .dataset-results-feedback {
397
+ float: right;
398
+ text-align: right;
399
+ color: rgb(48, 49, 51);
400
+ font-family: Asap;
401
+ font-size: 18px;
402
+ font-weight: 500;
403
+ padding-top: 8px;
404
+ }
405
+
406
+ .search-filters {
407
+ position: relative;
408
+ float: left;
409
+ padding-right: 15px;
410
+ padding-bottom: 12px;
411
+ }
412
+
413
+ .number-shown-select {
414
+ float: right;
415
+ }
416
+
417
+ .number-shown-select >>> .el-input__inner {
418
+ width: 68px;
419
+ height: 40px;
420
+ color: rgb(48, 49, 51);
421
+ }
422
+
423
+ .search-filters >>> .el-cascader-node.is-active {
424
+ color: #8300bf;
425
+ }
426
+
427
+ .search-filters >>> .el-cascader-node.in-active-path {
428
+ color: #8300bf;
429
+ }
430
+
431
+ .search-filters >>> .el-checkbox__input.is-checked > .el-checkbox__inner {
432
+ background-color: #8300bf;
433
+ border-color: #8300bf;
434
+ }
435
+
436
+ .cascader >>> .el-cascader-menu:nth-child(2) .el-cascader-node:first-child {
437
+ border-bottom: 1px solid #e4e7ed;
438
+ }
439
+
440
+ .cascader >>> .el-cascader-node__label {
441
+ text-align: left;
442
+ }
443
+ </style>