@abi-software/map-side-bar 1.3.0 → 1.3.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.
- package/LICENSE +201 -201
- package/README.md +53 -53
- package/babel.config.js +14 -14
- package/dist/map-side-bar.common.js +293 -212
- package/dist/map-side-bar.common.js.map +1 -1
- package/dist/map-side-bar.css +1 -1
- package/dist/map-side-bar.umd.js +293 -212
- package/dist/map-side-bar.umd.js.map +1 -1
- package/dist/map-side-bar.umd.min.js +1 -1
- package/dist/map-side-bar.umd.min.js.map +1 -1
- package/package-lock.json +13698 -13698
- package/package.json +65 -65
- package/public/index.html +17 -17
- package/scaffold_context_info.json +30 -0
- package/src/App.vue +137 -133
- package/src/algolia/algolia.js +173 -127
- package/src/algolia/utils.js +60 -51
- package/src/components/BadgesGroup.vue +141 -141
- package/src/components/Cascader.vue +49 -49
- package/src/components/ContextCard.vue +265 -240
- package/src/components/DatasetCard.vue +325 -324
- package/src/components/EventBus.js +3 -3
- package/src/components/ImageGallery.vue +505 -502
- package/src/components/SearchFilters.vue +557 -557
- package/src/components/SideBar.vue +245 -239
- package/src/components/SidebarContent.vue +482 -476
- package/src/components/Tabs.vue +78 -78
- package/src/components/hardcoded-context-info.js +79 -79
- package/src/components/index.js +8 -8
- package/src/components/processFilters.js +22 -0
- package/src/components/species-map.js +8 -8
- package/src/main.js +8 -8
- package/static.json +6 -6
- package/vue.config.js +11 -11
package/src/algolia/algolia.js
CHANGED
|
@@ -1,127 +1,173 @@
|
|
|
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
|
-
_processResultsForCards(results) {
|
|
76
|
-
let newResults = []
|
|
77
|
-
let newResult = {}
|
|
78
|
-
for (let res of results) {
|
|
79
|
-
newResult = {...res}
|
|
80
|
-
newResult = {
|
|
81
|
-
doi: res.item.curie.split(':')[1],
|
|
82
|
-
name: res.item.name,
|
|
83
|
-
description: res.item.description,
|
|
84
|
-
updated: res.pennsieve.updatedAt,
|
|
85
|
-
publishDate: res.pennsieve.publishDate,
|
|
86
|
-
datasetId: res.objectID,
|
|
87
|
-
detailsReady: false
|
|
88
|
-
}
|
|
89
|
-
newResults.push(newResult)
|
|
90
|
-
}
|
|
91
|
-
return newResults
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
+
_processResultsForCards(results) {
|
|
76
|
+
let newResults = []
|
|
77
|
+
let newResult = {}
|
|
78
|
+
for (let res of results) {
|
|
79
|
+
newResult = {...res}
|
|
80
|
+
newResult = {
|
|
81
|
+
doi: res.item.curie.split(':')[1],
|
|
82
|
+
name: res.item.name,
|
|
83
|
+
description: res.item.description,
|
|
84
|
+
updated: res.pennsieve.updatedAt,
|
|
85
|
+
publishDate: res.pennsieve.publishDate,
|
|
86
|
+
datasetId: res.objectID,
|
|
87
|
+
detailsReady: false
|
|
88
|
+
}
|
|
89
|
+
newResults.push(newResult)
|
|
90
|
+
}
|
|
91
|
+
return newResults
|
|
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._splitUberonURL(keyword))
|
|
103
|
+
uniqueKeywords = [...new Set(foundKeyWords)]
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
return uniqueKeywords
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
_splitUberonURL(url){
|
|
112
|
+
return url.split('/').pop()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get Search results
|
|
117
|
+
* This is using fetch from the Algolia API
|
|
118
|
+
*/
|
|
119
|
+
search (filter, query='', hitsperPage=10, page=1) {
|
|
120
|
+
return new Promise(resolve => {
|
|
121
|
+
this.index
|
|
122
|
+
.search(query, {
|
|
123
|
+
facets:['*'],
|
|
124
|
+
hitsPerPage: hitsperPage,
|
|
125
|
+
page: page-1,
|
|
126
|
+
filters: filter,
|
|
127
|
+
attributesToHighlight: [],
|
|
128
|
+
attributesToRetrieve: [
|
|
129
|
+
'pennsieve.publishDate',
|
|
130
|
+
'pennsieve.updatedAt',
|
|
131
|
+
'item.curie',
|
|
132
|
+
'item.name',
|
|
133
|
+
'item.description',
|
|
134
|
+
'objectID',
|
|
135
|
+
],
|
|
136
|
+
})
|
|
137
|
+
.then(response => {
|
|
138
|
+
let searchData = {
|
|
139
|
+
items: this._processResultsForCards(response.hits),
|
|
140
|
+
total: response.nbHits,
|
|
141
|
+
discoverIds: response.hits.map(r=>r.pennsieve.identifier),
|
|
142
|
+
dois: response.hits.map(r=>r.item.curie.split(':')[1])
|
|
143
|
+
}
|
|
144
|
+
resolve(searchData)
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get key words
|
|
151
|
+
* This is used to return all keywords for a given search. Note that you often want the hits per page to be maxed out
|
|
152
|
+
*/
|
|
153
|
+
keywordsInSearch (filter, query='', hitsperPage=999999, page=1) {
|
|
154
|
+
return new Promise(resolve => {
|
|
155
|
+
this.index
|
|
156
|
+
.search(query, {
|
|
157
|
+
facets:['*'],
|
|
158
|
+
hitsPerPage: hitsperPage,
|
|
159
|
+
page: page-1,
|
|
160
|
+
filters: filter,
|
|
161
|
+
attributesToHighlight: [],
|
|
162
|
+
attributesToRetrieve: [
|
|
163
|
+
'item.keywords.keyword',
|
|
164
|
+
],
|
|
165
|
+
})
|
|
166
|
+
.then(response => {
|
|
167
|
+
let keywords = this._processKeywords(response.hits)
|
|
168
|
+
console.log(response.hits)
|
|
169
|
+
resolve(keywords)
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
}
|
package/src/algolia/utils.js
CHANGED
|
@@ -1,52 +1,61 @@
|
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
+
'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',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Returns filter for searching algolia. All facets of the same category are joined with OR,
|
|
23
|
+
* and each of those results is then joined with an AND.
|
|
24
|
+
* i.e. (color:blue OR color:red) AND (shape:circle OR shape:red) */
|
|
25
|
+
export function getFilters(selectedFacetArray=undefined) {
|
|
26
|
+
console.log('calling getFilters!')
|
|
27
|
+
// return all datasets if no filter
|
|
28
|
+
if (selectedFacetArray === undefined) {
|
|
29
|
+
return 'NOT item.published.status:embargo'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Switch the 'term' attribute to 'label' if 'label' does not exist
|
|
33
|
+
selectedFacetArray.forEach(f=>f.label=f.facet)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
let facets = removeShowAllFacets(selectedFacetArray)
|
|
37
|
+
|
|
38
|
+
let filters = "NOT item.published.status:embargo";
|
|
39
|
+
filters = `(${filters}) AND `;
|
|
40
|
+
|
|
41
|
+
const facetPropPaths = Object.keys(facetPropPathMapping);
|
|
42
|
+
facetPropPaths.map((facetPropPath) => {
|
|
43
|
+
const facetsToOr = facets.filter(
|
|
44
|
+
(facet) => facet.facetPropPath == facetPropPath
|
|
45
|
+
);
|
|
46
|
+
var filter = "";
|
|
47
|
+
facetsToOr.map((facet) => {
|
|
48
|
+
filter += `"${facetPropPath}":"${facet.label}" OR `;
|
|
49
|
+
});
|
|
50
|
+
if (filter == "") {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
filter = `(${filter.substring(0, filter.lastIndexOf(" OR "))})`;
|
|
54
|
+
filters += `${filter} AND `;
|
|
55
|
+
});
|
|
56
|
+
return filters.substring(0, filters.lastIndexOf(" AND "));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function removeShowAllFacets(facetArray){
|
|
60
|
+
return facetArray.filter( f => f.label !== 'Show all')
|
|
52
61
|
}
|