@abi-software/map-side-bar 1.3.2 → 1.3.5

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-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "1.3.2",
3
+ "version": "1.3.5",
4
4
  "main": "./dist/map-side-bar.common.js",
5
5
  "files": [
6
6
  "dist/*",
package/src/App.vue CHANGED
@@ -7,6 +7,7 @@
7
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
+ <el-button @click="keywordSearch">keyword search</el-button>
10
11
  <SideBar :envVars="envVars" class="side-bar" ref="sideBar" :visible="sideBarVisibility"
11
12
  :tabs="tabs" :activeId="activeId" @tabClicked="tabClicked"
12
13
  @search-changed="searchChanged($event)" @actionClick="action"/>
@@ -113,8 +114,11 @@ export default {
113
114
  multiFacets: function(){
114
115
  this.$refs.sideBar.openSearch([{facet: 'Male', term:'Sex', facetPropPath:'attributes.subject.sex.value'}, {facet: 'Heart', term:'Anatomical structure', facetPropPath: 'anatomy.organ.name'}], '')
115
116
  },
117
+ keywordSearch: function(){
118
+ this.$refs.sideBar.openSearch([{facet: 'http://purl.obolibrary.org/obo/UBERON_0001103', term:'Keywords', facetPropPath:'item.keywords.keyword'}])
119
+ },
116
120
  neuronSearch: function(){
117
- this.$refs.sideBar.openNeuronSearch('neuron-type-keast-10')
121
+ this.$refs.sideBar.openNeuronSearch('ilxtr:neuron-type-keast-10')
118
122
  }
119
123
  }
120
124
  }
@@ -90,6 +90,28 @@ export class AlgoliaClient {
90
90
  }
91
91
  return newResults
92
92
  }
93
+
94
+ _processKeywords(hits){
95
+ let foundKeyWords = []
96
+ let uniqueKeywords = []
97
+ hits.forEach(hit=>{
98
+ if ( hit.item && hit.item.keywords) {
99
+ hit.item.keywords.forEach(keywordObj=>{
100
+ let keyword = keywordObj.keyword
101
+ if (keyword.includes('UBERON') || keyword.includes('ilxtr') || keyword.includes('ILX')) {
102
+ foundKeyWords.push(this._processUberonURL(keyword))
103
+ uniqueKeywords = [...new Set(foundKeyWords)]
104
+ }
105
+ })
106
+ }
107
+ })
108
+ return uniqueKeywords
109
+ }
110
+
111
+ _processUberonURL(url){
112
+ let ub = url.split('/').pop()
113
+ ub.replace('_',':')
114
+ }
93
115
 
94
116
  /**
95
117
  * Get Search results
@@ -124,4 +146,28 @@ export class AlgoliaClient {
124
146
  })
125
147
  })
126
148
  }
149
+
150
+ /**
151
+ * Get key words
152
+ * This is used to return all keywords for a given search. Note that you often want the hits per page to be maxed out
153
+ */
154
+ keywordsInSearch (filter, query='', hitsperPage=999999, page=1) {
155
+ return new Promise(resolve => {
156
+ this.index
157
+ .search(query, {
158
+ facets:['*'],
159
+ hitsPerPage: hitsperPage,
160
+ page: page-1,
161
+ filters: filter,
162
+ attributesToHighlight: [],
163
+ attributesToRetrieve: [
164
+ 'item.keywords.keyword',
165
+ ],
166
+ })
167
+ .then(response => {
168
+ let keywords = this._processKeywords(response.hits)
169
+ resolve(keywords)
170
+ })
171
+ })
172
+ }
127
173
  }
@@ -8,13 +8,21 @@ export const facetPropPathMapping = {
8
8
  'item.modalities.keyword' : 'Experimental Approach',
9
9
  'attributes.subject.sex.value' : 'Sex',
10
10
  'attributes.subject.ageCategory.value' : 'Age Categories',
11
+ 'item.keywords.keyword' : 'Keywords'
12
+ }
13
+
14
+ export const shownFilters = {
15
+ 'anatomy.organ.name' : 'Anatomical Structure',
16
+ 'organisms.primary.species.name' : 'Species',
17
+ 'item.modalities.keyword' : 'Experimental Approach',
18
+ 'attributes.subject.sex.value' : 'Sex',
19
+ 'attributes.subject.ageCategory.value' : 'Age Categories',
11
20
  }
12
21
 
13
22
  /* Returns filter for searching algolia. All facets of the same category are joined with OR,
14
23
  * and each of those results is then joined with an AND.
15
24
  * i.e. (color:blue OR color:red) AND (shape:circle OR shape:red) */
16
25
  export function getFilters(selectedFacetArray=undefined) {
17
-
18
26
  // return all datasets if no filter
19
27
  if (selectedFacetArray === undefined) {
20
28
  return 'NOT item.published.status:embargo'
@@ -9,20 +9,20 @@
9
9
  </div>
10
10
  <div class="card-right scrollbar">
11
11
  <div class="title">{{contextData.heading}}</div>
12
- <div>{{contextData.description}}</div>
12
+ <div v-html="contextData.description"/>
13
13
  <br/>
14
14
  <div v-if="contextData.views && contextData.views.length > 0" class="subtitle">Scaffold Views</div>
15
15
  <template v-for="(view, i) in contextData.views">
16
- <span v-bind:key="i+'_1'" @click="openViewFile(view)" class="context-card-item">
17
- <img class="key-image" :src="getFileFromPath(view.thumbnail)">
18
- {{view.description}}
19
- </span>
20
- <br v-bind:key="i"/>
16
+ <div v-bind:key="i+'_1'" @click="openViewFile(view)" class="context-card-view">
17
+ <img class="view-image" :src="getFileFromPath(view.thumbnail)">
18
+ <div class="view-description">{{view.description}}</div>
19
+ </div>
20
+ <div v-bind:key="i" class="padding"/>
21
21
  </template>
22
22
  <div style="margin-bottom: 16px;"/>
23
23
  <div v-if="contextData.samples && contextData.samples.length > 0" class="subtitle">Samples on Scaffold</div>
24
24
  <template v-for="(sample, i) in contextData.samples">
25
- <span v-bind:key="i+'_3'" class="context-card-item" @click="toggleSampleDetails(i)">
25
+ <span v-bind:key="i+'_3'" class="context-card-item cursor-pointer" @click="toggleSampleDetails(i)">
26
26
  <div v-bind:key="i+'_6'" style="display: flex">
27
27
  <div v-if="sample.color" class="color-box" :style="'background-color:'+ sample.color"></div>
28
28
  <img class="key-image" v-else-if="sample.thumbnail" :src="getFileFromPath(sample.thumbnail)">
@@ -30,11 +30,9 @@
30
30
  <i class="el-icon-warning-outline info"></i>
31
31
  </div>
32
32
  </span>
33
- <div v-bind:key="i+'_4'" v-if="sampleDetails[i]">
34
- {{sample.description}}
35
- <a v-bind:key="i+'_5'" v-if="sampleDetails[i]" :href="generateFileLink(sample.path)" target="_blank">View Source</a>
36
- </div>
37
- <br v-bind:key="i+'_2'"/>
33
+ <div v-bind:key="i+'_4'" v-if="sampleDetails[i]" v-html="sample.description"/>
34
+ <a v-bind:key="i+'_5'" v-if="sampleDetails[i]" :href="generateFileLink(sample.path)" target="_blank">View Source</a>
35
+ <div v-bind:key="i+'_2'" class="padding"/>
38
36
  </template>
39
37
  </div>
40
38
  </el-card>
@@ -110,7 +108,6 @@ export default {
110
108
  })
111
109
  .then((data) => {
112
110
  this.contextData = data
113
- console.log(data)
114
111
  this.loading = false
115
112
  })
116
113
  .catch(() => {
@@ -179,14 +176,20 @@ export default {
179
176
  max-height: 258px;
180
177
  }
181
178
 
182
- .context-card-item{
179
+ .context-card-view{
183
180
  cursor: pointer;
184
181
  padding-bottom: 8px;
182
+ display: flex;
185
183
  }
186
184
 
187
- .key-image {
185
+ .view-image {
188
186
  width: 25px;
189
187
  height: auto;
188
+ flex: 1;
189
+ }
190
+
191
+ .view-descriptions {
192
+ flex: 8;
190
193
  }
191
194
 
192
195
  .context-card >>> .el-card__body {
@@ -221,7 +224,6 @@ export default {
221
224
 
222
225
  .cursor-pointer {
223
226
  cursor: pointer;
224
- height: 25px;
225
227
  }
226
228
 
227
229
  .info{
@@ -230,6 +232,10 @@ export default {
230
232
  margin-left: 8px;
231
233
  }
232
234
 
235
+ .padding {
236
+ padding-bottom: 8px;
237
+ }
238
+
233
239
  .title{
234
240
  font-weight: bold;
235
241
  }
@@ -72,7 +72,7 @@ import speciesMap from "./species-map";
72
72
  import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
73
73
 
74
74
  import {AlgoliaClient} from "../algolia/algolia.js";
75
- import { facetPropPathMapping } from "../algolia/utils.js";
75
+ import { shownFilters } from "../algolia/utils.js";
76
76
 
77
77
  locale.use(lang);
78
78
  Vue.use(Option);
@@ -149,7 +149,7 @@ export default {
149
149
  populateCascader: function () {
150
150
  return new Promise((resolve) => {
151
151
  // Algolia facet serach
152
- this.algoliaClient.getAlgoliaFacets(facetPropPathMapping)
152
+ this.algoliaClient.getAlgoliaFacets(shownFilters)
153
153
  .then((data) => {
154
154
  this.facets = data;
155
155
  this.options = data;
@@ -139,6 +139,12 @@ export default {
139
139
  EventBus.$on("PopoverActionClick", (payLoad) => {
140
140
  this.$emit("actionClick", payLoad);
141
141
  })
142
+ EventBus.$on('keywordsFound', (payLoad)=> {
143
+ this.$emit('search-changed', {
144
+ type: 'keyword-update',
145
+ value: payLoad
146
+ })
147
+ })
142
148
  }
143
149
  };
144
150
  </script>
@@ -61,6 +61,7 @@ import locale from "element-ui/lib/locale";
61
61
  import SearchFilters from "./SearchFilters";
62
62
  import DatasetCard from "./DatasetCard";
63
63
  import ContextCard from "./ContextCard.vue";
64
+ import EventBus from "./EventBus"
64
65
 
65
66
  import {AlgoliaClient} from "../algolia/algolia.js";
66
67
  import {getFilters} from "../algolia/utils.js"
@@ -191,6 +192,9 @@ export default {
191
192
  searchAlgolia(filters, query=''){
192
193
  // Algolia search
193
194
  this.loadingCards = true
195
+ this.algoliaClient.keywordsInSearch(getFilters(filters), query).then(keywords => {
196
+ EventBus.$emit("keywordsFound", keywords)
197
+ })
194
198
  this.algoliaClient.search(getFilters(filters), query, this.numberPerPage, this.page).then(searchData => {
195
199
  this.numberOfHits = searchData.total
196
200
  this.discoverIds = searchData.discoverIds