@abi-software/map-side-bar 2.3.1 → 2.4.0-isan-0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "2.3.1",
3
+ "version": "2.4.0-isan-0",
4
4
  "files": [
5
5
  "dist/*",
6
6
  "src/*",
package/src/App.vue CHANGED
@@ -112,6 +112,7 @@ export default {
112
112
  BL_SERVER_URL: import.meta.env.VITE_APP_BL_SERVER_URL,
113
113
  NL_LINK_PREFIX: import.meta.env.VITE_APP_NL_LINK_PREFIX,
114
114
  ROOT_URL: import.meta.env.VITE_APP_ROOT_URL,
115
+ FLATMAP_API_LOCATION: import.meta.env.VITE_APP_FLATMAP_API_LOCATION,
115
116
  },
116
117
  connectivityInput: exampleConnectivityInput,
117
118
  activeId: 1,
@@ -119,7 +120,7 @@ export default {
119
120
  },
120
121
  methods: {
121
122
  hoverChanged: function (data) {
122
- console.log('hoverChanged', data)
123
+ // console.log('hoverChanged', data)
123
124
  },
124
125
  searchChanged: function (data) {
125
126
  console.log(data)
@@ -131,16 +132,18 @@ export default {
131
132
  action: function (action) {
132
133
  console.log('action fired: ', action)
133
134
  let facets = [];
134
- facets.push(
135
- ...action.labels.map(val => ({
136
- facet: capitalise(val),
137
- term: "Anatomical structure",
138
- facetPropPath: "anatomy.organ.category.name",
139
- }))
140
- );
141
- if (this.$refs.sideBar) {
142
- console.log('openSearch', facets)
143
- this.$refs.sideBar.openSearch(facets, "");
135
+ if (action.labels) {
136
+ facets.push(
137
+ ...action.labels.map(val => ({
138
+ facet: capitalise(val),
139
+ term: "Anatomical structure",
140
+ facetPropPath: "anatomy.organ.category.name",
141
+ }))
142
+ );
143
+ if (this.$refs.sideBar) {
144
+ console.log('openSearch', facets)
145
+ this.$refs.sideBar.openSearch(facets, "");
146
+ }
144
147
  }
145
148
  },
146
149
  openSearch: function () {
@@ -100,6 +100,7 @@ export class AlgoliaClient {
100
100
  for (let res of results) {
101
101
  newResult = { ...res }
102
102
  newResult = {
103
+ dataSource: 'SPARC',
103
104
  anatomy: res.anatomy ? res.anatomy.organ.map((organ => organ.curie)) : undefined,
104
105
  doi: res.item.curie.split(':')[1],
105
106
  name: res.item.name,
@@ -152,35 +153,48 @@ export class AlgoliaClient {
152
153
  * Get Search results
153
154
  * This is using fetch from the Algolia API
154
155
  */
155
- search(filter, query = '', hitsperPage = 10, page = 1) {
156
- return new Promise(resolve => {
157
- this.index
158
- .search(query, {
159
- facets: ['*'],
160
- hitsPerPage: hitsperPage,
161
- page: page - 1,
162
- filters: filter,
163
- attributesToHighlight: [],
164
- attributesToRetrieve: [
165
- 'pennsieve.publishDate',
166
- 'pennsieve.updatedAt',
167
- 'item.curie',
168
- 'item.name',
169
- 'item.description',
170
- 'objectID',
171
- 'anatomy.organ.curie'
172
- ],
173
- })
174
- .then(response => {
175
- let searchData = {
176
- items: this._processResultsForCards(response.hits),
177
- total: response.nbHits,
178
- discoverIds: response.hits.map(r => r.pennsieve ? r.pennsieve.identifier : r.objectID),
179
- dois: response.hits.map(r => r.item.curie.split(':')[1])
180
- }
181
- resolve(searchData)
156
+ search(filter, query = '', offset = 0, length = 8) {
157
+ console.log('searching', filter, query, offset, length)
158
+ // If the length is 0, return an empty result
159
+ if (length === 0) {
160
+ return new Promise(resolve => {
161
+ resolve({
162
+ items: [],
163
+ total: 0,
164
+ discoverIds: [],
165
+ dois: []
182
166
  })
183
- })
167
+ })
168
+ } else {
169
+ return new Promise(resolve => {
170
+ this.index
171
+ .search(query, {
172
+ facets: ['*'],
173
+ offset: offset,
174
+ length: length,
175
+ filters: filter,
176
+ attributesToHighlight: [],
177
+ attributesToRetrieve: [
178
+ 'pennsieve.publishDate',
179
+ 'pennsieve.updatedAt',
180
+ 'item.curie',
181
+ 'item.name',
182
+ 'item.description',
183
+ 'objectID',
184
+ 'anatomy.organ.curie'
185
+ ],
186
+ })
187
+ .then(response => {
188
+ let searchData = {
189
+ items: this._processResultsForCards(response.hits),
190
+ total: response.nbHits,
191
+ discoverIds: response.hits.map(r => r.pennsieve ? r.pennsieve.identifier : r.objectID),
192
+ dois: response.hits.map(r => r.item.curie.split(':')[1])
193
+ }
194
+ resolve(searchData)
195
+ })
196
+ })
197
+ }
184
198
  }
185
199
 
186
200
  /**
@@ -60,8 +60,13 @@ export function getFilters(selectedFacetArray=undefined) {
60
60
  return 'NOT item.published.status:embargo'
61
61
  }
62
62
 
63
- // Switch the 'term' attribute to 'label' if 'label' does not exist
64
- selectedFacetArray.forEach(f=>f.label=f.facet)
63
+ // Switch the 'term' attribute to 'label' if 'label' does not exist. Use facet2 if available
64
+ selectedFacetArray.forEach(f=>{
65
+ f.label=f.facet
66
+ if (f.facet2) {
67
+ f.label = f.facet2
68
+ }
69
+ })
65
70
 
66
71
 
67
72
  let facets = removeShowAllFacets(selectedFacetArray)
@@ -19,6 +19,7 @@
19
19
  />
20
20
  </span>
21
21
  <div class="card-right">
22
+ <el-tag type="primary" class="source-tag">SPARC Dataset</el-tag>
22
23
  <div class="title" @click="cardClicked">{{ entry.name }}</div>
23
24
  <div class="details">
24
25
  {{ contributors }} {{ entry.publishDate ? `(${publishYear})` : '' }}
@@ -282,6 +283,15 @@ export default {
282
283
  color: #484848;
283
284
  cursor: pointer;
284
285
  }
286
+
287
+ .source-tag {
288
+ margin-bottom: 0.75rem;
289
+ margin-right: 2rem;
290
+ position: absolute;
291
+ bottom: 0;
292
+ right: 0;
293
+ }
294
+
285
295
  .card {
286
296
  padding-top: 18px;
287
297
  position: relative;
@@ -0,0 +1,303 @@
1
+ <template>
2
+ <div class="dataset-card-container" ref="container">
3
+ <div class="dataset-card" ref="card">
4
+ <div class="seperator-path"></div>
5
+ <div v-loading="loading" class="card" >
6
+ <span class="card-left">
7
+ <a class="card-image-container" :href="entry.exposure" target="_blank">
8
+ <img
9
+ class="card-image"
10
+ :src="thumbnail"
11
+ width="210"
12
+ height="210"
13
+ :alt="entry.title"
14
+ loading="lazy"
15
+ />
16
+ </a>
17
+ </span>
18
+ <div class="card-right">
19
+ <el-tag type="primary" class="source-tag">PMR</el-tag>
20
+ <div>
21
+ <h4 class="title">{{ entry.title }}</h4>
22
+ <div class="details">
23
+ {{ entry.authors }}
24
+ </div>
25
+ </div>
26
+ <div class="details" v-if="entry.description">
27
+ {{ entry.description }}
28
+ </div>
29
+ <div class="buttons-group">
30
+ <a
31
+ :href="entry.exposure"
32
+ target="_blank"
33
+ class="el-button el-button--small button"
34
+ >
35
+ Exposure
36
+ </a>
37
+ <a
38
+ v-if="entry.omex"
39
+ :href="entry.omex"
40
+ target="_blank"
41
+ class="el-button el-button--small button"
42
+ >
43
+ OMEX archive
44
+ </a>
45
+ <el-button v-if="entry.flatmap"
46
+ size="small"
47
+ class="button"
48
+ @click="onFlatmapClick(entry.flatmap)"
49
+ >
50
+ Flatmap
51
+ </el-button>
52
+ <el-button v-if="entry.simulation"
53
+ size="small"
54
+ class="button"
55
+ @click="onSimulationClick(entry.simulation)"
56
+ >
57
+ Simulation
58
+ </el-button>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </template>
65
+
66
+
67
+ <script>
68
+ /* eslint-disable no-alert, no-console */
69
+ import {
70
+ ElButton,
71
+ ElIcon,
72
+ ElTag
73
+ } from 'element-plus'
74
+
75
+ /**
76
+ * Entry Object - Data types
77
+ * ---------------------------------------
78
+ "exposure"
79
+ type: String
80
+ description: The exposure URL
81
+
82
+ "title"
83
+ type: String
84
+ description: The title
85
+
86
+ "sha"
87
+ type: String
88
+ description:
89
+
90
+ "workspace"
91
+ type: String
92
+ description: The workspace URL
93
+
94
+ "omex"
95
+ type: String
96
+ description:
97
+
98
+ "image"
99
+ type: String
100
+ description: The image URL
101
+
102
+ "authors"
103
+ type: String
104
+ description: Comma separated values if more than one
105
+
106
+ "description"
107
+ type: String
108
+ description: The description
109
+
110
+ "flatmap"
111
+ type: String
112
+ descriptin: (Optional) to link to flatmap
113
+ * ---------------------------------------
114
+ */
115
+
116
+ const placeholderThumbnail = 'assets/missing-image.svg';
117
+
118
+ export default {
119
+ name: "PMRDatasetCard",
120
+ components: {
121
+ ElButton,
122
+ ElIcon,
123
+ ElTag
124
+ },
125
+ props: {
126
+ /**
127
+ * Object containing information for
128
+ * the required viewing.
129
+ */
130
+ entry: {
131
+ type: Object,
132
+ default: () => {}
133
+ },
134
+ envVars: {
135
+ type: Object,
136
+ default: () => {}
137
+ },
138
+ },
139
+ data: function () {
140
+ return {
141
+ thumbnail: this.entry.image || placeholderThumbnail,
142
+ loading: false,
143
+ };
144
+ },
145
+ methods: {
146
+ onFlatmapClick: function (payload) {
147
+ this.$emit('flatmap-clicked', payload)
148
+ },
149
+ onSimulationClick: function (payload) {
150
+ const simulationData = {
151
+ title: this.entry.title,
152
+ description: this.entry.description,
153
+ resource: payload,
154
+ };
155
+ this.$emit('simulation-clicked', simulationData)
156
+ },
157
+ }
158
+ };
159
+ </script>
160
+
161
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
162
+ <style scoped lang="scss">
163
+
164
+ .dataset-card-container {
165
+ padding: 0 1rem;
166
+ }
167
+
168
+ .dataset-card {
169
+ position: relative;
170
+ min-height:17rem;
171
+ }
172
+
173
+ .title {
174
+ padding-bottom: 0.75rem;
175
+ font-family: Asap;
176
+ font-size: 14px;
177
+ font-weight: bold;
178
+ font-stretch: normal;
179
+ font-style: normal;
180
+ line-height: 1.5;
181
+ letter-spacing: 1.05px;
182
+ color: #484848;
183
+ }
184
+ .card {
185
+ font-family: Asap;
186
+ padding-top: 18px;
187
+ position: relative;
188
+ display: flex;
189
+
190
+ h4,
191
+ p {
192
+ margin: 0;
193
+ }
194
+ }
195
+
196
+ .card-left{
197
+ flex: 1;
198
+ }
199
+
200
+ .card-right {
201
+ flex: 1.3;
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 1rem;
205
+ min-height: 17rem;
206
+ }
207
+
208
+ .details {
209
+ font-family: Asap;
210
+ font-size: 14px;
211
+ font-weight: normal;
212
+ font-stretch: normal;
213
+ font-style: normal;
214
+ line-height: 1.5;
215
+ letter-spacing: 1.05px;
216
+ color: #484848;
217
+ }
218
+
219
+ .el-button {
220
+ font-family: Asap;
221
+ font-size: 14px;
222
+ font-weight: normal;
223
+ font-stretch: normal;
224
+ font-style: normal;
225
+ line-height: normal;
226
+ letter-spacing: normal;
227
+ text-decoration: none;
228
+ }
229
+
230
+ .button {
231
+ background-color: $app-primary-color;
232
+ border: $app-primary-color;
233
+ color: white;
234
+ transition: all 0.3s ease;
235
+
236
+ &:hover,
237
+ &:focus {
238
+ color: white;
239
+ background-color: $app-primary-color;
240
+ outline: none;
241
+ }
242
+ }
243
+
244
+ .card-image-container {
245
+ display: block;
246
+ width: 244px; // gallery image full-size width
247
+ }
248
+
249
+ .card-image {
250
+ max-width: 100%;
251
+ height: auto;
252
+ object-fit: cover;
253
+ }
254
+
255
+ .buttons-group {
256
+ display: flex;
257
+ flex-direction: row;
258
+ flex-wrap: wrap;
259
+ gap: 0.75rem;
260
+
261
+ .el-button {
262
+ border-radius: 4px!important;
263
+ font-size: 0.75rem!important;
264
+ padding: 0.2rem 0.2rem!important;
265
+ background: #f9f2fc!important;
266
+ border: 1px solid $app-primary-color!important;
267
+ color: $app-primary-color!important;
268
+
269
+ &.active {
270
+ background: $app-primary-color!important;
271
+ border: 1px solid $app-primary-color!important;
272
+ color: #fff!important;
273
+ }
274
+ }
275
+
276
+ .el-button + .el-button {
277
+ margin: 0;
278
+ }
279
+ }
280
+
281
+ .source-tag {
282
+ margin-bottom: 0.75rem;
283
+ margin-right: 2rem;
284
+ position: absolute;
285
+ bottom: 0;
286
+ right: 0;
287
+ }
288
+
289
+ .loading-icon {
290
+ z-index: 20;
291
+ width: 40px;
292
+ height: 40px;
293
+ left: 80px;
294
+ }
295
+
296
+ .loading-icon ::v-deep(.el-loading-mask) {
297
+ background-color: rgba(117, 190, 218, 0.0) !important;
298
+ }
299
+
300
+ .loading-icon ::v-deep(.el-loading-spinner .path) {
301
+ stroke: $app-primary-color;
302
+ }
303
+ </style>
@@ -261,12 +261,29 @@ export default {
261
261
  }
262
262
  })
263
263
  })
264
+
265
+ this.populatePMRinCascader();
264
266
  })
265
267
  .finally(() => {
266
268
  resolve()
267
269
  })
268
270
  })
269
271
  },
272
+ /**
273
+ * Add PMR checkbox in filters (cascader)
274
+ */
275
+ populatePMRinCascader: function () {
276
+ for (let i = 0; i < this.options.length; i += 1) {
277
+ const option = this.options[i];
278
+ // match with "Data type"'s' key
279
+ if (option.key === 'item.types.name') {
280
+ option.children.push({
281
+ label: 'PMR',
282
+ value: this.createCascaderItemValue("Data type", "PMR"),
283
+ });
284
+ }
285
+ }
286
+ },
270
287
  /**
271
288
  * Create manual events when cascader tag is closed
272
289
  */
@@ -468,7 +485,7 @@ export default {
468
485
  facetSubPropPath: facetSubPropPath, // will be used for filters if we are at the third level of the cascader
469
486
  }
470
487
  })
471
-
488
+
472
489
  this.$emit('loading', true) // let sidebarcontent wait for the requests
473
490
  this.$emit('filterResults', filters) // emit filters for apps above sidebar
474
491
  this.setCascader(filterKeys) //update our cascader v-model if we modified the event
@@ -630,7 +647,7 @@ export default {
630
647
  let filters = createFilter(e)
631
648
  return filters
632
649
  })
633
-
650
+
634
651
  // Unforttunately the cascader is very particular about it's v-model
635
652
  // to get around this we create a clone of it and use this clone for adding our boolean information
636
653
  this.cascadeSelectedWithBoolean = filterFacets.map((e) => {
@@ -46,6 +46,8 @@
46
46
  :contextCardEntry="tab.contextCard"
47
47
  :envVars="envVars"
48
48
  :ref="'searchTab_' + tab.id"
49
+ @flatmap-clicked="onFlatmapClicked"
50
+ @simulation-clicked="onSimulationClicked"
49
51
  @search-changed="searchChanged(tab.id, $event)"
50
52
  @hover-changed="hoverChanged($event)"
51
53
  />
@@ -246,6 +248,24 @@ export default {
246
248
  setDrawerOpen: function (value = true) {
247
249
  this.drawerOpen = value
248
250
  },
251
+ onFlatmapClicked: function (data) {
252
+ const payload = {
253
+ type: 'Flatmap',
254
+ data: data
255
+ };
256
+ this.$emit('actionClick', payload);
257
+ },
258
+ onSimulationClicked: function (data) {
259
+ const payload = {
260
+ type: 'Simulation',
261
+ title: 'View simulation',
262
+ apiLocation: this.envVars.API_LOCATION,
263
+ name: data.title,
264
+ description: data.description,
265
+ resource: data.resource,
266
+ };
267
+ this.$emit('actionClick', payload);
268
+ },
249
269
  /**
250
270
  * @vuese
251
271
  * The function to emit 'tabClicked' event with tab's `id` and tab's `type`