@abi-software/map-side-bar 2.14.1-simulation.1 → 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.
@@ -1,108 +1,118 @@
1
1
  <template>
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"
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
- <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>
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
- <el-button
49
- type="primary"
50
- class="button"
51
- @click="searchEvent"
52
- size="large"
53
- >
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>
64
- </div>
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
- />
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-pagination
95
- class="pagination"
96
- v-model:current-page="page"
97
- hide-on-single-page
98
- large
99
- layout="prev, pager, next"
100
- :page-size="numberPerPage"
101
- :total="numberOfHits"
102
- @current-change="pageChange"
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.unshift(...data)
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>