@abi-software/map-side-bar 1.1.8 → 1.1.9

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