@abi-software/map-side-bar 1.1.5-beta-0 → 1.1.5-beta-1

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": "1.1.5-beta-0",
3
+ "version": "1.1.5-beta-1",
4
4
  "main": "./dist/map-side-bar.common.js",
5
5
  "files": [
6
6
  "dist/*",
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@abi-software/svg-sprite": "^0.1.12",
21
+ "algoliasearch": "^4.10.5",
21
22
  "element-ui": "^2.13.0",
22
23
  "vue": "^2.6.10"
23
24
  },
@@ -32,6 +33,7 @@
32
33
  "file-loader": "^5.0.2",
33
34
  "raw-loader": "^0.5.1",
34
35
  "transform-loader": "^0.2.4",
36
+ "typescript": "^4.4.3",
35
37
  "vue-custom-element": "^3.3.0",
36
38
  "vue-template-compiler": "^2.6.10",
37
39
  "webpack-node-externals": "^2.5.2"
package/src/App.vue CHANGED
@@ -3,11 +3,11 @@
3
3
  <link rel="stylesheet"
4
4
  href="https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap">
5
5
  Click arrow to open sidebar
6
- <el-button @click="openSearch">search 'islet' from refs</el-button>
7
- <el-button @click="singleFacets">single facets</el-button>
6
+ <el-button @click="openSearch">search 'heart' from refs</el-button>
7
+ <el-button @click="singleFacets">Add to Filter</el-button>
8
8
  <el-button @click="multiFacets">multiple facets</el-button>
9
9
  <el-button @click="neuronSearch">open neuron search</el-button>
10
- <SideBar class="side-bar" ref="sideBar" :apiLocation="apiLocation" :visible="sideBarVisibility"
10
+ <SideBar :envVars="envVars" class="side-bar" ref="sideBar" :visible="sideBarVisibility"
11
11
  :tabs="tabArray" :activeId="activeId" @tabClicked="tabClicked"
12
12
  @search-changed="searchChanged($event)" @actionClick="action"/>
13
13
  </div>
@@ -63,7 +63,13 @@ export default {
63
63
  ]
64
64
  }],
65
65
  sideBarVisibility: true,
66
- apiLocation: process.env.VUE_APP_API_LOCATION,
66
+ envVars: {
67
+ API_LOCATION: process.env.VUE_APP_API_LOCATION,
68
+ ALGOLIA_KEY: process.env.VUE_APP_ALGOLIA_KEY,
69
+ ALGOLIA_ID: process.env.VUE_APP_ALGOLIA_ID,
70
+ ALGOLIA_INDEX: process.env.VUE_APP_ALGOLIA_INDEX,
71
+ PENNSIEVE_API_LOCATION: process.env.VUE_APP_PENNSIEVE_API_LOCATION
72
+ },
67
73
  activeId: 1,
68
74
  }
69
75
  },
@@ -78,16 +84,13 @@ export default {
78
84
  console.log("action fired: ", val)
79
85
  },
80
86
  openSearch: function(){
81
- this.$refs.sideBar.openSearch('islet', [{facet: "show all", term:'organ'},
82
- {facet: "show all", term:'species'},
83
- {facet: "show all", term:'gender'},
84
- {facet: "show all", term:'datasets'}] )
87
+ this.$refs.sideBar.openSearch('heart', [])
85
88
  },
86
89
  singleFacets: function(){
87
- this.$refs.sideBar.openSearch('', [{facet: 'Heart', term:'organ'}])
90
+ this.$refs.sideBar.addFilter({facet: 'Heart', term:'Anatomical structure', facetPropPath: 'anatomy.organ.name'})
88
91
  },
89
92
  multiFacets: function(){
90
- this.$refs.sideBar.openSearch('', [{facet: 'Rat', term:'species'}, {facet: 'Heart', term:'organ'}])
93
+ this.$refs.sideBar.openSearch('', [{facet: 'Male', term:'Sex', facetPropPath:'attributes.subject.sex.value'}, {facet: 'Heart', term:'Anatomical structure', facetPropPath: 'anatomy.organ.name'}])
91
94
  },
92
95
  neuronSearch: function(){
93
96
  this.$refs.sideBar.openNeuronSearch('neuron-type-keast-10')
@@ -0,0 +1,98 @@
1
+ /* eslint-disable no-alert, no-console */
2
+ import algoliasearch from 'algoliasearch'
3
+
4
+ // export `createAlgoliaClient` to use it in page components
5
+ export class AlgoliaClient {
6
+ constructor(algoliaId, algoliaKey, PENNSIEVE_API_LOCATION='https://api.pennsieve.io') {
7
+ this.client = algoliasearch(
8
+ algoliaId,
9
+ algoliaKey
10
+ )
11
+ this.PENNSIEVE_API_LOCATION = PENNSIEVE_API_LOCATION
12
+ }
13
+ initIndex(ALGOLIA_INDEX) {
14
+ this.index = this.client.initIndex(ALGOLIA_INDEX);
15
+ }
16
+
17
+ getAlgoliaFacets (propPathMapping) {
18
+ const map = new Map(Object.entries(propPathMapping));
19
+ const facetPropPaths = Array.from(map.keys() );
20
+ let facetData = []
21
+ let facetId = 0
22
+ return this.index
23
+ .search('', {
24
+ sortFacetValuesBy: 'alpha',
25
+ facets: facetPropPaths
26
+ })
27
+ .then(response => {
28
+ facetPropPaths.map((facetPropPath) => {
29
+ var children = []
30
+ const responseFacets = response.facets
31
+ if (responseFacets === undefined) {return}
32
+ const responseFacetChildren =
33
+ responseFacets[facetPropPath] == undefined
34
+ ? {}
35
+ : responseFacets[facetPropPath]
36
+ Object.keys(responseFacetChildren).map(facet => {
37
+ children.push({
38
+ label: facet,
39
+ id: facetId++,
40
+ facetPropPath: facetPropPath
41
+ })
42
+ })
43
+ if (children.length > 0) {
44
+ facetData.push({
45
+ label: map.get(facetPropPath),
46
+ id: facetId++,
47
+ children: children,
48
+ key: facetPropPath
49
+ })
50
+ }
51
+ })
52
+ return facetData
53
+ })
54
+ }
55
+
56
+ // Returns all DOIs of all versions for a given discover dataset
57
+ _discoverAllDois (discoverId, PENNSIEVE_API_LOCATION='https://api.pennsieve.io') {
58
+ return new Promise(resolve => {
59
+ fetch(`${PENNSIEVE_API_LOCATION}/discover/datasets/${discoverId}/versions`).then(r=>r.json()).then(dataset => {
60
+ resolve(dataset.map(version => version.doi))
61
+ })
62
+ })
63
+ }
64
+
65
+ // Get all dois given a list of discoverIds
66
+ _expandDois (discoverIds, PENNSIEVE_API_LOCATION='https://api.pennsieve.io') {
67
+ return new Promise(resolve => {
68
+ let promiseList = discoverIds.map(discoverId => this._discoverAllDois(discoverId, PENNSIEVE_API_LOCATION))
69
+ Promise.all(promiseList).then((values) => {
70
+ resolve(values.flat())
71
+ });
72
+ })
73
+ }
74
+
75
+ /**
76
+ * Get Search results
77
+ * This is using fetch from the Algolia API
78
+ */
79
+ search (filter, query='', hitsperPage=10, page=1) {
80
+ return new Promise(resolve => {
81
+ this.index
82
+ .search(query, {
83
+ facets:['*'],
84
+ hitsPerPage: hitsperPage,
85
+ page: page-1,
86
+ filters: filter
87
+ })
88
+ .then(response => {
89
+ let searchData = {
90
+ items: response.hits,
91
+ total: response.nbHits,
92
+ discoverIds: response.hits.map(r=>r.pennsieve.identifier)
93
+ }
94
+ resolve(searchData)
95
+ })
96
+ })
97
+ }
98
+ }
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-alert, no-console */
2
+
3
+ // Mapping between display categories and their Algolia index property path
4
+ // Used for populating the Dataset Search Results facet menu dynamically
5
+ export const facetPropPathMapping = {
6
+ 'anatomy.organ.name' : 'Anatomical Structure',
7
+ 'organisms.primary.species.name' : 'Species',
8
+ 'item.modalities.keyword' : 'Experimental Approach',
9
+ 'attributes.subject.sex.value' : 'Sex',
10
+ 'attributes.subject.ageCategory.value' : 'Age Categories',
11
+ }
12
+
13
+ /* Returns filter for searching algolia. All facets of the same category are joined with OR,
14
+ * and each of those results is then joined with an AND.
15
+ * i.e. (color:blue OR color:red) AND (shape:circle OR shape:red) */
16
+ export function getFilters(selectedFacetArray=undefined) {
17
+
18
+ // return all datasets if no filter
19
+ if (selectedFacetArray === undefined) {
20
+ return 'NOT item.published.status:embargo'
21
+ }
22
+
23
+ // Switch the 'term' attribute to 'label' if 'label' does not exist
24
+ selectedFacetArray.forEach(f=>f.label=f.facet)
25
+
26
+
27
+ let facets = removeShowAllFacets(selectedFacetArray)
28
+
29
+ let filters = "NOT item.published.status:embargo";
30
+ filters = `(${filters}) AND `;
31
+
32
+ const facetPropPaths = Object.keys(facetPropPathMapping);
33
+ facetPropPaths.map((facetPropPath) => {
34
+ const facetsToOr = facets.filter(
35
+ (facet) => facet.facetPropPath == facetPropPath
36
+ );
37
+ var filter = "";
38
+ facetsToOr.map((facet) => {
39
+ filter += `"${facetPropPath}":"${facet.label}" OR `;
40
+ });
41
+ if (filter == "") {
42
+ return;
43
+ }
44
+ filter = `(${filter.substring(0, filter.lastIndexOf(" OR "))})`;
45
+ filters += `${filter} AND `;
46
+ });
47
+ return filters.substring(0, filters.lastIndexOf(" AND "));
48
+ }
49
+
50
+ function removeShowAllFacets(facetArray){
51
+ return facetArray.filter( f => f.label !== 'Show all')
52
+ }
@@ -68,9 +68,9 @@ export default {
68
68
  * the required viewing.
69
69
  */
70
70
  entry: Object,
71
- apiLocation: {
72
- type: String,
73
- default: ""
71
+ envVars: {
72
+ type: Object,
73
+ default: () => {}
74
74
  },
75
75
  },
76
76
  data: function () {
@@ -102,18 +102,28 @@ export default {
102
102
  },
103
103
  samples: function() {
104
104
  let text = "";
105
- if (this.entry.numberSamples === 1) {
106
- text = this.entry.numberSamples + " sample";
107
- } else if (this.entry.numberSamples > 1) {
108
- text = this.entry.numberSamples + " samples";
109
- }
110
105
  if (this.entry.species) {
111
106
  if (speciesMap[this.entry.species[0].toLowerCase()]){
112
- text += ` (${speciesMap[this.entry.species[0].toLowerCase()]})`
107
+ text = `${speciesMap[this.entry.species[0].toLowerCase()]}`;
113
108
  } else {
114
- text += ` (${this.entry.species})`
109
+ text = `${this.entry.species}`;
115
110
  }
116
111
  }
112
+ if (this.entry.numberSamples > 0) {
113
+ text += " (";
114
+ if (this.entry.numberSamples === 1) {
115
+ text += `${this.entry.numberSamples} sample`;
116
+ } else if (this.entry.numberSamples > 1) {
117
+ text += `${this.entry.numberSamples} samples`;
118
+ }
119
+ if (this.entry.numberSubjects === 1) {
120
+ text += ` from ${this.entry.numberSubjects} subject`;
121
+ } else if (this.entry.numberSamples > 1) {
122
+ text += ` from ${this.entry.numberSubjects} subjects`;
123
+ }
124
+ text += ")";
125
+ }
126
+
117
127
  return text;
118
128
  },
119
129
  label: function(){
@@ -156,7 +166,7 @@ export default {
156
166
  window.open(this.dataLocation,'_blank');
157
167
  },
158
168
  openRepository: function() {
159
- let apiLocation = this.apiLocation;
169
+ let apiLocation = this.envVars.API_LOCATION;
160
170
  this.entry.additionalLinks.forEach(function(el) {
161
171
  if (el.description == "Repository") {
162
172
  let xmlhttp = new XMLHttpRequest();
@@ -250,11 +260,11 @@ export default {
250
260
  },
251
261
  getScaffoldPath: function(discoverId, version, scaffoldPath){
252
262
  let id = discoverId
253
- let path = `${this.apiLocation}s3-resource/${id}/${version}/files/${scaffoldPath}`
263
+ let path = `${this.envVars.API_LOCATION}s3-resource/${id}/${version}/files/${scaffoldPath}`
254
264
  return path
255
265
  },
256
266
  getFileFromPath: function(discoverId, version, path){
257
- return `${this.apiLocation}s3-resource/${discoverId}/${version}/files/${path}`
267
+ return `${this.envVars.API_LOCATION}s3-resource/${discoverId}/${version}/files/${path}`
258
268
  },
259
269
  isOverflown: function(el){
260
270
  return el.clientHeight < el.scrollHeight
@@ -292,7 +302,8 @@ export default {
292
302
  return fullName.split(',')[0]
293
303
  },
294
304
  getBiolucidaInfo: function(id) {
295
- let endpoint = this.apiLocation + "image_search/" + id;
305
+ let apiLocation = this.envVars.API_LOCATION;
306
+ let endpoint = apiLocation + "image_search/" + id;
296
307
  // Add parameters if we are sent them
297
308
  fetch(endpoint)
298
309
  .then(response => response.json())