@abi-software/map-side-bar 2.2.0 → 2.2.1-alpha-2
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/.eslintrc.js +12 -12
- package/.postcssrc.json +5 -5
- package/LICENSE +201 -201
- package/README.md +168 -168
- package/dist/map-side-bar.js +6982 -7170
- package/dist/map-side-bar.umd.cjs +50 -103
- package/dist/style.css +1 -1
- package/package.json +72 -72
- package/src/App.vue +233 -233
- package/src/algolia/algolia.js +242 -211
- package/src/algolia/utils.js +101 -101
- package/src/assets/_variables.scss +43 -43
- package/src/assets/styles.scss +6 -6
- package/src/components/BadgesGroup.vue +124 -124
- package/src/components/DatasetCard.vue +356 -356
- package/src/components/EventBus.js +3 -3
- package/src/components/ImageGallery.vue +542 -542
- package/src/components/SearchFilters.vue +1000 -1000
- package/src/components/SearchHistory.vue +175 -175
- package/src/components/SideBar.vue +347 -338
- package/src/components/SidebarContent.vue +576 -576
- package/src/components/Tabs.vue +78 -78
- package/src/components/index.js +8 -8
- package/src/components/species-map.js +8 -8
- package/src/main.js +9 -9
- package/src/mixins/S3Bucket.vue +37 -37
- package/static.json +6 -6
- package/vite.config.js +55 -55
- package/vuese-generator.js +65 -65
|
@@ -1,576 +1,576 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<el-card :body-style="bodyStyle" class="content-card">
|
|
3
|
-
<template #header>
|
|
4
|
-
<div class="header">
|
|
5
|
-
<el-input
|
|
6
|
-
class="search-input"
|
|
7
|
-
placeholder="Search"
|
|
8
|
-
v-model="searchInput"
|
|
9
|
-
@keyup="searchEvent"
|
|
10
|
-
clearable
|
|
11
|
-
@clear="clearSearchClicked"
|
|
12
|
-
></el-input>
|
|
13
|
-
<el-button
|
|
14
|
-
type="primary"
|
|
15
|
-
class="button"
|
|
16
|
-
@click="searchEvent"
|
|
17
|
-
size="large"
|
|
18
|
-
>
|
|
19
|
-
Search
|
|
20
|
-
</el-button>
|
|
21
|
-
</div>
|
|
22
|
-
</template>
|
|
23
|
-
<SearchFilters
|
|
24
|
-
class="filters"
|
|
25
|
-
ref="filtersRef"
|
|
26
|
-
:entry="filterEntry"
|
|
27
|
-
:envVars="envVars"
|
|
28
|
-
@filterResults="filterUpdate"
|
|
29
|
-
@numberPerPage="numberPerPageUpdate"
|
|
30
|
-
@loading="filtersLoading"
|
|
31
|
-
@cascaderReady="cascaderReady"
|
|
32
|
-
></SearchFilters>
|
|
33
|
-
<SearchHistory
|
|
34
|
-
ref="searchHistory"
|
|
35
|
-
@search="searchHistorySearch"
|
|
36
|
-
></SearchHistory>
|
|
37
|
-
<div class="content scrollbar" v-loading="loadingCards" ref="content">
|
|
38
|
-
<div class="error-feedback" v-if="results.length === 0 && !loadingCards">
|
|
39
|
-
No results found - Please change your search / filter criteria.
|
|
40
|
-
</div>
|
|
41
|
-
<div v-for="result in results" :key="result.doi" class="step-item">
|
|
42
|
-
<DatasetCard
|
|
43
|
-
class="dataset-card"
|
|
44
|
-
:entry="result"
|
|
45
|
-
:envVars="envVars"
|
|
46
|
-
@mouseenter="hoverChanged(result)"
|
|
47
|
-
@mouseleave="hoverChanged(undefined)"
|
|
48
|
-
/>
|
|
49
|
-
</div>
|
|
50
|
-
<el-pagination
|
|
51
|
-
class="pagination"
|
|
52
|
-
v-model:current-page="page"
|
|
53
|
-
hide-on-single-page
|
|
54
|
-
large
|
|
55
|
-
layout="prev, pager, next"
|
|
56
|
-
:page-size="numberPerPage"
|
|
57
|
-
:total="numberOfHits"
|
|
58
|
-
@current-change="pageChange"
|
|
59
|
-
></el-pagination>
|
|
60
|
-
</div>
|
|
61
|
-
</el-card>
|
|
62
|
-
</template>
|
|
63
|
-
|
|
64
|
-
<script>
|
|
65
|
-
/* eslint-disable no-alert, no-console */
|
|
66
|
-
import {
|
|
67
|
-
ElButton as Button,
|
|
68
|
-
ElCard as Card,
|
|
69
|
-
ElDrawer as Drawer,
|
|
70
|
-
ElIcon as Icon,
|
|
71
|
-
ElInput as Input,
|
|
72
|
-
ElPagination as Pagination,
|
|
73
|
-
} from 'element-plus'
|
|
74
|
-
import SearchFilters from './SearchFilters.vue'
|
|
75
|
-
import SearchHistory from './SearchHistory.vue'
|
|
76
|
-
import DatasetCard from './DatasetCard.vue'
|
|
77
|
-
import EventBus from './EventBus.js'
|
|
78
|
-
|
|
79
|
-
import { AlgoliaClient } from '../algolia/algolia.js'
|
|
80
|
-
import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
|
|
81
|
-
|
|
82
|
-
// handleErrors: A custom fetch error handler to recieve messages from the server
|
|
83
|
-
// even when an error is found
|
|
84
|
-
var handleErrors = async function (response) {
|
|
85
|
-
if (!response.ok) {
|
|
86
|
-
let parse = await response.json()
|
|
87
|
-
if (parse) {
|
|
88
|
-
throw new Error(parse.message)
|
|
89
|
-
} else {
|
|
90
|
-
throw new Error(response)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return response
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
var initial_state = {
|
|
97
|
-
searchInput: '',
|
|
98
|
-
lastSearch: '',
|
|
99
|
-
results: [],
|
|
100
|
-
numberOfHits: 0,
|
|
101
|
-
filter: [],
|
|
102
|
-
loadingCards: false,
|
|
103
|
-
numberPerPage: 10,
|
|
104
|
-
page: 1,
|
|
105
|
-
pageModel: 1,
|
|
106
|
-
start: 0,
|
|
107
|
-
hasSearched: false,
|
|
108
|
-
contextCardEnabled: false,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default {
|
|
112
|
-
components: {
|
|
113
|
-
SearchFilters,
|
|
114
|
-
DatasetCard,
|
|
115
|
-
SearchHistory,
|
|
116
|
-
Button,
|
|
117
|
-
Card,
|
|
118
|
-
Drawer,
|
|
119
|
-
Icon,
|
|
120
|
-
Input,
|
|
121
|
-
Pagination
|
|
122
|
-
},
|
|
123
|
-
name: 'SideBarContent',
|
|
124
|
-
props: {
|
|
125
|
-
visible: {
|
|
126
|
-
type: Boolean,
|
|
127
|
-
default: false,
|
|
128
|
-
},
|
|
129
|
-
isDrawer: {
|
|
130
|
-
type: Boolean,
|
|
131
|
-
default: true,
|
|
132
|
-
},
|
|
133
|
-
entry: {
|
|
134
|
-
type: Object,
|
|
135
|
-
default: () => initial_state,
|
|
136
|
-
},
|
|
137
|
-
envVars: {
|
|
138
|
-
type: Object,
|
|
139
|
-
default: () => {},
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
data: function () {
|
|
143
|
-
return {
|
|
144
|
-
...this.entry,
|
|
145
|
-
bodyStyle: {
|
|
146
|
-
flex: '1 1 auto',
|
|
147
|
-
'flex-flow': 'column',
|
|
148
|
-
display: 'flex',
|
|
149
|
-
},
|
|
150
|
-
cascaderIsReady: false,
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
computed: {
|
|
154
|
-
// This computed property populates filter data's entry object with $data from this sidebar
|
|
155
|
-
filterEntry: function () {
|
|
156
|
-
return {
|
|
157
|
-
numberOfHits: this.numberOfHits,
|
|
158
|
-
filterFacets: this.filter,
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
methods: {
|
|
163
|
-
hoverChanged: function (data) {
|
|
164
|
-
this.$emit('hover-changed', data)
|
|
165
|
-
},
|
|
166
|
-
resetSearch: function () {
|
|
167
|
-
this.numberOfHits = 0
|
|
168
|
-
this.discoverIds = []
|
|
169
|
-
this._dois = []
|
|
170
|
-
this.results = []
|
|
171
|
-
this.loadingCards = false
|
|
172
|
-
},
|
|
173
|
-
openSearch: function (filter, search = '') {
|
|
174
|
-
this.searchInput = search
|
|
175
|
-
this.resetPageNavigation()
|
|
176
|
-
//Proceed normally if cascader is ready
|
|
177
|
-
if (this.cascaderIsReady) {
|
|
178
|
-
this.filter =
|
|
179
|
-
this.$refs.filtersRef.getHierarchicalValidatedFilters(filter)
|
|
180
|
-
//Facets provided but cannot find at least one valid
|
|
181
|
-
//facet. Tell the users the search is invalid and reset
|
|
182
|
-
//facets check boxes.
|
|
183
|
-
if (
|
|
184
|
-
filter &&
|
|
185
|
-
filter.length > 0 &&
|
|
186
|
-
this.filter &&
|
|
187
|
-
this.filter.length === 0
|
|
188
|
-
) {
|
|
189
|
-
this.$refs.filtersRef.checkShowAllBoxes()
|
|
190
|
-
this.resetSearch()
|
|
191
|
-
} else if (this.filter) {
|
|
192
|
-
this.searchAlgolia(this.filter, search)
|
|
193
|
-
this.$refs.filtersRef.setCascader(this.filter)
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
//cascader is not ready, perform search if no filter is set,
|
|
197
|
-
//otherwise waith for cascader to be ready
|
|
198
|
-
this.filter = filter
|
|
199
|
-
if (!filter || filter.length == 0) {
|
|
200
|
-
this.searchAlgolia(this.filter, search)
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
addFilter: function (filter) {
|
|
205
|
-
if (this.cascaderIsReady) {
|
|
206
|
-
this.resetPageNavigation()
|
|
207
|
-
if (filter) {
|
|
208
|
-
if (this.$refs.filtersRef.addFilter(filter))
|
|
209
|
-
this.$refs.filtersRef.initiateSearch()
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
if (Array.isArray(this.filter)) {
|
|
213
|
-
this.filter.push(filter)
|
|
214
|
-
} else {
|
|
215
|
-
this.filter = [filter]
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
cascaderReady: function () {
|
|
220
|
-
this.cascaderIsReady = true
|
|
221
|
-
this.openSearch(this.filter, this.searchInput)
|
|
222
|
-
},
|
|
223
|
-
clearSearchClicked: function () {
|
|
224
|
-
this.searchInput = ''
|
|
225
|
-
this.resetPageNavigation()
|
|
226
|
-
this.searchAlgolia(this.filters, this.searchInput)
|
|
227
|
-
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
228
|
-
},
|
|
229
|
-
searchEvent: function (event = false) {
|
|
230
|
-
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
231
|
-
this.resetPageNavigation()
|
|
232
|
-
this.searchAlgolia(this.filters, this.searchInput)
|
|
233
|
-
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
234
|
-
this.$refs.searchHistory.addSearchToHistory(
|
|
235
|
-
this.filters,
|
|
236
|
-
this.searchInput
|
|
237
|
-
)
|
|
238
|
-
}
|
|
239
|
-
},
|
|
240
|
-
filterUpdate: function (filters) {
|
|
241
|
-
this.filters = [...filters]
|
|
242
|
-
this.resetPageNavigation()
|
|
243
|
-
this.searchAlgolia(filters, this.searchInput)
|
|
244
|
-
this.$emit('search-changed', {
|
|
245
|
-
value: filters,
|
|
246
|
-
type: 'filter-update',
|
|
247
|
-
})
|
|
248
|
-
},
|
|
249
|
-
searchAlgolia(filters, query = '') {
|
|
250
|
-
// Algolia search
|
|
251
|
-
|
|
252
|
-
this.
|
|
253
|
-
|
|
254
|
-
.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
})
|
|
260
|
-
this.algoliaClient
|
|
261
|
-
.search(getFilters(filters), query, this.numberPerPage, this.page)
|
|
262
|
-
.then((searchData) => {
|
|
263
|
-
this.numberOfHits = searchData.total
|
|
264
|
-
this.discoverIds = searchData.discoverIds
|
|
265
|
-
this._dois = searchData.dois
|
|
266
|
-
this.results = searchData.items
|
|
267
|
-
this.loadingCards = false
|
|
268
|
-
this.scrollToTop()
|
|
269
|
-
this.$emit('search-changed', {
|
|
270
|
-
value: this.searchInput,
|
|
271
|
-
type: 'query-update',
|
|
272
|
-
})
|
|
273
|
-
if (this._abortController) this._abortController.abort()
|
|
274
|
-
this._abortController = new AbortController()
|
|
275
|
-
const signal = this._abortController.signal
|
|
276
|
-
//Search ongoing, let the current flow progress
|
|
277
|
-
this.perItemSearch(signal, { count: 0 })
|
|
278
|
-
})
|
|
279
|
-
},
|
|
280
|
-
filtersLoading: function (val) {
|
|
281
|
-
this.loadingCards = val
|
|
282
|
-
},
|
|
283
|
-
numberPerPageUpdate: function (val) {
|
|
284
|
-
this.numberPerPage = val
|
|
285
|
-
this.pageChange(1)
|
|
286
|
-
},
|
|
287
|
-
pageChange: function (page) {
|
|
288
|
-
this.start = (page - 1) * this.numberPerPage
|
|
289
|
-
this.page = page
|
|
290
|
-
this.searchAlgolia(
|
|
291
|
-
this.filters,
|
|
292
|
-
this.searchInput,
|
|
293
|
-
this.numberPerPage,
|
|
294
|
-
this.page
|
|
295
|
-
)
|
|
296
|
-
},
|
|
297
|
-
handleMissingData: function (doi) {
|
|
298
|
-
let i = this.results.findIndex((res) => res.doi === doi)
|
|
299
|
-
if (this.results[i]) this.results[i].detailsReady = true
|
|
300
|
-
},
|
|
301
|
-
perItemSearch: function (signal, data) {
|
|
302
|
-
//Maximum 10 downloads at once to prevent long waiting time
|
|
303
|
-
//between unfinished search and new search
|
|
304
|
-
const maxDownloads = 10
|
|
305
|
-
if (maxDownloads > data.count) {
|
|
306
|
-
const doi = this._dois.shift()
|
|
307
|
-
if (doi) {
|
|
308
|
-
data.count++
|
|
309
|
-
this.callSciCrunch(this.envVars.API_LOCATION, { dois: [doi] }, signal)
|
|
310
|
-
.then((result) => {
|
|
311
|
-
if (result.numberOfHits === 0) this.handleMissingData(doi)
|
|
312
|
-
else this.resultsProcessing(result)
|
|
313
|
-
this.$refs.content.style['overflow-y'] = 'scroll'
|
|
314
|
-
data.count--
|
|
315
|
-
//Async::Download finished, get the next one
|
|
316
|
-
this.perItemSearch(signal, data)
|
|
317
|
-
})
|
|
318
|
-
.catch((result) => {
|
|
319
|
-
if (result.name !== 'AbortError') {
|
|
320
|
-
this.handleMissingData(doi)
|
|
321
|
-
data.count--
|
|
322
|
-
//Async::Download not aborted, get the next one
|
|
323
|
-
this.perItemSearch(signal, data)
|
|
324
|
-
}
|
|
325
|
-
})
|
|
326
|
-
//Check and make another request until it gets to max downloads
|
|
327
|
-
this.perItemSearch(signal, data)
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
},
|
|
331
|
-
scrollToTop: function () {
|
|
332
|
-
if (this.$refs.content) {
|
|
333
|
-
this.$refs.content.scroll({ top: 0, behavior: 'smooth' })
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
|
-
resetPageNavigation: function () {
|
|
337
|
-
this.start = 0
|
|
338
|
-
this.page = 1
|
|
339
|
-
},
|
|
340
|
-
resultsProcessing: function (data) {
|
|
341
|
-
this.lastSearch = this.searchInput
|
|
342
|
-
|
|
343
|
-
if (data.results.length === 0) {
|
|
344
|
-
return
|
|
345
|
-
}
|
|
346
|
-
data.results.forEach((element) => {
|
|
347
|
-
// match the scicrunch result with algolia result
|
|
348
|
-
let i = this.results.findIndex((res) =>
|
|
349
|
-
element.doi ? element.doi.includes(res.doi) : false
|
|
350
|
-
)
|
|
351
|
-
// Assign scicrunch results to the object
|
|
352
|
-
Object.assign(this.results[i], element)
|
|
353
|
-
// Assign the attributes that need some processing
|
|
354
|
-
Object.assign(this.results[i], {
|
|
355
|
-
numberSamples: element.sampleSize ? parseInt(element.sampleSize) : 0,
|
|
356
|
-
numberSubjects: element.subjectSize
|
|
357
|
-
? parseInt(element.subjectSize)
|
|
358
|
-
: 0,
|
|
359
|
-
updated:
|
|
360
|
-
(element.updated && element.updated.length) > 0
|
|
361
|
-
? element.updated[0].timestamp.split('T')[0]
|
|
362
|
-
: '',
|
|
363
|
-
url: element.uri[0],
|
|
364
|
-
datasetId: element.dataset_identifier,
|
|
365
|
-
datasetRevision: element.dataset_revision,
|
|
366
|
-
datasetVersion: element.dataset_version,
|
|
367
|
-
organs:
|
|
368
|
-
element.organs && element.organs.length > 0
|
|
369
|
-
? [...new Set(element.organs.map((v) => v.name))]
|
|
370
|
-
: undefined,
|
|
371
|
-
species: element.organisms
|
|
372
|
-
? element.organisms[0].species
|
|
373
|
-
? [
|
|
374
|
-
...new Set(
|
|
375
|
-
element.organisms.map((v) =>
|
|
376
|
-
v.species ? v.species.name : null
|
|
377
|
-
)
|
|
378
|
-
),
|
|
379
|
-
]
|
|
380
|
-
: undefined
|
|
381
|
-
: undefined, // This processing only includes each gender once into 'sexes'
|
|
382
|
-
scaffolds: element['abi-scaffold-metadata-file'],
|
|
383
|
-
thumbnails: element['abi-thumbnail']
|
|
384
|
-
? element['abi-thumbnail']
|
|
385
|
-
: element['abi-scaffold-thumbnail'],
|
|
386
|
-
scaffoldViews: element['abi-scaffold-view-file'],
|
|
387
|
-
videos: element.video,
|
|
388
|
-
plots: element['abi-plot'],
|
|
389
|
-
images: element['common-images'],
|
|
390
|
-
contextualInformation:
|
|
391
|
-
element['abi-contextual-information'].length > 0
|
|
392
|
-
? element['abi-contextual-information']
|
|
393
|
-
: undefined,
|
|
394
|
-
segmentation: element['mbf-segmentation'],
|
|
395
|
-
simulation: element['abi-simulation-file'],
|
|
396
|
-
additionalLinks: element.additionalLinks,
|
|
397
|
-
detailsReady: true,
|
|
398
|
-
})
|
|
399
|
-
this.results[i] = this.results[i]
|
|
400
|
-
})
|
|
401
|
-
},
|
|
402
|
-
createfilterParams: function (params) {
|
|
403
|
-
let p = new URLSearchParams()
|
|
404
|
-
//Check if field is array or value
|
|
405
|
-
for (const key in params) {
|
|
406
|
-
if (Array.isArray(params[key])) {
|
|
407
|
-
params[key].forEach((e) => {
|
|
408
|
-
p.append(key, e)
|
|
409
|
-
})
|
|
410
|
-
} else {
|
|
411
|
-
p.append(key, params[key])
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return p.toString()
|
|
415
|
-
},
|
|
416
|
-
callSciCrunch: function (apiLocation, params = {}, signal) {
|
|
417
|
-
return new Promise((resolve, reject) => {
|
|
418
|
-
// Add parameters if we are sent them
|
|
419
|
-
let fullEndpoint =
|
|
420
|
-
this.envVars.API_LOCATION +
|
|
421
|
-
this.searchEndpoint +
|
|
422
|
-
'?' +
|
|
423
|
-
this.createfilterParams(params)
|
|
424
|
-
fetch(fullEndpoint, { signal })
|
|
425
|
-
.then(handleErrors)
|
|
426
|
-
.then((response) => response.json())
|
|
427
|
-
.then((data) => resolve(data))
|
|
428
|
-
.catch((data) => reject(data))
|
|
429
|
-
})
|
|
430
|
-
},
|
|
431
|
-
getAlgoliaFacets: async function () {
|
|
432
|
-
let facets = await this.algoliaClient.getAlgoliaFacets(
|
|
433
|
-
facetPropPathMapping
|
|
434
|
-
)
|
|
435
|
-
return facets
|
|
436
|
-
},
|
|
437
|
-
searchHistorySearch: function (item) {
|
|
438
|
-
this.searchInput = item.search
|
|
439
|
-
this.filters = item.filters
|
|
440
|
-
this.openSearch(item.filters, item.search)
|
|
441
|
-
},
|
|
442
|
-
},
|
|
443
|
-
mounted: function () {
|
|
444
|
-
// initialise algolia
|
|
445
|
-
this.algoliaClient = new AlgoliaClient(
|
|
446
|
-
this.envVars.ALGOLIA_ID,
|
|
447
|
-
this.envVars.ALGOLIA_KEY,
|
|
448
|
-
this.envVars.PENNSIEVE_API_LOCATION
|
|
449
|
-
)
|
|
450
|
-
this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX)
|
|
451
|
-
this.openSearch(this.filter, this.searchInput)
|
|
452
|
-
},
|
|
453
|
-
created: function () {
|
|
454
|
-
//Create non-reactive local variables
|
|
455
|
-
this.searchEndpoint = 'dataset_info/using_multiple_dois/'
|
|
456
|
-
},
|
|
457
|
-
}
|
|
458
|
-
</script>
|
|
459
|
-
|
|
460
|
-
<style lang="scss" scoped>
|
|
461
|
-
.dataset-card:hover {
|
|
462
|
-
border-style: solid;
|
|
463
|
-
border-color: var(--el-color-primary);
|
|
464
|
-
border-radius: 5px;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
.content-card {
|
|
468
|
-
height: 100%;
|
|
469
|
-
flex-flow: column;
|
|
470
|
-
display: flex;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.step-item {
|
|
474
|
-
font-size: 14px;
|
|
475
|
-
margin-bottom: 18px;
|
|
476
|
-
text-align: left;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
.search-input {
|
|
480
|
-
width: 298px !important;
|
|
481
|
-
height: 40px;
|
|
482
|
-
padding-right: 14px;
|
|
483
|
-
align-items: left;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
.header {
|
|
487
|
-
border: solid 1px #292b66;
|
|
488
|
-
background-color: #292b66;
|
|
489
|
-
text-align: left;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
.pagination {
|
|
493
|
-
padding-bottom: 16px;
|
|
494
|
-
background-color: white;
|
|
495
|
-
padding-left: 95px;
|
|
496
|
-
font-weight: bold;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
.pagination :deep(button) {
|
|
500
|
-
background-color: white !important;
|
|
501
|
-
}
|
|
502
|
-
.pagination :deep(li) {
|
|
503
|
-
background-color: white !important;
|
|
504
|
-
}
|
|
505
|
-
.pagination :deep(li.is-active) {
|
|
506
|
-
color: $app-primary-color;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
.error-feedback {
|
|
510
|
-
font-family: Asap;
|
|
511
|
-
font-size: 14px;
|
|
512
|
-
font-style: italic;
|
|
513
|
-
padding-top: 15px;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
.content-card :deep(.el-card__header) {
|
|
517
|
-
background-color: #292b66;
|
|
518
|
-
border: solid 1px #292b66;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
.content-card :deep(.el-card__body) {
|
|
522
|
-
background-color: #f7faff;
|
|
523
|
-
overflow-y: hidden;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
.content {
|
|
527
|
-
width: 515px;
|
|
528
|
-
flex: 1 1 auto;
|
|
529
|
-
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
530
|
-
border: solid 1px #e4e7ed;
|
|
531
|
-
background-color: #ffffff;
|
|
532
|
-
overflow-y: scroll;
|
|
533
|
-
scrollbar-width: thin;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
.content :deep(.el-loading-spinner .path) {
|
|
537
|
-
stroke: $app-primary-color;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
.content :deep(.step-item:first-child .seperator-path) {
|
|
541
|
-
display: none;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
.content :deep(.step-item:not(:first-child) .seperator-path) {
|
|
545
|
-
width: 455px;
|
|
546
|
-
height: 0px;
|
|
547
|
-
border: solid 1px #e4e7ed;
|
|
548
|
-
background-color: #e4e7ed;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
.scrollbar::-webkit-scrollbar-track {
|
|
552
|
-
border-radius: 10px;
|
|
553
|
-
background-color: #f5f5f5;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
.scrollbar::-webkit-scrollbar {
|
|
557
|
-
width: 12px;
|
|
558
|
-
right: -12px;
|
|
559
|
-
background-color: #f5f5f5;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
.scrollbar::-webkit-scrollbar-thumb {
|
|
563
|
-
border-radius: 4px;
|
|
564
|
-
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
|
|
565
|
-
background-color: #979797;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
:deep(.el-input__suffix) {
|
|
569
|
-
padding-right: 0px;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
:deep(.my-drawer) {
|
|
573
|
-
background: rgba(0, 0, 0, 0);
|
|
574
|
-
box-shadow: none;
|
|
575
|
-
}
|
|
576
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<el-card :body-style="bodyStyle" class="content-card">
|
|
3
|
+
<template #header>
|
|
4
|
+
<div class="header">
|
|
5
|
+
<el-input
|
|
6
|
+
class="search-input"
|
|
7
|
+
placeholder="Search"
|
|
8
|
+
v-model="searchInput"
|
|
9
|
+
@keyup="searchEvent"
|
|
10
|
+
clearable
|
|
11
|
+
@clear="clearSearchClicked"
|
|
12
|
+
></el-input>
|
|
13
|
+
<el-button
|
|
14
|
+
type="primary"
|
|
15
|
+
class="button"
|
|
16
|
+
@click="searchEvent"
|
|
17
|
+
size="large"
|
|
18
|
+
>
|
|
19
|
+
Search
|
|
20
|
+
</el-button>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
<SearchFilters
|
|
24
|
+
class="filters"
|
|
25
|
+
ref="filtersRef"
|
|
26
|
+
:entry="filterEntry"
|
|
27
|
+
:envVars="envVars"
|
|
28
|
+
@filterResults="filterUpdate"
|
|
29
|
+
@numberPerPage="numberPerPageUpdate"
|
|
30
|
+
@loading="filtersLoading"
|
|
31
|
+
@cascaderReady="cascaderReady"
|
|
32
|
+
></SearchFilters>
|
|
33
|
+
<SearchHistory
|
|
34
|
+
ref="searchHistory"
|
|
35
|
+
@search="searchHistorySearch"
|
|
36
|
+
></SearchHistory>
|
|
37
|
+
<div class="content scrollbar" v-loading="loadingCards" ref="content">
|
|
38
|
+
<div class="error-feedback" v-if="results.length === 0 && !loadingCards">
|
|
39
|
+
No results found - Please change your search / filter criteria.
|
|
40
|
+
</div>
|
|
41
|
+
<div v-for="result in results" :key="result.doi" class="step-item">
|
|
42
|
+
<DatasetCard
|
|
43
|
+
class="dataset-card"
|
|
44
|
+
:entry="result"
|
|
45
|
+
:envVars="envVars"
|
|
46
|
+
@mouseenter="hoverChanged(result)"
|
|
47
|
+
@mouseleave="hoverChanged(undefined)"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
<el-pagination
|
|
51
|
+
class="pagination"
|
|
52
|
+
v-model:current-page="page"
|
|
53
|
+
hide-on-single-page
|
|
54
|
+
large
|
|
55
|
+
layout="prev, pager, next"
|
|
56
|
+
:page-size="numberPerPage"
|
|
57
|
+
:total="numberOfHits"
|
|
58
|
+
@current-change="pageChange"
|
|
59
|
+
></el-pagination>
|
|
60
|
+
</div>
|
|
61
|
+
</el-card>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script>
|
|
65
|
+
/* eslint-disable no-alert, no-console */
|
|
66
|
+
import {
|
|
67
|
+
ElButton as Button,
|
|
68
|
+
ElCard as Card,
|
|
69
|
+
ElDrawer as Drawer,
|
|
70
|
+
ElIcon as Icon,
|
|
71
|
+
ElInput as Input,
|
|
72
|
+
ElPagination as Pagination,
|
|
73
|
+
} from 'element-plus'
|
|
74
|
+
import SearchFilters from './SearchFilters.vue'
|
|
75
|
+
import SearchHistory from './SearchHistory.vue'
|
|
76
|
+
import DatasetCard from './DatasetCard.vue'
|
|
77
|
+
import EventBus from './EventBus.js'
|
|
78
|
+
|
|
79
|
+
import { AlgoliaClient } from '../algolia/algolia.js'
|
|
80
|
+
import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
|
|
81
|
+
|
|
82
|
+
// handleErrors: A custom fetch error handler to recieve messages from the server
|
|
83
|
+
// even when an error is found
|
|
84
|
+
var handleErrors = async function (response) {
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
let parse = await response.json()
|
|
87
|
+
if (parse) {
|
|
88
|
+
throw new Error(parse.message)
|
|
89
|
+
} else {
|
|
90
|
+
throw new Error(response)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return response
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
var initial_state = {
|
|
97
|
+
searchInput: '',
|
|
98
|
+
lastSearch: '',
|
|
99
|
+
results: [],
|
|
100
|
+
numberOfHits: 0,
|
|
101
|
+
filter: [],
|
|
102
|
+
loadingCards: false,
|
|
103
|
+
numberPerPage: 10,
|
|
104
|
+
page: 1,
|
|
105
|
+
pageModel: 1,
|
|
106
|
+
start: 0,
|
|
107
|
+
hasSearched: false,
|
|
108
|
+
contextCardEnabled: false,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default {
|
|
112
|
+
components: {
|
|
113
|
+
SearchFilters,
|
|
114
|
+
DatasetCard,
|
|
115
|
+
SearchHistory,
|
|
116
|
+
Button,
|
|
117
|
+
Card,
|
|
118
|
+
Drawer,
|
|
119
|
+
Icon,
|
|
120
|
+
Input,
|
|
121
|
+
Pagination
|
|
122
|
+
},
|
|
123
|
+
name: 'SideBarContent',
|
|
124
|
+
props: {
|
|
125
|
+
visible: {
|
|
126
|
+
type: Boolean,
|
|
127
|
+
default: false,
|
|
128
|
+
},
|
|
129
|
+
isDrawer: {
|
|
130
|
+
type: Boolean,
|
|
131
|
+
default: true,
|
|
132
|
+
},
|
|
133
|
+
entry: {
|
|
134
|
+
type: Object,
|
|
135
|
+
default: () => initial_state,
|
|
136
|
+
},
|
|
137
|
+
envVars: {
|
|
138
|
+
type: Object,
|
|
139
|
+
default: () => {},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
data: function () {
|
|
143
|
+
return {
|
|
144
|
+
...this.entry,
|
|
145
|
+
bodyStyle: {
|
|
146
|
+
flex: '1 1 auto',
|
|
147
|
+
'flex-flow': 'column',
|
|
148
|
+
display: 'flex',
|
|
149
|
+
},
|
|
150
|
+
cascaderIsReady: false,
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
computed: {
|
|
154
|
+
// This computed property populates filter data's entry object with $data from this sidebar
|
|
155
|
+
filterEntry: function () {
|
|
156
|
+
return {
|
|
157
|
+
numberOfHits: this.numberOfHits,
|
|
158
|
+
filterFacets: this.filter,
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
methods: {
|
|
163
|
+
hoverChanged: function (data) {
|
|
164
|
+
this.$emit('hover-changed', data)
|
|
165
|
+
},
|
|
166
|
+
resetSearch: function () {
|
|
167
|
+
this.numberOfHits = 0
|
|
168
|
+
this.discoverIds = []
|
|
169
|
+
this._dois = []
|
|
170
|
+
this.results = []
|
|
171
|
+
this.loadingCards = false
|
|
172
|
+
},
|
|
173
|
+
openSearch: function (filter, search = '') {
|
|
174
|
+
this.searchInput = search
|
|
175
|
+
this.resetPageNavigation()
|
|
176
|
+
//Proceed normally if cascader is ready
|
|
177
|
+
if (this.cascaderIsReady) {
|
|
178
|
+
this.filter =
|
|
179
|
+
this.$refs.filtersRef.getHierarchicalValidatedFilters(filter)
|
|
180
|
+
//Facets provided but cannot find at least one valid
|
|
181
|
+
//facet. Tell the users the search is invalid and reset
|
|
182
|
+
//facets check boxes.
|
|
183
|
+
if (
|
|
184
|
+
filter &&
|
|
185
|
+
filter.length > 0 &&
|
|
186
|
+
this.filter &&
|
|
187
|
+
this.filter.length === 0
|
|
188
|
+
) {
|
|
189
|
+
this.$refs.filtersRef.checkShowAllBoxes()
|
|
190
|
+
this.resetSearch()
|
|
191
|
+
} else if (this.filter) {
|
|
192
|
+
this.searchAlgolia(this.filter, search)
|
|
193
|
+
this.$refs.filtersRef.setCascader(this.filter)
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
//cascader is not ready, perform search if no filter is set,
|
|
197
|
+
//otherwise waith for cascader to be ready
|
|
198
|
+
this.filter = filter
|
|
199
|
+
if (!filter || filter.length == 0) {
|
|
200
|
+
this.searchAlgolia(this.filter, search)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
addFilter: function (filter) {
|
|
205
|
+
if (this.cascaderIsReady) {
|
|
206
|
+
this.resetPageNavigation()
|
|
207
|
+
if (filter) {
|
|
208
|
+
if (this.$refs.filtersRef.addFilter(filter))
|
|
209
|
+
this.$refs.filtersRef.initiateSearch()
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
if (Array.isArray(this.filter)) {
|
|
213
|
+
this.filter.push(filter)
|
|
214
|
+
} else {
|
|
215
|
+
this.filter = [filter]
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
cascaderReady: function () {
|
|
220
|
+
this.cascaderIsReady = true
|
|
221
|
+
this.openSearch(this.filter, this.searchInput)
|
|
222
|
+
},
|
|
223
|
+
clearSearchClicked: function () {
|
|
224
|
+
this.searchInput = ''
|
|
225
|
+
this.resetPageNavigation()
|
|
226
|
+
this.searchAlgolia(this.filters, this.searchInput)
|
|
227
|
+
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
228
|
+
},
|
|
229
|
+
searchEvent: function (event = false) {
|
|
230
|
+
if (event.keyCode === 13 || event instanceof MouseEvent) {
|
|
231
|
+
this.resetPageNavigation()
|
|
232
|
+
this.searchAlgolia(this.filters, this.searchInput)
|
|
233
|
+
this.$refs.searchHistory.selectValue = 'Full search history'
|
|
234
|
+
this.$refs.searchHistory.addSearchToHistory(
|
|
235
|
+
this.filters,
|
|
236
|
+
this.searchInput
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
filterUpdate: function (filters) {
|
|
241
|
+
this.filters = [...filters]
|
|
242
|
+
this.resetPageNavigation()
|
|
243
|
+
this.searchAlgolia(filters, this.searchInput)
|
|
244
|
+
this.$emit('search-changed', {
|
|
245
|
+
value: filters,
|
|
246
|
+
type: 'filter-update',
|
|
247
|
+
})
|
|
248
|
+
},
|
|
249
|
+
searchAlgolia(filters, query = '') {
|
|
250
|
+
// Algolia search
|
|
251
|
+
|
|
252
|
+
this.loadingCards = true
|
|
253
|
+
this.algoliaClient
|
|
254
|
+
.anatomyInSearch(getFilters(filters), query)
|
|
255
|
+
.then((r) => {
|
|
256
|
+
// Send result anatomy to the scaffold and flatmap
|
|
257
|
+
EventBus.emit('anatomy-in-datasets', r.forFlatmap)
|
|
258
|
+
EventBus.emit('number-of-datasets-for-anatomies', r.forScaffold)
|
|
259
|
+
})
|
|
260
|
+
this.algoliaClient
|
|
261
|
+
.search(getFilters(filters), query, this.numberPerPage, this.page)
|
|
262
|
+
.then((searchData) => {
|
|
263
|
+
this.numberOfHits = searchData.total
|
|
264
|
+
this.discoverIds = searchData.discoverIds
|
|
265
|
+
this._dois = searchData.dois
|
|
266
|
+
this.results = searchData.items
|
|
267
|
+
this.loadingCards = false
|
|
268
|
+
this.scrollToTop()
|
|
269
|
+
this.$emit('search-changed', {
|
|
270
|
+
value: this.searchInput,
|
|
271
|
+
type: 'query-update',
|
|
272
|
+
})
|
|
273
|
+
if (this._abortController) this._abortController.abort()
|
|
274
|
+
this._abortController = new AbortController()
|
|
275
|
+
const signal = this._abortController.signal
|
|
276
|
+
//Search ongoing, let the current flow progress
|
|
277
|
+
this.perItemSearch(signal, { count: 0 })
|
|
278
|
+
})
|
|
279
|
+
},
|
|
280
|
+
filtersLoading: function (val) {
|
|
281
|
+
this.loadingCards = val
|
|
282
|
+
},
|
|
283
|
+
numberPerPageUpdate: function (val) {
|
|
284
|
+
this.numberPerPage = val
|
|
285
|
+
this.pageChange(1)
|
|
286
|
+
},
|
|
287
|
+
pageChange: function (page) {
|
|
288
|
+
this.start = (page - 1) * this.numberPerPage
|
|
289
|
+
this.page = page
|
|
290
|
+
this.searchAlgolia(
|
|
291
|
+
this.filters,
|
|
292
|
+
this.searchInput,
|
|
293
|
+
this.numberPerPage,
|
|
294
|
+
this.page
|
|
295
|
+
)
|
|
296
|
+
},
|
|
297
|
+
handleMissingData: function (doi) {
|
|
298
|
+
let i = this.results.findIndex((res) => res.doi === doi)
|
|
299
|
+
if (this.results[i]) this.results[i].detailsReady = true
|
|
300
|
+
},
|
|
301
|
+
perItemSearch: function (signal, data) {
|
|
302
|
+
//Maximum 10 downloads at once to prevent long waiting time
|
|
303
|
+
//between unfinished search and new search
|
|
304
|
+
const maxDownloads = 10
|
|
305
|
+
if (maxDownloads > data.count) {
|
|
306
|
+
const doi = this._dois.shift()
|
|
307
|
+
if (doi) {
|
|
308
|
+
data.count++
|
|
309
|
+
this.callSciCrunch(this.envVars.API_LOCATION, { dois: [doi] }, signal)
|
|
310
|
+
.then((result) => {
|
|
311
|
+
if (result.numberOfHits === 0) this.handleMissingData(doi)
|
|
312
|
+
else this.resultsProcessing(result)
|
|
313
|
+
this.$refs.content.style['overflow-y'] = 'scroll'
|
|
314
|
+
data.count--
|
|
315
|
+
//Async::Download finished, get the next one
|
|
316
|
+
this.perItemSearch(signal, data)
|
|
317
|
+
})
|
|
318
|
+
.catch((result) => {
|
|
319
|
+
if (result.name !== 'AbortError') {
|
|
320
|
+
this.handleMissingData(doi)
|
|
321
|
+
data.count--
|
|
322
|
+
//Async::Download not aborted, get the next one
|
|
323
|
+
this.perItemSearch(signal, data)
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
//Check and make another request until it gets to max downloads
|
|
327
|
+
this.perItemSearch(signal, data)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
scrollToTop: function () {
|
|
332
|
+
if (this.$refs.content) {
|
|
333
|
+
this.$refs.content.scroll({ top: 0, behavior: 'smooth' })
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
resetPageNavigation: function () {
|
|
337
|
+
this.start = 0
|
|
338
|
+
this.page = 1
|
|
339
|
+
},
|
|
340
|
+
resultsProcessing: function (data) {
|
|
341
|
+
this.lastSearch = this.searchInput
|
|
342
|
+
|
|
343
|
+
if (data.results.length === 0) {
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
data.results.forEach((element) => {
|
|
347
|
+
// match the scicrunch result with algolia result
|
|
348
|
+
let i = this.results.findIndex((res) =>
|
|
349
|
+
element.doi ? element.doi.includes(res.doi) : false
|
|
350
|
+
)
|
|
351
|
+
// Assign scicrunch results to the object
|
|
352
|
+
Object.assign(this.results[i], element)
|
|
353
|
+
// Assign the attributes that need some processing
|
|
354
|
+
Object.assign(this.results[i], {
|
|
355
|
+
numberSamples: element.sampleSize ? parseInt(element.sampleSize) : 0,
|
|
356
|
+
numberSubjects: element.subjectSize
|
|
357
|
+
? parseInt(element.subjectSize)
|
|
358
|
+
: 0,
|
|
359
|
+
updated:
|
|
360
|
+
(element.updated && element.updated.length) > 0
|
|
361
|
+
? element.updated[0].timestamp.split('T')[0]
|
|
362
|
+
: '',
|
|
363
|
+
url: element.uri[0],
|
|
364
|
+
datasetId: element.dataset_identifier,
|
|
365
|
+
datasetRevision: element.dataset_revision,
|
|
366
|
+
datasetVersion: element.dataset_version,
|
|
367
|
+
organs:
|
|
368
|
+
element.organs && element.organs.length > 0
|
|
369
|
+
? [...new Set(element.organs.map((v) => v.name))]
|
|
370
|
+
: undefined,
|
|
371
|
+
species: element.organisms
|
|
372
|
+
? element.organisms[0].species
|
|
373
|
+
? [
|
|
374
|
+
...new Set(
|
|
375
|
+
element.organisms.map((v) =>
|
|
376
|
+
v.species ? v.species.name : null
|
|
377
|
+
)
|
|
378
|
+
),
|
|
379
|
+
]
|
|
380
|
+
: undefined
|
|
381
|
+
: undefined, // This processing only includes each gender once into 'sexes'
|
|
382
|
+
scaffolds: element['abi-scaffold-metadata-file'],
|
|
383
|
+
thumbnails: element['abi-thumbnail']
|
|
384
|
+
? element['abi-thumbnail']
|
|
385
|
+
: element['abi-scaffold-thumbnail'],
|
|
386
|
+
scaffoldViews: element['abi-scaffold-view-file'],
|
|
387
|
+
videos: element.video,
|
|
388
|
+
plots: element['abi-plot'],
|
|
389
|
+
images: element['common-images'],
|
|
390
|
+
contextualInformation:
|
|
391
|
+
element['abi-contextual-information'].length > 0
|
|
392
|
+
? element['abi-contextual-information']
|
|
393
|
+
: undefined,
|
|
394
|
+
segmentation: element['mbf-segmentation'],
|
|
395
|
+
simulation: element['abi-simulation-file'],
|
|
396
|
+
additionalLinks: element.additionalLinks,
|
|
397
|
+
detailsReady: true,
|
|
398
|
+
})
|
|
399
|
+
this.results[i] = this.results[i]
|
|
400
|
+
})
|
|
401
|
+
},
|
|
402
|
+
createfilterParams: function (params) {
|
|
403
|
+
let p = new URLSearchParams()
|
|
404
|
+
//Check if field is array or value
|
|
405
|
+
for (const key in params) {
|
|
406
|
+
if (Array.isArray(params[key])) {
|
|
407
|
+
params[key].forEach((e) => {
|
|
408
|
+
p.append(key, e)
|
|
409
|
+
})
|
|
410
|
+
} else {
|
|
411
|
+
p.append(key, params[key])
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return p.toString()
|
|
415
|
+
},
|
|
416
|
+
callSciCrunch: function (apiLocation, params = {}, signal) {
|
|
417
|
+
return new Promise((resolve, reject) => {
|
|
418
|
+
// Add parameters if we are sent them
|
|
419
|
+
let fullEndpoint =
|
|
420
|
+
this.envVars.API_LOCATION +
|
|
421
|
+
this.searchEndpoint +
|
|
422
|
+
'?' +
|
|
423
|
+
this.createfilterParams(params)
|
|
424
|
+
fetch(fullEndpoint, { signal })
|
|
425
|
+
.then(handleErrors)
|
|
426
|
+
.then((response) => response.json())
|
|
427
|
+
.then((data) => resolve(data))
|
|
428
|
+
.catch((data) => reject(data))
|
|
429
|
+
})
|
|
430
|
+
},
|
|
431
|
+
getAlgoliaFacets: async function () {
|
|
432
|
+
let facets = await this.algoliaClient.getAlgoliaFacets(
|
|
433
|
+
facetPropPathMapping
|
|
434
|
+
)
|
|
435
|
+
return facets
|
|
436
|
+
},
|
|
437
|
+
searchHistorySearch: function (item) {
|
|
438
|
+
this.searchInput = item.search
|
|
439
|
+
this.filters = item.filters
|
|
440
|
+
this.openSearch(item.filters, item.search)
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
mounted: function () {
|
|
444
|
+
// initialise algolia
|
|
445
|
+
this.algoliaClient = new AlgoliaClient(
|
|
446
|
+
this.envVars.ALGOLIA_ID,
|
|
447
|
+
this.envVars.ALGOLIA_KEY,
|
|
448
|
+
this.envVars.PENNSIEVE_API_LOCATION
|
|
449
|
+
)
|
|
450
|
+
this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX)
|
|
451
|
+
this.openSearch(this.filter, this.searchInput)
|
|
452
|
+
},
|
|
453
|
+
created: function () {
|
|
454
|
+
//Create non-reactive local variables
|
|
455
|
+
this.searchEndpoint = 'dataset_info/using_multiple_dois/'
|
|
456
|
+
},
|
|
457
|
+
}
|
|
458
|
+
</script>
|
|
459
|
+
|
|
460
|
+
<style lang="scss" scoped>
|
|
461
|
+
.dataset-card:hover {
|
|
462
|
+
border-style: solid;
|
|
463
|
+
border-color: var(--el-color-primary);
|
|
464
|
+
border-radius: 5px;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.content-card {
|
|
468
|
+
height: 100%;
|
|
469
|
+
flex-flow: column;
|
|
470
|
+
display: flex;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.step-item {
|
|
474
|
+
font-size: 14px;
|
|
475
|
+
margin-bottom: 18px;
|
|
476
|
+
text-align: left;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.search-input {
|
|
480
|
+
width: 298px !important;
|
|
481
|
+
height: 40px;
|
|
482
|
+
padding-right: 14px;
|
|
483
|
+
align-items: left;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.header {
|
|
487
|
+
border: solid 1px #292b66;
|
|
488
|
+
background-color: #292b66;
|
|
489
|
+
text-align: left;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.pagination {
|
|
493
|
+
padding-bottom: 16px;
|
|
494
|
+
background-color: white;
|
|
495
|
+
padding-left: 95px;
|
|
496
|
+
font-weight: bold;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.pagination :deep(button) {
|
|
500
|
+
background-color: white !important;
|
|
501
|
+
}
|
|
502
|
+
.pagination :deep(li) {
|
|
503
|
+
background-color: white !important;
|
|
504
|
+
}
|
|
505
|
+
.pagination :deep(li.is-active) {
|
|
506
|
+
color: $app-primary-color;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.error-feedback {
|
|
510
|
+
font-family: Asap;
|
|
511
|
+
font-size: 14px;
|
|
512
|
+
font-style: italic;
|
|
513
|
+
padding-top: 15px;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.content-card :deep(.el-card__header) {
|
|
517
|
+
background-color: #292b66;
|
|
518
|
+
border: solid 1px #292b66;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.content-card :deep(.el-card__body) {
|
|
522
|
+
background-color: #f7faff;
|
|
523
|
+
overflow-y: hidden;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.content {
|
|
527
|
+
width: 515px;
|
|
528
|
+
flex: 1 1 auto;
|
|
529
|
+
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
|
|
530
|
+
border: solid 1px #e4e7ed;
|
|
531
|
+
background-color: #ffffff;
|
|
532
|
+
overflow-y: scroll;
|
|
533
|
+
scrollbar-width: thin;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.content :deep(.el-loading-spinner .path) {
|
|
537
|
+
stroke: $app-primary-color;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.content :deep(.step-item:first-child .seperator-path) {
|
|
541
|
+
display: none;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.content :deep(.step-item:not(:first-child) .seperator-path) {
|
|
545
|
+
width: 455px;
|
|
546
|
+
height: 0px;
|
|
547
|
+
border: solid 1px #e4e7ed;
|
|
548
|
+
background-color: #e4e7ed;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
.scrollbar::-webkit-scrollbar-track {
|
|
552
|
+
border-radius: 10px;
|
|
553
|
+
background-color: #f5f5f5;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.scrollbar::-webkit-scrollbar {
|
|
557
|
+
width: 12px;
|
|
558
|
+
right: -12px;
|
|
559
|
+
background-color: #f5f5f5;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.scrollbar::-webkit-scrollbar-thumb {
|
|
563
|
+
border-radius: 4px;
|
|
564
|
+
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
|
|
565
|
+
background-color: #979797;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
:deep(.el-input__suffix) {
|
|
569
|
+
padding-right: 0px;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
:deep(.my-drawer) {
|
|
573
|
+
background: rgba(0, 0, 0, 0);
|
|
574
|
+
box-shadow: none;
|
|
575
|
+
}
|
|
576
|
+
</style>
|