@abi-software/map-side-bar 1.1.5-beta-0 → 1.1.5-beta-1
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.
- package/README.md +11 -2
- package/dist/map-side-bar.common.js +607 -318
- package/dist/map-side-bar.common.js.map +1 -1
- package/dist/map-side-bar.css +1 -1
- package/dist/map-side-bar.umd.js +607 -318
- package/dist/map-side-bar.umd.js.map +1 -1
- package/dist/map-side-bar.umd.min.js +1 -1
- package/dist/map-side-bar.umd.min.js.map +1 -1
- package/package-lock.json +384 -146
- package/package.json +3 -1
- package/src/App.vue +13 -10
- package/src/algolia/algolia.js +98 -0
- package/src/algolia/utils.js +52 -0
- package/src/components/DatasetCard.vue +25 -14
- package/src/components/SearchFilters.vue +137 -128
- package/src/components/SideBar.vue +11 -6
- package/src/components/SidebarContent.vue +58 -70
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
@tags-changed="tagsChangedCallback"
|
|
19
19
|
></custom-cascader>
|
|
20
20
|
<div v-if="showFiltersText" class="filter-default-value">
|
|
21
|
-
<svg-icon icon="noun-filter" class="filter-icon-inside" />Apply
|
|
21
|
+
<svg-icon icon="noun-filter" class="filter-icon-inside" />Apply
|
|
22
|
+
Filters
|
|
22
23
|
</div>
|
|
23
24
|
</span>
|
|
24
25
|
</transition>
|
|
@@ -29,9 +30,14 @@
|
|
|
29
30
|
placeholder="10"
|
|
30
31
|
@change="numberShownChanged($event)"
|
|
31
32
|
>
|
|
32
|
-
<el-option
|
|
33
|
+
<el-option
|
|
34
|
+
v-for="item in numberDatasetsShown"
|
|
35
|
+
:key="item"
|
|
36
|
+
:label="item"
|
|
37
|
+
:value="item"
|
|
38
|
+
></el-option>
|
|
33
39
|
</el-select>
|
|
34
|
-
<span class="dataset-results-feedback">{{this.numberOfResultsText}}</span>
|
|
40
|
+
<span class="dataset-results-feedback">{{ this.numberOfResultsText }}</span>
|
|
35
41
|
</div>
|
|
36
42
|
</template>
|
|
37
43
|
|
|
@@ -46,30 +52,33 @@ import locale from "element-ui/lib/locale";
|
|
|
46
52
|
import speciesMap from "./species-map";
|
|
47
53
|
import { SvgIcon, SvgSpriteColor } from "@abi-software/svg-sprite";
|
|
48
54
|
|
|
55
|
+
import {AlgoliaClient} from "../algolia/algolia.js";
|
|
56
|
+
import { facetPropPathMapping } from "../algolia/utils.js";
|
|
57
|
+
|
|
49
58
|
Vue.component("svg-icon", SvgIcon);
|
|
50
59
|
|
|
51
60
|
locale.use(lang);
|
|
52
61
|
Vue.use(Option);
|
|
53
62
|
Vue.use(Select);
|
|
54
63
|
|
|
55
|
-
const capitalise = function(txt) {
|
|
64
|
+
const capitalise = function (txt) {
|
|
56
65
|
return txt.charAt(0).toUpperCase() + txt.slice(1);
|
|
57
66
|
};
|
|
58
67
|
|
|
59
|
-
const convertReadableLabel = function(original) {
|
|
68
|
+
const convertReadableLabel = function (original) {
|
|
60
69
|
const name = original.toLowerCase();
|
|
61
|
-
if (speciesMap[name]){
|
|
70
|
+
if (speciesMap[name]) {
|
|
62
71
|
return capitalise(speciesMap[name]);
|
|
63
72
|
} else {
|
|
64
73
|
return capitalise(name);
|
|
65
74
|
}
|
|
66
|
-
}
|
|
75
|
+
};
|
|
67
76
|
|
|
68
77
|
export default {
|
|
69
78
|
name: "SearchFilters",
|
|
70
79
|
components: {
|
|
71
80
|
CustomCascader,
|
|
72
|
-
SvgSpriteColor
|
|
81
|
+
SvgSpriteColor,
|
|
73
82
|
},
|
|
74
83
|
props: {
|
|
75
84
|
/**
|
|
@@ -77,19 +86,19 @@ export default {
|
|
|
77
86
|
* the required viewing.
|
|
78
87
|
*/
|
|
79
88
|
entry: Object,
|
|
80
|
-
|
|
81
|
-
type:
|
|
82
|
-
default:
|
|
83
|
-
}
|
|
89
|
+
envVars: {
|
|
90
|
+
type: Object,
|
|
91
|
+
default: ()=>{}
|
|
92
|
+
},
|
|
84
93
|
},
|
|
85
|
-
data: function() {
|
|
94
|
+
data: function () {
|
|
86
95
|
return {
|
|
87
96
|
cascaderIsReady: false,
|
|
88
97
|
previousShowAllChecked: {
|
|
89
98
|
species: false,
|
|
90
99
|
gender: false,
|
|
91
100
|
organ: false,
|
|
92
|
-
datasets: false
|
|
101
|
+
datasets: false,
|
|
93
102
|
},
|
|
94
103
|
showFilters: true,
|
|
95
104
|
showFiltersText: true,
|
|
@@ -103,109 +112,91 @@ export default {
|
|
|
103
112
|
{
|
|
104
113
|
value: "Species",
|
|
105
114
|
label: "Species",
|
|
106
|
-
children: [{}]
|
|
107
|
-
}
|
|
108
|
-
]
|
|
115
|
+
children: [{}],
|
|
116
|
+
},
|
|
117
|
+
],
|
|
109
118
|
};
|
|
110
119
|
},
|
|
111
120
|
computed: {
|
|
112
|
-
numberOfResultsText: function() {
|
|
121
|
+
numberOfResultsText: function () {
|
|
113
122
|
return `${this.entry.numberOfHits} results | Showing`;
|
|
114
|
-
}
|
|
123
|
+
},
|
|
115
124
|
},
|
|
116
125
|
methods: {
|
|
117
|
-
createCascaderItemValue: function(term, facet) {
|
|
126
|
+
createCascaderItemValue: function (term, facet) {
|
|
118
127
|
if (facet) return term + "/" + facet;
|
|
119
128
|
else return term;
|
|
120
129
|
},
|
|
121
|
-
populateCascader: function() {
|
|
122
|
-
return new Promise(resolve => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
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
|
+
});
|
|
168
160
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
161
|
+
})
|
|
162
|
+
.finally(() => {
|
|
163
|
+
resolve();
|
|
164
|
+
});
|
|
172
165
|
});
|
|
173
166
|
},
|
|
174
|
-
|
|
175
|
-
switchTermToRequest: function(term) {
|
|
176
|
-
return term.split(" ")[0].toLowerCase();
|
|
177
|
-
},
|
|
178
|
-
tagsChangedCallback: function(presentTags) {
|
|
167
|
+
tagsChangedCallback: function (presentTags) {
|
|
179
168
|
if (presentTags.length > 0) {
|
|
180
169
|
this.showFiltersText = false;
|
|
181
170
|
} else {
|
|
182
171
|
this.showFiltersText = true;
|
|
183
172
|
}
|
|
184
173
|
},
|
|
185
|
-
cascadeEvent:
|
|
186
|
-
|
|
174
|
+
// cascadeEvent: initiate searches based off cascader changes
|
|
175
|
+
cascadeEvent: function (event) {
|
|
187
176
|
if (event) {
|
|
188
177
|
// Check for show all in selected cascade options
|
|
189
178
|
event = this.showAllEventModifier(event);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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();
|
|
200
192
|
}
|
|
201
|
-
this.$emit("filterResults", filters);
|
|
202
|
-
this.setCascader(filters); //update our cascader v-model if we modified the event
|
|
203
|
-
this.makeCascadeLabelsClickable();
|
|
204
193
|
},
|
|
205
|
-
showAllEventModifier:
|
|
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) {
|
|
206
197
|
// check if show all is in the cascader checked option list
|
|
207
198
|
let hasShowAll = event
|
|
208
|
-
.map(ev => (ev ? ev[1].toLowerCase().includes("show all") : false))
|
|
199
|
+
.map((ev) => (ev ? ev[1].toLowerCase().includes("show all") : false))
|
|
209
200
|
.includes(true);
|
|
210
201
|
// remove all selected options below the show all if checked
|
|
211
202
|
if (hasShowAll) {
|
|
@@ -260,63 +251,78 @@ export default {
|
|
|
260
251
|
} else {
|
|
261
252
|
return 0;
|
|
262
253
|
}
|
|
263
|
-
} else
|
|
264
|
-
return 0;
|
|
254
|
+
} else return 0;
|
|
265
255
|
});
|
|
266
256
|
}
|
|
267
257
|
return event;
|
|
268
258
|
},
|
|
269
|
-
cascadeExpandChange: function(event) {
|
|
259
|
+
cascadeExpandChange: function (event) {
|
|
270
260
|
//work around as the expand item may change on modifying the cascade props
|
|
271
261
|
this.__expandItem__ = event;
|
|
272
262
|
this.makeCascadeLabelsClickable();
|
|
273
263
|
},
|
|
274
|
-
numberShownChanged: function(event) {
|
|
264
|
+
numberShownChanged: function (event) {
|
|
275
265
|
this.$emit("numberPerPage", parseInt(event));
|
|
276
266
|
},
|
|
277
|
-
|
|
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) {
|
|
267
|
+
updatePreviousShowAllChecked: function (options) {
|
|
287
268
|
//Reset the states
|
|
288
269
|
for (const facet in this.previousShowAllChecked) {
|
|
289
270
|
this.previousShowAllChecked[facet] = false;
|
|
290
271
|
}
|
|
291
|
-
options.forEach(element => {
|
|
272
|
+
options.forEach((element) => {
|
|
292
273
|
if (element[1].toLowerCase().includes("show all"))
|
|
293
274
|
this.previousShowAllChecked[element[0]] = true;
|
|
294
275
|
});
|
|
295
276
|
},
|
|
296
|
-
setCascader:
|
|
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) {
|
|
297
285
|
//Do not set the value unless it is ready
|
|
298
|
-
if (this.cascaderIsReady) {
|
|
299
|
-
this.cascadeSelected =
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
e.term.
|
|
303
|
-
|
|
304
|
-
e.term.toLowerCase(),
|
|
305
|
-
e.facet.toLowerCase()
|
|
306
|
-
)
|
|
307
|
-
]);
|
|
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
|
+
]
|
|
308
292
|
});
|
|
309
293
|
this.updatePreviousShowAllChecked(this.cascadeSelected);
|
|
310
294
|
}
|
|
311
295
|
},
|
|
312
|
-
|
|
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 () {
|
|
313
319
|
// Next tick allows the cascader menu to change
|
|
314
320
|
this.$nextTick(() => {
|
|
315
321
|
this.$refs.cascader.$el
|
|
316
322
|
.querySelectorAll(".el-cascader-node__label")
|
|
317
|
-
.forEach(el => {
|
|
323
|
+
.forEach((el) => {
|
|
318
324
|
// step through each cascade label
|
|
319
|
-
el.onclick = function() {
|
|
325
|
+
el.onclick = function () {
|
|
320
326
|
const checkbox = this.previousElementSibling;
|
|
321
327
|
if (checkbox) {
|
|
322
328
|
if (!checkbox.parentElement.attributes["aria-owns"]) {
|
|
@@ -327,19 +333,18 @@ export default {
|
|
|
327
333
|
};
|
|
328
334
|
});
|
|
329
335
|
});
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
|
-
created: function() {
|
|
333
|
-
//Create non-reactive local variables
|
|
334
|
-
this.facetEndpoint = "get-facets/";
|
|
336
|
+
},
|
|
335
337
|
},
|
|
336
|
-
mounted: function() {
|
|
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);
|
|
337
341
|
this.populateCascader().then(() => {
|
|
338
342
|
this.cascaderIsReady = true;
|
|
343
|
+
this.checkShowAllBoxes()
|
|
339
344
|
this.setCascader(this.entry.filterFacets);
|
|
340
345
|
this.makeCascadeLabelsClickable();
|
|
341
346
|
});
|
|
342
|
-
}
|
|
347
|
+
},
|
|
343
348
|
};
|
|
344
349
|
</script>
|
|
345
350
|
|
|
@@ -375,6 +380,10 @@ export default {
|
|
|
375
380
|
padding-bottom: 6px;
|
|
376
381
|
}
|
|
377
382
|
|
|
383
|
+
.cascader >>> .el-cascder-panel {
|
|
384
|
+
max-height: 500px;
|
|
385
|
+
}
|
|
386
|
+
|
|
378
387
|
.cascader >>> .el-scrollbar__wrap {
|
|
379
388
|
overflow-x: hidden;
|
|
380
389
|
margin-bottom: 2px !important;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<template v-for="tab in tabs">
|
|
25
25
|
<sidebar-content class="sidebar-content-container"
|
|
26
26
|
v-show="tab.id===activeId" :contextCardEntry="tab.contextCard"
|
|
27
|
-
:
|
|
27
|
+
:envVars="envVars"
|
|
28
28
|
v-bind:key="tab.id" :ref="tab.id"
|
|
29
29
|
@search-changed="searchChanged(tab.id, $event)"/>
|
|
30
30
|
</template>
|
|
@@ -81,9 +81,9 @@ export default {
|
|
|
81
81
|
type: Object,
|
|
82
82
|
default: () => (initial_state)
|
|
83
83
|
},
|
|
84
|
-
|
|
85
|
-
type:
|
|
86
|
-
default:
|
|
84
|
+
envVars: {
|
|
85
|
+
type: Object,
|
|
86
|
+
default: () => {}
|
|
87
87
|
},
|
|
88
88
|
tabs: {
|
|
89
89
|
type: Array,
|
|
@@ -113,10 +113,15 @@ export default {
|
|
|
113
113
|
toggleDrawer: function () {
|
|
114
114
|
this.drawerOpen = !this.drawerOpen;
|
|
115
115
|
},
|
|
116
|
-
openSearch: function(
|
|
116
|
+
openSearch: function(facets, query){
|
|
117
|
+
this.drawerOpen = true;
|
|
118
|
+
// Because refs are in v-for, nextTick is needed here
|
|
119
|
+
Vue.nextTick(()=>{this.$refs[this.activeId][0].openSearch(facets, query)})
|
|
120
|
+
},
|
|
121
|
+
addFilter: function(filter){
|
|
117
122
|
this.drawerOpen = true;
|
|
118
123
|
// Because refs are in v-for, nextTick is needed here
|
|
119
|
-
Vue.nextTick(()=>{this.$refs[this.activeId][0].
|
|
124
|
+
Vue.nextTick(()=>{this.$refs[this.activeId][0].addFilter(filter)})
|
|
120
125
|
},
|
|
121
126
|
openNeuronSearch: function(neuron){
|
|
122
127
|
this.drawerOpen = true;
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
class="filters"
|
|
17
17
|
ref="filtersRef"
|
|
18
18
|
:entry="filterEntry"
|
|
19
|
-
:
|
|
19
|
+
:envVars="envVars"
|
|
20
20
|
@filterResults="filterUpdate"
|
|
21
21
|
@numberPerPage="numberPerPageUpdate"
|
|
22
|
+
@loading="filtersLoading"
|
|
22
23
|
></SearchFilters>
|
|
23
24
|
<div class="content scrollbar" v-loading="loadingCards" ref="content">
|
|
24
25
|
<div
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
>No results found - Please change your search / filter criteria.</div>
|
|
28
29
|
<div class="error-feedback" v-if="sciCrunchError">{{sciCrunchError}}</div>
|
|
29
30
|
<div v-for="o in results" :key="o.id" class="step-item">
|
|
30
|
-
<DatasetCard :entry="o" :
|
|
31
|
+
<DatasetCard :entry="o" :envVars="envVars"></DatasetCard>
|
|
31
32
|
</div>
|
|
32
33
|
<el-pagination
|
|
33
34
|
class="pagination"
|
|
@@ -62,6 +63,9 @@ import SearchFilters from "./SearchFilters";
|
|
|
62
63
|
import DatasetCard from "./DatasetCard";
|
|
63
64
|
import ContextCard from "./ContextCard.vue";
|
|
64
65
|
|
|
66
|
+
import {AlgoliaClient} from "../algolia/algolia.js";
|
|
67
|
+
import {getFilters} from "../algolia/utils.js"
|
|
68
|
+
|
|
65
69
|
locale.use(lang);
|
|
66
70
|
Vue.use(Button);
|
|
67
71
|
Vue.use(Card);
|
|
@@ -120,9 +124,9 @@ export default {
|
|
|
120
124
|
type: Object,
|
|
121
125
|
default: undefined
|
|
122
126
|
},
|
|
123
|
-
|
|
124
|
-
type:
|
|
125
|
-
default:
|
|
127
|
+
envVars: {
|
|
128
|
+
type: Object,
|
|
129
|
+
default: () => {}
|
|
126
130
|
},
|
|
127
131
|
firstSearch: {
|
|
128
132
|
type: String,
|
|
@@ -149,54 +153,69 @@ export default {
|
|
|
149
153
|
}
|
|
150
154
|
},
|
|
151
155
|
methods: {
|
|
152
|
-
openSearch: function(
|
|
153
|
-
endpoint = undefined, params = undefined) {
|
|
156
|
+
openSearch: function(filter, search='') {
|
|
154
157
|
this.searchInput = search;
|
|
155
158
|
this.resetPageNavigation();
|
|
156
|
-
this.
|
|
159
|
+
this.searchAlgolia(filter, search);
|
|
157
160
|
if (filter) {
|
|
158
161
|
this.filter = [...filter];
|
|
159
162
|
this.$refs.filtersRef.setCascader(this.filter);
|
|
160
163
|
}
|
|
161
164
|
},
|
|
165
|
+
addFilter: function(filter) {
|
|
166
|
+
this.resetPageNavigation();
|
|
167
|
+
if (filter) {
|
|
168
|
+
this.$refs.filtersRef.addFilter(filter);
|
|
169
|
+
this.$refs.filtersRef.initiateSearch()
|
|
170
|
+
}
|
|
171
|
+
},
|
|
162
172
|
clearSearchClicked: function() {
|
|
163
173
|
this.searchInput = "";
|
|
164
174
|
this.resetPageNavigation();
|
|
165
|
-
this.
|
|
175
|
+
this.searchAlgolia(this.filters, this.searchInput);
|
|
166
176
|
},
|
|
167
177
|
searchEvent: function(event = false) {
|
|
168
178
|
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
169
179
|
this.resetPageNavigation();
|
|
170
|
-
this.
|
|
180
|
+
this.searchAlgolia(this.filters, this.searchInput);
|
|
171
181
|
}
|
|
172
182
|
},
|
|
173
|
-
filterUpdate: function(
|
|
174
|
-
this.
|
|
175
|
-
this.
|
|
176
|
-
this.
|
|
183
|
+
filterUpdate: function(filters) {
|
|
184
|
+
this.filters = [...filters]
|
|
185
|
+
this.resetPageNavigation()
|
|
186
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
177
187
|
this.$emit("search-changed", {
|
|
178
188
|
value: this.filter,
|
|
179
189
|
type: "filter-update"
|
|
180
190
|
});
|
|
181
191
|
},
|
|
192
|
+
searchAlgolia(filters, query=''){
|
|
193
|
+
// Algolia search
|
|
194
|
+
this.algoliaClient.search(getFilters(filters), query, this.numberPerPage, this.page).then(searchData => {
|
|
195
|
+
this.numberOfHits = searchData.total
|
|
196
|
+
this.discoverIds = searchData.discoverIds
|
|
197
|
+
this.results = searchData.items
|
|
198
|
+
this.searchSciCrunch({'discoverIds':this.discoverIds})
|
|
199
|
+
})
|
|
200
|
+
},
|
|
201
|
+
filtersLoading: function (val) {
|
|
202
|
+
this.loadingCards = val;
|
|
203
|
+
},
|
|
182
204
|
numberPerPageUpdate: function(val) {
|
|
183
205
|
this.numberPerPage = val;
|
|
184
206
|
this.pageChange(1);
|
|
185
207
|
},
|
|
186
208
|
pageChange: function(page) {
|
|
187
209
|
this.start = (page - 1) * this.numberPerPage;
|
|
188
|
-
this.
|
|
210
|
+
this.page = page
|
|
211
|
+
this.searchAlgolia(this.filters, this.searchInput, this.numberPerPage, this.page)
|
|
189
212
|
},
|
|
190
|
-
searchSciCrunch: function(
|
|
191
|
-
searchEndpoint = undefined, params = undefined) {
|
|
213
|
+
searchSciCrunch: function(params) {
|
|
192
214
|
this.loadingCards = true;
|
|
193
215
|
this.results = [];
|
|
194
216
|
this.disableCards();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
params = this.createParams(filter, this.start, this.numberPerPage);
|
|
198
|
-
this.$emit("search-changed", { value: search, type: "query-update" });
|
|
199
|
-
this.callSciCrunch(this.apiLocation, searchEndpoint, search, params)
|
|
217
|
+
this.$emit("search-changed", { value: this.searchInput, type: "query-update" });
|
|
218
|
+
this.callSciCrunch(this.envVars.API_LOCATION, params)
|
|
200
219
|
.then(result => {
|
|
201
220
|
//Only process if the search term is the same as the last search term.
|
|
202
221
|
//This avoid old search being displayed.
|
|
@@ -222,32 +241,6 @@ export default {
|
|
|
222
241
|
this.start = 0;
|
|
223
242
|
this.page = 1;
|
|
224
243
|
},
|
|
225
|
-
createParams: function(filter, start, size) {
|
|
226
|
-
//Deconstruct list of fitlers to list of term
|
|
227
|
-
//and facet.
|
|
228
|
-
let params = {};
|
|
229
|
-
let term = [];
|
|
230
|
-
let facet = [];
|
|
231
|
-
let f = undefined;
|
|
232
|
-
if (filter !== undefined) {
|
|
233
|
-
f = filter;
|
|
234
|
-
} else {
|
|
235
|
-
f = this.filter;
|
|
236
|
-
}
|
|
237
|
-
if (f)
|
|
238
|
-
f.forEach(e => {
|
|
239
|
-
//Do not ask for any "show all" request
|
|
240
|
-
if (e.facet !== "show all") {
|
|
241
|
-
term.push(e.term);
|
|
242
|
-
facet.push(e.facet);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
params.term = term;
|
|
246
|
-
params.facet = facet;
|
|
247
|
-
params.start = start;
|
|
248
|
-
params.size = size;
|
|
249
|
-
return params;
|
|
250
|
-
},
|
|
251
244
|
resultsProcessing: function(data) {
|
|
252
245
|
this.lastSearch = this.searchInput;
|
|
253
246
|
this.results = [];
|
|
@@ -261,9 +254,12 @@ export default {
|
|
|
261
254
|
name: element.name,
|
|
262
255
|
description: element.description,
|
|
263
256
|
contributors: element.contributors,
|
|
264
|
-
numberSamples:
|
|
265
|
-
? element.
|
|
266
|
-
:
|
|
257
|
+
numberSamples: element.sampleSize
|
|
258
|
+
? parseInt(element.sampleSize)
|
|
259
|
+
: 0,
|
|
260
|
+
numberSubjects: element.subjectSize
|
|
261
|
+
? parseInt(element.subjectSize)
|
|
262
|
+
: 0,
|
|
267
263
|
updated: element.updated[0].timestamp.split("T")[0],
|
|
268
264
|
url: element.uri[0],
|
|
269
265
|
datasetId: element.dataset_identifier,
|
|
@@ -305,21 +301,16 @@ export default {
|
|
|
305
301
|
}
|
|
306
302
|
return p.toString();
|
|
307
303
|
},
|
|
308
|
-
callSciCrunch: function(apiLocation,
|
|
304
|
+
callSciCrunch: function(apiLocation, params = {}) {
|
|
309
305
|
return new Promise((resolve, reject) => {
|
|
310
306
|
// the following controller will abort current search
|
|
311
307
|
// if a new one has been started
|
|
312
308
|
if (this._controller) this._controller.abort();
|
|
313
309
|
this._controller = new AbortController();
|
|
314
310
|
let signal = this._controller.signal;
|
|
315
|
-
var endpoint = apiLocation + searchEndpoint;
|
|
316
311
|
// Add parameters if we are sent them
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
} else {
|
|
320
|
-
endpoint = endpoint + "?" + this.createfilterParams(params);
|
|
321
|
-
}
|
|
322
|
-
fetch(endpoint, { signal })
|
|
312
|
+
let fullEndpoint = this.envVars.API_LOCATION + this.searchEndpoint + "?" + this.createfilterParams(params);
|
|
313
|
+
fetch(fullEndpoint, { signal })
|
|
323
314
|
.then(handleErrors)
|
|
324
315
|
.then(response => response.json())
|
|
325
316
|
.then(data => resolve(data))
|
|
@@ -328,24 +319,21 @@ export default {
|
|
|
328
319
|
},
|
|
329
320
|
},
|
|
330
321
|
mounted: function() {
|
|
322
|
+
// initialise algolia
|
|
323
|
+
this.algoliaClient = new AlgoliaClient(this.envVars.ALGOLIA_ID, this.envVars.ALGOLIA_KEY, this.envVars.PENNSIEVE_API_LOCATION);
|
|
324
|
+
this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX);
|
|
325
|
+
console.log('Algolia initialised in sidebar')
|
|
326
|
+
|
|
331
327
|
// temporarily disable flatmap search since there are no datasets
|
|
332
328
|
if (this.firstSearch === "Flatmap" || this.firstSearch === "flatmap") {
|
|
333
|
-
this.openSearch(''
|
|
334
|
-
{facet: "show all", term:'species'},
|
|
335
|
-
{facet: "show all", term:'gender'},
|
|
336
|
-
{facet: "show all", term:'organ'},
|
|
337
|
-
{facet: "show all", term:'datasets'}]);
|
|
329
|
+
this.openSearch(undefined, '')
|
|
338
330
|
} else {
|
|
339
|
-
this.openSearch(
|
|
340
|
-
{facet: "show all", term:'species'},
|
|
341
|
-
{facet: "show all", term:'gender'},
|
|
342
|
-
{facet: "show all", term:'organ'},
|
|
343
|
-
{facet: "show all", term:'datasets'}]);
|
|
331
|
+
this.openSearch(undefined, '');
|
|
344
332
|
}
|
|
345
333
|
},
|
|
346
334
|
created: function() {
|
|
347
335
|
//Create non-reactive local variables
|
|
348
|
-
this.searchEndpoint = "
|
|
336
|
+
this.searchEndpoint = "dataset_info/using_multiple_discoverIds/";
|
|
349
337
|
}
|
|
350
338
|
};
|
|
351
339
|
</script>
|