@abi-software/map-side-bar 2.11.4 → 2.12.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/dist/map-side-bar.js +2641 -2573
- package/dist/map-side-bar.umd.cjs +56 -56
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/algolia/algolia.js +41 -18
- package/src/assets/searchPopover.scss +90 -0
- package/src/components/ConnectivityExplorer.vue +1 -76
- package/src/components/DatasetExplorer.vue +49 -32
- package/src/services/flatmapKnowledge.js +0 -94
- package/src/services/flatmapQueries.js +0 -498
package/package.json
CHANGED
package/src/algolia/algolia.js
CHANGED
|
@@ -187,24 +187,47 @@ export class AlgoliaClient {
|
|
|
187
187
|
* This is using fetch from the Algolia API
|
|
188
188
|
*/
|
|
189
189
|
search(filter, query = '', hitsperPage = 10, page = 1) {
|
|
190
|
+
const terms = query.replaceAll('"', '').split(",")
|
|
191
|
+
let processed = "";
|
|
192
|
+
const optionalWords = [];
|
|
193
|
+
if (terms) {
|
|
194
|
+
if (terms.length === 1 && (!(query.includes(" ")))) {
|
|
195
|
+
processed = query;
|
|
196
|
+
} else {
|
|
197
|
+
terms.forEach(term => {
|
|
198
|
+
optionalWords.push(term.trim())
|
|
199
|
+
processed += `"${term.trim()}" `;
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
processed = processed.trim()
|
|
204
|
+
|
|
205
|
+
const payload = {
|
|
206
|
+
advancedSyntax: true,
|
|
207
|
+
advancedSyntaxFeatures: ['exactPhrase'],
|
|
208
|
+
queryType: 'prefixAll',
|
|
209
|
+
facets: ['*'],
|
|
210
|
+
hitsPerPage: hitsperPage,
|
|
211
|
+
page: page - 1,
|
|
212
|
+
filters: filter,
|
|
213
|
+
attributesToHighlight: [],
|
|
214
|
+
attributesToRetrieve: [
|
|
215
|
+
'pennsieve.publishDate',
|
|
216
|
+
'pennsieve.updatedAt',
|
|
217
|
+
'item.curie',
|
|
218
|
+
'item.name',
|
|
219
|
+
'item.description',
|
|
220
|
+
'objectID',
|
|
221
|
+
'anatomy.organ.curie'
|
|
222
|
+
],
|
|
223
|
+
}
|
|
224
|
+
if (optionalWords.length > 1) {
|
|
225
|
+
payload.optionalWords = optionalWords
|
|
226
|
+
}
|
|
227
|
+
|
|
190
228
|
return new Promise(resolve => {
|
|
191
229
|
this.index
|
|
192
|
-
.search(
|
|
193
|
-
facets: ['*'],
|
|
194
|
-
hitsPerPage: hitsperPage,
|
|
195
|
-
page: page - 1,
|
|
196
|
-
filters: filter,
|
|
197
|
-
attributesToHighlight: [],
|
|
198
|
-
attributesToRetrieve: [
|
|
199
|
-
'pennsieve.publishDate',
|
|
200
|
-
'pennsieve.updatedAt',
|
|
201
|
-
'item.curie',
|
|
202
|
-
'item.name',
|
|
203
|
-
'item.description',
|
|
204
|
-
'objectID',
|
|
205
|
-
'anatomy.organ.curie'
|
|
206
|
-
],
|
|
207
|
-
})
|
|
230
|
+
.search(processed, payload)
|
|
208
231
|
.then(response => {
|
|
209
232
|
let searchData = {
|
|
210
233
|
items: this._processResultsForCards(response.hits),
|
|
@@ -299,7 +322,7 @@ export class AlgoliaClient {
|
|
|
299
322
|
const anatomyOrganSubcategoryNames = anatomyOrganSubcategoryName ? Object.keys(anatomyOrganSubcategoryName) : []
|
|
300
323
|
const anatomyOrganSubsubcategoryNames = anatomyOrganSubsubcategoryName ? Object.keys(anatomyOrganSubsubcategoryName) : []
|
|
301
324
|
const filteredOrganNames = []
|
|
302
|
-
|
|
325
|
+
|
|
303
326
|
anatomyOrganCategoryNames.forEach((_categoryName) => {
|
|
304
327
|
const categoryName = _categoryName.toLowerCase();
|
|
305
328
|
anatomyOrganNames.forEach((_organName) => {
|
|
@@ -313,7 +336,7 @@ export class AlgoliaClient {
|
|
|
313
336
|
} else {
|
|
314
337
|
return anatomyOrganSubsubcategoryNames.find((name) => {
|
|
315
338
|
const fullsubsubname = `${subcategoryName}.${organName}`
|
|
316
|
-
return (fullsubsubname === name)
|
|
339
|
+
return (fullsubsubname === name)
|
|
317
340
|
})
|
|
318
341
|
}
|
|
319
342
|
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
|
|
2
|
+
.filter-help-popover {
|
|
3
|
+
font-family: 'Asap', sans-serif;
|
|
4
|
+
background: #f3ecf6 !important;
|
|
5
|
+
border: 1px solid $app-primary-color !important;
|
|
6
|
+
border-radius: 4px !important;
|
|
7
|
+
color: #303133 !important;
|
|
8
|
+
font-size: 12px !important;
|
|
9
|
+
line-height: 18px !important;
|
|
10
|
+
|
|
11
|
+
> div {
|
|
12
|
+
word-break: break-word;
|
|
13
|
+
text-align: initial;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
ul {
|
|
17
|
+
padding-left: 1.5rem;
|
|
18
|
+
|
|
19
|
+
> li + li {
|
|
20
|
+
margin-top: 0.5rem;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.el-popper__arrow::before {
|
|
25
|
+
background: #f3ecf6 !important;
|
|
26
|
+
border-color: $app-primary-color !important;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&[data-popper-placement^=bottom] .el-popper__arrow:before {
|
|
30
|
+
border-bottom-color: transparent !important;
|
|
31
|
+
border-right-color: transparent !important;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
code {
|
|
35
|
+
font-size: 90%;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.header {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
|
|
43
|
+
.el-button {
|
|
44
|
+
font-family: inherit;
|
|
45
|
+
|
|
46
|
+
&:hover,
|
|
47
|
+
&:focus {
|
|
48
|
+
background: $app-primary-color;
|
|
49
|
+
box-shadow: -3px 2px 4px #00000040;
|
|
50
|
+
color: #ffffff;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.help {
|
|
56
|
+
width: 24px !important;
|
|
57
|
+
height: 24px;
|
|
58
|
+
transform: scale(1.1);
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
color: #ffffff !important;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.search-input {
|
|
64
|
+
width: 298px !important;
|
|
65
|
+
height: 40px;
|
|
66
|
+
padding-right: 14px;
|
|
67
|
+
font-family: inherit;
|
|
68
|
+
|
|
69
|
+
:deep(.el-input__inner) {
|
|
70
|
+
font-family: inherit;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.search-input-container {
|
|
75
|
+
position: relative;
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
|
|
79
|
+
.map-icon {
|
|
80
|
+
position: absolute;
|
|
81
|
+
right: 18px;
|
|
82
|
+
color: $app-primary-color !important;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&.is-focus {
|
|
86
|
+
.map-icon {
|
|
87
|
+
display: none;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -646,6 +646,7 @@ export default {
|
|
|
646
646
|
</script>
|
|
647
647
|
|
|
648
648
|
<style lang="scss" scoped>
|
|
649
|
+
@import '../assets/searchPopover.scss';
|
|
649
650
|
@import '../assets/pagination.scss';
|
|
650
651
|
|
|
651
652
|
.connectivity-card {
|
|
@@ -700,51 +701,6 @@ export default {
|
|
|
700
701
|
}
|
|
701
702
|
}
|
|
702
703
|
|
|
703
|
-
.search-input {
|
|
704
|
-
width: 298px !important;
|
|
705
|
-
height: 40px;
|
|
706
|
-
padding-right: 14px;
|
|
707
|
-
font-family: inherit;
|
|
708
|
-
|
|
709
|
-
:deep(.el-input__inner) {
|
|
710
|
-
font-family: inherit;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
.search-input-container {
|
|
715
|
-
position: relative;
|
|
716
|
-
display: flex;
|
|
717
|
-
align-items: center;
|
|
718
|
-
|
|
719
|
-
.map-icon {
|
|
720
|
-
position: absolute;
|
|
721
|
-
right: 18px;
|
|
722
|
-
color: $app-primary-color !important;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
&.is-focus {
|
|
726
|
-
.map-icon {
|
|
727
|
-
display: none;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
.header {
|
|
733
|
-
display: flex;
|
|
734
|
-
align-items: center;
|
|
735
|
-
|
|
736
|
-
.el-button {
|
|
737
|
-
font-family: inherit;
|
|
738
|
-
|
|
739
|
-
&:hover,
|
|
740
|
-
&:focus {
|
|
741
|
-
background: $app-primary-color;
|
|
742
|
-
box-shadow: -3px 2px 4px #00000040;
|
|
743
|
-
color: #ffffff;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
704
|
.error-feedback {
|
|
749
705
|
font-family: Asap;
|
|
750
706
|
font-size: 14px;
|
|
@@ -864,35 +820,4 @@ export default {
|
|
|
864
820
|
}
|
|
865
821
|
}
|
|
866
822
|
|
|
867
|
-
.help {
|
|
868
|
-
width: 24px !important;
|
|
869
|
-
height: 24px;
|
|
870
|
-
transform: scale(1.1);
|
|
871
|
-
cursor: pointer;
|
|
872
|
-
color: #ffffff !important;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
.filter-help-popover {
|
|
876
|
-
font-family: 'Asap', sans-serif;
|
|
877
|
-
background: #f3ecf6 !important;
|
|
878
|
-
border: 1px solid $app-primary-color !important;
|
|
879
|
-
border-radius: 4px !important;
|
|
880
|
-
color: #303133 !important;
|
|
881
|
-
font-size: 12px !important;
|
|
882
|
-
line-height: 18px !important;
|
|
883
|
-
|
|
884
|
-
.el-popper__arrow::before {
|
|
885
|
-
background: #f3ecf6 !important;
|
|
886
|
-
border-color: $app-primary-color !important;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
&[data-popper-placement^=bottom] .el-popper__arrow:before {
|
|
890
|
-
border-bottom-color: transparent !important;
|
|
891
|
-
border-right-color: transparent !important;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
code {
|
|
895
|
-
font-size: 90%;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
823
|
</style>
|
|
@@ -2,14 +2,50 @@
|
|
|
2
2
|
<el-card :body-style="bodyStyle" class="content-card">
|
|
3
3
|
<template #header>
|
|
4
4
|
<div class="header">
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
<div class="search-input-container" :class="{'is-focus': searchInput}">
|
|
6
|
+
<el-input
|
|
7
|
+
class="search-input"
|
|
8
|
+
placeholder="Search"
|
|
9
|
+
v-model="searchInput"
|
|
10
|
+
@keyup="searchEvent"
|
|
11
|
+
clearable
|
|
12
|
+
@clear="clearSearchClicked"
|
|
13
|
+
></el-input>
|
|
14
|
+
<el-popover
|
|
15
|
+
width="350"
|
|
16
|
+
trigger="hover"
|
|
17
|
+
popper-class="filter-help-popover"
|
|
18
|
+
>
|
|
19
|
+
<template #reference>
|
|
20
|
+
<MapSvgIcon icon="help" class="help" />
|
|
21
|
+
</template>
|
|
22
|
+
<div>
|
|
23
|
+
<strong>Search rules:</strong>
|
|
24
|
+
<ul>
|
|
25
|
+
<li>
|
|
26
|
+
<strong>Multiple Terms:</strong> Separate terms with a comma (<code>,</code>).
|
|
27
|
+
This will find dataset that match any of the terms (an "OR" search).
|
|
28
|
+
</li>
|
|
29
|
+
<li>
|
|
30
|
+
<strong>Exact Phrase:</strong> Terms within a comma block will be matched as exact phrase.
|
|
31
|
+
</li>
|
|
32
|
+
</ul>
|
|
33
|
+
<br/>
|
|
34
|
+
<strong>Examples:</strong>
|
|
35
|
+
<ul>
|
|
36
|
+
<li>
|
|
37
|
+
<strong>To find by exact phrase:</strong>
|
|
38
|
+
Searching for <code>vagus nerve</code> will find any dataset containing <code>vagus nerve</code>.
|
|
39
|
+
</li>
|
|
40
|
+
<li>
|
|
41
|
+
<strong>To find by multiple terms:</strong>
|
|
42
|
+
Searching for <code>kidney, vagus</code> will find data that contains either <code>kidney</code> OR <code>vagus</code>.
|
|
43
|
+
Due to the limitation of the search engine, space between words in a comma block will be treated as comma when multiple terms search is active.
|
|
44
|
+
</li>
|
|
45
|
+
</ul>
|
|
46
|
+
</div>
|
|
47
|
+
</el-popover>
|
|
48
|
+
</div>
|
|
13
49
|
<el-button
|
|
14
50
|
type="primary"
|
|
15
51
|
class="button"
|
|
@@ -90,6 +126,7 @@ import EventBus from './EventBus.js'
|
|
|
90
126
|
import { AlgoliaClient } from '../algolia/algolia.js'
|
|
91
127
|
import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
|
|
92
128
|
import { markRaw } from 'vue'
|
|
129
|
+
import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
|
|
93
130
|
|
|
94
131
|
// handleErrors: A custom fetch error handler to recieve messages from the server
|
|
95
132
|
// even when an error is found
|
|
@@ -130,7 +167,9 @@ export default {
|
|
|
130
167
|
Drawer,
|
|
131
168
|
Icon,
|
|
132
169
|
Input,
|
|
133
|
-
Pagination
|
|
170
|
+
Pagination,
|
|
171
|
+
MapSvgIcon,
|
|
172
|
+
MapSvgSpriteColor
|
|
134
173
|
},
|
|
135
174
|
name: 'DatasetExplorer',
|
|
136
175
|
props: {
|
|
@@ -537,6 +576,7 @@ export default {
|
|
|
537
576
|
</script>
|
|
538
577
|
|
|
539
578
|
<style lang="scss" scoped>
|
|
579
|
+
@import '../assets/searchPopover.scss';
|
|
540
580
|
@import '../assets/pagination.scss';
|
|
541
581
|
|
|
542
582
|
.dataset-card {
|
|
@@ -577,29 +617,6 @@ export default {
|
|
|
577
617
|
text-align: left;
|
|
578
618
|
}
|
|
579
619
|
|
|
580
|
-
.search-input {
|
|
581
|
-
width: 298px !important;
|
|
582
|
-
height: 40px;
|
|
583
|
-
padding-right: 14px;
|
|
584
|
-
|
|
585
|
-
:deep(.el-input__inner) {
|
|
586
|
-
font-family: inherit;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
.header {
|
|
591
|
-
.el-button {
|
|
592
|
-
font-family: inherit;
|
|
593
|
-
|
|
594
|
-
&:hover,
|
|
595
|
-
&:focus {
|
|
596
|
-
background: $app-primary-color;
|
|
597
|
-
box-shadow: -3px 2px 4px #00000040;
|
|
598
|
-
color: #fff;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
620
|
.error-feedback {
|
|
604
621
|
font-family: Asap;
|
|
605
622
|
font-size: 14px;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
async function getReferenceConnectivitiesFromStorage(resource) {
|
|
2
|
-
const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge');
|
|
3
|
-
|
|
4
|
-
if (flatmapKnowledgeRaw) {
|
|
5
|
-
const flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw);
|
|
6
|
-
const dataWithRefs = flatmapKnowledge.filter((x) => x.references && x.references.length);
|
|
7
|
-
const foundData = dataWithRefs.filter((x) => x.references.includes(resource));
|
|
8
|
-
|
|
9
|
-
if (foundData.length) {
|
|
10
|
-
const featureIds = foundData.map((x) => x.id);
|
|
11
|
-
return featureIds;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function getReferenceConnectivitiesByAPI(mapImp, resource, flatmapQueries) {
|
|
18
|
-
const knowledgeSource = getKnowledgeSource(mapImp);
|
|
19
|
-
const sql = `select knowledge from knowledge
|
|
20
|
-
where source="${knowledgeSource}" and
|
|
21
|
-
knowledge like "%${resource}%" order by source desc`;
|
|
22
|
-
console.log(sql)
|
|
23
|
-
const response = await flatmapQueries.flatmapQuery(sql);
|
|
24
|
-
const mappedData = response.values.map((x) => x[0]);
|
|
25
|
-
const parsedData = mappedData.map((x) => JSON.parse(x));
|
|
26
|
-
const featureIds = parsedData.map((x) => x.id);
|
|
27
|
-
return featureIds;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getKnowledgeSource(mapImp) {
|
|
31
|
-
let mapKnowledgeSource = '';
|
|
32
|
-
if (mapImp.provenance?.connectivity) {
|
|
33
|
-
const sckanProvenance = mapImp.provenance.connectivity;
|
|
34
|
-
if ('knowledge-source' in sckanProvenance) {
|
|
35
|
-
mapKnowledgeSource = sckanProvenance['knowledge-source'];
|
|
36
|
-
} else if ('npo' in sckanProvenance) {
|
|
37
|
-
mapKnowledgeSource = `${sckanProvenance.npo.release}-npo`;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return mapKnowledgeSource;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function loadAndStoreKnowledge(mapImp, flatmapQueries) {
|
|
45
|
-
const knowledgeSource = getKnowledgeSource(mapImp);
|
|
46
|
-
const sql = `select knowledge from knowledge
|
|
47
|
-
where source="${knowledgeSource}"
|
|
48
|
-
order by source desc`;
|
|
49
|
-
const flatmapKnowledge = sessionStorage.getItem('flatmap-knowledge');
|
|
50
|
-
|
|
51
|
-
if (!flatmapKnowledge) {
|
|
52
|
-
flatmapQueries.flatmapQuery(sql).then((response) => {
|
|
53
|
-
const mappedData = response.values.map(x => x[0]);
|
|
54
|
-
const parsedData = mappedData.map(x => JSON.parse(x));
|
|
55
|
-
sessionStorage.setItem('flatmap-knowledge', JSON.stringify(parsedData));
|
|
56
|
-
updateFlatmapKnowledgeCache();
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function updateFlatmapKnowledgeCache() {
|
|
62
|
-
const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day
|
|
63
|
-
const now = new Date();
|
|
64
|
-
const expiry = now.getTime() + CACHE_LIFETIME;
|
|
65
|
-
|
|
66
|
-
sessionStorage.setItem('flatmap-knowledge-expiry', expiry);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function removeFlatmapKnowledgeCache() {
|
|
70
|
-
const keys = [
|
|
71
|
-
'flatmap-knowledge',
|
|
72
|
-
'flatmap-knowledge-expiry',
|
|
73
|
-
];
|
|
74
|
-
keys.forEach((key) => {
|
|
75
|
-
sessionStorage.removeItem(key);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function refreshFlatmapKnowledgeCache() {
|
|
80
|
-
const expiry = sessionStorage.getItem('flatmap-knowledge-expiry');
|
|
81
|
-
const now = new Date();
|
|
82
|
-
|
|
83
|
-
if (now.getTime() > expiry) {
|
|
84
|
-
removeFlatmapKnowledgeCache();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export {
|
|
89
|
-
getReferenceConnectivitiesFromStorage,
|
|
90
|
-
getReferenceConnectivitiesByAPI,
|
|
91
|
-
loadAndStoreKnowledge,
|
|
92
|
-
getKnowledgeSource,
|
|
93
|
-
refreshFlatmapKnowledgeCache,
|
|
94
|
-
}
|