@abi-software/map-side-bar 2.14.1-simulation.1 → 2.14.1-simulation.3

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,122 @@
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.
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>
84
106
  </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)"
107
+ <el-dialog
108
+ v-model="fileBrowserVisible"
109
+ title="File browser"
110
+ width="700"
111
+ top="16px"
112
+ >
113
+ <FileBrowser
114
+ ref="fileBrowserRef"
115
+ @fileActionTriggered="fileActionTriggered"
92
116
  />
93
- </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>
117
+ </el-dialog>
118
+ </el-card>
119
+
106
120
  </template>
107
121
 
108
122
  <script>
@@ -110,17 +124,20 @@
110
124
  import {
111
125
  ElButton as Button,
112
126
  ElCard as Card,
127
+ ElDialog as Dialog,
113
128
  ElDrawer as Drawer,
114
129
  ElIcon as Icon,
115
130
  ElInput as Input,
116
131
  ElPagination as Pagination,
117
132
  ElMessage as Message,
118
133
  } from 'element-plus'
119
- import 'element-plus/es/components/message/style/css';
134
+ import 'element-plus/es/components/message/style/css'
120
135
  import SearchFilters from './SearchFilters.vue'
121
136
  import SearchHistory from './SearchHistory.vue'
122
137
  import DatasetCard from './DatasetCard.vue'
138
+ import FileBrowser from './FileBrowser.vue'
123
139
  import EventBus from './EventBus.js'
140
+ import { processProtocolsData } from './scripts/utilities.js'
124
141
 
125
142
  import { AlgoliaClient } from '../algolia/algolia.js'
126
143
  import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
@@ -158,11 +175,13 @@ var initial_state = {
158
175
 
159
176
  export default {
160
177
  components: {
161
- SearchFilters,
162
178
  DatasetCard,
179
+ FileBrowser,
180
+ SearchFilters,
163
181
  SearchHistory,
164
182
  Button,
165
183
  Card,
184
+ Dialog,
166
185
  Drawer,
167
186
  Icon,
168
187
  Input,
@@ -199,6 +218,12 @@ export default {
199
218
  display: 'flex',
200
219
  },
201
220
  cascaderIsReady: false,
221
+ fileBrowserVisible: false,
222
+ fileSearch: {
223
+ onGoing: false,
224
+ datasetId: undefined,
225
+ searchTerm: undefined,
226
+ }
202
227
  }
203
228
  },
204
229
  computed: {
@@ -216,6 +241,25 @@ export default {
216
241
  },
217
242
  },
218
243
  methods: {
244
+ fileActionTriggered: function(action) {
245
+ this.fileBrowserVisible = false
246
+ EventBus.emit('PopoverActionClick', action)
247
+ EventBus.emit('contextUpdate', action) // Pass to mapintegratedvuer
248
+ },
249
+ fileInfoReady: function(payload) {
250
+ if (this.fileSearch.onGoing) {
251
+ if (payload.id === this.fileSearch.datasetID) {
252
+ payload.instance.openFileBrowser()
253
+ }
254
+ }
255
+ },
256
+ displayFileInfo: function(datasetID, fileSearch, searchTerm = "") {
257
+ let query = searchTerm ? searchTerm : datasetID
258
+ this.openSearch([], query)
259
+ this.fileSearch.onGoing = true
260
+ this.fileSearch.datasetID = datasetID
261
+ this.fileSearch.searchTerm = fileSearch
262
+ },
219
263
  hoverChanged: function (data) {
220
264
  const payload = data ? { ...data, tabType: 'dataset' } : { tabType: 'dataset' }
221
265
  this.$emit('hover-changed', payload)
@@ -227,6 +271,18 @@ export default {
227
271
  this.results = []
228
272
  this.loadingCards = false
229
273
  },
274
+ openFileBrowser: function(data) {
275
+ this.fileBrowserVisible = true
276
+ this.$nextTick(() => {
277
+ this.$refs.fileBrowserRef.setData(data.items)
278
+ if (this.fileSearch.onGoing) {
279
+ if (this.fileSearch.datasetID === data.datasetID) {
280
+ this.$refs.fileBrowserRef.setSearchTerm(this.fileSearch.searchTerm)
281
+ }
282
+ this.fileSearch.onGoing = false
283
+ }
284
+ })
285
+ },
230
286
  openSearch: function (filter, search = '') {
231
287
  this.searchInput = search
232
288
  this.resetPageNavigation()
@@ -418,7 +474,7 @@ export default {
418
474
  })
419
475
  .then((data) => {
420
476
  if (this.searchInput.toLowerCase().includes("reveal")) {
421
- this.results.unshift(...data)
477
+ processProtocolsData(this.results, data, this.envVars.TEST_DATA_LOCATION)
422
478
  }
423
479
  })
424
480
  }
@@ -478,6 +534,8 @@ export default {
478
534
  let i = this.results.findIndex((res) =>
479
535
  element.doi ? element.doi.includes(res.doi) : false
480
536
  )
537
+
538
+
481
539
  // Assign scicrunch results to the object
482
540
  Object.assign(this.results[i], element)
483
541
  // Assign the attributes that need some processing
@@ -0,0 +1,199 @@
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
+ this.$emit("fileActionTriggered", row.action)
113
+ },
114
+ downloadThumbnail: async function(url, entry) {
115
+ const response = await fetch(url)
116
+ if (response.ok) {
117
+ let data = await response.text()
118
+ if (typeof data === 'string' && data.startsWith('data:')) {
119
+ entry.thumbnail = data
120
+ } else {
121
+ if (entry.mimetype) {
122
+ entry.thumbnail = `data:${entry.mimetype};base64,${data}`
123
+ } else {
124
+ entry.thumbnail = data
125
+ }
126
+ let index = this.tableData.findIndex((item) => item.filePath === entry.filePath);
127
+ if (index > -1) {
128
+ this.tableData[index] = {...entry}
129
+ }
130
+ }
131
+ }
132
+ },
133
+ setData: function(data) {
134
+ this.tableData = ref([])
135
+ this.search = ""
136
+ Object.keys(data).forEach((key) => {
137
+ if (key !== "Dataset") {
138
+ data[key].forEach((item) => {
139
+ const entry = {
140
+ action: item.userData,
141
+ description: item.description ? item.description : "",
142
+ protocol: item.protocol ? item.protocol : "",
143
+ columns: [],
144
+ fileName: item.title,
145
+ filePath: item.filePath,
146
+ mimetype: item.mimetype,
147
+ type: key,
148
+ }
149
+ if (item.columns && item.columns.length > 0) {
150
+ item.columns.forEach((column) => entry.columns.push(JSON.stringify(column)))
151
+ }
152
+
153
+ this.tableData.push(entry)
154
+ if (item.thumbnail?.includes("encodeBase64")) {
155
+ this.downloadThumbnail(item.thumbnail, entry)
156
+ } else {
157
+ entry.thumbnail = item.thumbnail
158
+ }
159
+ })
160
+ }
161
+ })
162
+ }
163
+ },
164
+ computed: {
165
+ fileLists() {
166
+ if (!this.search) return this.tableData
167
+ const keys = ["fileName", "filePath", "description", "type", "protocol"]
168
+ const lower = this.search.toLowerCase()
169
+ const list = this.tableData.filter((data) => {
170
+ for (let key of keys) {
171
+ if (data[key] && data[key].toLowerCase().includes(lower)) {
172
+ return true
173
+ }
174
+ }
175
+ if (data.columns) {
176
+ for (let column of data.columns) {
177
+ if (column.toLowerCase().includes(lower)) {
178
+ return true
179
+ }
180
+ }
181
+ }
182
+ })
183
+ return list
184
+ }
185
+ },
186
+ }
187
+ </script>
188
+
189
+ <style lang="scss" scoped>
190
+ :deep(.el-table__body-wrapper) {
191
+ .title-text {
192
+ font-size: 10px;
193
+ }
194
+ }
195
+
196
+ .file-details {
197
+ font-size: 10px;
198
+ }
199
+ </style>