@abi-software/map-side-bar 2.14.1-simulation.0 → 2.14.1-simulation.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/dist/map-side-bar.js +17630 -13113
- package/dist/map-side-bar.umd.cjs +84 -68
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +5 -0
- package/src/components/BadgesGroup.vue +1 -0
- package/src/components/DatasetCard.vue +418 -8
- package/src/components/DatasetExplorer.vue +154 -104
- package/src/components/FileBrowser.vue +200 -0
- package/src/components/ImageGallery.vue +11 -366
- package/src/components/SideBar.vue +8 -0
- package/src/components/scripts/utilities.js +50 -0
- package/src/components.d.ts +5 -0
|
@@ -1,108 +1,118 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
<el-card :body-style="bodyStyle" class="content-card">
|
|
3
|
+
<template #header>
|
|
4
|
+
<div class="header">
|
|
5
|
+
<div class="search-input-container" :class="{'is-focus': searchInput}">
|
|
6
|
+
<el-input
|
|
7
|
+
class="search-input"
|
|
8
|
+
placeholder="Search"
|
|
9
|
+
v-model="searchInput"
|
|
10
|
+
@keyup="searchEvent"
|
|
11
|
+
clearable
|
|
12
|
+
@clear="clearSearchClicked"
|
|
13
|
+
></el-input>
|
|
14
|
+
<el-popover
|
|
15
|
+
width="350"
|
|
16
|
+
trigger="hover"
|
|
17
|
+
popper-class="filter-help-popover"
|
|
18
|
+
>
|
|
19
|
+
<template #reference>
|
|
20
|
+
<MapSvgIcon icon="help" class="help" />
|
|
21
|
+
</template>
|
|
22
|
+
<div>
|
|
23
|
+
<strong>Search rules:</strong>
|
|
24
|
+
<ul>
|
|
25
|
+
<li>
|
|
26
|
+
<strong>Multiple Terms:</strong> Separate terms with a comma (<code>,</code>).
|
|
27
|
+
This will find datasets that match any of the terms (an "OR" search).
|
|
28
|
+
</li>
|
|
29
|
+
<li>
|
|
30
|
+
<strong>Exact Phrase:</strong> Terms within a comma block will be matched as an exact phrase.
|
|
31
|
+
</li>
|
|
32
|
+
</ul>
|
|
33
|
+
<br/>
|
|
34
|
+
<strong>Examples:</strong>
|
|
35
|
+
<ul>
|
|
36
|
+
<li>
|
|
37
|
+
<strong>To find by exact phrase:</strong>
|
|
38
|
+
Searching for <code>vagus nerve</code> will find any dataset containing <code>"vagus nerve"</code>.
|
|
39
|
+
</li>
|
|
40
|
+
<li>
|
|
41
|
+
<strong>To find by multiple terms:</strong>
|
|
42
|
+
Searching for <code>nerve, vagus</code> will find data that contains either <code>nerve</code> OR <code>vagus</code>.
|
|
43
|
+
</li>
|
|
44
|
+
</ul>
|
|
45
|
+
</div>
|
|
46
|
+
</el-popover>
|
|
47
|
+
</div>
|
|
48
|
+
<el-button
|
|
49
|
+
type="primary"
|
|
50
|
+
class="button"
|
|
51
|
+
@click="searchEvent"
|
|
52
|
+
size="large"
|
|
18
53
|
>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<li>
|
|
30
|
-
<strong>Exact Phrase:</strong> Terms within a comma block will be matched as an exact phrase.
|
|
31
|
-
</li>
|
|
32
|
-
</ul>
|
|
33
|
-
<br/>
|
|
34
|
-
<strong>Examples:</strong>
|
|
35
|
-
<ul>
|
|
36
|
-
<li>
|
|
37
|
-
<strong>To find by exact phrase:</strong>
|
|
38
|
-
Searching for <code>vagus nerve</code> will find any dataset containing <code>"vagus nerve"</code>.
|
|
39
|
-
</li>
|
|
40
|
-
<li>
|
|
41
|
-
<strong>To find by multiple terms:</strong>
|
|
42
|
-
Searching for <code>nerve, vagus</code> will find data that contains either <code>nerve</code> OR <code>vagus</code>.
|
|
43
|
-
</li>
|
|
44
|
-
</ul>
|
|
45
|
-
</div>
|
|
46
|
-
</el-popover>
|
|
54
|
+
Search
|
|
55
|
+
</el-button>
|
|
56
|
+
<el-button
|
|
57
|
+
link
|
|
58
|
+
class="el-button-link"
|
|
59
|
+
@click="onResetClick"
|
|
60
|
+
size="large"
|
|
61
|
+
>
|
|
62
|
+
Reset
|
|
63
|
+
</el-button>
|
|
47
64
|
</div>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
:envVars="envVars"
|
|
90
|
-
@mouseenter="hoverChanged(result)"
|
|
91
|
-
@mouseleave="hoverChanged(undefined)"
|
|
92
|
-
/>
|
|
65
|
+
</template>
|
|
66
|
+
<SearchFilters
|
|
67
|
+
class="filters"
|
|
68
|
+
ref="filtersRef"
|
|
69
|
+
:entry="filterEntry"
|
|
70
|
+
:envVars="envVars"
|
|
71
|
+
@filterResults="filterUpdate"
|
|
72
|
+
@numberPerPage="numberPerPageUpdate"
|
|
73
|
+
@loading="filtersLoading"
|
|
74
|
+
@cascaderReady="cascaderReady"
|
|
75
|
+
></SearchFilters>
|
|
76
|
+
<SearchHistory
|
|
77
|
+
ref="searchHistory"
|
|
78
|
+
localStorageKey="sparc.science-dataset-search-history"
|
|
79
|
+
@search="searchHistorySearch"
|
|
80
|
+
></SearchHistory>
|
|
81
|
+
<div class="content scrollbar" v-loading="loadingCards" ref="content">
|
|
82
|
+
<div class="error-feedback" v-if="results.length === 0 && !loadingCards">
|
|
83
|
+
No results found - Please change your search / filter criteria.
|
|
84
|
+
</div>
|
|
85
|
+
<div v-for="result in results" :key="result.doi" class="step-item">
|
|
86
|
+
<DatasetCard
|
|
87
|
+
class="dataset-card"
|
|
88
|
+
:entry="result"
|
|
89
|
+
:envVars="envVars"
|
|
90
|
+
@mouseenter="hoverChanged(result)"
|
|
91
|
+
@mouseleave="hoverChanged(undefined)"
|
|
92
|
+
@openFileBrowser="openFileBrowser"
|
|
93
|
+
@fileInfoReady="fileInfoReady"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
<el-pagination
|
|
97
|
+
class="pagination"
|
|
98
|
+
v-model:current-page="page"
|
|
99
|
+
hide-on-single-page
|
|
100
|
+
large
|
|
101
|
+
layout="prev, pager, next"
|
|
102
|
+
:page-size="numberPerPage"
|
|
103
|
+
:total="numberOfHits"
|
|
104
|
+
@current-change="pageChange"
|
|
105
|
+
></el-pagination>
|
|
93
106
|
</div>
|
|
94
|
-
<el-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
></el-pagination>
|
|
104
|
-
</div>
|
|
105
|
-
</el-card>
|
|
107
|
+
<el-dialog
|
|
108
|
+
v-model="fileBrowserVisible"
|
|
109
|
+
title="File browser"
|
|
110
|
+
width="700"
|
|
111
|
+
top="16px">
|
|
112
|
+
<FileBrowser ref="fileBrowserRef" />
|
|
113
|
+
</el-dialog>
|
|
114
|
+
</el-card>
|
|
115
|
+
|
|
106
116
|
</template>
|
|
107
117
|
|
|
108
118
|
<script>
|
|
@@ -110,17 +120,20 @@
|
|
|
110
120
|
import {
|
|
111
121
|
ElButton as Button,
|
|
112
122
|
ElCard as Card,
|
|
123
|
+
ElDialog as Dialog,
|
|
113
124
|
ElDrawer as Drawer,
|
|
114
125
|
ElIcon as Icon,
|
|
115
126
|
ElInput as Input,
|
|
116
127
|
ElPagination as Pagination,
|
|
117
128
|
ElMessage as Message,
|
|
118
129
|
} from 'element-plus'
|
|
119
|
-
import 'element-plus/es/components/message/style/css'
|
|
130
|
+
import 'element-plus/es/components/message/style/css'
|
|
120
131
|
import SearchFilters from './SearchFilters.vue'
|
|
121
132
|
import SearchHistory from './SearchHistory.vue'
|
|
122
133
|
import DatasetCard from './DatasetCard.vue'
|
|
134
|
+
import FileBrowser from './FileBrowser.vue'
|
|
123
135
|
import EventBus from './EventBus.js'
|
|
136
|
+
import { processProtocolsData } from './scripts/utilities.js'
|
|
124
137
|
|
|
125
138
|
import { AlgoliaClient } from '../algolia/algolia.js'
|
|
126
139
|
import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
|
|
@@ -158,11 +171,13 @@ var initial_state = {
|
|
|
158
171
|
|
|
159
172
|
export default {
|
|
160
173
|
components: {
|
|
161
|
-
SearchFilters,
|
|
162
174
|
DatasetCard,
|
|
175
|
+
FileBrowser,
|
|
176
|
+
SearchFilters,
|
|
163
177
|
SearchHistory,
|
|
164
178
|
Button,
|
|
165
179
|
Card,
|
|
180
|
+
Dialog,
|
|
166
181
|
Drawer,
|
|
167
182
|
Icon,
|
|
168
183
|
Input,
|
|
@@ -199,6 +214,12 @@ export default {
|
|
|
199
214
|
display: 'flex',
|
|
200
215
|
},
|
|
201
216
|
cascaderIsReady: false,
|
|
217
|
+
fileBrowserVisible: false,
|
|
218
|
+
fileSearch: {
|
|
219
|
+
onGoing: false,
|
|
220
|
+
datasetId: undefined,
|
|
221
|
+
searchTerm: undefined,
|
|
222
|
+
}
|
|
202
223
|
}
|
|
203
224
|
},
|
|
204
225
|
computed: {
|
|
@@ -216,6 +237,21 @@ export default {
|
|
|
216
237
|
},
|
|
217
238
|
},
|
|
218
239
|
methods: {
|
|
240
|
+
fileInfoReady: function(payload) {
|
|
241
|
+
if (this.fileSearch.onGoing) {
|
|
242
|
+
if (payload.id === this.fileSearch.datasetID) {
|
|
243
|
+
console.log(payload.id)
|
|
244
|
+
payload.instance.openFileBrowser()
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
displayFileInfo: function(datasetID, fileSearch, searchTerm = "") {
|
|
249
|
+
let query = searchTerm ? searchTerm : datasetID
|
|
250
|
+
this.openSearch([], query)
|
|
251
|
+
this.fileSearch.onGoing = true
|
|
252
|
+
this.fileSearch.datasetID = datasetID
|
|
253
|
+
this.fileSearch.searchTerm = fileSearch
|
|
254
|
+
},
|
|
219
255
|
hoverChanged: function (data) {
|
|
220
256
|
const payload = data ? { ...data, tabType: 'dataset' } : { tabType: 'dataset' }
|
|
221
257
|
this.$emit('hover-changed', payload)
|
|
@@ -227,6 +263,18 @@ export default {
|
|
|
227
263
|
this.results = []
|
|
228
264
|
this.loadingCards = false
|
|
229
265
|
},
|
|
266
|
+
openFileBrowser: function(data) {
|
|
267
|
+
this.fileBrowserVisible = true
|
|
268
|
+
this.$nextTick(() => {
|
|
269
|
+
this.$refs.fileBrowserRef.setData(data.items)
|
|
270
|
+
if (this.fileSearch.onGoing) {
|
|
271
|
+
if (this.fileSearch.datasetID === data.datasetID) {
|
|
272
|
+
this.$refs.fileBrowserRef.setSearchTerm(this.fileSearch.searchTerm)
|
|
273
|
+
}
|
|
274
|
+
this.fileSearch.onGoing = false
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
},
|
|
230
278
|
openSearch: function (filter, search = '') {
|
|
231
279
|
this.searchInput = search
|
|
232
280
|
this.resetPageNavigation()
|
|
@@ -418,7 +466,7 @@ export default {
|
|
|
418
466
|
})
|
|
419
467
|
.then((data) => {
|
|
420
468
|
if (this.searchInput.toLowerCase().includes("reveal")) {
|
|
421
|
-
this.results.
|
|
469
|
+
processProtocolsData(this.results, data, this.envVars.TEST_DATA_LOCATION)
|
|
422
470
|
}
|
|
423
471
|
})
|
|
424
472
|
}
|
|
@@ -478,6 +526,8 @@ export default {
|
|
|
478
526
|
let i = this.results.findIndex((res) =>
|
|
479
527
|
element.doi ? element.doi.includes(res.doi) : false
|
|
480
528
|
)
|
|
529
|
+
|
|
530
|
+
|
|
481
531
|
// Assign scicrunch results to the object
|
|
482
532
|
Object.assign(this.results[i], element)
|
|
483
533
|
// Assign the attributes that need some processing
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
|
|
4
|
+
<el-table
|
|
5
|
+
v-if="fileLists"
|
|
6
|
+
:data="fileLists"
|
|
7
|
+
style="width: 100%;"
|
|
8
|
+
height="600"
|
|
9
|
+
:stripe="true"
|
|
10
|
+
>
|
|
11
|
+
<el-table-column type="expand">
|
|
12
|
+
<template #default="props">
|
|
13
|
+
<div class="file-details" m="4">
|
|
14
|
+
<p m="t-0 b-2" v-if="props.row.description">
|
|
15
|
+
Description: {{ props.row.description }}
|
|
16
|
+
</p>
|
|
17
|
+
<p m="t-0 b-2" v-if="props.row.protocol">
|
|
18
|
+
Protocol: {{ props.row.protocol }}
|
|
19
|
+
</p>
|
|
20
|
+
<div v-for="(val, key) in props.row.columns">
|
|
21
|
+
<p :key="key" m="t-0 b-2">Column {{ key + 1 }}: {{ val }}</p>
|
|
22
|
+
</div>
|
|
23
|
+
<p m="t-0 b-2">File path: {{ props.row.filePath }}</p>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
</el-table-column>
|
|
27
|
+
<el-table-column
|
|
28
|
+
prop="thumbnail"
|
|
29
|
+
label="Thumbnail"
|
|
30
|
+
width="170"
|
|
31
|
+
>
|
|
32
|
+
<template #default="scope">
|
|
33
|
+
<el-image
|
|
34
|
+
v-if="scope.row.thumbnail"
|
|
35
|
+
:src="scope.row.thumbnail"
|
|
36
|
+
style="max-width: 150px; max-height: 150px"
|
|
37
|
+
fit="contain"
|
|
38
|
+
lazy
|
|
39
|
+
/>
|
|
40
|
+
</template>
|
|
41
|
+
</el-table-column>
|
|
42
|
+
<el-table-column
|
|
43
|
+
prop="fileName"
|
|
44
|
+
label="File name"
|
|
45
|
+
width="200"
|
|
46
|
+
class-name="title-text"
|
|
47
|
+
/>
|
|
48
|
+
<el-table-column
|
|
49
|
+
prop="type"
|
|
50
|
+
label="Type"
|
|
51
|
+
width="100"
|
|
52
|
+
/>
|
|
53
|
+
<el-table-column
|
|
54
|
+
fixed="right"
|
|
55
|
+
>
|
|
56
|
+
<template #header>
|
|
57
|
+
<el-input v-model="search" size="small" placeholder="Type to search" />
|
|
58
|
+
</template>
|
|
59
|
+
<template #default="scope">
|
|
60
|
+
<el-button
|
|
61
|
+
size="small"
|
|
62
|
+
@click="handleView(scope.row)"
|
|
63
|
+
>
|
|
64
|
+
{{ getActionLabel(scope.row.type) }}
|
|
65
|
+
</el-button>
|
|
66
|
+
</template>
|
|
67
|
+
</el-table-column>
|
|
68
|
+
</el-table>
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script>
|
|
73
|
+
//provide the s3Bucket related methods and data.
|
|
74
|
+
import {
|
|
75
|
+
ElButton as Button,
|
|
76
|
+
ElImage as Image,
|
|
77
|
+
ElInput as Input,
|
|
78
|
+
ElTable as Table,
|
|
79
|
+
ElTableColumn as TableColumn
|
|
80
|
+
} from "element-plus";
|
|
81
|
+
import EventBus from './EventBus.js'
|
|
82
|
+
import { ref } from 'vue'
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
name: 'FileBrowser',
|
|
86
|
+
components: {
|
|
87
|
+
Button,
|
|
88
|
+
Image,
|
|
89
|
+
Input,
|
|
90
|
+
Table,
|
|
91
|
+
TableColumn
|
|
92
|
+
},
|
|
93
|
+
data() {
|
|
94
|
+
return {
|
|
95
|
+
category: "All",
|
|
96
|
+
search: "",
|
|
97
|
+
tableData: undefined,
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
methods: {
|
|
101
|
+
getActionLabel: function(type) {
|
|
102
|
+
if (type === "Simulations" || type === "Protocol Data") {
|
|
103
|
+
return "Run"
|
|
104
|
+
} else {
|
|
105
|
+
return "View"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
setSearchTerm: function(searchTerm) {
|
|
109
|
+
this.search = searchTerm
|
|
110
|
+
},
|
|
111
|
+
handleView: function(row) {
|
|
112
|
+
EventBus.emit('PopoverActionClick', row.action)
|
|
113
|
+
EventBus.emit('contextUpdate', row.action) // Pass to mapintegratedvuer
|
|
114
|
+
},
|
|
115
|
+
downloadThumbnail: async function(url, entry) {
|
|
116
|
+
const response = await fetch(url)
|
|
117
|
+
if (response.ok) {
|
|
118
|
+
let data = await response.text()
|
|
119
|
+
if (typeof data === 'string' && data.startsWith('data:')) {
|
|
120
|
+
entry.thumbnail = data
|
|
121
|
+
} else {
|
|
122
|
+
if (entry.mimetype) {
|
|
123
|
+
entry.thumbnail = `data:${entry.mimetype};base64,${data}`
|
|
124
|
+
} else {
|
|
125
|
+
entry.thumbnail = data
|
|
126
|
+
}
|
|
127
|
+
let index = this.tableData.findIndex((item) => item.filePath === entry.filePath);
|
|
128
|
+
if (index > -1) {
|
|
129
|
+
this.tableData[index] = {...entry}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
setData: function(data) {
|
|
135
|
+
this.tableData = ref([])
|
|
136
|
+
this.search = ""
|
|
137
|
+
Object.keys(data).forEach((key) => {
|
|
138
|
+
if (key !== "Dataset") {
|
|
139
|
+
data[key].forEach((item) => {
|
|
140
|
+
const entry = {
|
|
141
|
+
action: item.userData,
|
|
142
|
+
description: item.description ? item.description : "",
|
|
143
|
+
protocol: item.protocol ? item.protocol : "",
|
|
144
|
+
columns: [],
|
|
145
|
+
fileName: item.title,
|
|
146
|
+
filePath: item.filePath,
|
|
147
|
+
mimetype: item.mimetype,
|
|
148
|
+
type: key,
|
|
149
|
+
}
|
|
150
|
+
if (item.columns && item.columns.length > 0) {
|
|
151
|
+
item.columns.forEach((column) => entry.columns.push(JSON.stringify(column)))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.tableData.push(entry)
|
|
155
|
+
if (item.thumbnail?.includes("encodeBase64")) {
|
|
156
|
+
this.downloadThumbnail(item.thumbnail, entry)
|
|
157
|
+
} else {
|
|
158
|
+
entry.thumbnail = item.thumbnail
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
computed: {
|
|
166
|
+
fileLists() {
|
|
167
|
+
if (!this.search) return this.tableData
|
|
168
|
+
const keys = ["fileName", "filePath", "description", "type", "protocol"]
|
|
169
|
+
const lower = this.search.toLowerCase()
|
|
170
|
+
const list = this.tableData.filter((data) => {
|
|
171
|
+
for (let key of keys) {
|
|
172
|
+
if (data[key] && data[key].toLowerCase().includes(lower)) {
|
|
173
|
+
return true
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (data.columns) {
|
|
177
|
+
for (let column of data.columns) {
|
|
178
|
+
if (column.toLowerCase().includes(lower)) {
|
|
179
|
+
return true
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
return list
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
</script>
|
|
189
|
+
|
|
190
|
+
<style lang="scss" scoped>
|
|
191
|
+
:deep(.el-table__body-wrapper) {
|
|
192
|
+
.title-text {
|
|
193
|
+
font-size: 10px;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.file-details {
|
|
198
|
+
font-size: 10px;
|
|
199
|
+
}
|
|
200
|
+
</style>
|