@abi-software/map-side-bar 2.18.0 → 2.19.1-demo.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.
Files changed (41) hide show
  1. package/.postcssrc.json +5 -5
  2. package/README.md +8 -9
  3. package/cypress.config.js +6 -7
  4. package/dist/map-side-bar.js +6890 -6026
  5. package/dist/map-side-bar.umd.cjs +65 -62
  6. package/dist/style.css +1 -1
  7. package/eslint.config.js +44 -9
  8. package/package.json +10 -3
  9. package/reporter-config.json +1 -1
  10. package/src/App.vue +89 -80
  11. package/src/algolia/algolia.js +173 -167
  12. package/src/algolia/utils.js +34 -38
  13. package/src/assets/_variables.scss +12 -10
  14. package/src/assets/connectivity-explorer.scss +1 -1
  15. package/src/assets/fonts.scss +0 -1
  16. package/src/assets/searchPopover.scss +1 -2
  17. package/src/components/AnnotationTool.vue +9 -32
  18. package/src/components/BadgesGroup.vue +29 -32
  19. package/src/components/CellCard.vue +992 -0
  20. package/src/components/CellCardExplorer.vue +879 -0
  21. package/src/components/ConnectivityCard.vue +22 -19
  22. package/src/components/ConnectivityExplorer.vue +109 -130
  23. package/src/components/ConnectivityInfo.vue +142 -171
  24. package/src/components/ContributorItem.vue +15 -11
  25. package/src/components/DatasetCard.vue +166 -201
  26. package/src/components/DatasetExplorer.vue +160 -201
  27. package/src/components/ImageGallery.vue +35 -36
  28. package/src/components/SearchFilters.vue +384 -407
  29. package/src/components/SearchHistory.vue +69 -103
  30. package/src/components/SideBar.vue +186 -94
  31. package/src/components/Tabs.vue +25 -21
  32. package/src/components/icons/IconOpenExternal.vue +23 -0
  33. package/src/components/index.js +3 -5
  34. package/src/components/species-map.js +7 -7
  35. package/src/components.d.ts +3 -0
  36. package/src/exampleConnectivityInput.js +310 -318
  37. package/src/main.js +6 -6
  38. package/src/mixins/S3Bucket.vue +10 -13
  39. package/src/utils/common.js +59 -0
  40. package/vite.config.js +62 -61
  41. package/vuese-generator.js +47 -55
@@ -1,8 +1,7 @@
1
- /* eslint-disable no-alert, no-console */
2
- import algoliasearch from 'algoliasearch'
1
+ import algoliasearch from 'algoliasearch';
3
2
 
4
3
  const getFacetsChildrenMap = (childFacets, numberOfLayers) => {
5
- const mapping = {}
4
+ const mapping = {};
6
5
  childFacets.forEach((facet) => {
7
6
  const info = facet.split('.');
8
7
  if (info.length !== numberOfLayers) {
@@ -17,169 +16,169 @@ const getFacetsChildrenMap = (childFacets, numberOfLayers) => {
17
16
  }
18
17
  });
19
18
  return mapping;
20
- }
19
+ };
21
20
 
22
21
  // export `createAlgoliaClient` to use it in page components
23
22
  export class AlgoliaClient {
24
23
  constructor(algoliaId, algoliaKey, PENNSIEVE_API_LOCATION = 'https://api.pennsieve.io') {
25
- this.client = algoliasearch(
26
- algoliaId,
27
- algoliaKey
28
- )
29
- this.PENNSIEVE_API_LOCATION = PENNSIEVE_API_LOCATION
24
+ this.client = algoliasearch(algoliaId, algoliaKey);
25
+ this.PENNSIEVE_API_LOCATION = PENNSIEVE_API_LOCATION;
30
26
  }
31
27
  initIndex(ALGOLIA_INDEX) {
32
28
  this.index = this.client.initIndex(ALGOLIA_INDEX);
33
29
  }
34
30
 
35
31
  getAlgoliaFacets(propPathMapping) {
36
- const facetPropPaths = propPathMapping.map(facet => facet.facetPropPath)
37
- const facetSubpropPaths = propPathMapping.map(item => item.facetSubpropPath)
38
- const facetSubsubpropPaths = propPathMapping.map(
39
- item => item.facetSubsubpropPath).filter(
40
- i => i !== undefined
41
- )
32
+ const facetPropPaths = propPathMapping.map((facet) => facet.facetPropPath);
33
+ const facetSubpropPaths = propPathMapping.map((item) => item.facetSubpropPath);
34
+ const facetSubsubpropPaths = propPathMapping
35
+ .map((item) => item.facetSubsubpropPath)
36
+ .filter((i) => i !== undefined);
42
37
  return this.index
43
38
  .search('', {
44
39
  sortFacetValuesBy: 'alpha',
45
40
  facets: facetPropPaths.concat(facetSubpropPaths).concat(facetSubsubpropPaths),
46
41
  })
47
- .then(response => {
48
- let facetData = []
49
- let facetId = 0
42
+ .then((response) => {
43
+ let facetData = [];
44
+ let facetId = 0;
50
45
  facetPropPaths.map((facetPropPath) => {
51
- const parentFacet = propPathMapping.find(item => item.facetPropPath == facetPropPath)
52
- var children = []
53
- const responseFacets = response.facets
54
- if (responseFacets === undefined) {return}
46
+ const parentFacet = propPathMapping.find((item) => item.facetPropPath == facetPropPath);
47
+ var children = [];
48
+ const responseFacets = response.facets;
49
+ if (responseFacets === undefined) {
50
+ return;
51
+ }
55
52
  const responseFacetChildren =
56
53
  responseFacets[facetPropPath] == undefined // if no facets, return empty object
57
54
  ? {}
58
- : responseFacets[facetPropPath]
59
- const allSubfacets = parentFacet && responseFacets[parentFacet.facetSubpropPath] ? Object.keys(responseFacets[parentFacet.facetSubpropPath]) : []
60
- const allSubsubfacets = (parentFacet && parentFacet.facetSubsubpropPath &&
61
- responseFacets[parentFacet.facetSubsubpropPath]) ?
62
- Object.keys(responseFacets[parentFacet.facetSubsubpropPath]) : []
55
+ : responseFacets[facetPropPath];
56
+ const allSubfacets =
57
+ parentFacet && responseFacets[parentFacet.facetSubpropPath]
58
+ ? Object.keys(responseFacets[parentFacet.facetSubpropPath])
59
+ : [];
60
+ const allSubsubfacets =
61
+ parentFacet &&
62
+ parentFacet.facetSubsubpropPath &&
63
+ responseFacets[parentFacet.facetSubsubpropPath]
64
+ ? Object.keys(responseFacets[parentFacet.facetSubsubpropPath])
65
+ : [];
63
66
  const subFacetsMap = getFacetsChildrenMap(allSubfacets, 2);
64
67
  const subSubFacetsMap = getFacetsChildrenMap(allSubsubfacets, 3);
65
68
  // Loop through all subfacets and find the ones that are children of the current facet
66
- Object.keys(responseFacetChildren).map(facet => {
69
+ Object.keys(responseFacetChildren).map((facet) => {
67
70
  const childrenSubfacets = [];
68
71
  if (Object.keys(subFacetsMap).includes(facet)) {
69
72
  subFacetsMap[facet].forEach((label) => {
70
- const fullPath = `${facet}.${label}`
71
- const childrenSubsubfacets = []
73
+ const fullPath = `${facet}.${label}`;
74
+ const childrenSubsubfacets = [];
72
75
  if (Object.keys(subSubFacetsMap).includes(fullPath)) {
73
76
  subSubFacetsMap[fullPath].forEach((childLabel) => {
74
- childrenSubsubfacets.push(
75
- {
76
- label: childLabel,
77
- id: facetId++,
78
- facetPropPath: `${parentFacet ? parentFacet.facetSubsubpropPath : undefined}`
79
- }
80
- )
77
+ childrenSubsubfacets.push({
78
+ label: childLabel,
79
+ id: facetId++,
80
+ facetPropPath: `${parentFacet ? parentFacet.facetSubsubpropPath : undefined}`,
81
+ });
81
82
  });
82
83
  //REMOVE ME LATER: This is a hack to add an extra item for subsubcategory
83
- if (fullPath === "nerves and ganglia.dorsal root ganglion") {
84
- childrenSubsubfacets.push(
85
- {
86
- label: "Non specific",
87
- id: facetId++,
88
- facetPropPath: `${parentFacet ? parentFacet.facetSubsubpropPath : undefined}`
89
- }
90
- )
84
+ if (fullPath === 'nerves and ganglia.dorsal root ganglion') {
85
+ childrenSubsubfacets.push({
86
+ label: 'Non specific',
87
+ id: facetId++,
88
+ facetPropPath: `${parentFacet ? parentFacet.facetSubsubpropPath : undefined}`,
89
+ });
91
90
  }
92
91
  }
93
- childrenSubfacets.push(
94
- {
95
- label,
96
- id: facetId++,
97
- facetPropPath: `${parentFacet ? parentFacet.facetSubpropPath : undefined}`,
98
- children: childrenSubsubfacets.length ? childrenSubsubfacets : undefined,
99
- }
100
- );
101
- })
92
+ childrenSubfacets.push({
93
+ label,
94
+ id: facetId++,
95
+ facetPropPath: `${parentFacet ? parentFacet.facetSubpropPath : undefined}`,
96
+ children: childrenSubsubfacets.length ? childrenSubsubfacets : undefined,
97
+ });
98
+ });
102
99
  }
103
100
  let newChild = {
104
101
  label: facet,
105
102
  id: facetId++,
106
- facetPropPath: facetPropPath
107
- }
103
+ facetPropPath: facetPropPath,
104
+ };
108
105
  if (childrenSubfacets.length > 0) {
109
-
110
- newChild.children = childrenSubfacets
106
+ newChild.children = childrenSubfacets;
111
107
  }
112
- children.push(newChild)
113
- })
108
+ children.push(newChild);
109
+ });
114
110
  if (children.length > 0) {
115
111
  facetData.push({
116
112
  label: parentFacet ? parentFacet.label : '',
117
113
  id: facetId++,
118
114
  children: children,
119
- key: facetPropPath
120
- })
115
+ key: facetPropPath,
116
+ });
121
117
  }
122
- })
123
- return facetData
124
- })
118
+ });
119
+ return facetData;
120
+ });
125
121
  }
126
122
 
127
123
  // Returns all DOIs of all versions for a given discover dataset
128
124
  _discoverAllDois(discoverId, PENNSIEVE_API_LOCATION = 'https://api.pennsieve.io') {
129
- return new Promise(resolve => {
130
- fetch(`${PENNSIEVE_API_LOCATION}/discover/datasets/${discoverId}/versions`).then(r => r.json()).then(dataset => {
131
- resolve(dataset.map(version => version.doi))
132
- })
133
- })
125
+ return new Promise((resolve) => {
126
+ fetch(`${PENNSIEVE_API_LOCATION}/discover/datasets/${discoverId}/versions`)
127
+ .then((r) => r.json())
128
+ .then((dataset) => {
129
+ resolve(dataset.map((version) => version.doi));
130
+ });
131
+ });
134
132
  }
135
133
 
136
134
  // Get all dois given a list of discoverIds
137
135
  _expandDois(discoverIds, PENNSIEVE_API_LOCATION = 'https://api.pennsieve.io') {
138
- return new Promise(resolve => {
139
- let promiseList = discoverIds.map(discoverId => this._discoverAllDois(discoverId, PENNSIEVE_API_LOCATION))
136
+ return new Promise((resolve) => {
137
+ let promiseList = discoverIds.map((discoverId) =>
138
+ this._discoverAllDois(discoverId, PENNSIEVE_API_LOCATION),
139
+ );
140
140
  Promise.all(promiseList).then((values) => {
141
- resolve(values.flat())
141
+ resolve(values.flat());
142
142
  });
143
- })
143
+ });
144
144
  }
145
145
 
146
146
  _processResultsForCards(results) {
147
- let newResults = []
148
- let newResult = {}
147
+ let newResults = [];
148
+ let newResult;
149
149
  for (let res of results) {
150
- newResult = { ...res }
151
150
  newResult = {
152
- anatomy: res.anatomy ? res.anatomy.organ.map((organ => organ.curie)) : undefined,
151
+ anatomy: res.anatomy ? res.anatomy.organ.map((organ) => organ.curie) : undefined,
153
152
  doi: res.item.curie.split(':')[1],
154
153
  name: res.item.name,
155
154
  description: res.item.description,
156
155
  updated: res.pennsieve ? res.pennsieve.updatedAt : undefined,
157
156
  publishDate: res.pennsieve ? res.pennsieve.publishDate : undefined,
158
157
  datasetId: res.objectID,
159
- detailsReady: false
160
- }
161
- newResults.push(newResult)
158
+ detailsReady: false,
159
+ };
160
+ newResults.push(newResult);
162
161
  }
163
- return newResults
162
+ return newResults;
164
163
  }
165
164
 
166
165
  _processAnatomy(hits) {
167
- const anatomyUberonMapping = {}
168
- hits.forEach(hit => {
169
- if (hit.anatomy && hit.anatomy.organ ) {
170
- hit.anatomy.organ.forEach(anatomy => {
166
+ const anatomyUberonMapping = {};
167
+ hits.forEach((hit) => {
168
+ if (hit.anatomy && hit.anatomy.organ) {
169
+ hit.anatomy.organ.forEach((anatomy) => {
171
170
  if (anatomy.curie) {
172
171
  anatomyUberonMapping[anatomy.curie] = anatomy.name;
173
172
  }
174
- })
173
+ });
175
174
  }
176
- localStorage.setItem('available-name-curie-mapping', JSON.stringify(anatomyUberonMapping))
177
- })
175
+ localStorage.setItem('available-name-curie-mapping', JSON.stringify(anatomyUberonMapping));
176
+ });
178
177
  }
179
178
 
180
179
  _processUberonURL(url) {
181
- let ub = url.split('/').pop()
182
- return ub.replace('_', ':')
180
+ let ub = url.split('/').pop();
181
+ return ub.replace('_', ':');
183
182
  }
184
183
 
185
184
  /**
@@ -187,20 +186,20 @@ export class AlgoliaClient {
187
186
  * This is using fetch from the Algolia API
188
187
  */
189
188
  search(filter, query = '', hitsperPage = 10, page = 1) {
190
- const terms = query.replaceAll('"', '').split(",")
191
- let processed = "";
189
+ const terms = query.replaceAll('"', '').split(',');
190
+ let processed = '';
192
191
  const optionalWords = [];
193
192
  if (terms) {
194
- if (terms.length === 1 && (!(query.includes(" ")))) {
193
+ if (terms.length === 1 && !query.includes(' ')) {
195
194
  processed = query;
196
195
  } else {
197
- terms.forEach(term => {
198
- optionalWords.push(term.trim())
196
+ terms.forEach((term) => {
197
+ optionalWords.push(term.trim());
199
198
  processed += `"${term.trim()}" `;
200
199
  });
201
200
  }
202
201
  }
203
- processed = processed.trim()
202
+ processed = processed.trim();
204
203
 
205
204
  const payload = {
206
205
  advancedSyntax: true,
@@ -218,34 +217,34 @@ export class AlgoliaClient {
218
217
  'item.name',
219
218
  'item.description',
220
219
  'objectID',
221
- 'anatomy.organ.curie'
220
+ 'anatomy.organ.curie',
222
221
  ],
223
- }
222
+ };
224
223
  if (optionalWords.length > 1) {
225
- payload.optionalWords = optionalWords
224
+ payload.optionalWords = optionalWords;
226
225
  }
227
226
 
228
- return new Promise(resolve => {
229
- this.index
230
- .search(processed, payload)
231
- .then(response => {
232
- let searchData = {
233
- items: this._processResultsForCards(response.hits),
234
- total: response.nbHits,
235
- discoverIds: response.hits.map(r => r.pennsieve ? r.pennsieve.identifier : r.objectID),
236
- dois: response.hits.map(r => r.item.curie.split(':')[1])
237
- }
238
- resolve(searchData)
239
- })
240
- })
227
+ return new Promise((resolve) => {
228
+ this.index.search(processed, payload).then((response) => {
229
+ let searchData = {
230
+ items: this._processResultsForCards(response.hits),
231
+ total: response.nbHits,
232
+ discoverIds: response.hits.map((r) =>
233
+ r.pennsieve ? r.pennsieve.identifier : r.objectID,
234
+ ),
235
+ dois: response.hits.map((r) => r.item.curie.split(':')[1]),
236
+ };
237
+ resolve(searchData);
238
+ });
239
+ });
241
240
  }
242
241
 
243
242
  /**
244
- * Get key words
245
- * This is used to return all keywords for a given search. Note that you often want the hits per page to be maxed out
246
- */
243
+ * Get key words
244
+ * This is used to return all keywords for a given search. Note that you often want the hits per page to be maxed out
245
+ */
247
246
  anatomyInSearch(filter, query = '', hitsperPage = 999999, page = 1) {
248
- return new Promise(resolve => {
247
+ return new Promise((resolve) => {
249
248
  this.index
250
249
  .search(query, {
251
250
  facets: ['*'],
@@ -258,21 +257,21 @@ export class AlgoliaClient {
258
257
  'item.keywords.keyword',
259
258
  'anatomy.organ.name',
260
259
  'anatomy.organ.curie',
261
- 'anatomy.organ.subsubcategory.name'
260
+ 'anatomy.organ.subsubcategory.name',
262
261
  ],
263
262
  })
264
- .then(response => {
263
+ .then((response) => {
265
264
  // Saving the line below incase we want to starty using keywords again
266
265
  resolve({
267
- forFlatmap: this.processResultsForFlatmap(response.facets ,response.hits),
268
- forScaffold: this.processResultsForScaffold(response.hits)
269
- })
270
- })
271
- })
266
+ forFlatmap: this.processResultsForFlatmap(response.facets, response.hits),
267
+ forScaffold: this.processResultsForScaffold(response.hits),
268
+ });
269
+ });
270
+ });
272
271
  }
273
272
 
274
273
  setLocalStorageForTermMapping() {
275
- return new Promise(resolve => {
274
+ return new Promise((_resolve) => {
276
275
  this.index
277
276
  .search('', {
278
277
  facets: ['*'],
@@ -283,87 +282,94 @@ export class AlgoliaClient {
283
282
  'objectID',
284
283
  'item.keywords.keyword',
285
284
  'anatomy.organ.name',
286
- 'anatomy.organ.curie'
285
+ 'anatomy.organ.curie',
287
286
  ],
288
287
  })
289
- .then(response => {
288
+ .then((response) => {
290
289
  // Saving the line below incase we want to starty using keywords again
291
- this._processAnatomy(response.hits)
292
- })
293
- })
290
+ this._processAnatomy(response.hits);
291
+ });
292
+ });
294
293
  }
295
294
 
296
295
  processResultsForFlatmap(facets, hits) {
297
296
  const filteredOrganNames = this.filterAvailableAnatomies(facets);
298
297
 
299
- let curieForDatasets = hits.map(h=>{
298
+ let curieForDatasets = hits.map((h) => {
300
299
  const data = {
301
300
  id: h.objectID,
302
301
  terms: h.anatomy
303
- ? h.anatomy.organ.map(o => {
304
- if (filteredOrganNames.includes(o.name.toLowerCase())) {
305
- return o.curie
306
- }
307
- }).filter(Boolean)
308
- : []
309
- }
310
- return data
311
- })
302
+ ? h.anatomy.organ
303
+ .map((o) => {
304
+ if (filteredOrganNames.includes(o.name.toLowerCase())) {
305
+ return o.curie;
306
+ }
307
+ })
308
+ .filter(Boolean)
309
+ : [],
310
+ };
311
+ return data;
312
+ });
312
313
 
313
- return curieForDatasets
314
+ return curieForDatasets;
314
315
  }
315
316
  filterAvailableAnatomies(facets) {
316
- const anatomyOrganName = facets['anatomy.organ.name']
317
- const anatomyOrganCategoryName = facets['anatomy.organ.category.name']
318
- const anatomyOrganSubcategoryName = facets['anatomy.organ.subcategory.name']
319
- const anatomyOrganSubsubcategoryName = facets['anatomy.organ.subsubcategory.name']
320
- const anatomyOrganNames = anatomyOrganName ? Object.keys(anatomyOrganName) : []
321
- const anatomyOrganCategoryNames = anatomyOrganCategoryName ? Object.keys(anatomyOrganCategoryName) : []
322
- const anatomyOrganSubcategoryNames = anatomyOrganSubcategoryName ? Object.keys(anatomyOrganSubcategoryName) : []
323
- const anatomyOrganSubsubcategoryNames = anatomyOrganSubsubcategoryName ? Object.keys(anatomyOrganSubsubcategoryName) : []
324
- const filteredOrganNames = []
317
+ const anatomyOrganName = facets['anatomy.organ.name'];
318
+ const anatomyOrganCategoryName = facets['anatomy.organ.category.name'];
319
+ const anatomyOrganSubcategoryName = facets['anatomy.organ.subcategory.name'];
320
+ const anatomyOrganSubsubcategoryName = facets['anatomy.organ.subsubcategory.name'];
321
+ const anatomyOrganNames = anatomyOrganName ? Object.keys(anatomyOrganName) : [];
322
+ const anatomyOrganCategoryNames = anatomyOrganCategoryName
323
+ ? Object.keys(anatomyOrganCategoryName)
324
+ : [];
325
+ const anatomyOrganSubcategoryNames = anatomyOrganSubcategoryName
326
+ ? Object.keys(anatomyOrganSubcategoryName)
327
+ : [];
328
+ const anatomyOrganSubsubcategoryNames = anatomyOrganSubsubcategoryName
329
+ ? Object.keys(anatomyOrganSubsubcategoryName)
330
+ : [];
331
+ const filteredOrganNames = [];
325
332
 
326
333
  anatomyOrganCategoryNames.forEach((_categoryName) => {
327
334
  const categoryName = _categoryName.toLowerCase();
328
335
  anatomyOrganNames.forEach((_organName) => {
329
336
  const organName = _organName.toLowerCase();
330
337
  //This will be incorrect for subsubcategory
331
- const fullName = `${categoryName}.${organName}`
338
+ const fullName = `${categoryName}.${organName}`;
332
339
  const found = anatomyOrganSubcategoryNames.some((_subcategoryName) => {
333
340
  const subcategoryName = _subcategoryName.toLowerCase();
334
341
  if (subcategoryName === fullName) {
335
- return true
342
+ return true;
336
343
  } else {
337
344
  return anatomyOrganSubsubcategoryNames.find((name) => {
338
- const fullsubsubname = `${subcategoryName}.${organName}`
339
- return (fullsubsubname === name)
340
- })
345
+ const fullsubsubname = `${subcategoryName}.${organName}`;
346
+ return fullsubsubname === name;
347
+ });
341
348
  }
342
349
  });
343
350
 
344
351
  if (found) {
345
352
  filteredOrganNames.push(organName);
346
353
  }
347
- })
348
- })
354
+ });
355
+ });
349
356
  return filteredOrganNames;
350
357
  }
351
358
  processResultsForScaffold(hits) {
352
- let numberOfDatasetsForAnatomy = {}
353
- hits.forEach(hit => {
354
- if (hit.anatomy && hit.anatomy.organ ) {
355
- hit.anatomy.organ.forEach(anatomy => {
359
+ let numberOfDatasetsForAnatomy = {};
360
+ hits.forEach((hit) => {
361
+ if (hit.anatomy && hit.anatomy.organ) {
362
+ hit.anatomy.organ.forEach((anatomy) => {
356
363
  if (anatomy.name) {
357
364
  if (numberOfDatasetsForAnatomy[anatomy.name]) {
358
- numberOfDatasetsForAnatomy[anatomy.name]++
365
+ numberOfDatasetsForAnatomy[anatomy.name]++;
359
366
  } else {
360
- numberOfDatasetsForAnatomy[anatomy.name] = 1
367
+ numberOfDatasetsForAnatomy[anatomy.name] = 1;
361
368
  }
362
369
  }
363
- })
370
+ });
364
371
  }
365
- })
366
- return numberOfDatasetsForAnatomy
372
+ });
373
+ return numberOfDatasetsForAnatomy;
367
374
  }
368
-
369
375
  }